Merge lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces into lp:compiz/0.9.10

Proposed by MC Return
Status: Superseded
Proposed branch: lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces
Merge into: lp:compiz/0.9.10
Diff against target: 390 lines (+136/-35)
5 files modified
plugins/expo/src/expo.cpp (+6/-0)
plugins/grid/src/grid.cpp (+96/-34)
plugins/grid/src/grid.h (+2/-1)
plugins/move/src/move.cpp (+29/-0)
plugins/move/src/move.h (+3/-0)
To merge this branch: bzr merge lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces
Reviewer Review Type Date Requested Status
Sami Jaktholm (community) Approve
Compiz Maintainers Pending
Review via email: mp+156663@code.launchpad.net

This proposal has been superseded by a proposal from 2013-04-05.

Commit message

Grid:
Prevent top and bottom gridded windows from jumping viewports.

Those are actually semi-maximized horizontally, so we will treat
them as such and let core handle the restoring, just like we
already do for semi-maximized vertically grid windows (left/right).

Now "Strg+Super+Down" will restore top and bottom gridded windows
correctly as well.

Also multiple gridding to top, bottom, left or right will not
overwrite the stored original size anymore.

Restore windows also when workspace switcher is active.
(Thanks and credits for this go to Sami Jaktholm)

Expo:
Tell grid when viewport change is in progress.
(Thanks and credits for this go to Sami Jaktholm)

Move:
Implemented strategy to snap off horizontally semi-maximized
windows by dragging the titlebar in direction of the x-axis.

(fixes: LP: #1082001, LP: #1165198)
(partially fixes: LP: #1116538, LP: #1164332)

Description of the change

Note: Problems unfortunately remain for corner- and center-gridded windows...

Any ideas ?

To post a comment you must log in.
Revision history for this message
MC Return (mc-return) wrote :

Ping ?

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

Hey, I'm pretty busy at the moment. I'll get on to this ASAP.

On Thu, Apr 4, 2013 at 12:11 PM, MC Return <email address hidden> wrote:
> Ping ?
> --
> https://code.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/+merge/156663
> Your team Compiz Maintainers is requested to review the proposed merge of lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces into lp:compiz.

--
Sam Spilsbury

Revision history for this message
MC Return (mc-return) wrote :

> Hey, I'm pretty busy at the moment. I'll get on to this ASAP.
>
Please take your time. I am honestly sorry for stressing.
I am just so excited that this MP already fixes 3 IMHO important
Grid usability bugs and so I was curious about your opinion... ;)

I will continue to work on it in the meantime, because I am
confident now that I am able to fully fix the bugs linked here...

Once all the bugs are fixed, I want to continue with optimization
of the logic and splitting out the various codeparts into separate
functions... - but this should probably be made in a separate MP
as this diff is already large enough, which complicates your review
effort (I am sorry for that)...

I can only ensure you that all changes are tested well and extensively
and manually by myself, which reduces the risk of errors or regressions
slipping through undetected ->
http://bazaar.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/revision/3648
is an example for this ;)

Hope that I have all Grid bugs fixed, once you get to the review ;)

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

Some thoughts:
1) Top or bottom gridded windows can't be restored by dragging. The window does move up and down but doesn't snap off without pressing restore button/key (seems to be the default behavior for horizontally maximized windows).
2) Code duplication for GridTop || GridBottom case in initiateCommon. This could go like:
    if Top || Bottom || Left || Right
      *restore original geometry and change sizeHints*
      Resized = false

      if Top || Bottom
         maximize(HorzMask)
         HorzMaximized = true
         VertMaximized = false
      else
         maximize(VertMask)
         HorzMaximized = false
         VertMaximized = true

3) The easiest solution to fix bug 1082001 is to make expo send start/end_viewport_switch event at the start/end of viewport switch. Grid listens for those events and knows not to block the window movement while viewport switch is in progress. Currently only wall and rotate are emitting those events although expo and cube are also triggering viewport switches (so cube might need the change too).

The first point definitely needs fixing, the second one is just an opinion...

review: Needs Fixing
Revision history for this message
MC Return (mc-return) wrote :

Hey sampo555 :)
Thanks a lot 4 your review, it is very appreciated.

> Some thoughts:
> 1) Top or bottom gridded windows can't be restored by dragging. The window
> does move up and down but doesn't snap off without pressing restore button/key
> (seems to be the default behavior for horizontally maximized windows).
>

I did not notice that problem, because on multimonitor systems it snaps off, once
your pointer crosses monitors when dragging.
I also have "Rotate Cube"->"Edge Flip DnD" enabled, which makes the top/bottom
gridded window restore as well.

But of course this should be no excuse. I'll try to find the problem and fix it.

> 2) Code duplication for GridTop || GridBottom case in initiateCommon. This
> could go like:
> if Top || Bottom || Left || Right
> *restore original geometry and change sizeHints*
> Resized = false
>
> if Top || Bottom
> maximize(HorzMask)
> HorzMaximized = true
> VertMaximized = false
> else
> maximize(VertMask)
> HorzMaximized = false
> VertMaximized = true
>

Yes. Will fix that also (was already on the TODO list).

> 3) The easiest solution to fix bug 1082001 is to make expo send
> start/end_viewport_switch event at the start/end of viewport switch. Grid
> listens for those events and knows not to block the window movement while
> viewport switch is in progress. Currently only wall and rotate are emitting
> those events although expo and cube are also triggering viewport switches (so
> cube might need the change too).
>

Very good observation. Actually awesome, sounds like the key to the solution. \o/
I still was unsure about the best way to approach the problem...
I think I'll have to conduct some experiments with that...

> The first point definitely needs fixing, the second one is just an opinion...
>

All of your points are valid and your review is very welcome.
They'll all get fixed ;).

sampo555, thanks for your involvement with Compiz.
I hope to see some new MPs from you soon...

P.S.: I'll change the status of this MP to "WIP", but additional comments are
always welcome...

Revision history for this message
MC Return (mc-return) wrote :

@sampo55:
Did some experiments with making expo send the start/end_viewport_switch event at the start/end of viewport switch, but I was not able to get it right :(
The main new problem I got by doing that, was that Expo drag-and-dropping windows failed to work once Expo announces start_viewport_switch...
I am quite clueless @ the moment, so if you have a working solution or did experiments yourself, please propose a MP, so we can test it...

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

I don't have any code to show as I just checked what wall did but expo didn't. As DnD fails, I assume you're emitting those events right when expo starts/quits(?). If you emit the events only when expo calls moveViewport, it shouldn't affect DnD windows (emitting those events equals to situation without grid). So something like this could work:
  screen->handleCompizEvent ("expo","start_viewport_switch", CompOption::Vector());
  screen->moveViewport(...)
  screen->handleCompizEvent ("expo","end_viewport_switch", CompOption::Vector());

I don't have time to test it right now, but I can try it later...

Revision history for this message
MC Return (mc-return) wrote :

> I don't have any code to show as I just checked what wall did but expo didn't.
> As DnD fails, I assume you're emitting those events right when expo
> starts/quits(?). If you emit the events only when expo calls moveViewport, it
> shouldn't affect DnD windows (emitting those events equals to situation
> without grid). So something like this could work:
> screen->handleCompizEvent ("expo","start_viewport_switch",
> CompOption::Vector());
> screen->moveViewport(...)
> screen->handleCompizEvent ("expo","end_viewport_switch",
> CompOption::Vector());
>
> I don't have time to test it right now, but I can try it later...

Yeah - that might indeed be the problem. I'll try that and will report here...
Thanks 4 your involvement, sampo555 - and sorry for spelling your synonym
incorrectly before ;)

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

That seems to work, but there's still a problem as gridded windows (corners) can't be dragged anywhere in expo (also present in the current trunk). That's because grid ignores the fact that window is dragged in expo (for valid reasons) but still stops the window from moving.

Seems a bit tricky to get this one right :)

Revision history for this message
MC Return (mc-return) wrote :

> That seems to work, but there's still a problem as gridded windows (corners)
> can't be dragged anywhere in expo (also present in the current trunk). That's
> because grid ignores the fact that window is dragged in expo (for valid
> reasons) but still stops the window from moving.
>
> Seems a bit tricky to get this one right :)

Hehe, tricky describes it perfectly ;)
It would really be nice if you could propose the expo/cube code, as I did just get
to the point, where gridded corner windows do not jump viewports anymore, but I am
not able to drag any window in expo mode currently, which is ofc inacceptable...

Other observations:
In trunk it is currently possible to drag and drop corner-gridded windows in expo,
just dragging itself is not animated and the window disappears in one viewport and
suddenly pops up in the viewport it is dragged to once you release the mousebutton...

But on multimonitor systems it is not possible to drag the same windows from one
screen to the other, just from viewport to viewport...

Revision history for this message
MC Return (mc-return) wrote :

One other point:
Seems the cube does not need any changes, as just rotate cube seems to be responsible
for moving windows...
If you unfold the cube (which is a cube option) and change workspace corner-gridded
windows stay in their position, so it seems no fix is needed here...

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

It seems to be very tricky to restore the gridded window inside expo. We can't use pointer location to calculate the restored position as it's absolute to the screen, not relative to expo viewport. We also can't restore it to original location as it might jump anywhere.

So there's pretty much two solutions:
1) Restore the window in place. Problem: the restored window might detach from the pointer, if the it's smaller than the gridded window (depending on where user grabs the window). This can't be easily solved as we don't know where the pointer is relative to the window.
2) Don't restore the window. If the window is moved inside expo, just forgot that it's gridded. This is less likely to cause any issues but it's not consistent with rest of grid behavior or nice thing to do to the user (I wouldn't like it).

Personally I like the first one more as it has a chance to get it right at least some times. The second option just feels a little broken. Anyways, an implementation of the first option can be found from lp:~sjakthol/compiz/grid-expo-interaction. Please test it, and if you think it's good, you can merge it to your branch and start debugging those horizontally maximized windows.

(I'm still the same guy - just did some profile reconfiguration)

Revision history for this message
MC Return (mc-return) wrote :

> It seems to be very tricky to restore the gridded window inside expo. We can't
> use pointer location to calculate the restored position as it's absolute to
> the screen, not relative to expo viewport. We also can't restore it to
> original location as it might jump anywhere.
>
> So there's pretty much two solutions:
> 1) Restore the window in place. Problem: the restored window might detach from
> the pointer, if the it's smaller than the gridded window (depending on where
> user grabs the window). This can't be easily solved as we don't know where the
> pointer is relative to the window.
> 2) Don't restore the window. If the window is moved inside expo, just forgot
> that it's gridded. This is less likely to cause any issues but it's not
> consistent with rest of grid behavior or nice thing to do to the user (I
> wouldn't like it).
>
> Personally I like the first one more as it has a chance to get it right at
> least some times. The second option just feels a little broken. Anyways, an
> implementation of the first option can be found from lp:~sjakthol/compiz/grid-
> expo-interaction. Please test it, and if you think it's good, you can merge it
> to your branch and start debugging those horizontally maximized windows.
>
> (I'm still the same guy - just did some profile reconfiguration)

Hi, Sami Jaktholm :)

I've tested your branch now and this looks like another big improvement to me.
Everything works exactly like you described. Top job !

I also think that the solution you found is our best bet at the moment and it
will still affect just corner- and center-gridded windows to restore to original
size when dragged inside expo.

This solution is just slightly inconsistent, compared to the behaviour of grid-
semi-maximized and maximized windows, which will keep their size when dragged to
a new viewport - but it is 100 times better than the version we have in trunk now,
which also acts inconsistent and makes gridded windows jump around and follow the
user's moves in expo...

Restoring the window to original size is always the best solution, because gridding
it back requires just one shortcut, while it can be nerving to have to manually resize
to get back to original size.
Btw, there is still a working workaround for users, who want to move a corner- or center-
gridded window from one workspace to another (rotate to cube face with window) - this
one works perfectly for gridded windows as well...

I still have to apply your other improvements here, and still have to find a solution
for snapping off horizontally maximized windows correctly and easily...

Revision history for this message
MC Return (mc-return) wrote :

> Some thoughts:
> 1) Top or bottom gridded windows can't be restored by dragging. The window
> does move up and down but doesn't snap off without pressing restore button/key
> (seems to be the default behavior for horizontally maximized windows).

Yes. The problem is actually hidden in the move plugin. The option SnapoffMaximized ()
does not take care of & CompWindowStateMaximizedHorzMask windows.

You can easily check this wrong behaviour by horizontally maximizing a window by
right-mousebutton clicking the maximize button and you'll get the same behaviour
like for top and bottom gridded windows with this branch here...

Actually I should file another bug and fix that in another branch I guess, but I
do not know, maybe I'll simply attach another bug report here...

Revision history for this message
MC Return (mc-return) wrote :

I have now filed bug #1165198 about "Horizontally semi-maximized windows do not snap off easily"...

@Sami Jaktholm: Can you confirm ?

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

A second branch might be a better solution. Let's keep this as a fix for grid&expo problem only. Once the other fix lands, I'm ok with this (although I'm probably not the best judge as I have very narrow understanding of how this stuff actually works).

review: Approve
Revision history for this message
MC Return (mc-return) wrote :

> A second branch might be a better solution. Let's keep this as a fix for
> grid&expo problem only. Once the other fix lands, I'm ok with this (although
> I'm probably not the best judge as I have very narrow understanding of how
> this stuff actually works).

Okay. The fix for the move snapoff problem should be relatively easy. I already
got a working solution (just a quick hack), but I am confident I can fix this
correctly soonish...

If you are interested: the problem is hidden in static void moveHandleMotionEvent (...)

There:
if (ms->optionGetSnapoffMaximized ())
does not check:
if (w->state () & CompWindowStateMaximizedHorzMask)

and thus Compiz has no strategy to snap off a horizontally semi-maximized window...

Revision history for this message
MC Return (mc-return) wrote :

> A second branch might be a better solution. Let's keep this as a fix for
> grid&expo problem only. Once the other fix lands, I'm ok with this (although
> I'm probably not the best judge as I have very narrow understanding of how
> this stuff actually works).

I've uploaded the fix for bug #1165198 to this branch now anyway as it is somehow
related and is very separated fromthe rest (as the fix is in the move plugin).

Re-review and re-test needed ;)

3653. By MC Return

Grid:
Forbid cycling through different sizes for corner and center-gridded
windows also, now fully fixing bug #878820 and following the design
specification for now

TODO: Make the behaviour configurable for the user as many prefer
cycling through different sizes

Added comment
Minor whitespace fixes
Declare CompOutput out and assign a value to it in one line

3654. By MC Return

Simplified the condition check to bail out if the last target was the
same like the current one to prevent corner and centered windows from
cycling through sizes

3655. By MC Return

plugins/grid/grid.xml.in:

Added cycle_sizes bool option, which allows the user to choose the
prefered behaviour (fixed versus flexible sizes on multiple presses
 on the same grid keyboard shortcut)
Default of this option is off, cycling disabled as specified by design

Added punctuation where missing and removed it where usually is none
Fixed typos, improved description and titles

grid:

Allow cycling for corner/center gridded windows if specified by the
user

3656. By MC Return

Allow cycling through different sizes for top/bottom and left/right
gridded windows as well, if the user specified it in CCSM explicitely
(default is off)

3657. By MC Return

Reverted r3652 as this change to the move plugin is not tightly related
to this branch and thus will be proposed seperately to reduce diff size
here

3658. By MC Return

Grid:
We want to use the same functionality like the unmaximize_or_minimize_window
shortcut normally provides, so if our window has not been touched by grid, we
will do the same with that window that core would normally do
(see src/actions.cpp, unmaximizeOrMinimizeWin and
 launchpad bug LP: #1116538 for details)

Note: If we use the same shortcut for unmaximize_or_minimize_window_key (core)
and put_restore_key (grid) core will take over again, if grid gets disabled
If grid is enabled the unmaximize_or_minimize_window_key will be overridden,
because core always loads first and grid later

Also note that this commit did not change any shortcut yet, but just provides
the functionality for grid - Please use your grid restore keybinding like you
would use the unmaximize_or_minimize_window_key normally to test

3659. By MC Return

Grid xml:
Improved tooltip for the "put_restore_key" reflecting it's enhanced
functionality.

3660. By MC Return

Merged Grid from latest lp:compiz

Simplified bool GridScreen::restoreWindow (...):
If Grid has not touched the window we return false and let core do the
dirty work (Thanks go to Sam Spilsbury for suggesting this)

Improved the CCSM grid restore tooltip

3661. By MC Return

Merged latest lp:compiz

Unmerged revisions

3661. By MC Return

Merged latest lp:compiz

3660. By MC Return

Merged Grid from latest lp:compiz

Simplified bool GridScreen::restoreWindow (...):
If Grid has not touched the window we return false and let core do the
dirty work (Thanks go to Sam Spilsbury for suggesting this)

Improved the CCSM grid restore tooltip

3659. By MC Return

Grid xml:
Improved tooltip for the "put_restore_key" reflecting it's enhanced
functionality.

3658. By MC Return

Grid:
We want to use the same functionality like the unmaximize_or_minimize_window
shortcut normally provides, so if our window has not been touched by grid, we
will do the same with that window that core would normally do
(see src/actions.cpp, unmaximizeOrMinimizeWin and
 launchpad bug LP: #1116538 for details)

Note: If we use the same shortcut for unmaximize_or_minimize_window_key (core)
and put_restore_key (grid) core will take over again, if grid gets disabled
If grid is enabled the unmaximize_or_minimize_window_key will be overridden,
because core always loads first and grid later

Also note that this commit did not change any shortcut yet, but just provides
the functionality for grid - Please use your grid restore keybinding like you
would use the unmaximize_or_minimize_window_key normally to test

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/expo/src/expo.cpp'
--- plugins/expo/src/expo.cpp 2013-03-26 22:02:39 +0000
+++ plugins/expo/src/expo.cpp 2013-04-05 21:36:18 +0000
@@ -247,10 +247,13 @@
247void247void
248ExpoScreen::finishWindowMovement ()248ExpoScreen::finishWindowMovement ()
249{249{
250 CompOption::Vector o(0);
250 dndWindow->ungrabNotify ();251 dndWindow->ungrabNotify ();
251252
253 screen->handleCompizEvent ("expo", "start_viewport_switch", o);
252 screen->moveViewport (screen->vp ().x () - selectedVp.x (),254 screen->moveViewport (screen->vp ().x () - selectedVp.x (),
253 screen->vp ().y () - selectedVp.y (), true);255 screen->vp ().y () - selectedVp.y (), true);
256 screen->handleCompizEvent ("expo", "end_viewport_switch", o);
254257
255 /* update saved window attributes in case we moved the258 /* update saved window attributes in case we moved the
256 window to a new viewport */259 window to a new viewport */
@@ -486,6 +489,8 @@
486void489void
487ExpoScreen::donePaint ()490ExpoScreen::donePaint ()
488{491{
492 CompOption::Vector o(0);
493 screen->handleCompizEvent ("expo", "start_viewport_switch", o);
489 switch (vpUpdateMode) {494 switch (vpUpdateMode) {
490 case VPUpdateMouseOver:495 case VPUpdateMouseOver:
491 screen->moveViewport (screen->vp ().x () - selectedVp.x (),496 screen->moveViewport (screen->vp ().x () - selectedVp.x (),
@@ -504,6 +509,7 @@
504 default:509 default:
505 break;510 break;
506 }511 }
512 screen->handleCompizEvent ("expo", "end_viewport_switch", o);
507513
508 if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone)514 if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone)
509 cScreen->damageScreen ();515 cScreen->damageScreen ();
510516
=== modified file 'plugins/grid/src/grid.cpp'
--- plugins/grid/src/grid.cpp 2013-03-22 11:58:33 +0000
+++ plugins/grid/src/grid.cpp 2013-04-05 21:36:18 +0000
@@ -63,7 +63,6 @@
63 const CompRect& slot)63 const CompRect& slot)
64{64{
65 int cw, ch;65 int cw, ch;
66
67 CompRect result = slotToRect (w, slot);66 CompRect result = slotToRect (w, slot);
6867
69 if (w->constrainNewWindowSize (result.width (), result.height (), &cw, &ch))68 if (w->constrainNewWindowSize (result.width (), result.height (), &cw, &ch))
@@ -169,17 +168,15 @@
169 if (props.numCellsX == 1)168 if (props.numCellsX == 1)
170 centerCheck = true;169 centerCheck = true;
171170
172 if (!gw->isGridResized)171 if (!gw->isGridResized && !gw->isGridHorzMaximized && !gw->isGridVertMaximized)
173 /* Store size not including borders when using a keybinding */172 /* Store size not including borders when using a keybinding */
174 gw->originalSize = slotToRect(cw, cw->serverBorderRect ());173 gw->originalSize = slotToRect(cw, cw->serverBorderRect ());
175 }174 }
176175
177 if ((cw->state () & MAXIMIZE_STATE) &&176 if ((cw->state () & MAXIMIZE_STATE) &&
178 (resize || optionGetSnapoffMaximized ()))177 (resize || optionGetSnapoffMaximized ()))
179 {
180 /* maximized state interferes with us, clear it */178 /* maximized state interferes with us, clear it */
181 cw->maximize (0);179 cw->maximize (0);
182 }
183180
184 if ((where & GridMaximize) && resize)181 if ((where & GridMaximize) && resize)
185 {182 {
@@ -198,7 +195,9 @@
198 * gridded one.195 * gridded one.
199 */196 */
200 gw->isGridResized = false;197 gw->isGridResized = false;
201 gw->isGridSemiMaximized = false;198 gw->isGridHorzMaximized = false;
199 gw->isGridVertMaximized = false;
200
202 for (unsigned int i = 0; i < animations.size (); i++)201 for (unsigned int i = 0; i < animations.size (); i++)
203 animations.at (i).fadingOut = true;202 animations.at (i).fadingOut = true;
204 return true;203 return true;
@@ -220,7 +219,8 @@
220 desiredSlot.setWidth (workarea.width () / props.numCellsX);219 desiredSlot.setWidth (workarea.width () / props.numCellsX);
221220
222 /* Adjust for constraints and decorations */221 /* Adjust for constraints and decorations */
223 if (where & ~(GridMaximize | GridLeft | GridRight))222 if (where & ~(GridMaximize |
223 GridLeft | GridRight | GridTop | GridBottom))
224 desiredRect = constrainSize (cw, desiredSlot);224 desiredRect = constrainSize (cw, desiredSlot);
225 else225 else
226 desiredRect = slotToRect (cw, desiredSlot);226 desiredRect = slotToRect (cw, desiredSlot);
@@ -232,7 +232,9 @@
232232
233 if (desiredRect.y () == currentRect.y () &&233 if (desiredRect.y () == currentRect.y () &&
234 desiredRect.height () == currentRect.height () &&234 desiredRect.height () == currentRect.height () &&
235 where & ~(GridMaximize | GridLeft | GridRight) && gw->lastTarget & where)235 where & ~(GridMaximize |
236 GridLeft | GridRight | GridTop | GridBottom) &&
237 gw->lastTarget & where)
236 {238 {
237 int slotWidth25 = workarea.width () / 4;239 int slotWidth25 = workarea.width () / 4;
238 int slotWidth33 = (workarea.width () / 3) + cw->border ().left;240 int slotWidth33 = (workarea.width () / 3) + cw->border ().left;
@@ -352,9 +354,11 @@
352354
353 gw->sizeHintsFlags = 0;355 gw->sizeHintsFlags = 0;
354356
355 /* Special case for left and right, actually vertically maximize357 /* Special cases for left/right and top/bottom gridded windows, where we
356 * the window */358 * actually vertically respective horizontally semi-maximize the window
357 if (where & GridLeft || where & GridRight)359 */
360 if (where & GridLeft || where & GridRight ||
361 where & GridTop || where & GridBottom)
358 {362 {
359 /* First restore the window to its original size */363 /* First restore the window to its original size */
360 XWindowChanges rwc;364 XWindowChanges rwc;
@@ -366,11 +370,24 @@
366370
367 cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &rwc);371 cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &rwc);
368372
369 gw->isGridSemiMaximized = true;373 if (where & GridLeft || where & GridRight)
370 gw->isGridResized = false;374 {
371375 gw->isGridVertMaximized = true;
372 /* Maximize the window */376 gw->isGridHorzMaximized = false;
373 cw->maximize (CompWindowStateMaximizedVertMask);377 gw->isGridResized = false;
378
379 /* Semi-maximize the window vertically */
380 cw->maximize (CompWindowStateMaximizedVertMask);
381 }
382 else /* GridTop || GridBottom */
383 {
384 gw->isGridHorzMaximized = true;
385 gw->isGridVertMaximized = false;
386 gw->isGridResized = false;
387
388 /* Semi-maximize the window horizontally */
389 cw->maximize (CompWindowStateMaximizedHorzMask);
390 }
374391
375 /* Be evil */392 /* Be evil */
376 if (cw->sizeHints ().flags & PResizeInc)393 if (cw->sizeHints ().flags & PResizeInc)
@@ -379,10 +396,11 @@
379 gw->window->sizeHints ().flags &= ~(PResizeInc);396 gw->window->sizeHints ().flags &= ~(PResizeInc);
380 }397 }
381 }398 }
382 else399 else /* GridCorners || GridCenter */
383 {400 {
384 gw->isGridResized = true;401 gw->isGridResized = true;
385 gw->isGridSemiMaximized = false;402 gw->isGridHorzMaximized = false;
403 gw->isGridVertMaximized = false;
386 }404 }
387405
388 int dw = (lastBorder.left + lastBorder.right) -406 int dw = (lastBorder.left + lastBorder.right) -
@@ -843,8 +861,8 @@
843861
844 /* Don't allow non-pagers to change862 /* Don't allow non-pagers to change
845 * the size of the window, the user863 * the size of the window, the user
846 * specified this size, thank-you */864 * specified this size */
847 if (isGridSemiMaximized)865 if (isGridHorzMaximized || isGridVertMaximized)
848 if (source != ClientTypePager)866 if (source != ClientTypePager)
849 xwcm = 0;867 xwcm = 0;
850}868}
@@ -868,7 +886,10 @@
868 pointerBufDx = pointerBufDy = 0;886 pointerBufDx = pointerBufDy = 0;
869 grabMask = mask;887 grabMask = mask;
870888
871 if (!isGridResized && !isGridSemiMaximized && gScreen->optionGetSnapbackWindows ())889 if (!isGridResized &&
890 !isGridHorzMaximized &&
891 !isGridVertMaximized &&
892 gScreen->optionGetSnapbackWindows ())
872 /* Store size not including borders when grabbing with cursor */893 /* Store size not including borders when grabbing with cursor */
873 originalSize = gScreen->slotToRect(window,894 originalSize = gScreen->slotToRect(window,
874 window->serverBorderRect ());895 window->serverBorderRect ());
@@ -909,8 +930,18 @@
909{930{
910 window->moveNotify (dx, dy, immediate);931 window->moveNotify (dx, dy, immediate);
911932
912 if (isGridResized && !isGridSemiMaximized && !GridScreen::get (screen)->mSwitchingVp)933 if (isGridResized &&
934 !isGridHorzMaximized &&
935 !isGridVertMaximized &&
936 !GridScreen::get (screen)->mSwitchingVp)
913 {937 {
938 if (window->grabbed () && screen->grabExist ("expo"))
939 {
940 /* Window is being dragged in expo. Restore the original geometry
941 * right away to avoid any confusion. */
942 gScreen->restoreWindow (0, 0, gScreen->o);
943 return;
944 }
914 if (window->grabbed () && (grabMask & CompWindowGrabMoveMask))945 if (window->grabbed () && (grabMask & CompWindowGrabMoveMask))
915 {946 {
916 pointerBufDx += dx;947 pointerBufDx += dx;
@@ -933,7 +964,10 @@
933 !(window->state () & MAXIMIZE_STATE))964 !(window->state () & MAXIMIZE_STATE))
934 {965 {
935 lastTarget = GridUnknown;966 lastTarget = GridUnknown;
936 if (isGridSemiMaximized && (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedVertMask)967 if ((isGridHorzMaximized &&
968 (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedHorzMask) ||
969 (isGridVertMaximized &&
970 (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedVertMask))
937 gScreen->restoreWindow(0, 0, gScreen->o);971 gScreen->restoreWindow(0, 0, gScreen->o);
938 }972 }
939 else if (!(lastState & MAXIMIZE_STATE) &&973 else if (!(lastState & MAXIMIZE_STATE) &&
@@ -969,7 +1003,9 @@
9691003
970 GRID_WINDOW (cw);1004 GRID_WINDOW (cw);
9711005
972 if (!gw->isGridResized && !gw->isGridSemiMaximized)1006 if (!gw->isGridResized &&
1007 !gw->isGridHorzMaximized &&
1008 !gw->isGridVertMaximized)
973 {1009 {
974 /* Grid hasn't touched this window or has maximized it. If it's1010 /* Grid hasn't touched this window or has maximized it. If it's
975 * maximized, unmaximize it and get out. */1011 * maximized, unmaximize it and get out. */
@@ -977,25 +1013,38 @@
977 cw->maximize(0);1013 cw->maximize(0);
978 return true;1014 return true;
979 }1015 }
9801016 else if (!gw->isGridResized &&
981 else if (!gw->isGridResized && gw->isGridSemiMaximized)1017 gw->isGridHorzMaximized &&
1018 !gw->isGridVertMaximized)
1019 {
1020 /* Window has been horizontally maximized by grid. We only need
1021 * to restore Y and height - core handles X and width. */
1022 if (gw->sizeHintsFlags)
1023 gw->window->sizeHints ().flags |= gw->sizeHintsFlags;
1024 xwcm |= CWY | CWHeight;
1025 }
1026 else if (!gw->isGridResized &&
1027 !gw->isGridHorzMaximized &&
1028 gw->isGridVertMaximized)
982 {1029 {
983 /* Window has been vertically maximized by grid. We only need1030 /* Window has been vertically maximized by grid. We only need
984 * to restore the X and width - core handles Y and height. */1031 * to restore X and width - core handles Y and height. */
985 if (gw->sizeHintsFlags)1032 if (gw->sizeHintsFlags)
986 gw->window->sizeHints ().flags |= gw->sizeHintsFlags;1033 gw->window->sizeHints ().flags |= gw->sizeHintsFlags;
987 xwcm |= CWX | CWWidth;1034 xwcm |= CWX | CWWidth;
988 }1035 }
9891036 else if (gw->isGridResized &&
990 else if (gw->isGridResized && !gw->isGridSemiMaximized)1037 !gw->isGridHorzMaximized &&
991 /* Window is just gridded (top, bottom, center, corners). We1038 !gw->isGridVertMaximized)
992 * need to handle everything. */1039 /* Window is just gridded (center, corners).
1040 * We need to handle everything. */
993 xwcm |= CWX | CWY | CWWidth | CWHeight;1041 xwcm |= CWX | CWY | CWWidth | CWHeight;
994 else1042 else
995 {1043 {
996 /* This should never happen. But if it does, just bail out1044 /* This should never happen. But if it does, just bail out
997 * gracefully. */1045 * gracefully. */
998 assert (gw->isGridResized && gw->isGridSemiMaximized);1046 assert (gw->isGridResized &&
1047 (gw->isGridHorzMaximized || gw->isGridVertMaximized));
999 return false;1048 return false;
1000 }1049 }
10011050
@@ -1004,6 +1053,16 @@
1004 xwc.x = pointerX - (gw->originalSize.width () / 2);1053 xwc.x = pointerX - (gw->originalSize.width () / 2);
1005 xwc.y = pointerY + (cw->border ().top / 2);1054 xwc.y = pointerY + (cw->border ().top / 2);
1006 }1055 }
1056 else if (cw->grabbed () && screen->grabExist ("expo"))
1057 {
1058 /* We're restoring a window inside expo by dragging. This is a bit
1059 * tricky. Pointer location is absolute to the screen, not relative
1060 * to expo viewport. So we can't use pointer location to calculate
1061 * the position of the restore window.
1062 *
1063 * The best solution is to resize it in place. */
1064 xwcm = CWWidth | CWHeight;
1065 }
1007 else1066 else
1008 {1067 {
1009 xwc.x = gw->originalSize.x ();1068 xwc.x = gw->originalSize.x ();
@@ -1018,7 +1077,8 @@
1018 gw->currentSize = CompRect ();1077 gw->currentSize = CompRect ();
1019 gw->pointerBufDx = 0;1078 gw->pointerBufDx = 0;
1020 gw->pointerBufDy = 0;1079 gw->pointerBufDy = 0;
1021 gw->isGridSemiMaximized = false;1080 gw->isGridHorzMaximized = false;
1081 gw->isGridVertMaximized = false;
1022 gw->isGridResized = false;1082 gw->isGridResized = false;
1023 if (cw->state () & MAXIMIZE_STATE)1083 if (cw->state () & MAXIMIZE_STATE)
1024 cw->maximize(0);1084 cw->maximize(0);
@@ -1035,7 +1095,8 @@
1035 GRID_WINDOW (screen->findWindow1095 GRID_WINDOW (screen->findWindow
1036 (CompOption::getIntOptionNamed (o, "window")));1096 (CompOption::getIntOptionNamed (o, "window")));
1037 gw->isGridResized = false;1097 gw->isGridResized = false;
1038 gw->isGridSemiMaximized = false;1098 gw->isGridHorzMaximized = false;
1099 gw->isGridVertMaximized = false;
1039 gw->resizeCount = 0;1100 gw->resizeCount = 0;
1040}1101}
10411102
@@ -1197,7 +1258,8 @@
1197 gWindow (GLWindow::get(window)),1258 gWindow (GLWindow::get(window)),
1198 gScreen (GridScreen::get (screen)),1259 gScreen (GridScreen::get (screen)),
1199 isGridResized (false),1260 isGridResized (false),
1200 isGridSemiMaximized (false),1261 isGridHorzMaximized (false),
1262 isGridVertMaximized (false),
1201 grabMask (0),1263 grabMask (0),
1202 pointerBufDx (0),1264 pointerBufDx (0),
1203 pointerBufDy (0),1265 pointerBufDy (0),
12041266
=== modified file 'plugins/grid/src/grid.h'
--- plugins/grid/src/grid.h 2013-01-21 15:17:50 +0000
+++ plugins/grid/src/grid.h 2013-04-05 21:36:18 +0000
@@ -182,7 +182,8 @@
182 GridScreen *gScreen;182 GridScreen *gScreen;
183183
184 bool isGridResized;184 bool isGridResized;
185 bool isGridSemiMaximized;185 bool isGridHorzMaximized;
186 bool isGridVertMaximized;
186 unsigned int grabMask;187 unsigned int grabMask;
187 int pointerBufDx;188 int pointerBufDx;
188 int pointerBufDy;189 int pointerBufDy;
189190
=== modified file 'plugins/move/src/move.cpp'
--- plugins/move/src/move.cpp 2013-03-26 22:02:39 +0000
+++ plugins/move/src/move.cpp 2013-04-05 21:36:18 +0000
@@ -112,6 +112,9 @@
112112
113 workArea = s->getWorkareaForOutput (w->outputDevice ());113 workArea = s->getWorkareaForOutput (w->outputDevice ());
114114
115 ms->snapBackX = w->serverGeometry ().x () - workArea.x ();
116 ms->snapOffX = x - workArea.x ();
117
115 ms->snapBackY = w->serverGeometry ().y () - workArea.y ();118 ms->snapBackY = w->serverGeometry ().y () - workArea.y ();
116 ms->snapOffY = y - workArea.y ();119 ms->snapOffY = y - workArea.y ();
117120
@@ -436,6 +439,32 @@
436 }439 }
437 }440 }
438 }441 }
442 else if (w->state () & CompWindowStateMaximizedHorzMask)
443 {
444 if (abs (xRoot - workArea.x () - ms->snapOffX) >= SNAP_OFF)
445 {
446 if (!s->otherGrabExist ("move", NULL))
447 {
448 int width = w->serverGeometry ().width ();
449
450 w->saveMask () |= CWX | CWY;
451
452 if (w->saveMask ()& CWWidth)
453 width = w->saveWc ().width;
454
455 w->saveWc ().x = xRoot - (width >> 1);
456 w->saveWc ().y = yRoot + (w->border ().top >> 1);
457
458 ms->x = ms->y = 0;
459
460 w->maximize (0);
461
462 ms->snapOffX = ms->snapBackX;
463
464 return;
465 }
466 }
467 }
439 else if (ms->origState & CompWindowStateMaximizedVertMask)468 else if (ms->origState & CompWindowStateMaximizedVertMask)
440 {469 {
441 if (abs (yRoot - workArea.y () - ms->snapBackY) < SNAP_BACK)470 if (abs (yRoot - workArea.y () - ms->snapBackY) < SNAP_BACK)
442471
=== modified file 'plugins/move/src/move.h'
--- plugins/move/src/move.h 2013-01-03 16:05:26 +0000
+++ plugins/move/src/move.h 2013-04-05 21:36:18 +0000
@@ -89,6 +89,9 @@
8989
90 unsigned int origState;90 unsigned int origState;
9191
92 int snapOffX;
93 int snapBackX;
94
92 int snapOffY;95 int snapOffY;
93 int snapBackY;96 int snapBackY;
9497

Subscribers

People subscribed via source and target branches