Merge lp:~smspillaz/compiz-core/compiz-core.maximization into lp:compiz-core/0.9.5

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 2809
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.maximization
Merge into: lp:compiz-core/0.9.5
Diff against target: 279 lines (+177/-52)
1 file modified
src/window.cpp (+177/-52)
To merge this branch: bzr merge lp:~smspillaz/compiz-core/compiz-core.maximization
Reviewer Review Type Date Requested Status
Neil J. Patel (community) Approve
Review via email: mp+68135@code.launchpad.net

Description of the change

Tries to work around some of the problems in maximizing windows which must be larger than the available screen size.

The old behaviour was to try and position these windows so that they were never offscreen. That resulted in jumping windows. The new behaviour is to now remove CompWindowActionMaximize*Mask from wmActions if it is not possible to sanely maximize that window (for example, the output is too small). However, if there is another monitor that could accomadate the application specified window size then we will maximize to the closest possible monitor that can do that.

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :

On Sat, 16 Jul 2011 09:29:53 you wrote:
> Sam Spilsbury has proposed merging
> lp:~smspillaz/compiz-core/compiz-core.maximization into lp:compiz-core.

         int distance = 999999;

Please use std::numeric_limits<int>::max rather than the rather mystic
999999.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

On Mon, Jul 18, 2011 at 9:16 AM, Tim Penhey <email address hidden> wrote:
> On Sat, 16 Jul 2011 09:29:53 you wrote:
>> Sam Spilsbury has proposed merging
>> lp:~smspillaz/compiz-core/compiz-core.maximization into lp:compiz-core.
>
>         int        distance = 999999;
>
> Please use  std::numeric_limits<int>::max  rather than the rather mystic
> 999999.

Ah, didn't know that existed. Was looking for something to replace MAXINT

>
> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.maximization/+merge/68135
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.maximization.
>

--
Sam Spilsbury

2780. By Sam Spilsbury

Use std::numeric_limits <int>::max () rather than a constant

Revision history for this message
Marco Biscaro (marcobiscaro2112) wrote :

Sam, there is another 999999 (now, in height verification). I think it should be replaced to std::numeric_limits <int>::max (), right?

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Yes

On Tue, Jul 19, 2011 at 9:38 PM, Marco Biscaro
<email address hidden> wrote:
> Sam, there is another 999999 (now, in height verification). I think it should be replaced to std::numeric_limits <int>::max (), right?
> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.maximization/+merge/68135
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.maximization.
>

--
Sam Spilsbury

Revision history for this message
Neil J. Patel (njpatel) wrote :

Sam, please update the 999999 to what Tim suggests before merge, but apart from that it looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/window.cpp'
2--- src/window.cpp 2011-06-24 14:43:00 +0000
3+++ src/window.cpp 2011-07-18 06:31:20 +0000
4@@ -623,6 +623,32 @@
5 CompWindowActionMaximizeVertMask |
6 CompWindowActionFullscreenMask);
7
8+ /* Don't allow maximization or fullscreen
9+ * of windows which are too big to fit
10+ * the screen */
11+ bool foundVert = false;
12+ bool foundHorz = false;
13+
14+ foreach (CompOutput &o, screen->outputDevs ())
15+ {
16+ if (o.width () > (priv->sizeHints.min_width + priv->border.left + priv->border.right))
17+ foundHorz = true;
18+ if (o.height () > (priv->sizeHints.min_height + priv->border.top + priv->border.bottom))
19+ foundVert = true;
20+ }
21+
22+ if (!foundHorz)
23+ {
24+ actions &= ~(CompWindowActionMaximizeHorzMask |
25+ CompWindowActionFullscreenMask);
26+ }
27+
28+ if (!foundVert)
29+ {
30+ actions &= ~(CompWindowActionMaximizeVertMask |
31+ CompWindowActionFullscreenMask);
32+ }
33+
34 if (!(priv->mwmFunc & MwmFuncAll))
35 {
36 if (!(priv->mwmFunc & MwmFuncResize))
37@@ -2764,7 +2790,7 @@
38 CompRect workArea;
39 int mask = 0;
40 int x, y;
41- int output;
42+ CompOutput *output;
43 CompPoint viewport;
44
45 screen->viewportForGeometry (old, viewport);
46@@ -2772,8 +2798,80 @@
47 x = (viewport.x () - screen->vp ().x ()) * screen->width ();
48 y = (viewport.y () - screen->vp ().y ()) * screen->height ();
49
50- output = screen->outputDeviceForGeometry (old);
51- workArea = screen->getWorkareaForOutput (output);
52+ /* Try to select and output device that the window is on first
53+ * and make sure if we are fullscreening or maximizing that the
54+ * window is actually able to fit on this output ... otherwise
55+ * we're going to have to use another output device which sucks
56+ * but at least the user will be able to see all of the window */
57+ output = &screen->outputDevs ().at (screen->outputDeviceForGeometry (old));
58+
59+ if (state & CompWindowStateFullscreenMask ||
60+ state & CompWindowStateMaximizedHorzMask)
61+ {
62+ int width = (mask & CWWidth) ? xwc->width : old.width ();
63+ int height = (mask & CWHeight) ? xwc->height : old.height ();
64+
65+ window->constrainNewWindowSize (width, height, &width, &height);
66+
67+ if (width > output->width ())
68+ {
69+ int distance = std::numeric_limits <int>::max ();
70+ CompOutput *selected = output;
71+ /* That's no good ... try and find the closest output device to this one
72+ * which has a large enough size */
73+ foreach (CompOutput &o, screen->outputDevs ())
74+ {
75+ if (o.workArea ().width () > width)
76+ {
77+ int tDistance = sqrt (pow (abs (o.x () - output->x ()), 2) +
78+ pow (abs (o.y () - output->y ()), 2));
79+
80+ if (tDistance < distance)
81+ {
82+ selected = &o;
83+ tDistance = distance;
84+ }
85+ }
86+ }
87+
88+ output = selected;
89+ }
90+ }
91+
92+ if (state & CompWindowStateFullscreenMask ||
93+ state & CompWindowStateMaximizedVertMask)
94+ {
95+ int width = (mask & CWWidth) ? xwc->width : old.width ();
96+ int height = (mask & CWHeight) ? xwc->height : old.height ();
97+
98+ window->constrainNewWindowSize (width, height, &width, &height);
99+
100+ if (height > output->height ())
101+ {
102+ int distance = 999999;
103+ CompOutput *selected = output;
104+ /* That's no good ... try and find the closest output device to this one
105+ * which has a large enough size */
106+ foreach (CompOutput &o, screen->outputDevs ())
107+ {
108+ if (o.workArea ().height () > height)
109+ {
110+ int tDistance = sqrt (pow (abs (o.x () - output->x ()), 2) +
111+ pow (abs (o.y () - output->y ()), 2));
112+
113+ if (tDistance < distance)
114+ {
115+ selected = &o;
116+ tDistance = distance;
117+ }
118+ }
119+ }
120+
121+ output = selected;
122+ }
123+ }
124+
125+ workArea = output->workArea ();
126
127 if (type & CompWindowTypeFullscreenMask)
128 {
129@@ -2788,10 +2886,10 @@
130 }
131 else
132 {
133- xwc->x = x + screen->outputDevs ()[output].x ();
134- xwc->y = y + screen->outputDevs ()[output].y ();
135- xwc->width = screen->outputDevs ()[output].width ();
136- xwc->height = screen->outputDevs ()[output].height ();
137+ xwc->x = x + output->x ();
138+ xwc->y = y + output->y ();
139+ xwc->width = output->width ();
140+ xwc->height = output->height ();
141 }
142
143 xwc->border_width = 0;
144@@ -2801,7 +2899,6 @@
145 else
146 {
147 mask |= restoreGeometry (xwc, CWBorderWidth);
148-
149 if (state & CompWindowStateMaximizedVertMask)
150 {
151 saveGeometry (CWY | CWHeight);
152@@ -2888,55 +2985,83 @@
153
154 if (state & CompWindowStateMaximizedVertMask)
155 {
156- if (old.y () < y + workArea.y () + input.top)
157- {
158- xwc->y = y + workArea.y () + input.top;
159- mask |= CWY;
160- }
161- else
162- {
163- height = xwc->height + old.border () * 2;
164-
165- max = y + workArea.bottom ();
166- if (old.y () + (int) old.height () + input.bottom > max)
167- {
168- xwc->y = max - height - input.bottom;
169- mask |= CWY;
170- }
171- else if (old.y () + height + input.bottom > max)
172- {
173- xwc->y = y + workArea.y () +
174- (workArea.height () - input.top - height -
175- input.bottom) / 2 + input.top;
176- mask |= CWY;
177- }
178+ /* If the window is still offscreen, then we need to constrain it
179+ * by the gravity value (so that the corner that the gravity specifies
180+ * is 'anchored' to that edge of the workarea) */
181+
182+ xwc->y = y + workArea.y () + input.top;
183+ mask |= CWY;
184+
185+ switch (priv->sizeHints.win_gravity)
186+ {
187+ case SouthWestGravity:
188+ case SouthEastGravity:
189+ case SouthGravity:
190+ /* Shift the window so that the bottom meets the top of the bottom */
191+ height = xwc->height + old.border () * 2;
192+
193+ max = y + workArea.bottom ();
194+ if (xwc->y + xwc->height + input.bottom > max)
195+ {
196+ xwc->y = max - height - input.bottom;
197+ mask |= CWY;
198+ }
199+ break;
200+ /* For EastGravity, WestGravity and CenterGravity we default to the top
201+ * of the window since the user should at least be able to close it
202+ * (but not for SouthGravity, SouthWestGravity and SouthEastGravity since
203+ * that indicates that the application has requested positioning in that area
204+ */
205+ case EastGravity:
206+ case WestGravity:
207+ case CenterGravity:
208+ case NorthWestGravity:
209+ case NorthEastGravity:
210+ case NorthGravity:
211+ default:
212+ /* Shift the window so that the top meets the top of the screen */
213+ break;
214 }
215 }
216
217 if (state & CompWindowStateMaximizedHorzMask)
218 {
219- if (old.x () < x + workArea.x () + input.left)
220- {
221- xwc->x = x + workArea.x () + input.left;
222- mask |= CWX;
223- }
224- else
225- {
226- width = xwc->width + old.border () * 2;
227-
228- max = x + workArea.right ();
229- if (old.x () + (int) old.width () + input.right > max)
230- {
231- xwc->x = max - width - input.right;
232- mask |= CWX;
233- }
234- else if (old.x () + width + input.right > max)
235- {
236- xwc->x = x + workArea.x () +
237- (workArea.width () - input.left - width -
238- input.right) / 2 + input.left;
239- mask |= CWX;
240- }
241+ xwc->x = x + workArea.x () + input.left;
242+ mask |= CWX;
243+
244+ switch (priv->sizeHints.win_gravity)
245+ {
246+ case NorthEastGravity:
247+ case SouthEastGravity:
248+ case EastGravity:
249+ width = xwc->width + old.border () * 2;
250+
251+ max = x + workArea.right ();
252+ if (old.x () + (int) old.width () + input.right > max)
253+ {
254+ xwc->x = max - width - input.right;
255+ mask |= CWX;
256+ }
257+ else if (old.x () + width + input.right > max)
258+ {
259+ xwc->x = x + workArea.x () +
260+ (workArea.width () - input.left - width -
261+ input.right) / 2 + input.left;
262+ mask |= CWX;
263+ }
264+ /* For NorthGravity, SouthGravity and CenterGravity we default to the top
265+ * of the window since the user should at least be able to close it
266+ * (but not for SouthGravity, SouthWestGravity and SouthEastGravity since
267+ * that indicates that the application has requested positioning in that area
268+ */
269+ case NorthGravity:
270+ case SouthGravity:
271+ case CenterGravity:
272+ case NorthWestGravity:
273+ case SouthWestGravity:
274+ case WestGravity:
275+ default:
276+ break;
277 }
278 }
279 }

Subscribers

People subscribed via source and target branches