Merge lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces into lp:compiz/0.9.10
- compiz.merge-fix1082001-gridded-windows-jump-workspaces
- Merge into 0.9.10
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sami Jaktholm (community) | Approve | ||
Compiz Maintainers | Pending | ||
Review via email:
|
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 ?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MC Return (mc-return) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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:/
> 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
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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://
is an example for this ;)
Hope that I have all Grid bugs fixed, once you get to the review ;)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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
else
3) The easiest solution to fix bug 1082001 is to make expo send start/end_
The first point definitely needs fixing, the second one is just an opinion...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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_
> 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...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MC Return (mc-return) wrote : | # |
@sampo55:
Did some experiments with making expo send the start/end_
The main new problem I got by doing that, was that Expo drag-and-dropping windows failed to work once Expo announces start_viewport_
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...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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-
screen-
screen-
I don't have time to test it right now, but I can try it later...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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-
> CompOption:
> screen-
> screen-
> CompOption:
>
> 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 ;)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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 :)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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 & CompWindowState
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...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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 ?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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).
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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 moveHandleMotio
There:
if (ms->optionGetS
does not check:
if (w->state () & CompWindowState
and thus Compiz has no strategy to snap off a horizontally semi-maximized window...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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 nowTODO: Make the behaviour configurable for the user as many prefer
cycling through different sizesAdded 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 designAdded punctuation where missing and removed it where usually is none
Fixed typos, improved description and titlesgrid:
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 laterAlso 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 laterAlso 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
1 | === modified file 'plugins/expo/src/expo.cpp' | |||
2 | --- plugins/expo/src/expo.cpp 2013-03-26 22:02:39 +0000 | |||
3 | +++ plugins/expo/src/expo.cpp 2013-04-05 21:36:18 +0000 | |||
4 | @@ -247,10 +247,13 @@ | |||
5 | 247 | void | 247 | void |
6 | 248 | ExpoScreen::finishWindowMovement () | 248 | ExpoScreen::finishWindowMovement () |
7 | 249 | { | 249 | { |
8 | 250 | CompOption::Vector o(0); | ||
9 | 250 | dndWindow->ungrabNotify (); | 251 | dndWindow->ungrabNotify (); |
10 | 251 | 252 | ||
11 | 253 | screen->handleCompizEvent ("expo", "start_viewport_switch", o); | ||
12 | 252 | screen->moveViewport (screen->vp ().x () - selectedVp.x (), | 254 | screen->moveViewport (screen->vp ().x () - selectedVp.x (), |
13 | 253 | screen->vp ().y () - selectedVp.y (), true); | 255 | screen->vp ().y () - selectedVp.y (), true); |
14 | 256 | screen->handleCompizEvent ("expo", "end_viewport_switch", o); | ||
15 | 254 | 257 | ||
16 | 255 | /* update saved window attributes in case we moved the | 258 | /* update saved window attributes in case we moved the |
17 | 256 | window to a new viewport */ | 259 | window to a new viewport */ |
18 | @@ -486,6 +489,8 @@ | |||
19 | 486 | void | 489 | void |
20 | 487 | ExpoScreen::donePaint () | 490 | ExpoScreen::donePaint () |
21 | 488 | { | 491 | { |
22 | 492 | CompOption::Vector o(0); | ||
23 | 493 | screen->handleCompizEvent ("expo", "start_viewport_switch", o); | ||
24 | 489 | switch (vpUpdateMode) { | 494 | switch (vpUpdateMode) { |
25 | 490 | case VPUpdateMouseOver: | 495 | case VPUpdateMouseOver: |
26 | 491 | screen->moveViewport (screen->vp ().x () - selectedVp.x (), | 496 | screen->moveViewport (screen->vp ().x () - selectedVp.x (), |
27 | @@ -504,6 +509,7 @@ | |||
28 | 504 | default: | 509 | default: |
29 | 505 | break; | 510 | break; |
30 | 506 | } | 511 | } |
31 | 512 | screen->handleCompizEvent ("expo", "end_viewport_switch", o); | ||
32 | 507 | 513 | ||
33 | 508 | if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone) | 514 | if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone) |
34 | 509 | cScreen->damageScreen (); | 515 | cScreen->damageScreen (); |
35 | 510 | 516 | ||
36 | === modified file 'plugins/grid/src/grid.cpp' | |||
37 | --- plugins/grid/src/grid.cpp 2013-03-22 11:58:33 +0000 | |||
38 | +++ plugins/grid/src/grid.cpp 2013-04-05 21:36:18 +0000 | |||
39 | @@ -63,7 +63,6 @@ | |||
40 | 63 | const CompRect& slot) | 63 | const CompRect& slot) |
41 | 64 | { | 64 | { |
42 | 65 | int cw, ch; | 65 | int cw, ch; |
43 | 66 | |||
44 | 67 | CompRect result = slotToRect (w, slot); | 66 | CompRect result = slotToRect (w, slot); |
45 | 68 | 67 | ||
46 | 69 | if (w->constrainNewWindowSize (result.width (), result.height (), &cw, &ch)) | 68 | if (w->constrainNewWindowSize (result.width (), result.height (), &cw, &ch)) |
47 | @@ -169,17 +168,15 @@ | |||
48 | 169 | if (props.numCellsX == 1) | 168 | if (props.numCellsX == 1) |
49 | 170 | centerCheck = true; | 169 | centerCheck = true; |
50 | 171 | 170 | ||
52 | 172 | if (!gw->isGridResized) | 171 | if (!gw->isGridResized && !gw->isGridHorzMaximized && !gw->isGridVertMaximized) |
53 | 173 | /* Store size not including borders when using a keybinding */ | 172 | /* Store size not including borders when using a keybinding */ |
54 | 174 | gw->originalSize = slotToRect(cw, cw->serverBorderRect ()); | 173 | gw->originalSize = slotToRect(cw, cw->serverBorderRect ()); |
55 | 175 | } | 174 | } |
56 | 176 | 175 | ||
57 | 177 | if ((cw->state () & MAXIMIZE_STATE) && | 176 | if ((cw->state () & MAXIMIZE_STATE) && |
58 | 178 | (resize || optionGetSnapoffMaximized ())) | 177 | (resize || optionGetSnapoffMaximized ())) |
59 | 179 | { | ||
60 | 180 | /* maximized state interferes with us, clear it */ | 178 | /* maximized state interferes with us, clear it */ |
61 | 181 | cw->maximize (0); | 179 | cw->maximize (0); |
62 | 182 | } | ||
63 | 183 | 180 | ||
64 | 184 | if ((where & GridMaximize) && resize) | 181 | if ((where & GridMaximize) && resize) |
65 | 185 | { | 182 | { |
66 | @@ -198,7 +195,9 @@ | |||
67 | 198 | * gridded one. | 195 | * gridded one. |
68 | 199 | */ | 196 | */ |
69 | 200 | gw->isGridResized = false; | 197 | gw->isGridResized = false; |
71 | 201 | gw->isGridSemiMaximized = false; | 198 | gw->isGridHorzMaximized = false; |
72 | 199 | gw->isGridVertMaximized = false; | ||
73 | 200 | |||
74 | 202 | for (unsigned int i = 0; i < animations.size (); i++) | 201 | for (unsigned int i = 0; i < animations.size (); i++) |
75 | 203 | animations.at (i).fadingOut = true; | 202 | animations.at (i).fadingOut = true; |
76 | 204 | return true; | 203 | return true; |
77 | @@ -220,7 +219,8 @@ | |||
78 | 220 | desiredSlot.setWidth (workarea.width () / props.numCellsX); | 219 | desiredSlot.setWidth (workarea.width () / props.numCellsX); |
79 | 221 | 220 | ||
80 | 222 | /* Adjust for constraints and decorations */ | 221 | /* Adjust for constraints and decorations */ |
82 | 223 | if (where & ~(GridMaximize | GridLeft | GridRight)) | 222 | if (where & ~(GridMaximize | |
83 | 223 | GridLeft | GridRight | GridTop | GridBottom)) | ||
84 | 224 | desiredRect = constrainSize (cw, desiredSlot); | 224 | desiredRect = constrainSize (cw, desiredSlot); |
85 | 225 | else | 225 | else |
86 | 226 | desiredRect = slotToRect (cw, desiredSlot); | 226 | desiredRect = slotToRect (cw, desiredSlot); |
87 | @@ -232,7 +232,9 @@ | |||
88 | 232 | 232 | ||
89 | 233 | if (desiredRect.y () == currentRect.y () && | 233 | if (desiredRect.y () == currentRect.y () && |
90 | 234 | desiredRect.height () == currentRect.height () && | 234 | desiredRect.height () == currentRect.height () && |
92 | 235 | where & ~(GridMaximize | GridLeft | GridRight) && gw->lastTarget & where) | 235 | where & ~(GridMaximize | |
93 | 236 | GridLeft | GridRight | GridTop | GridBottom) && | ||
94 | 237 | gw->lastTarget & where) | ||
95 | 236 | { | 238 | { |
96 | 237 | int slotWidth25 = workarea.width () / 4; | 239 | int slotWidth25 = workarea.width () / 4; |
97 | 238 | int slotWidth33 = (workarea.width () / 3) + cw->border ().left; | 240 | int slotWidth33 = (workarea.width () / 3) + cw->border ().left; |
98 | @@ -352,9 +354,11 @@ | |||
99 | 352 | 354 | ||
100 | 353 | gw->sizeHintsFlags = 0; | 355 | gw->sizeHintsFlags = 0; |
101 | 354 | 356 | ||
105 | 355 | /* Special case for left and right, actually vertically maximize | 357 | /* Special cases for left/right and top/bottom gridded windows, where we |
106 | 356 | * the window */ | 358 | * actually vertically respective horizontally semi-maximize the window |
107 | 357 | if (where & GridLeft || where & GridRight) | 359 | */ |
108 | 360 | if (where & GridLeft || where & GridRight || | ||
109 | 361 | where & GridTop || where & GridBottom) | ||
110 | 358 | { | 362 | { |
111 | 359 | /* First restore the window to its original size */ | 363 | /* First restore the window to its original size */ |
112 | 360 | XWindowChanges rwc; | 364 | XWindowChanges rwc; |
113 | @@ -366,11 +370,24 @@ | |||
114 | 366 | 370 | ||
115 | 367 | cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &rwc); | 371 | cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &rwc); |
116 | 368 | 372 | ||
122 | 369 | gw->isGridSemiMaximized = true; | 373 | if (where & GridLeft || where & GridRight) |
123 | 370 | gw->isGridResized = false; | 374 | { |
124 | 371 | 375 | gw->isGridVertMaximized = true; | |
125 | 372 | /* Maximize the window */ | 376 | gw->isGridHorzMaximized = false; |
126 | 373 | cw->maximize (CompWindowStateMaximizedVertMask); | 377 | gw->isGridResized = false; |
127 | 378 | |||
128 | 379 | /* Semi-maximize the window vertically */ | ||
129 | 380 | cw->maximize (CompWindowStateMaximizedVertMask); | ||
130 | 381 | } | ||
131 | 382 | else /* GridTop || GridBottom */ | ||
132 | 383 | { | ||
133 | 384 | gw->isGridHorzMaximized = true; | ||
134 | 385 | gw->isGridVertMaximized = false; | ||
135 | 386 | gw->isGridResized = false; | ||
136 | 387 | |||
137 | 388 | /* Semi-maximize the window horizontally */ | ||
138 | 389 | cw->maximize (CompWindowStateMaximizedHorzMask); | ||
139 | 390 | } | ||
140 | 374 | 391 | ||
141 | 375 | /* Be evil */ | 392 | /* Be evil */ |
142 | 376 | if (cw->sizeHints ().flags & PResizeInc) | 393 | if (cw->sizeHints ().flags & PResizeInc) |
143 | @@ -379,10 +396,11 @@ | |||
144 | 379 | gw->window->sizeHints ().flags &= ~(PResizeInc); | 396 | gw->window->sizeHints ().flags &= ~(PResizeInc); |
145 | 380 | } | 397 | } |
146 | 381 | } | 398 | } |
148 | 382 | else | 399 | else /* GridCorners || GridCenter */ |
149 | 383 | { | 400 | { |
150 | 384 | gw->isGridResized = true; | 401 | gw->isGridResized = true; |
152 | 385 | gw->isGridSemiMaximized = false; | 402 | gw->isGridHorzMaximized = false; |
153 | 403 | gw->isGridVertMaximized = false; | ||
154 | 386 | } | 404 | } |
155 | 387 | 405 | ||
156 | 388 | int dw = (lastBorder.left + lastBorder.right) - | 406 | int dw = (lastBorder.left + lastBorder.right) - |
157 | @@ -843,8 +861,8 @@ | |||
158 | 843 | 861 | ||
159 | 844 | /* Don't allow non-pagers to change | 862 | /* Don't allow non-pagers to change |
160 | 845 | * the size of the window, the user | 863 | * the size of the window, the user |
163 | 846 | * specified this size, thank-you */ | 864 | * specified this size */ |
164 | 847 | if (isGridSemiMaximized) | 865 | if (isGridHorzMaximized || isGridVertMaximized) |
165 | 848 | if (source != ClientTypePager) | 866 | if (source != ClientTypePager) |
166 | 849 | xwcm = 0; | 867 | xwcm = 0; |
167 | 850 | } | 868 | } |
168 | @@ -868,7 +886,10 @@ | |||
169 | 868 | pointerBufDx = pointerBufDy = 0; | 886 | pointerBufDx = pointerBufDy = 0; |
170 | 869 | grabMask = mask; | 887 | grabMask = mask; |
171 | 870 | 888 | ||
173 | 871 | if (!isGridResized && !isGridSemiMaximized && gScreen->optionGetSnapbackWindows ()) | 889 | if (!isGridResized && |
174 | 890 | !isGridHorzMaximized && | ||
175 | 891 | !isGridVertMaximized && | ||
176 | 892 | gScreen->optionGetSnapbackWindows ()) | ||
177 | 872 | /* Store size not including borders when grabbing with cursor */ | 893 | /* Store size not including borders when grabbing with cursor */ |
178 | 873 | originalSize = gScreen->slotToRect(window, | 894 | originalSize = gScreen->slotToRect(window, |
179 | 874 | window->serverBorderRect ()); | 895 | window->serverBorderRect ()); |
180 | @@ -909,8 +930,18 @@ | |||
181 | 909 | { | 930 | { |
182 | 910 | window->moveNotify (dx, dy, immediate); | 931 | window->moveNotify (dx, dy, immediate); |
183 | 911 | 932 | ||
185 | 912 | if (isGridResized && !isGridSemiMaximized && !GridScreen::get (screen)->mSwitchingVp) | 933 | if (isGridResized && |
186 | 934 | !isGridHorzMaximized && | ||
187 | 935 | !isGridVertMaximized && | ||
188 | 936 | !GridScreen::get (screen)->mSwitchingVp) | ||
189 | 913 | { | 937 | { |
190 | 938 | if (window->grabbed () && screen->grabExist ("expo")) | ||
191 | 939 | { | ||
192 | 940 | /* Window is being dragged in expo. Restore the original geometry | ||
193 | 941 | * right away to avoid any confusion. */ | ||
194 | 942 | gScreen->restoreWindow (0, 0, gScreen->o); | ||
195 | 943 | return; | ||
196 | 944 | } | ||
197 | 914 | if (window->grabbed () && (grabMask & CompWindowGrabMoveMask)) | 945 | if (window->grabbed () && (grabMask & CompWindowGrabMoveMask)) |
198 | 915 | { | 946 | { |
199 | 916 | pointerBufDx += dx; | 947 | pointerBufDx += dx; |
200 | @@ -933,7 +964,10 @@ | |||
201 | 933 | !(window->state () & MAXIMIZE_STATE)) | 964 | !(window->state () & MAXIMIZE_STATE)) |
202 | 934 | { | 965 | { |
203 | 935 | lastTarget = GridUnknown; | 966 | lastTarget = GridUnknown; |
205 | 936 | if (isGridSemiMaximized && (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedVertMask) | 967 | if ((isGridHorzMaximized && |
206 | 968 | (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedHorzMask) || | ||
207 | 969 | (isGridVertMaximized && | ||
208 | 970 | (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedVertMask)) | ||
209 | 937 | gScreen->restoreWindow(0, 0, gScreen->o); | 971 | gScreen->restoreWindow(0, 0, gScreen->o); |
210 | 938 | } | 972 | } |
211 | 939 | else if (!(lastState & MAXIMIZE_STATE) && | 973 | else if (!(lastState & MAXIMIZE_STATE) && |
212 | @@ -969,7 +1003,9 @@ | |||
213 | 969 | 1003 | ||
214 | 970 | GRID_WINDOW (cw); | 1004 | GRID_WINDOW (cw); |
215 | 971 | 1005 | ||
217 | 972 | if (!gw->isGridResized && !gw->isGridSemiMaximized) | 1006 | if (!gw->isGridResized && |
218 | 1007 | !gw->isGridHorzMaximized && | ||
219 | 1008 | !gw->isGridVertMaximized) | ||
220 | 973 | { | 1009 | { |
221 | 974 | /* Grid hasn't touched this window or has maximized it. If it's | 1010 | /* Grid hasn't touched this window or has maximized it. If it's |
222 | 975 | * maximized, unmaximize it and get out. */ | 1011 | * maximized, unmaximize it and get out. */ |
223 | @@ -977,25 +1013,38 @@ | |||
224 | 977 | cw->maximize(0); | 1013 | cw->maximize(0); |
225 | 978 | return true; | 1014 | return true; |
226 | 979 | } | 1015 | } |
229 | 980 | 1016 | else if (!gw->isGridResized && | |
230 | 981 | else if (!gw->isGridResized && gw->isGridSemiMaximized) | 1017 | gw->isGridHorzMaximized && |
231 | 1018 | !gw->isGridVertMaximized) | ||
232 | 1019 | { | ||
233 | 1020 | /* Window has been horizontally maximized by grid. We only need | ||
234 | 1021 | * to restore Y and height - core handles X and width. */ | ||
235 | 1022 | if (gw->sizeHintsFlags) | ||
236 | 1023 | gw->window->sizeHints ().flags |= gw->sizeHintsFlags; | ||
237 | 1024 | xwcm |= CWY | CWHeight; | ||
238 | 1025 | } | ||
239 | 1026 | else if (!gw->isGridResized && | ||
240 | 1027 | !gw->isGridHorzMaximized && | ||
241 | 1028 | gw->isGridVertMaximized) | ||
242 | 982 | { | 1029 | { |
243 | 983 | /* Window has been vertically maximized by grid. We only need | 1030 | /* Window has been vertically maximized by grid. We only need |
245 | 984 | * to restore the X and width - core handles Y and height. */ | 1031 | * to restore X and width - core handles Y and height. */ |
246 | 985 | if (gw->sizeHintsFlags) | 1032 | if (gw->sizeHintsFlags) |
247 | 986 | gw->window->sizeHints ().flags |= gw->sizeHintsFlags; | 1033 | gw->window->sizeHints ().flags |= gw->sizeHintsFlags; |
248 | 987 | xwcm |= CWX | CWWidth; | 1034 | xwcm |= CWX | CWWidth; |
249 | 988 | } | 1035 | } |
254 | 989 | 1036 | else if (gw->isGridResized && | |
255 | 990 | else if (gw->isGridResized && !gw->isGridSemiMaximized) | 1037 | !gw->isGridHorzMaximized && |
256 | 991 | /* Window is just gridded (top, bottom, center, corners). We | 1038 | !gw->isGridVertMaximized) |
257 | 992 | * need to handle everything. */ | 1039 | /* Window is just gridded (center, corners). |
258 | 1040 | * We need to handle everything. */ | ||
259 | 993 | xwcm |= CWX | CWY | CWWidth | CWHeight; | 1041 | xwcm |= CWX | CWY | CWWidth | CWHeight; |
260 | 994 | else | 1042 | else |
261 | 995 | { | 1043 | { |
262 | 996 | /* This should never happen. But if it does, just bail out | 1044 | /* This should never happen. But if it does, just bail out |
263 | 997 | * gracefully. */ | 1045 | * gracefully. */ |
265 | 998 | assert (gw->isGridResized && gw->isGridSemiMaximized); | 1046 | assert (gw->isGridResized && |
266 | 1047 | (gw->isGridHorzMaximized || gw->isGridVertMaximized)); | ||
267 | 999 | return false; | 1048 | return false; |
268 | 1000 | } | 1049 | } |
269 | 1001 | 1050 | ||
270 | @@ -1004,6 +1053,16 @@ | |||
271 | 1004 | xwc.x = pointerX - (gw->originalSize.width () / 2); | 1053 | xwc.x = pointerX - (gw->originalSize.width () / 2); |
272 | 1005 | xwc.y = pointerY + (cw->border ().top / 2); | 1054 | xwc.y = pointerY + (cw->border ().top / 2); |
273 | 1006 | } | 1055 | } |
274 | 1056 | else if (cw->grabbed () && screen->grabExist ("expo")) | ||
275 | 1057 | { | ||
276 | 1058 | /* We're restoring a window inside expo by dragging. This is a bit | ||
277 | 1059 | * tricky. Pointer location is absolute to the screen, not relative | ||
278 | 1060 | * to expo viewport. So we can't use pointer location to calculate | ||
279 | 1061 | * the position of the restore window. | ||
280 | 1062 | * | ||
281 | 1063 | * The best solution is to resize it in place. */ | ||
282 | 1064 | xwcm = CWWidth | CWHeight; | ||
283 | 1065 | } | ||
284 | 1007 | else | 1066 | else |
285 | 1008 | { | 1067 | { |
286 | 1009 | xwc.x = gw->originalSize.x (); | 1068 | xwc.x = gw->originalSize.x (); |
287 | @@ -1018,7 +1077,8 @@ | |||
288 | 1018 | gw->currentSize = CompRect (); | 1077 | gw->currentSize = CompRect (); |
289 | 1019 | gw->pointerBufDx = 0; | 1078 | gw->pointerBufDx = 0; |
290 | 1020 | gw->pointerBufDy = 0; | 1079 | gw->pointerBufDy = 0; |
292 | 1021 | gw->isGridSemiMaximized = false; | 1080 | gw->isGridHorzMaximized = false; |
293 | 1081 | gw->isGridVertMaximized = false; | ||
294 | 1022 | gw->isGridResized = false; | 1082 | gw->isGridResized = false; |
295 | 1023 | if (cw->state () & MAXIMIZE_STATE) | 1083 | if (cw->state () & MAXIMIZE_STATE) |
296 | 1024 | cw->maximize(0); | 1084 | cw->maximize(0); |
297 | @@ -1035,7 +1095,8 @@ | |||
298 | 1035 | GRID_WINDOW (screen->findWindow | 1095 | GRID_WINDOW (screen->findWindow |
299 | 1036 | (CompOption::getIntOptionNamed (o, "window"))); | 1096 | (CompOption::getIntOptionNamed (o, "window"))); |
300 | 1037 | gw->isGridResized = false; | 1097 | gw->isGridResized = false; |
302 | 1038 | gw->isGridSemiMaximized = false; | 1098 | gw->isGridHorzMaximized = false; |
303 | 1099 | gw->isGridVertMaximized = false; | ||
304 | 1039 | gw->resizeCount = 0; | 1100 | gw->resizeCount = 0; |
305 | 1040 | } | 1101 | } |
306 | 1041 | 1102 | ||
307 | @@ -1197,7 +1258,8 @@ | |||
308 | 1197 | gWindow (GLWindow::get(window)), | 1258 | gWindow (GLWindow::get(window)), |
309 | 1198 | gScreen (GridScreen::get (screen)), | 1259 | gScreen (GridScreen::get (screen)), |
310 | 1199 | isGridResized (false), | 1260 | isGridResized (false), |
312 | 1200 | isGridSemiMaximized (false), | 1261 | isGridHorzMaximized (false), |
313 | 1262 | isGridVertMaximized (false), | ||
314 | 1201 | grabMask (0), | 1263 | grabMask (0), |
315 | 1202 | pointerBufDx (0), | 1264 | pointerBufDx (0), |
316 | 1203 | pointerBufDy (0), | 1265 | pointerBufDy (0), |
317 | 1204 | 1266 | ||
318 | === modified file 'plugins/grid/src/grid.h' | |||
319 | --- plugins/grid/src/grid.h 2013-01-21 15:17:50 +0000 | |||
320 | +++ plugins/grid/src/grid.h 2013-04-05 21:36:18 +0000 | |||
321 | @@ -182,7 +182,8 @@ | |||
322 | 182 | GridScreen *gScreen; | 182 | GridScreen *gScreen; |
323 | 183 | 183 | ||
324 | 184 | bool isGridResized; | 184 | bool isGridResized; |
326 | 185 | bool isGridSemiMaximized; | 185 | bool isGridHorzMaximized; |
327 | 186 | bool isGridVertMaximized; | ||
328 | 186 | unsigned int grabMask; | 187 | unsigned int grabMask; |
329 | 187 | int pointerBufDx; | 188 | int pointerBufDx; |
330 | 188 | int pointerBufDy; | 189 | int pointerBufDy; |
331 | 189 | 190 | ||
332 | === modified file 'plugins/move/src/move.cpp' | |||
333 | --- plugins/move/src/move.cpp 2013-03-26 22:02:39 +0000 | |||
334 | +++ plugins/move/src/move.cpp 2013-04-05 21:36:18 +0000 | |||
335 | @@ -112,6 +112,9 @@ | |||
336 | 112 | 112 | ||
337 | 113 | workArea = s->getWorkareaForOutput (w->outputDevice ()); | 113 | workArea = s->getWorkareaForOutput (w->outputDevice ()); |
338 | 114 | 114 | ||
339 | 115 | ms->snapBackX = w->serverGeometry ().x () - workArea.x (); | ||
340 | 116 | ms->snapOffX = x - workArea.x (); | ||
341 | 117 | |||
342 | 115 | ms->snapBackY = w->serverGeometry ().y () - workArea.y (); | 118 | ms->snapBackY = w->serverGeometry ().y () - workArea.y (); |
343 | 116 | ms->snapOffY = y - workArea.y (); | 119 | ms->snapOffY = y - workArea.y (); |
344 | 117 | 120 | ||
345 | @@ -436,6 +439,32 @@ | |||
346 | 436 | } | 439 | } |
347 | 437 | } | 440 | } |
348 | 438 | } | 441 | } |
349 | 442 | else if (w->state () & CompWindowStateMaximizedHorzMask) | ||
350 | 443 | { | ||
351 | 444 | if (abs (xRoot - workArea.x () - ms->snapOffX) >= SNAP_OFF) | ||
352 | 445 | { | ||
353 | 446 | if (!s->otherGrabExist ("move", NULL)) | ||
354 | 447 | { | ||
355 | 448 | int width = w->serverGeometry ().width (); | ||
356 | 449 | |||
357 | 450 | w->saveMask () |= CWX | CWY; | ||
358 | 451 | |||
359 | 452 | if (w->saveMask ()& CWWidth) | ||
360 | 453 | width = w->saveWc ().width; | ||
361 | 454 | |||
362 | 455 | w->saveWc ().x = xRoot - (width >> 1); | ||
363 | 456 | w->saveWc ().y = yRoot + (w->border ().top >> 1); | ||
364 | 457 | |||
365 | 458 | ms->x = ms->y = 0; | ||
366 | 459 | |||
367 | 460 | w->maximize (0); | ||
368 | 461 | |||
369 | 462 | ms->snapOffX = ms->snapBackX; | ||
370 | 463 | |||
371 | 464 | return; | ||
372 | 465 | } | ||
373 | 466 | } | ||
374 | 467 | } | ||
375 | 439 | else if (ms->origState & CompWindowStateMaximizedVertMask) | 468 | else if (ms->origState & CompWindowStateMaximizedVertMask) |
376 | 440 | { | 469 | { |
377 | 441 | if (abs (yRoot - workArea.y () - ms->snapBackY) < SNAP_BACK) | 470 | if (abs (yRoot - workArea.y () - ms->snapBackY) < SNAP_BACK) |
378 | 442 | 471 | ||
379 | === modified file 'plugins/move/src/move.h' | |||
380 | --- plugins/move/src/move.h 2013-01-03 16:05:26 +0000 | |||
381 | +++ plugins/move/src/move.h 2013-04-05 21:36:18 +0000 | |||
382 | @@ -89,6 +89,9 @@ | |||
383 | 89 | 89 | ||
384 | 90 | unsigned int origState; | 90 | unsigned int origState; |
385 | 91 | 91 | ||
386 | 92 | int snapOffX; | ||
387 | 93 | int snapBackX; | ||
388 | 94 | |||
389 | 92 | int snapOffY; | 95 | int snapOffY; |
390 | 93 | int snapBackY; | 96 | int snapBackY; |
391 | 94 | 97 |
Ping ?