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

Proposed by MC Return
Status: Merged
Approved by: Sam Spilsbury
Approved revision: no longer in the revision history of the source branch.
Merged at revision: 3650
Proposed branch: lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces
Merge into: lp:compiz/0.9.10
Diff against target: 739 lines (+219/-88)
4 files modified
plugins/expo/src/expo.cpp (+6/-0)
plugins/grid/grid.xml.in (+31/-26)
plugins/grid/src/grid.cpp (+180/-61)
plugins/grid/src/grid.h (+2/-1)
To merge this branch: bzr merge lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Sami Jaktholm (community) Approve
Sam Spilsbury Approve
MC Return Pending
Review via email: mp+157817@code.launchpad.net

This proposal supersedes a proposal from 2013-04-08.

Commit message

*Grid code:

Prevent center and corner gridded windows from jumping viewports.
(Thanks and credits for this go to Sami Jaktholm)

Prevent top and bottom gridded windows from jumping viewports by
making those semi-maximize horizontally.

As those are actually semi-maximized horizontally, we will treat
them as such and let core handle the restoring, just like we
already do for vertically semi-maximized 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 (expo) is active.
(Thanks and credits for this go to Sami Jaktholm)

Allow cycling for all gridded windows if explicitly specified by the
user in CCSM.

Forbid cycling through different sizes for corner and center-gridded
windows also per default, now fully fixing bug #878820 and following
the design specification by Ayatana Design there, making behaviour
consistent.

Introduced 3 new bools:
horzMaximizedGridPosition,
vertMaximizedGridPosition,
anyMaximizedGridPosition

Used these bools inside the if condition checks.
Simplified complicated if condition by removing redundant additional
size check.

Cleanup all around.

*Grid xml:

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.

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

(fixes: LP: #878820, LP: #879218, LP: #882754 and LP: #1082001,
 partially fixes: #1116538, #1164332)

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

Ping ?

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

> 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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

@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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

> 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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

> 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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

> 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 : Posted in a previous version of this proposal

> 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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

> 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 : Posted in a previous version of this proposal

> 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 ;)

Revision history for this message
Sami Jaktholm (sjakthol) wrote : Posted in a previous version of this proposal

The change to move code might cause a change in behavior in a corner case. If the window is HorzMaximized but not VertMaximized, the code will never enter the next else if clause (where it would remaximize the window) as it returns in the new else if block. However I haven't found a way to trigger this case so it shouldn't be a problem.

I still think you should split these changes up as the move changes have nothing to do with the original problem.

Other than that, it looks good and works fine.

review: Approve
Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

Hey Sami :)

Thanks for the review and testing.
I have tested the changes extensively as well and could find no regressions.

/offtopic on
But during testing I found a new bug unfortunately... it seems to have nothing to do with this MP and can be reproduced in trunk as well, but a multimonitor system is needed:

1.Semi-maximize horizontally or maximize a window on monitor 2
2.Change the viewport
3.Switch back to your window with a switcher, or via click on its icon in a dock/launcher

Result: The viewport will change correctly, but the window will move to the main monitor and maximize/semi-maximize horizontally there

Can you reproduce this also (without this branch) ?
/offtopic off

Regarding move: Sure, I can make a new MP for that - my only personal problem is that my SSD is 96,8% full and each
MP with a compiled/tested Compiz build takes another 400MB away ;) - so I am quite handicapped with available space @ the moment...

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

I've changed the partial fixes in the commit message to numbers, but I might have to remove the linked bug reports, so launchpad won't auto-track them and change them to "Fix Committed" when committing this to trunk, but I'll better adjust the status of those manually after the merge...

Revision history for this message
Sami Jaktholm (sjakthol) wrote : Posted in a previous version of this proposal

I don't have a second monitor to test that.

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

> I don't have a second monitor to test that.
No problem, seems to be completely unrelated anyway... will check that one @ a later stage...

We are now bailing out if we are repeating the same action:
Probably this would have been enough:

if (gw->lastTarget == where &&
    gw->isGridResized)
    return false

but it works now also (with a little bit of redundancy in the condition check) ;)

I'll have to optimize that a bit...

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

Okay, behaviour is configurable now (at least for corner and center gridded windows), so we won't regress for noone...

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

Made the behaviour now fully configurable for all gridded windows.

Revision history for this message
Sami Jaktholm (sjakthol) wrote : Posted in a previous version of this proposal

This has way too much going on. Please split these changes up (one fix per MP).

review: Needs Fixing
Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

> This has way too much going on. Please split these changes up (one fix per
> MP).

I will explain first what happened after r3652, which is the last revision
you approved...
Btw, there are subcommits, which all have their own diff - making it easier
to follow development:

In
http://bazaar.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/revision/3653
I forbid cycling through different sizes for corner and center-gridded
windows also, now fully fixing bug #878820 and following the design
specification for now.

In
http://bazaar.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/revision/3654
I 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, so that it looked like this:

if (gw->lastTarget == where &&
    gw->isGridResized)
    return false;

That means we bail out if the last target is the same as current one and
the window is already grid-resized, so we won't resize a corner/center
gridded window again.

In
http://bazaar.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/revision/3655
I added a 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.
This is the relevant part in the xml, the rest are just minor punctuation/
wording fixes:
<option name="cycle_sizes" type="bool">
    <_short>Cycle Through Multiple Sizes</_short>
    <_long>Cycle through multiple different sizes by using the same keyboard shortcut multiple times in a row.</_long>
    <default>false</default>
</option>

The only code change in this revision is this:
/* We do not want to allow cycling through sizes,
 * unless the user explicitely specified that in CCSM */
if (gw->lastTarget == where &&
    gw->isGridResized &&
    !optionGetCycleSizes ())
    return false;

That means we allow to cycle center and corner gridded
windows now, if the user specifies explicitly in CCSM.

In the final revision
http://bazaar.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/revision/3656
I had to implement the same choice for the rest of the
grid windows, namely left/right/top/bottom, which will
act like normal grid windows, if the user selects the
"want to cycle through sizes" option in CCSM

Voila, everything works perfectly :)

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal
Download full text (3.5 KiB)

Hey MCR1. Excellent work, here's some comments so far.

8 + CompOption::Vector o(0);
9 dndWindow->ungrabNotify ();
10
11 + screen->handleCompizEvent ("expo", "start_viewport_switch", o);

I believe there is a constant somewhere, either as a static member of CompOption or just as a global called "noOptions". I'd suggest using that.

43 - <_long>Warp and resize windows to fit an imaginary grid.</_long>
44 + <_long>Warp and resize windows to fit an imaginary grid</_long>
45 <category>Window Management</category>
46 <deps>
47 <requirement>
48 @@ -83,7 +83,7 @@
49 <_long>Window resize action</_long>
50 <option name="top_left_corner_action" type="int">
51 <_short>Upper Left Corner</_short>
52 - <_long>Action to be performed when window is dropped on the top left corner</_long>
53 + <_long>Action to be performed when window is dropped on the top left corner.</_long>

Try to avoid mixing formatting changes with substantive changes.

319 - * computing what the 33% and 66% offsets would be
320 - */
321 + * computing what the 33% and 66% offsets would be
322 + */

I think that's probably an undesired formatting change.

Statements like this:

377 + if (where & GridLeft || where & GridRight ||
378 + where & GridTop || where & GridBottom)

And this:

308 + (where & ~(GridMaximize) ||
309 + (where & ~(GridLeft | GridRight | GridTop | GridBottom) &&

Can be combined, eg

unsigned int VerticalGrid = GridLeft | GridRight;
unsigned int HorizontalGrid = GridTop | GridBottom;
unsigned int ConstrainedGrid = VerticalGrid | HorizontalGrid | GridMaximize;

if (where & ~ConstrinedGrid)

...

if (where & VerticalGrid)
{
}
else if (where & HorizontalGrid)
{
}

530 + else if (!gw->isGridResized &&
531 + gw->isGridHorzMaximized &&
532 + !gw->isGridVertMaximized)
533 + {
534 + /* Window has been horizontally maximized by grid. We only need
535 + * to restore Y and height - core handles X and width. */
536 + if (gw->sizeHintsFlags)
537 + gw->window->sizeHints ().flags |= gw->sizeHintsFlags;
538 + xwcm |= CWY | CWHeight;
539 + }
540 + else if (!gw->isGridResized &&
541 + !gw->isGridHorzMaximized &&
542 + gw->isGridVertMaximized)
543 {
544 /* Window has been vertically maximized by grid. We only need
545 - * to restore the X and width - core handles Y and height. */
546 + * to restore X and width - core handles Y and height. */
547 if (gw->sizeHintsFlags)
548 gw->window->sizeHints ().flags |= gw->sizeHintsFlags;
549 xwcm |= CWX | CWWidth;
550 }
551 -
552 - else if (gw->isGridResized && !gw->isGridSemiMaximized)
553 - /* Window is just gridded (top, bottom, center, corners). We
554 - * need to handle everything. */
555 + else if (gw->isGridResized &&
556 + !gw->isGridHorzMaximized &&
557 + !gw->isGridVertMaximized)
558 + /* Window is just gridded (center, corners).
559 + * We need to handle everything. */

It might make sense to nest these blocks.

if (!isGridResized)
{
    assert (isGridHorzMaximized != isGridVertMaximized);

    if (isGridHorzMaximized)
    {
        ...
    }
    else if (isGridVertMaximized)
   ...

Read more...

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal
Download full text (4.9 KiB)

> Hey MCR1. Excellent work, here's some comments so far.
>
Hi Sam. First of all thanks for the review. It is very appreciated.

> 8 + CompOption::Vector o(0);
> 9 dndWindow->ungrabNotify ();
> 10
> 11 + screen->handleCompizEvent ("expo", "start_viewport_switch", o);
>
> I believe there is a constant somewhere, either as a static member of
> CompOption or just as a global called "noOptions". I'd suggest using that.
>
I am not sure where to find that, but I'll search...

> 43 - <_long>Warp and resize windows to fit an imaginary
> grid.</_long>
> 44 + <_long>Warp and resize windows to fit an imaginary
> grid</_long>
> 45 <category>Window Management</category>
> 46 <deps>
> 47 <requirement>
> 48 @@ -83,7 +83,7 @@
> 49 <_long>Window resize action</_long>
> 50 <option name="top_left_corner_action"
> type="int">
> 51 <_short>Upper Left Corner</_short>
> 52 - <_long>Action to be performed when window
> is dropped on the top left corner</_long>
> 53 + <_long>Action to be performed when window
> is dropped on the top left corner.</_long>
>
> Try to avoid mixing formatting changes with substantive changes.
>
I am sorry - I just can't help myself. I want to harmonize how plugins and their
tooltips look & feel, so if I am fixing stuff in the xml - I automatically just
have to fix those also...

> 319 - * computing what the 33% and 66% offsets would be
> 320 - */
> 321 + * computing what the 33% and 66% offsets would be
> 322 + */
>
> I think that's probably an undesired formatting change.
>
Not sure, have to check...

> Statements like this:
>
> 377 + if (where & GridLeft || where & GridRight ||
> 378 + where & GridTop || where & GridBottom)
>
> And this:
>
> 308 + (where & ~(GridMaximize) ||
> 309 + (where & ~(GridLeft | GridRight | GridTop | GridBottom)
> &&
>
> Can be combined, eg
>
> unsigned int VerticalGrid = GridLeft | GridRight;
> unsigned int HorizontalGrid = GridTop | GridBottom;
> unsigned int ConstrainedGrid = VerticalGrid | HorizontalGrid | GridMaximize;
>
> if (where & ~ConstrinedGrid)
>
> ...
>
> if (where & VerticalGrid)
> {
> }
> else if (where & HorizontalGrid)
> {
> }
>
Yeah, I did not touch that any further for the sake of the diffs' size and
readability, but if you want me to fix it in this MP, I'll do it...

> 530 + else if (!gw->isGridResized &&
> 531 + gw->isGridHorzMaximized &&
> 532 + !gw->isGridVertMaximized)
> 533 + {
> 534 + /* Window has been horizontally maximized by grid. We only
> need
> 535 + * to restore Y and height - core handles X and width. */
> 536 + if (gw->sizeHintsFlags)
> 537 + gw->window->sizeHints ().flags |= gw->sizeHintsFlags;
> 538 + xwcm |= CWY | CWHeight;
> 539 + }
> 540 + else if...

Read more...

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

> Hey MCR1. Excellent work, here's some comments so far.
>
> 8 + CompOption::Vector o(0);
> 9 dndWindow->ungrabNotify ();
> 10
> 11 + screen->handleCompizEvent ("expo", "start_viewport_switch", o);
>
> I believe there is a constant somewhere, either as a static member of
> CompOption or just as a global called "noOptions". I'd suggest using that.
>

Hmm, I do not know exactly what to change here, as searching through the code
shows it is almost always used like that, if there are no options - this is from
wall.cpp for example:

    CompOption::Vector o(0);
...
...
    screen->handleCompizEvent ("wall", "start_viewport_switch", o);

I am quite clueless here, but the version we use seems correct...

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

> > 319 - * computing what the 33% and 66% offsets would be
> > 320 - */
> > 321 + * computing what the 33% and 66% offsets would
> be
> > 322 + */
> >
> > I think that's probably an undesired formatting change.
> >

Fixed (not yet pushed).

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

Sam, it would really be cool if we could merge this at current stage as it is a quasi Grid milestone.

Also I got another branch I stacked on this one:
https://code.launchpad.net/~mc-return/compiz/compiz.merge-fix1116538-isgridresized-windows-do-not-react-to-strg-super-down/+merge/157759

and making too many changes here will complicate further merging :(

I can assure you this here fully works, but I am somehow too lazy to make a video proving that all those bugs are fixed... ;)

Sam, I can assure you I will get to all of your points in a later follow-up MP, but please give this one here a green light first ;)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Sure, before that, can you:

1. Look into merging some of the bitflags (at the very least, doing if
(where & ~(GridLeft | GridRight | GridTop | GridBottom) is much better
than doing where & ~(GridLeft) || where &~(GridRight) etc
2. Look into whether or not an enum can replace those bools, as they
seem to be mutually exclusive.

On Tue, Apr 9, 2013 at 5:59 AM, MC Return <email address hidden> wrote:
> Sam, it would really be cool if we could merge this at current stage as it is a quasi Grid milestone.
>
> Also I got another branch I stacked on this one:
> https://code.launchpad.net/~mc-return/compiz/compiz.merge-fix1116538-isgridresized-windows-do-not-react-to-strg-super-down/+merge/157759
>
> and making too many changes here will complicate further merging :(
>
> I can assure you this here fully works, but I am somehow too lazy to make a video proving that all those bugs are fixed... ;)
>
> Sam, I can assure you I will get to all of your points in a later follow-up MP, but please give this one here a green light first ;)
> --
> https://code.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/+merge/157760
> 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 : Posted in a previous version of this proposal

> Sure, before that, can you:
>
> 1. Look into merging some of the bitflags (at the very least, doing if
> (where & ~(GridLeft | GridRight | GridTop | GridBottom) is much better
> than doing where & ~(GridLeft) || where &~(GridRight) etc
> 2. Look into whether or not an enum can replace those bools, as they
> seem to be mutually exclusive.
>
1 & 2: Done. Even simplified one complicated if condition check additionally.
       I used 3 new bools, like you suggested before - it is much nicer already.
       I think an enum is not necessary here, the bools seem to be enough to
       clean that mess up.

review: Needs Resubmitting
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Coolio, you don't need to resubmit this, I can just reack it when I have
time to look over it next ..

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

> Coolio, you don't need to resubmit this, I can just reack it when I have
> time to look over it next ..

I was not sure... I think Daniel once asked me to always resumbmit, or he won't notice it - so I am using this workflow now - I would prefer it to not always have to resubmit, but do not care, if it is prefered to be done this way either...

/offtopic on

I want to create a blueprint on launchpad, where I want to throw in all bugs that are still valid and reproducable.
The bugtracker is a bit of a mess, so I think something like a blueprint combining the most important of them would be
nice...
I want to sort them by: Feature-Requests/Wishlist / Multimonitor only / Regressions / Window-management / Other

Maybe some other categories as well - we'll see...

How do you like that idea ?

/offtopic off

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

> /offtopic on
>
> I want to create a blueprint on launchpad, where I want to throw in all bugs
> that are still valid and reproducable.
> The bugtracker is a bit of a mess, so I think something like a blueprint
> combining the most important of them would be
> nice...
> I want to sort them by: Feature-Requests/Wishlist / Multimonitor only /
> Regressions / Window-management / Other
>
> Maybe some other categories as well - we'll see...
>
> How do you like that idea ?
>
> /offtopic off

The best thing to do would be to add them to the 0.9.10.0 milestone. Dunno if that exists yet - I will create it if need be.

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

I'm fine with this as is. Sami, what are your thoughts?

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

>
> The best thing to do would be to add them to the 0.9.10.0 milestone. Dunno if
> that exists yet - I will create it if need be.

The problem here is that I am not a member of the Compiz team
- so I am not able to change bug priority levels and also cannot add bugs to milestones.

BTW, milestone 0.9.10 already exists:
https://launchpad.net/compiz/+milestone/0.9.10.0

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

On Tue, Apr 9, 2013 at 6:04 PM, MC Return <email address hidden> wrote:
>>
>> The best thing to do would be to add them to the 0.9.10.0 milestone. Dunno if
>> that exists yet - I will create it if need be.
>
> The problem here is that I am not a member of the Compiz team
> - so I am not able to change bug priority levels and also cannot add bugs to milestones.
>
> BTW, milestone 0.9.10 already exists:
> https://launchpad.net/compiz/+milestone/0.9.10.0

Okay, we'll need to fix that.

>
> --
> https://code.launchpad.net/~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces/+merge/157817
> You are reviewing the proposed merge of lp:~mc-return/compiz/compiz.merge-fix1082001-gridded-windows-jump-workspaces into lp:compiz.

--
Sam Spilsbury

3659. By MC Return

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

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

Looks good and works fine.

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

> Looks good and works fine.

Thanks :)

Really time to get this thingy merged ;)

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

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-09 08:47:24 +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/grid.xml.in'
--- plugins/grid/grid.xml.in 2013-01-16 23:12:46 +0000
+++ plugins/grid/grid.xml.in 2013-04-09 08:47:24 +0000
@@ -2,7 +2,7 @@
2<compiz>2<compiz>
3 <plugin name="grid" useBcop="true">3 <plugin name="grid" useBcop="true">
4 <_short>Grid</_short>4 <_short>Grid</_short>
5 <_long>Warp and resize windows to fit an imaginary grid.</_long>5 <_long>Warp and resize windows to fit an imaginary grid</_long>
6 <category>Window Management</category>6 <category>Window Management</category>
7 <deps>7 <deps>
8 <requirement>8 <requirement>
@@ -83,7 +83,7 @@
83 <_long>Window resize action</_long>83 <_long>Window resize action</_long>
84 <option name="top_left_corner_action" type="int">84 <option name="top_left_corner_action" type="int">
85 <_short>Upper Left Corner</_short>85 <_short>Upper Left Corner</_short>
86 <_long>Action to be performed when window is dropped on the top left corner</_long>86 <_long>Action to be performed when window is dropped on the top left corner.</_long>
87 <default>4</default>87 <default>4</default>
88 <min>0</min>88 <min>0</min>
89 <max>10</max>89 <max>10</max>
@@ -134,7 +134,7 @@
134 </option>134 </option>
135 <option name="top_edge_action" type="int">135 <option name="top_edge_action" type="int">
136 <_short>Top Edge</_short>136 <_short>Top Edge</_short>
137 <_long>Action to be performed when window is dropped on the top edge</_long>137 <_long>Action to be performed when window is dropped on the top edge.</_long>
138 <default>10</default>138 <default>10</default>
139 <min>0</min>139 <min>0</min>
140 <max>10</max>140 <max>10</max>
@@ -185,7 +185,7 @@
185 </option>185 </option>
186 <option name="top_right_corner_action" type="int">186 <option name="top_right_corner_action" type="int">
187 <_short>Upper Right Corner</_short>187 <_short>Upper Right Corner</_short>
188 <_long>Action to be performed when window is dropped on the top right corner</_long>188 <_long>Action to be performed when window is dropped on the top right corner.</_long>
189 <default>6</default>189 <default>6</default>
190 <min>0</min>190 <min>0</min>
191 <max>10</max>191 <max>10</max>
@@ -236,7 +236,7 @@
236 </option>236 </option>
237 <option name="left_edge_action" type="int">237 <option name="left_edge_action" type="int">
238 <_short>Left Edge</_short>238 <_short>Left Edge</_short>
239 <_long>Action to be performed when window is dropped on the left edge</_long>239 <_long>Action to be performed when window is dropped on the left edge.</_long>
240 <default>4</default>240 <default>4</default>
241 <min>0</min>241 <min>0</min>
242 <max>10</max>242 <max>10</max>
@@ -287,7 +287,7 @@
287 </option>287 </option>
288 <option name="right_edge_action" type="int">288 <option name="right_edge_action" type="int">
289 <_short>Right Edge</_short>289 <_short>Right Edge</_short>
290 <_long>Action to be performed when window is dropped on the right edge</_long>290 <_long>Action to be performed when window is dropped on the right edge.</_long>
291 <default>6</default>291 <default>6</default>
292 <min>0</min>292 <min>0</min>
293 <max>10</max>293 <max>10</max>
@@ -338,7 +338,7 @@
338 </option>338 </option>
339 <option name="bottom_left_corner_action" type="int">339 <option name="bottom_left_corner_action" type="int">
340 <_short>Bottom Left Corner</_short>340 <_short>Bottom Left Corner</_short>
341 <_long>Action to be performed when window is dropped on the bottom left corner</_long>341 <_long>Action to be performed when window is dropped on the bottom left corner.</_long>
342 <default>4</default>342 <default>4</default>
343 <min>0</min>343 <min>0</min>
344 <max>10</max>344 <max>10</max>
@@ -389,7 +389,7 @@
389 </option>389 </option>
390 <option name="bottom_edge_action" type="int">390 <option name="bottom_edge_action" type="int">
391 <_short>Bottom Edge</_short>391 <_short>Bottom Edge</_short>
392 <_long>Action to be performed when window is dropped on the bottom edge</_long>392 <_long>Action to be performed when window is dropped on the bottom edge.</_long>
393 <default>0</default>393 <default>0</default>
394 <min>0</min>394 <min>0</min>
395 <max>10</max>395 <max>10</max>
@@ -440,7 +440,7 @@
440 </option>440 </option>
441 <option name="bottom_right_corner_action" type="int">441 <option name="bottom_right_corner_action" type="int">
442 <_short>Bottom Right Corner</_short>442 <_short>Bottom Right Corner</_short>
443 <_long>Action to be performed when window is dropped on the bottom right corner</_long>443 <_long>Action to be performed when window is dropped on the bottom right corner.</_long>
444 <default>6</default>444 <default>6</default>
445 <min>0</min>445 <min>0</min>
446 <max>10</max>446 <max>10</max>
@@ -490,42 +490,47 @@
490 </desc>490 </desc>
491 </option>491 </option>
492 <option name="snapoff_maximized" type="bool">492 <option name="snapoff_maximized" type="bool">
493 <_short>Snapoff maximized windows</_short>493 <_short>Snapoff Maximized/Semi-maximized Windows</_short>
494 <_long>Snapoff maximized windows when pulling to edge.</_long>494 <_long>Snapoff maximized and vertically maximized windows by dragging them up or down and horizontally maximized ones by dragging them left or right.</_long>
495 <default>false</default>495 <default>false</default>
496 </option>496 </option>
497 <option name="snapback_windows" type="bool">497 <option name="snapback_windows" type="bool">
498 <_short>Snap windows back to original size</_short>498 <_short>Snap Windows Back To Original Size</_short>
499 <_long>Snaps windows back to their original size if dragged away from their gridded position.</_long>499 <_long>Snaps windows back to their original size if dragged away from their gridded position.</_long>
500 <default>true</default>500 <default>true</default>
501 </option>501 </option>
502 <option name="cycle_sizes" type="bool">
503 <_short>Cycle Through Multiple Sizes</_short>
504 <_long>Cycle through multiple different sizes by using the same keyboard shortcut multiple times in a row.</_long>
505 <default>false</default>
506 </option>
502 </subgroup>507 </subgroup>
503 <subgroup>508 <subgroup>
504 <_short>Thresholds</_short>509 <_short>Thresholds</_short>
505 <option name="left_edge_threshold" type="int">510 <option name="left_edge_threshold" type="int">
506 <_short>Left Edge</_short>511 <_short>Left Edge</_short>
507 <_long>Maximum number of pixels from the left edge a window can be dropped</_long>512 <_long>Maximum number of pixels from the left edge a window can be dropped.</_long>
508 <default>15</default>513 <default>15</default>
509 <min>0</min>514 <min>0</min>
510 <max>500</max>515 <max>500</max>
511 </option>516 </option>
512 <option name="right_edge_threshold" type="int">517 <option name="right_edge_threshold" type="int">
513 <_short>Right Edge</_short>518 <_short>Right Edge</_short>
514 <_long>Maximum number of pixels from the right edge a window can be dropped</_long>519 <_long>Maximum number of pixels from the right edge a window can be dropped.</_long>
515 <default>15</default>520 <default>15</default>
516 <min>0</min>521 <min>0</min>
517 <max>500</max>522 <max>500</max>
518 </option>523 </option>
519 <option name="top_edge_threshold" type="int">524 <option name="top_edge_threshold" type="int">
520 <_short>Top Edge</_short>525 <_short>Top Edge</_short>
521 <_long>Maximum number of pixels from the top edge a window can be dropped</_long>526 <_long>Maximum number of pixels from the top edge a window can be dropped.</_long>
522 <default>20</default>527 <default>20</default>
523 <min>0</min>528 <min>0</min>
524 <max>500</max>529 <max>500</max>
525 </option>530 </option>
526 <option name="bottom_edge_threshold" type="int">531 <option name="bottom_edge_threshold" type="int">
527 <_short>Bottom Edge</_short>532 <_short>Bottom Edge</_short>
528 <_long>Maximum number of pixels from the Bottom edge a window can be dropped</_long>533 <_long>Maximum number of pixels from the bottom edge a window can be dropped.</_long>
529 <default>5</default>534 <default>5</default>
530 <min>0</min>535 <min>0</min>
531 <max>500</max>536 <max>500</max>
@@ -535,24 +540,24 @@
535 <group>540 <group>
536 <_short>Appearance</_short>541 <_short>Appearance</_short>
537 <option name="draw_indicator" type="bool">542 <option name="draw_indicator" type="bool">
538 <_short>Draw Indicator</_short>543 <_short>Preview Indicator</_short>
539 <_long>Draw Window Resize Indicator</_long>544 <_long>Draw a window resize indicator preview.</_long>
540 <default>true</default>545 <default>true</default>
541 </option>546 </option>
542 <option name="draw_stretched_window" type="bool">547 <option name="draw_stretched_window" type="bool">
543 <_short>Draw Stretched Window</_short>548 <_short>Stretched Live Window Preview</_short>
544 <_long>Draw stretched window animation</_long>549 <_long>Draw a stretched live window content animation.</_long>
545 <default>true</default>550 <default>true</default>
546 </option>551 </option>
547 <option name="animation_duration" type="int">552 <option name="animation_duration" type="int">
548 <_short>Animation Duration</_short>553 <_short>Preview Animation Duration</_short>
549 <_long>Grid animation duration (in ms)</_long>554 <_long>Preview animation duration (in ms).</_long>
550 <default>350</default>555 <default>350</default>
551 <min>0</min>556 <min>0</min>
552 </option>557 </option>
553 <option name="outline_color" type="color">558 <option name="outline_color" type="color">
554 <_short>Outline Color</_short>559 <_short>Preview Outline Color</_short>
555 <_long>Color of the resize indicator outline</_long>560 <_long>Color and opacity of the resize indicator preview outline.</_long>
556 <default>561 <default>
557 <red>0xfbfb</red>562 <red>0xfbfb</red>
558 <green>0x8b8b</green>563 <green>0x8b8b</green>
@@ -561,8 +566,8 @@
561 </default>566 </default>
562 </option>567 </option>
563 <option name="fill_color" type="color">568 <option name="fill_color" type="color">
564 <_short>Fill Color</_short>569 <_short>Preview Fill Color</_short>
565 <_long>Fill color of the resize indicator</_long>570 <_long>Fill color and opacity of the resize indicator preview.</_long>
566 <default>571 <default>
567 <red>0xfbfb</red>572 <red>0xfbfb</red>
568 <green>0x8b8b</green>573 <green>0x8b8b</green>
569574
=== 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-09 08:47:24 +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))
@@ -137,6 +136,12 @@
137 bool maximizeH = where & (GridBottom | GridTop | GridMaximize);136 bool maximizeH = where & (GridBottom | GridTop | GridMaximize);
138 bool maximizeV = where & (GridLeft | GridRight | GridMaximize);137 bool maximizeV = where & (GridLeft | GridRight | GridMaximize);
139138
139 bool horzMaximizedGridPosition = where & (GridTop | GridBottom);
140 bool vertMaximizedGridPosition = where & (GridLeft | GridRight);
141 bool anyMaximizedGridPosition = horzMaximizedGridPosition ||
142 vertMaximizedGridPosition ||
143 where & GridMaximize;
144
140 if (!(cw->actions () & CompWindowActionResizeMask))145 if (!(cw->actions () & CompWindowActionResizeMask))
141 return false;146 return false;
142147
@@ -169,23 +174,23 @@
169 if (props.numCellsX == 1)174 if (props.numCellsX == 1)
170 centerCheck = true;175 centerCheck = true;
171176
172 if (!gw->isGridResized)177 /* Do not overwrite the original size if we already have been gridded */
178 if (!gw->isGridResized && !gw->isGridHorzMaximized && !gw->isGridVertMaximized)
173 /* Store size not including borders when using a keybinding */179 /* Store size not including borders when using a keybinding */
174 gw->originalSize = slotToRect(cw, cw->serverBorderRect ());180 gw->originalSize = slotToRect(cw, cw->serverBorderRect ());
175 }181 }
176182
177 if ((cw->state () & MAXIMIZE_STATE) &&183 if ((cw->state () & MAXIMIZE_STATE) &&
178 (resize || optionGetSnapoffMaximized ()))184 (resize || optionGetSnapoffMaximized ()))
179 {
180 /* maximized state interferes with us, clear it */185 /* maximized state interferes with us, clear it */
181 cw->maximize (0);186 cw->maximize (0);
182 }
183187
184 if ((where & GridMaximize) && resize)188 if ((where & GridMaximize) && resize)
185 {189 {
186 /* move the window to the correct output */190 /* move the window to the correct output */
187 if (cw == mGrabWindow)191 if (cw == mGrabWindow)
188 {192 {
193 /* TODO: Remove these magic numbers */
189 xwc.x = workarea.x () + 50;194 xwc.x = workarea.x () + 50;
190 xwc.y = workarea.y () + 50;195 xwc.y = workarea.y () + 50;
191 xwc.width = workarea.width ();196 xwc.width = workarea.width ();
@@ -198,7 +203,9 @@
198 * gridded one.203 * gridded one.
199 */204 */
200 gw->isGridResized = false;205 gw->isGridResized = false;
201 gw->isGridSemiMaximized = false;206 gw->isGridHorzMaximized = false;
207 gw->isGridVertMaximized = false;
208
202 for (unsigned int i = 0; i < animations.size (); i++)209 for (unsigned int i = 0; i < animations.size (); i++)
203 animations.at (i).fadingOut = true;210 animations.at (i).fadingOut = true;
204 return true;211 return true;
@@ -219,20 +226,43 @@
219 (workarea.width () / props.numCellsX));226 (workarea.width () / props.numCellsX));
220 desiredSlot.setWidth (workarea.width () / props.numCellsX);227 desiredSlot.setWidth (workarea.width () / props.numCellsX);
221228
222 /* Adjust for constraints and decorations */229 if (!optionGetCycleSizes ())
223 if (where & ~(GridMaximize | GridLeft | GridRight))230 {
224 desiredRect = constrainSize (cw, desiredSlot);231 /* Adjust for constraints and decorations */
225 else232 if (!anyMaximizedGridPosition)
226 desiredRect = slotToRect (cw, desiredSlot);233 desiredRect = constrainSize (cw, desiredSlot);
234 else
235 desiredRect = slotToRect (cw, desiredSlot);
236 }
237 else /* (optionGetCycleSizes ()) */
238 {
239 /* Adjust for constraints and decorations */
240 if (where & ~GridMaximize)
241 desiredRect = constrainSize (cw, desiredSlot);
242 else
243 desiredRect = slotToRect (cw, desiredSlot);
244 }
227245
228 /* Get current rect not including decorations */246 /* Get current rect not including decorations */
229 currentRect.setGeometry (cw->serverX (), cw->serverY (),247 currentRect.setGeometry (cw->serverX (), cw->serverY (),
230 cw->serverWidth (),248 cw->serverWidth (),
231 cw->serverHeight ());249 cw->serverHeight ());
232250
233 if (desiredRect.y () == currentRect.y () &&251 /* We do not want to allow cycling through sizes,
234 desiredRect.height () == currentRect.height () &&252 * unless the user explicitely specified that in CCSM
235 where & ~(GridMaximize | GridLeft | GridRight) && gw->lastTarget & where)253 */
254 if (gw->lastTarget == where &&
255 gw->isGridResized &&
256 !optionGetCycleSizes ())
257 return false;
258
259 /* !(Grid Left/Right/Top/Bottom) are only valid here, if
260 * cycling through sizes is disabled also
261 */
262 if ((where & ~(GridMaximize) ||
263 ((!horzMaximizedGridPosition || !vertMaximizedGridPosition) &&
264 !optionGetCycleSizes ())) &&
265 gw->lastTarget & where)
236 {266 {
237 int slotWidth25 = workarea.width () / 4;267 int slotWidth25 = workarea.width () / 4;
238 int slotWidth33 = (workarea.width () / 3) + cw->border ().left;268 int slotWidth33 = (workarea.width () / 3) + cw->border ().left;
@@ -258,34 +288,38 @@
258 props.gravityRight * slotWidth33);288 props.gravityRight * slotWidth33);
259 gw->resizeCount++;289 gw->resizeCount++;
260 break;290 break;
291
261 case 2:292 case 2:
262 gw->resizeCount++;293 gw->resizeCount++;
263 break;294 break;
295
264 case 3:296 case 3:
265 desiredSlot.setWidth (slotWidth33);297 desiredSlot.setWidth (slotWidth33);
266 desiredSlot.setX (workarea.x () +298 desiredSlot.setX (workarea.x () +
267 props.gravityRight * slotWidth66);299 props.gravityRight * slotWidth66);
268 gw->resizeCount++;300 gw->resizeCount++;
269 break;301 break;
302
270 case 4:303 case 4:
271 desiredSlot.setWidth (slotWidth25);304 desiredSlot.setWidth (slotWidth25);
272 desiredSlot.setX (workarea.x () +305 desiredSlot.setX (workarea.x () +
273 props.gravityRight * slotWidth75);306 props.gravityRight * slotWidth75);
274 gw->resizeCount++;307 gw->resizeCount++;
275 break;308 break;
309
276 case 5:310 case 5:
277 desiredSlot.setWidth (slotWidth75);311 desiredSlot.setWidth (slotWidth75);
278 desiredSlot.setX (workarea.x () +312 desiredSlot.setX (workarea.x () +
279 props.gravityRight * slotWidth25);313 props.gravityRight * slotWidth25);
280 gw->resizeCount++;314 gw->resizeCount++;
281 break;315 break;
316
282 default:317 default:
283 break;318 break;
284 }319 }
285 }320 }
286 else /* keys (2, 5, 8) */321 else /* keys (2, 5, 8) */
287 {322 {
288
289 if ((currentRect.width () == desiredRect.width () &&323 if ((currentRect.width () == desiredRect.width () &&
290 currentRect.x () == desiredRect.x ()) ||324 currentRect.x () == desiredRect.x ()) ||
291 (gw->resizeCount < 1) || (gw->resizeCount > 5))325 (gw->resizeCount < 1) || (gw->resizeCount > 5))
@@ -299,6 +333,7 @@
299 desiredSlot.setX (workarea.x () + slotWidth17);333 desiredSlot.setX (workarea.x () + slotWidth17);
300 gw->resizeCount++;334 gw->resizeCount++;
301 break;335 break;
336
302 case 2:337 case 2:
303 desiredSlot.setWidth ((slotWidth25 * 2) +338 desiredSlot.setWidth ((slotWidth25 * 2) +
304 (slotWidth17 * 2));339 (slotWidth17 * 2));
@@ -306,20 +341,25 @@
306 (slotWidth25 - slotWidth17));341 (slotWidth25 - slotWidth17));
307 gw->resizeCount++;342 gw->resizeCount++;
308 break;343 break;
344
309 case 3:345 case 3:
310 desiredSlot.setWidth ((slotWidth25 * 2));346 desiredSlot.setWidth ((slotWidth25 * 2));
311 desiredSlot.setX (workarea.x () + slotWidth25);347 desiredSlot.setX (workarea.x () + slotWidth25);
312 gw->resizeCount++;348 gw->resizeCount++;
313 break;349 break;
350
314 case 4:351 case 4:
315 desiredSlot.setWidth (slotWidth33 -352 desiredSlot.setWidth (slotWidth33 -
316 (cw->border ().left + cw->border ().right));353 (cw->border ().left +
354 cw->border ().right));
317 desiredSlot.setX (workarea.x () + slotWidth33);355 desiredSlot.setX (workarea.x () + slotWidth33);
318 gw->resizeCount++;356 gw->resizeCount++;
319 break;357 break;
358
320 case 5:359 case 5:
321 gw->resizeCount++;360 gw->resizeCount++;
322 break;361 break;
362
323 default:363 default:
324 break;364 break;
325 }365 }
@@ -352,37 +392,63 @@
352392
353 gw->sizeHintsFlags = 0;393 gw->sizeHintsFlags = 0;
354394
355 /* Special case for left and right, actually vertically maximize395 if (!optionGetCycleSizes ())
356 * the window */
357 if (where & GridLeft || where & GridRight)
358 {396 {
359 /* First restore the window to its original size */397 /* Special cases for left/right and top/bottom gridded windows, where we
360 XWindowChanges rwc;398 * actually vertically respective horizontally semi-maximize the window
361399 */
362 rwc.x = gw->originalSize.x ();400 if (horzMaximizedGridPosition || vertMaximizedGridPosition)
363 rwc.y = gw->originalSize.y ();401 {
364 rwc.width = gw->originalSize.width ();402 /* First restore the window to its original size */
365 rwc.height = gw->originalSize.height ();403 XWindowChanges rwc;
366404
367 cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &rwc);405 rwc.x = gw->originalSize.x ();
368406 rwc.y = gw->originalSize.y ();
369 gw->isGridSemiMaximized = true;407 rwc.width = gw->originalSize.width ();
370 gw->isGridResized = false;408 rwc.height = gw->originalSize.height ();
371409
372 /* Maximize the window */410 cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &rwc);
373 cw->maximize (CompWindowStateMaximizedVertMask);411
374412 /* GridLeft || GridRight */
375 /* Be evil */413 if (vertMaximizedGridPosition)
376 if (cw->sizeHints ().flags & PResizeInc)414 {
377 {415 gw->isGridVertMaximized = true;
378 gw->sizeHintsFlags |= PResizeInc;416 gw->isGridHorzMaximized = false;
379 gw->window->sizeHints ().flags &= ~(PResizeInc);417 gw->isGridResized = false;
418
419 /* Semi-maximize the window vertically */
420 cw->maximize (CompWindowStateMaximizedVertMask);
421 }
422 /* GridTop || GridBottom */
423 else /* (horzMaximizedGridPosition) */
424 {
425 gw->isGridHorzMaximized = true;
426 gw->isGridVertMaximized = false;
427 gw->isGridResized = false;
428
429 /* Semi-maximize the window horizontally */
430 cw->maximize (CompWindowStateMaximizedHorzMask);
431 }
432
433 /* Be evil */
434 if (cw->sizeHints ().flags & PResizeInc)
435 {
436 gw->sizeHintsFlags |= PResizeInc;
437 gw->window->sizeHints ().flags &= ~(PResizeInc);
438 }
439 }
440 else /* GridCorners || GridCenter */
441 {
442 gw->isGridResized = true;
443 gw->isGridHorzMaximized = false;
444 gw->isGridVertMaximized = false;
380 }445 }
381 }446 }
382 else447 else /* if (optionGetCycleSizes ()) */
383 {448 {
384 gw->isGridResized = true;449 gw->isGridResized = true;
385 gw->isGridSemiMaximized = false;450 gw->isGridHorzMaximized = false;
451 gw->isGridVertMaximized = false;
386 }452 }
387453
388 int dw = (lastBorder.left + lastBorder.right) -454 int dw = (lastBorder.left + lastBorder.right) -
@@ -657,31 +723,40 @@
657{723{
658 int ret;724 int ret;
659725
660 switch (edge) {726 switch (edge)
727 {
661 case Left:728 case Left:
662 ret = (int) optionGetLeftEdgeAction ();729 ret = (int) optionGetLeftEdgeAction ();
663 break;730 break;
731
664 case Right:732 case Right:
665 ret = (int) optionGetRightEdgeAction ();733 ret = (int) optionGetRightEdgeAction ();
666 break;734 break;
735
667 case Top:736 case Top:
668 ret = (int) optionGetTopEdgeAction ();737 ret = (int) optionGetTopEdgeAction ();
669 break;738 break;
739
670 case Bottom:740 case Bottom:
671 ret = (int) optionGetBottomEdgeAction ();741 ret = (int) optionGetBottomEdgeAction ();
672 break;742 break;
743
673 case TopLeft:744 case TopLeft:
674 ret = (int) optionGetTopLeftCornerAction ();745 ret = (int) optionGetTopLeftCornerAction ();
675 break;746 break;
747
676 case TopRight:748 case TopRight:
677 ret = (int) optionGetTopRightCornerAction ();749 ret = (int) optionGetTopRightCornerAction ();
678 break;750 break;
751
679 case BottomLeft:752 case BottomLeft:
680 ret = (int) optionGetBottomLeftCornerAction ();753 ret = (int) optionGetBottomLeftCornerAction ();
681 break;754 break;
755
682 case BottomRight:756 case BottomRight:
683 ret = (int) optionGetBottomRightCornerAction ();757 ret = (int) optionGetBottomRightCornerAction ();
684 break;758 break;
759
685 case NoEdge:760 case NoEdge:
686 default:761 default:
687 ret = -1;762 ret = -1;
@@ -694,7 +769,6 @@
694void769void
695GridScreen::handleEvent (XEvent *event)770GridScreen::handleEvent (XEvent *event)
696{771{
697 CompOutput out;
698 CompWindow *w;772 CompWindow *w;
699773
700 screen->handleEvent (event);774 screen->handleEvent (event);
@@ -706,6 +780,7 @@
706780
707 currentWorkarea = screen->getWorkareaForOutput781 currentWorkarea = screen->getWorkareaForOutput
708 (screen->outputDeviceForPoint (pointerX, pointerY));782 (screen->outputDeviceForPoint (pointerX, pointerY));
783
709 if (lastWorkarea != currentWorkarea)784 if (lastWorkarea != currentWorkarea)
710 {785 {
711 lastWorkarea = currentWorkarea;786 lastWorkarea = currentWorkarea;
@@ -719,7 +794,7 @@
719 cScreen->damageRegion (desiredSlot);794 cScreen->damageRegion (desiredSlot);
720 }795 }
721796
722 out = screen->outputDevs ().at (797 CompOutput out = screen->outputDevs ().at (
723 screen->outputDeviceForPoint (CompPoint (pointerX, pointerY)));798 screen->outputDeviceForPoint (CompPoint (pointerX, pointerY)));
724799
725 /* Detect corners first */800 /* Detect corners first */
@@ -843,8 +918,8 @@
843918
844 /* Don't allow non-pagers to change919 /* Don't allow non-pagers to change
845 * the size of the window, the user920 * the size of the window, the user
846 * specified this size, thank-you */921 * specified this size */
847 if (isGridSemiMaximized)922 if (isGridHorzMaximized || isGridVertMaximized)
848 if (source != ClientTypePager)923 if (source != ClientTypePager)
849 xwcm = 0;924 xwcm = 0;
850}925}
@@ -868,7 +943,10 @@
868 pointerBufDx = pointerBufDy = 0;943 pointerBufDx = pointerBufDy = 0;
869 grabMask = mask;944 grabMask = mask;
870945
871 if (!isGridResized && !isGridSemiMaximized && gScreen->optionGetSnapbackWindows ())946 if (!isGridResized &&
947 !isGridHorzMaximized &&
948 !isGridVertMaximized &&
949 gScreen->optionGetSnapbackWindows ())
872 /* Store size not including borders when grabbing with cursor */950 /* Store size not including borders when grabbing with cursor */
873 originalSize = gScreen->slotToRect(window,951 originalSize = gScreen->slotToRect(window,
874 window->serverBorderRect ());952 window->serverBorderRect ());
@@ -909,8 +987,18 @@
909{987{
910 window->moveNotify (dx, dy, immediate);988 window->moveNotify (dx, dy, immediate);
911989
912 if (isGridResized && !isGridSemiMaximized && !GridScreen::get (screen)->mSwitchingVp)990 if (isGridResized &&
991 !isGridHorzMaximized &&
992 !isGridVertMaximized &&
993 !GridScreen::get (screen)->mSwitchingVp)
913 {994 {
995 if (window->grabbed () && screen->grabExist ("expo"))
996 {
997 /* Window is being dragged in expo. Restore the original geometry
998 * right away to avoid any confusion. */
999 gScreen->restoreWindow (0, 0, gScreen->o);
1000 return;
1001 }
914 if (window->grabbed () && (grabMask & CompWindowGrabMoveMask))1002 if (window->grabbed () && (grabMask & CompWindowGrabMoveMask))
915 {1003 {
916 pointerBufDx += dx;1004 pointerBufDx += dx;
@@ -933,7 +1021,10 @@
933 !(window->state () & MAXIMIZE_STATE))1021 !(window->state () & MAXIMIZE_STATE))
934 {1022 {
935 lastTarget = GridUnknown;1023 lastTarget = GridUnknown;
936 if (isGridSemiMaximized && (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedVertMask)1024 if ((isGridHorzMaximized &&
1025 (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedHorzMask) ||
1026 (isGridVertMaximized &&
1027 (lastState & MAXIMIZE_STATE) == CompWindowStateMaximizedVertMask))
937 gScreen->restoreWindow(0, 0, gScreen->o);1028 gScreen->restoreWindow(0, 0, gScreen->o);
938 }1029 }
939 else if (!(lastState & MAXIMIZE_STATE) &&1030 else if (!(lastState & MAXIMIZE_STATE) &&
@@ -969,7 +1060,9 @@
9691060
970 GRID_WINDOW (cw);1061 GRID_WINDOW (cw);
9711062
972 if (!gw->isGridResized && !gw->isGridSemiMaximized)1063 if (!gw->isGridResized &&
1064 !gw->isGridHorzMaximized &&
1065 !gw->isGridVertMaximized)
973 {1066 {
974 /* Grid hasn't touched this window or has maximized it. If it's1067 /* Grid hasn't touched this window or has maximized it. If it's
975 * maximized, unmaximize it and get out. */1068 * maximized, unmaximize it and get out. */
@@ -977,25 +1070,38 @@
977 cw->maximize(0);1070 cw->maximize(0);
978 return true;1071 return true;
979 }1072 }
9801073 else if (!gw->isGridResized &&
981 else if (!gw->isGridResized && gw->isGridSemiMaximized)1074 gw->isGridHorzMaximized &&
1075 !gw->isGridVertMaximized)
1076 {
1077 /* Window has been horizontally maximized by grid. We only need
1078 * to restore Y and height - core handles X and width. */
1079 if (gw->sizeHintsFlags)
1080 gw->window->sizeHints ().flags |= gw->sizeHintsFlags;
1081 xwcm |= CWY | CWHeight;
1082 }
1083 else if (!gw->isGridResized &&
1084 !gw->isGridHorzMaximized &&
1085 gw->isGridVertMaximized)
982 {1086 {
983 /* Window has been vertically maximized by grid. We only need1087 /* Window has been vertically maximized by grid. We only need
984 * to restore the X and width - core handles Y and height. */1088 * to restore X and width - core handles Y and height. */
985 if (gw->sizeHintsFlags)1089 if (gw->sizeHintsFlags)
986 gw->window->sizeHints ().flags |= gw->sizeHintsFlags;1090 gw->window->sizeHints ().flags |= gw->sizeHintsFlags;
987 xwcm |= CWX | CWWidth;1091 xwcm |= CWX | CWWidth;
988 }1092 }
9891093 else if (gw->isGridResized &&
990 else if (gw->isGridResized && !gw->isGridSemiMaximized)1094 !gw->isGridHorzMaximized &&
991 /* Window is just gridded (top, bottom, center, corners). We1095 !gw->isGridVertMaximized)
992 * need to handle everything. */1096 /* Window is just gridded (center, corners).
1097 * We need to handle everything. */
993 xwcm |= CWX | CWY | CWWidth | CWHeight;1098 xwcm |= CWX | CWY | CWWidth | CWHeight;
994 else1099 else
995 {1100 {
996 /* This should never happen. But if it does, just bail out1101 /* This should never happen. But if it does, just bail out
997 * gracefully. */1102 * gracefully. */
998 assert (gw->isGridResized && gw->isGridSemiMaximized);1103 assert (gw->isGridResized &&
1104 (gw->isGridHorzMaximized || gw->isGridVertMaximized));
999 return false;1105 return false;
1000 }1106 }
10011107
@@ -1004,6 +1110,16 @@
1004 xwc.x = pointerX - (gw->originalSize.width () / 2);1110 xwc.x = pointerX - (gw->originalSize.width () / 2);
1005 xwc.y = pointerY + (cw->border ().top / 2);1111 xwc.y = pointerY + (cw->border ().top / 2);
1006 }1112 }
1113 else if (cw->grabbed () && screen->grabExist ("expo"))
1114 {
1115 /* We're restoring a window inside expo by dragging. This is a bit
1116 * tricky. Pointer location is absolute to the screen, not relative
1117 * to expo viewport. So we can't use pointer location to calculate
1118 * the position of the restore window.
1119 *
1120 * The best solution is to resize it in place. */
1121 xwcm = CWWidth | CWHeight;
1122 }
1007 else1123 else
1008 {1124 {
1009 xwc.x = gw->originalSize.x ();1125 xwc.x = gw->originalSize.x ();
@@ -1018,7 +1134,8 @@
1018 gw->currentSize = CompRect ();1134 gw->currentSize = CompRect ();
1019 gw->pointerBufDx = 0;1135 gw->pointerBufDx = 0;
1020 gw->pointerBufDy = 0;1136 gw->pointerBufDy = 0;
1021 gw->isGridSemiMaximized = false;1137 gw->isGridHorzMaximized = false;
1138 gw->isGridVertMaximized = false;
1022 gw->isGridResized = false;1139 gw->isGridResized = false;
1023 if (cw->state () & MAXIMIZE_STATE)1140 if (cw->state () & MAXIMIZE_STATE)
1024 cw->maximize(0);1141 cw->maximize(0);
@@ -1035,7 +1152,8 @@
1035 GRID_WINDOW (screen->findWindow1152 GRID_WINDOW (screen->findWindow
1036 (CompOption::getIntOptionNamed (o, "window")));1153 (CompOption::getIntOptionNamed (o, "window")));
1037 gw->isGridResized = false;1154 gw->isGridResized = false;
1038 gw->isGridSemiMaximized = false;1155 gw->isGridHorzMaximized = false;
1156 gw->isGridVertMaximized = false;
1039 gw->resizeCount = 0;1157 gw->resizeCount = 0;
1040}1158}
10411159
@@ -1197,7 +1315,8 @@
1197 gWindow (GLWindow::get(window)),1315 gWindow (GLWindow::get(window)),
1198 gScreen (GridScreen::get (screen)),1316 gScreen (GridScreen::get (screen)),
1199 isGridResized (false),1317 isGridResized (false),
1200 isGridSemiMaximized (false),1318 isGridHorzMaximized (false),
1319 isGridVertMaximized (false),
1201 grabMask (0),1320 grabMask (0),
1202 pointerBufDx (0),1321 pointerBufDx (0),
1203 pointerBufDy (0),1322 pointerBufDy (0),
12041323
=== 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-09 08:47:24 +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;

Subscribers

People subscribed via source and target branches