GNOME Bugzilla – Bug 645153
make windows resizable by window-border-drag when in half-fullscreen-snap-mode
Last modified: 2017-10-03 22:58:21 UTC
If a window is dragged to the right side of the screen it is switched to half-fullscreen-snap-mode, filling the half screen. Resizing the window at the left border works via Alt+MiddleClick but not by directly dragging the left border. As soon as it is resized via Alt+MiddleClick it can be dragged at the border again.
possibly NOTABUG; it's consistent with maximized behavior, although in the maximized case, there isn't any border to grab...
I think being able to change the division while keeping tiled would be fairly neat. We dont' really *have* a window border to grab (though 2 pixels in this case rather than just one), but maybe if you grabbed the resize handle on the window to the left? Non trivial, however, with the way that tiling is implemented.
*** Bug 647846 has been marked as a duplicate of this bug. ***
*** Bug 650149 has been marked as a duplicate of this bug. ***
*** Bug 654147 has been marked as a duplicate of this bug. ***
My comment from bug 654147: This would be really nice, since it seems typical to want to have one window larger than the other when they are side by side. Some details that need working out: 1) What proportion of the screen should windows use when they are snapped in place? Should smaller windows keep their previous width after being snapped, for example? 2) Should it be possible to snap windows that have a fixed size. I'm mostly thinking of the calculator here; are there any other relevant apps? 3) How should resizing be accomplished exactly?
1: 50/50, like now - or if you snap one window first and then resize it horizontally, the next window you snap on the opposite side could use up the rest of the available space instead of 50%. 2: I can't think of any use cases for that. 3: Currently Gnome disables the resize handles when windows are snapped and indeed draws no cursor for it. I assume that it would be possible to draw a <-||-> cursor on the right edge of the left window and left edge of the right window that when dragged would resize both?
(In reply to comment #6) > This would be really nice, since it seems typical to want to have one window > larger than the other when they are side by side. > > Some details that need working out: [...] For me the most important question is how "global" we want the resizing operation to be. For instance, if we have windows A and B tiled side-by-side, I think we want the resizing operation to affect both windows. But what should happen if we have windows A, C and B, with C being untiled? And what should then happen if the stacking order changes so A and B are again next to each other? With the current code, a global resizing factor that affects all tiled windows would be easiest to implement, while with the patch in bug 642580 it would be easier to treat each tiled window completely separately ...
My comment from bug 654147: 4) Should we try to resize the complementary window? There might be more than one, but I guess that a good heuristic is taking the one, if any, that's visible at resizing start without anything covering it. (In reply to comment #8) > For me the most important question is how "global" we want the resizing > operation to be. For instance, if we have windows A and B tiled side-by-side, I > think we want the resizing operation to affect both windows. But what should > happen if we have windows A, C and B, with C being untiled? And what should > then happen if the stacking order changes so A and B are again next to each > other? > > With the current code, a global resizing factor that affects all tiled windows > would be easiest to implement, while with the patch in bug 642580 it would be > easier to treat each tiled window completely separately ... Florian, have you started doing this? I can give it a try. Can I build on top of the patch in bug 642580?
my 2 cents: I think the feel should be that the two side-by-side tiled windows 'snap together'. That would include removing the shadow the cast on each other at the shared edge, as well as the ability to drag the shared edge the left and right to adjust their relative size.
I actually use most of my windows half-maximized or maximized. Most of the time, I have several half-maximized windows "stacked" on top of each other, i.e: - I view A and B side by side, the former snapped to the left and the latter snapped to the right - I have C snapped to the right, and with alt-tab I can easily change to view A and B or A and C How would the resize work then? Like Matthias, I agree that if A is snapped to the left and B is snapped to the right, then they should feel 'snapped together' (and I agree that the shadow they cast on each other is one of the major annoyance I have ATM). But if I drag the shared edge to change their relative size, what happens with C? (which, as a reminder, was snapped to the right but invisible because under B) 1. keeping it half-maximized makes it look out of place when alt-tabbing to view A and C side-by-side (i.e either A will be overlapping under C or there will be some empty space in between) 2. resizing along with B may be surprising/confusing for the user ("why did that window changed its size all by itself?)
(In reply to comment #11) > But if I drag the shared edge to change their relative size, what happens with > C? (which, as a reminder, was snapped to the right but invisible because under > B) > 1. keeping it half-maximized makes it look out of place when alt-tabbing to > view A and C side-by-side (i.e either A will be overlapping under C or there > will be some empty space in between) > 2. resizing along with B may be surprising/confusing for the user ("why did > that window changed its size all by itself?) Right, that's why I propose we implement your option 1 here. If the user is annoyed at C's size then he can resize it the first time after alt-tabbing to it.
Created attachment 192790 [details] [review] tiling: allow tiled windows to be resized We allow tiled windows to be resized but only on their left or right edge for right or left tiled windows respectively.
Created attachment 192791 [details] [review] tiling: allow resizing of two matching tiled windows in tandem
(In reply to comment #12) > (In reply to comment #11) > > But if I drag the shared edge to change their relative size, what happens with > > C? (which, as a reminder, was snapped to the right but invisible because under > > B) > > 1. keeping it half-maximized makes it look out of place when alt-tabbing to > > view A and C side-by-side (i.e either A will be overlapping under C or there > > will be some empty space in between) > > 2. resizing along with B may be surprising/confusing for the user ("why did > > that window changed its size all by itself?) > > Right, that's why I propose we implement your option 1 here. If the user is > annoyed at C's size then he can resize it the first time after alt-tabbing to > it. I implemented this. These patches depend on the patch in bug 642580.
Created attachment 192845 [details] [review] tiling: allow resizing of two matching tiled windows in tandem -- Fixed a thinko in the meta_window_find_tile_match() logic.
Created attachment 193000 [details] [review] tiling: allow tiled windows to be resized We allow tiled windows to be resized but only on their left or right edge for right or left tiled windows respectively. -- 1) take the frame into account when updating tile_rect.width
Created attachment 193005 [details] [review] tiling: allow resizing of two matching tiled windows in tandem This is stateless operation, i.e. we just group the windows while resizing, after that, there's no further link between them. The match to the resizing window is chosen at the operation's beginning according to an heuristic: it's the topmost tiled window in a complementary tile mode that is: - on the same monitor; - on the same workspace; - spanning the remaining monitor width; - totally uncovered by other "regular" windows. -- 1) wrote an actual commit message 2) use new_h instead of 0 for the match window resizing 3) style and comment fixes
Created attachment 193553 [details] [review] tiling: allow tiled windows to be resized We allow tiled windows to be resized but only on their left or right edge for right or left tiled windows respectively. -- - Rebased on master - This is now _much_ easier to test/use due to bug 644930 having been fixed
Created attachment 193554 [details] [review] tiling: allow resizing of two matching tiled windows in tandem This is a stateless operation, i.e. we just group the windows while resizing, after that, there's no further link between them. The match to the resizing window is chosen at the operation's beginning according to an heuristic: it's the topmost tiled window in a complementary tile mode that is: - on the same monitor; - on the same workspace; - spanning the remaining monitor width; - totally uncovered by other "regular" windows. -- - Rebased on master
Created attachment 193560 [details] [review] tiling: allow tiled windows to be resized We allow tiled windows to be resized but only on their left or right edge for right or left tiled windows respectively. -- Actually tested the rebase now... sorry for the churn.
Created attachment 193561 [details] [review] tiling: allow resizing of two matching tiled windows in tandem This is a stateless operation, i.e. we just group the windows while resizing, after that, there's no further link between them. The match to the resizing window is chosen at the operation's beginning according to an heuristic: it's the topmost tiled window in a complementary tile mode that is: - on the same monitor; - on the same workspace; - spanning the remaining monitor width; - totally uncovered by other "regular" windows. -- Actually tested the rebase now... sorry for the churn.
I'd like to advocate for a "global" resize option, where resizing one tiled window also resizes all the others to match and possibly preserves the divider position as a preference. I find that exactly half of the screen is rarely useful (a browser would not be wide enough to view a typical web page, for example). And I think the user surprise is not a problem as long as users understand that tiled windows are different (if they don't, it needs to be made more obvious; I'd suggest removing the outer edges completely, so that only the one resizeable border is visible). Failing that, if I attach something to the right edge while something on the left edge is topmost, it should complement that window's size, rather than defaulting to 50%. Thanks for working on this, by the way. Even without resizing in tandem, I feel this simple change will make Gnome 3 much more usable for me.
Created attachment 194539 [details] [review] tiling: allow resizing of two matching tiled windows in tandem This is a stateless operation, i.e. we just group the windows while resizing, after that, there's no further link between them. The match to the resizing window is chosen at the operation's beginning according to an heuristic: it's the topmost tiled window in a complementary tile mode that is: - on the same monitor; - on the same workspace; - spanning the remaining monitor width. -- - removed the "totally uncovered by other "regular" windows" requirement for finding a matching window since it doesn't look all that unsettling in practice and because it allows me to use this for bug 643075.
Florian, any progress on this ?
Sadly, not going to make it for 3.2 after all
Review of attachment 193560 [details] [review]: ::: src/ui/frames.c @@ +2640,3 @@ + + if (flags & META_FRAME_TILED_LEFT || flags & META_FRAME_TILED_RIGHT) + has_vert = has_horiz = FALSE; Instead of setting has_vert here, it should be in META_WINDOW_ALLOWS_VERTICAL_RESIZE. Instead of turning off has_horiz, have "has_horiz_w" and "has_horiz_e" which replace has_horiz. They're equivalent to: (flags & (META_FRAME_TILED_LEFT | META_FRAME_ALLOWS_HORIZONTAL_RESIZE)) != 0. This way the logic for the ordinal directions should be a lot more clear.
Review of attachment 194539 [details] [review]: Trying out this patch brings an interesting behavior when: tiling one window, resizing it, and tiling another on the other side. I feel that the other window should snap to the remaining area and be associated with the other window, rather than the half-width of my monitor. For something like an Empathy Buddy List + Empathy Chat Window, I would really appreciate this. ::: src/core/window.c @@ +8629,3 @@ + { + match_window->tile_rect.x += new_w - window->tile_rect.width; + match_window->tile_rect.width += window->tile_rect.width - new_w; Hard to read as well. Something like: int delta_width = new_w - window->tile_rect.width; match_window->tile_rect.x += delta_width; match_window->tile_rect.width -= delta_width; would be better. @@ +8862,3 @@ meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity); + + if (window->display->grab_tile_match_window) This should have braces. @@ +8869,3 @@ + meta_window_resize_with_gravity (window->display->grab_tile_match_window, + TRUE, 0, new_h, + gravity == EastGravity ? This should be a separate if statement above. It took me a minute to read it this way. @@ +10378,3 @@ + + /* Since @window is the one being resized it must be at the top of the stack + * given that it has focus. Therefore we search below. This isn't true. The user doesn't have to be resizing anything -- an external program could be: a gnome-shell extension, a random X utility, the window could be sending a ConfigureRequest itself. And it isn't really appropriate for a function called "meta_window_find_tile_match". It doesn't really make the assumption that the window needs to be the top-most. @@ +10380,3 @@ + * given that it has focus. Therefore we search below. + */ + if ((match = meta_stack_get_below (window->screen->stack, window, TRUE))) A while loop is much easier to read here: match = window; while ((match = meta_stack_get_below (window->screen->stack, match, TRUE)) { if (...) break; }
Review of attachment 194539 [details] [review]: To be honest, the behavior does not make much sense to me: 1. one window tiled at the bottom of the stack and another tiled at the top are tied together, independent from the number of "normal" windows in between 2. two tiled windows at the top of the stack are not tied together if the first one has been resized before the second one has been tiled I think it makes more sense to always tie windows together if they are "stack neighbors" (that implies that when resizing a tiled windows to 2/3, a newly tiled window should take up 1/3). I think using actual "neighbors" is probably good enough, we can always get fancier at a later point (e.g. tie windows together if they appear to be neighbors, i.e. normal windows "between" them are fully covered by the first tiled window). ::: src/core/window.c @@ +10378,3 @@ + + /* Since @window is the one being resized it must be at the top of the stack + * given that it has focus. Therefore we search below. There's a much more obvious case where the assumption is false: windows with the KEEP_ABOVE flag set are kept above the focus window.
*** Bug 648712 has been marked as a duplicate of this bug. ***
So, I'd like to restart working on this. This time though, let's try to agree on behavior first ;-) (In reply to comment #28) > Trying out this patch brings an interesting behavior when: tiling one window, > resizing it, and tiling another on the other side. > > I feel that the other window should snap to the remaining area and be > associated with the other window, rather than the half-width of my monitor. This sounds good yes. (In reply to comment #29) > 1. one window tiled at the bottom of the stack and another tiled at the top > are tied together, independent from the number of "normal" windows in between That wasn't true with these patches btw, windows were only tied when both were fully visible. Or were you proposing that that's how it should behave? > 2. two tiled windows at the top of the stack are not tied together if the > first one has been resized before the second one has been tiled > > I think it makes more sense to always tie windows together if they are "stack > neighbors" (that implies that when resizing a tiled windows to 2/3, a newly > tiled window should take up 1/3). You agree with with Jasper above, OK. > I think using actual "neighbors" is probably > good enough, we can always get fancier at a later point (e.g. tie windows > together if they appear to be neighbors, i.e. normal windows "between" them are > fully covered by the first tiled window). This was roughly how it worked. Summing it up, it seems I was only missing resizing new tiles to the "free" width between the monitor edge and an already tiled window on the other side.
(In reply to comment #31) > (In reply to comment #29) > > 1. one window tiled at the bottom of the stack and another tiled at the top > > are tied together, independent from the number of "normal" windows in between > > That wasn't true with these patches btw, windows were only tied when both were > fully visible. Maybe that was the intention, but it was not the behavior I saw in testing :)
In addition, I think it would be good to have a way to reset the size to 50/50 for two tandem windows (or a single snapped window), after having changed the ratio to something else. Something like a snap point in the middle of the screen, (Though snap points prevent you from choosing a point close to them, so it's not my favorite solution.)
*** Bug 667117 has been marked as a duplicate of this bug. ***
*** Bug 667888 has been marked as a duplicate of this bug. ***
someone can change the status to "CONFIRMED" ? Please!, this is a necessary feature for the 3.4 release!, i'm waiting for this from 3.0
*** Bug 684992 has been marked as a duplicate of this bug. ***
*** Bug 696348 has been marked as a duplicate of this bug. ***
*** Bug 701068 has been marked as a duplicate of this bug. ***
*** Bug 706981 has been marked as a duplicate of this bug. ***
Even after 3 years still UNCONFIRMED and resizing still doesn't work... you must be joking, right ?!
We don't differentiate between UNCONFIRMED and NEW -- all of them are equally valid bugs. But if you read above, you'll find that the behavior is nuanced and hard to design, especially when two are tiled side-by-side.
So why don't make it as usual, as it is in GNOME2, KDE, Xfce and LXDE, where windows tiled side-by-side just overlay each other when resized ??? At least we get resizing functionality back and you can change its behaviour when you come up with something better.
(In reply to comment #43) > So why don't make it as usual, as it is in GNOME2 [...] Uhm - GNOME 2 never did tiling?
Note that we treat tiling as a maximization state, and as for maximized windows, you can use mouse-button-modifier (<super> by default) + middle button to force a resize operation.
(In reply to comment #44) > (In reply to comment #43) > > So why don't make it as usual, as it is in GNOME2 [...] > > Uhm - GNOME 2 never did tiling? Oh yes, GNOME2 had no tiling. (In reply to comment #45) > Note that we treat tiling as a maximization state, and as for maximized > windows, you can use mouse-button-modifier (<super> by default) + middle button > to force a resize operation. Great, I didn't know about <super>+<middle button> feature. So what about make it default (because normal users have NO CHANCE to discover this <super>+<middle button> feature) ? You will still treat tiled window as maximized, you just change its vertical size on user action. I tested Ubuntu 13.04 recently and they had it like this and it is very intuitive, so try their live CD if you don't know how I mean it.
*** Bug 707990 has been marked as a duplicate of this bug. ***
I'm the one who submitted bug 707990 - thanks Florian and sorry for the noise! If https://bugzilla.gnome.org/robots.txt would not ban all search engines it would probably be easier to find existing bugs. On topic: In Windows 7 and Ubuntu, you can just drag the edge, it's intuitive and works quite well. The alt+middle über-combo will keep me from whining, though, now that I know about it.
*** Bug 712226 has been marked as a duplicate of this bug. ***
*** Bug 742986 has been marked as a duplicate of this bug. ***
(In reply to comment #0) > If a window is dragged to the right side of the screen it is switched to > half-fullscreen-snap-mode, filling the half screen. Resizing the window at the > left border works via Alt+MiddleClick but not by directly dragging the left > border. As soon as it is resized via Alt+MiddleClick it can be dragged at the > border again. The bad thing about using Alt+MiddleClick is that you cannot then return the window to its original state. In my opinion, the ideal implementation, is that two snapped windows should behave and resize together when resized (Chrome OS has this kind of implementation [1]). This should, as well, tell Mutter (or whatever manages this) that the windows are still snapped (i.e., they should return to their initial size via Super+Down). [1]: http://www.omgchrome.com/hidden-window-snap-resize-feature-chrome-os/
(In reply to comment #51) > (In reply to comment #0) > > If a window is dragged to the right side of the screen it is switched to > > half-fullscreen-snap-mode, filling the half screen. Resizing the window at the > > left border works via Alt+MiddleClick but not by directly dragging the left > > border. As soon as it is resized via Alt+MiddleClick it can be dragged at the > > border again. > > The bad thing about using Alt+MiddleClick is that you cannot then return the > window to its original state. > > In my opinion, the ideal implementation, is that two snapped windows should > behave and resize together when resized (Chrome OS has this kind of > implementation [1]). This should, as well, tell Mutter (or whatever manages > this) that the windows are still snapped (i.e., they should return to their > initial size via Super+Down). > > [1]: http://www.omgchrome.com/hidden-window-snap-resize-feature-chrome-os/ Totally agree. This is the way to go
*** Bug 686737 has been marked as a duplicate of this bug. ***
I just filed a related bug about the more general problem concerning vertically maximized windows (not just snapped ones): https://bugzilla.gnome.org/show_bug.cgi?id=760395 I don't know any other OS/DE that prohibits horizontal resizing for vertically maximized windows. Also, this behavior is inconsistent with horizontally maximized windows since they do allow vertical resizing. There is also the aesthetic issue concerning borders on vertically maximized windows, which look ugly without the rounded corners (with adwaita).
*** Bug 769497 has been marked as a duplicate of this bug. ***
Hello, Any news about this ? It's a long awaited feature that add some usability. I remember seeing it fixed on a video from a developing branch some time ago but that's still not in stable. By the way for me the "feature" <super>+<middle button> doesn't work (not yet checked for an existing bug report). Thanks !
@jeremy9856: Please refrain from adding comments to a bug report when your comment does not offer any additional information. Every comment creates notifications that someone has to read (who cannot write or fix code in that time), and advocacy is not welcome.
*** Bug 775968 has been marked as a duplicate of this bug. ***
Maybe there is some code that can be used from this extension that work really well ? https://git.gnome.org/browse/gtk%2B/commit/?id=fb0a13b7f070a14312dafa1e4df6ba03cf33be01
Oops ! Sorry, here it is the right link : https://extensions.gnome.org/extension/657/shelltile/
Created attachment 353586 [details] [review] window: Allow tiled windows be resized The current code forbids resizing tiled windows, and enforces that side-by-side tiled windows cover half of the current screen's width. This patch removes this restriction, and adds code to track the tiled window size isolated from the actual window size, using the following heuristics: * If the window was not tiled, cover 1/2 of the screen. * If the window was tiled, use the complement of the current width to cover the "hole" in the screen. Windows with client-side decoration does not follow this behavior for the moment, and patches for GTK+ shall be crafted to fix this in the client side. (Patch based on Tiago's 2011 work)
Created attachment 353587 [details] [review] window: Use auxiliary function to track tile mode Now that we must track the previous tile mode, updating this structure field manually is error-prone and would consume much more code than it's actually needed, when this can be delegated to a helper function. This patch, then, makes all the lines of code that used to set the tile_mode field use the newly introduced helper function.
Created attachment 353588 [details] [review] window: Tile and resize considering the tile match After the introduction of the possibility to resize tiled windows, it is a sensible decision to make windows aware of their tiling match. A tiling match is another window that is tiled in such a way that is the complement of the current window. The newly introduced behavior attepts to make tiling as smooth as possible, with the following rules: * Windows now compute their tile match when tiling and, if there's a match, they automatically complement the sibling's width. * Resizing a window with a sibling automatically resizes the sibling too to be the complement of the window's width. * It is not possible to resize below windows' minimum widths. !!!WARNING!!! This is work-in-progress, and is flawed. There are two big issues with this patch, that I'm yet to fix: Issue 1: Windows tiled in a complementary way in different workspaces, if moved to the same workspace, are considered matches and enters in an inconsistent state. Steps to reproduce: - Open window A and B. Move B to another workspace. - Tile A right, and B left. Resize them. - Move B to A's workspace. - Resize them again Issue 2: CSD windows, for some reason, change their heights on resize After a lot of debugging, I ultimately couldn't find a reason for this to be happening. (Notice that it's necessary to patch GTK+ in order to make CSD windows resizable when tiled - see bug 783669) (Patch loosely based on Tiago's 2011 work)
Created attachment 353784 [details] [review] window: Allow tiled windows be resized Fixes the CSD resizing, and in general is much improved compared to the first version. Thanks Jonas Adahl for explaining what window rects are and how these rects are supposed to be used.
Created attachment 353785 [details] [review] window: Use auxiliary function to track tile mode Now that we must track the previous tile mode, updating this structure field manually is error-prone and would consume much more code than it's actually needed, when this can be delegated to a helper function. This patch, then, makes all the lines of code that used to set the tile_mode field use the newly introduced helper function.
Created attachment 353786 [details] [review] constaints: Remove tiling constraint When it wasn't possible to resize windows when they were tiled, it made sense to have a constraint ensuring the tiled window has the correct width. Now, however, it is possible to freely resize tiled windows, and the constraint is calling unecessarily meta_window_get_current_tile_area(). This will bite us in the future. This patch removes the tiling constraint.
Created attachment 353787 [details] [review] window: Split tile mode into preview and actual After the introduction of the ability to resize tiled windows, the tiling field became stateful and should be treated carefuly, in order to keep the state valid. When dragging windows around, however, the actual tile mode is changed in order to retrieve a meaningful preview, causing many visual glitches and issues when changing tiling after dragging the window. Because of that, it is now required to track the preview tile mode differently than the actual tile mode. This patch does that, and updates the function that calculates the tile area to consider the preview tile mode as well.
Created attachment 353788 [details] [review] window: Tile and resize considering the tile match
Created attachment 353789 [details] [review] edge-resistance: Add snapping for tiled windows When windows are tiled, it improves the interaction with them when they have a set of snapping edges relative to the monitor. For example, when there's a document editor and a PDF file opened, I might want to rescale the former to 2/3 of the screen and the latter to 1/3. These snapping sections are not really tied to any other window, and only depend on the current work area of the window. Thus, it is not necessary to adapt the current snapping edge detection algorithm. This patch adds the necessary code in edge-resistance.c to special-case tiled windows and allow them to cover 1/4, 1/3 and 1/2 (horizontally) of the screen. These values are hardcoded.
Created attachment 353790 [details] [review] edge-resistance: Remove useless variable There is a variable in meta_window_edge_resistance_for_resize that isn't really helpful: it just assumes TRUE, and is passed to apply_edge_resistance_to_each_side. This patch removes that useless variable and simply pass TRUE instead.
Created attachment 353791 [details] [review] window: Allow tiled windows be resized I'm sorry for the noise. I found an error in the first two patches, so I'll reattach all of them to maintain the patch ordering.
Created attachment 353792 [details] [review] window: Use auxiliary function to track tile mode
Created attachment 353793 [details] [review] constaints: Remove tiling constraint
Created attachment 353794 [details] [review] window: Split tile mode into preview and actual
Created attachment 353795 [details] [review] window: Tile and resize considering the tile match
Created attachment 353796 [details] [review] edge-resistance: Add snapping for tiled windows
Created attachment 353797 [details] [review] edge-resistance: Remove useless variable
Hi everyone, sorry for the noise again. After fixing many other smaller issues with the code, I decided to use a branch to share the progress before actually uploading the patches here. Everyone is invited to test the "wip/gbsneto/mutter" branch, and share feedback here (or in IRC, in which case I'll document here too). When the patches are mature enough, I'll reupload them here - and oh lord, mind the Bugzilla spam. Keep in mind that CSD windows need the patch in bug 783669 to be able to resize when tiled. I'll be working on the GTK+ side after getting Mutter's patches in a good shape. With respect, Georges
I'm marking all the current patches as obsolete, and I'll attach the new ones. I've been using my branch for a couple of weeks now, and I couldn't spot any other big issues. The new patchset if orders of magnitude simpler and overall just better, and I'm pretty happy with how things are looking now. I'll continue to work on the other aspects of this feature, like passing constrained edges states to clients so that they can know about their current state and draw accordingly. This will require another patchset, and I really don't want to pollute this bug event more.
Created attachment 355372 [details] [review] window: Allow tiled windows be resized The current code forbids resizing tiled windows, and enforces that side-by-side tiled windows cover half of the current screen's width. This patch removes this restriction, and adds code to track the tiled window size isolated from the actual window size, using the following heuristics: * If the window was not tiled, cover 1/2 of the screen. * If the window was tiled, use the complement of the current width to cover the "hole" in the screen. * When resizing a tiled window to the oposite border, maximize the window. Windows with client-side decoration does not follow this behavior for the moment, and patches for GTK+ shall be crafted to fix this in the client side. To make the current code work with the tile constraint, the constraint had to ignore the width and x positions of the window, because now these axis are not constrained. Long term, the best way to handle it is using constrained edges rather than tile modes themselves. Constrained edges are more generic and are better suited to the future quarter tiling. With constrained edges, we can isolate the tiling logic from the CSD implementations.
Created attachment 355373 [details] [review] window: Tile and resize considering the tile match After the introduction of the possibility to resize tiled windows, it is a sensible decision to make windows aware of their tiling match. A tiling match is another window that is tiled in such a way that is the complement of the current window. The newly introduced behavior attepts to make tiling as smooth as possible, with the following rules: * Windows now compute their tile match when tiling and, if there's a match, they automatically complement the sibling's width. * Resizing a window with a sibling automatically resizes the sibling too to be the complement of the window's width. * It is not possible to resize below windows' minimum widths.
Created attachment 355374 [details] [review] edge-resistance: Add snapping for tiled windows When windows are tiled, it improves the interaction with them when they have a set of snapping edges relative to the monitor. For example, when there's a document editor and a PDF file opened, I might want to rescale the former to 2/3 of the screen and the latter to 1/3. These snapping sections are not really tied to any other window, and only depend on the current work area of the window. Thus, it is not necessary to adapt the current snapping edge detection algorithm. This patch adds the necessary code in edge-resistance.c to special-case tiled windows and allow them to cover 1/4, 1/3 and 1/2 (horizontally) of the screen. These values are hardcoded.
Created attachment 355375 [details] [review] edge-resistance: Remove useless variable There is a variable in meta_window_edge_resistance_for_resize that isn't really helpful: it just assumes TRUE, and is passed to apply_edge_resistance_to_each_side. This patch removes that useless variable and simply pass TRUE instead.
Created attachment 355376 [details] [review] window: Raise and lower tile match in tandem When a pair of tiled windows are grouped together, they are treated as parts of a whole and interacting with one affects the other. Following the idea that sibling tiled windows are treated as part of the same group, they should also be raised and lowered together. It is still possible to break tiled windows grouping by simply untiling the window with the keyboard or by grabbing and resizing or moving the window with the cursor. This patch makes sibling tiled windows be lowered and raised in tandem. For future reference, this behavior is documented in [1]. [1] https://wiki.gnome.org/GeorgesNeto/MinutesOfFeaneron/Tiling
Created attachment 355377 [details] [review] window: Also consider touching edges for matching tiled windows When computing a potential match for a tiled window, there is a chance we face the case where 2 windows really complement each other's tile mode (i.e. left and right) but they have different sizes, and their borders don't really touch each other. In that case, the current code would mistakenly assume they're tile matches, and would resize them with either a hole or an overlapping area between windows. This is clearly a misbehavior that is a consequence of the previous assumptions pre-resizable tiles. This patch adapts the tile match algorithm to also consider the touching edges when computing the matching tile. The touching edges, however, are not always considered. They obey the following rules: * After successfully resizing or moving, touching edges are considered. * When previewing the tile (i.e. when dragging the window to a corner), touching borders are ignored. * When actually tiling the window, touching edges are also ignored.
Created attachment 357939 [details] [review] window: Allow tiled windows be resized The current code forbids resizing tiled windows, and enforces that side-by-side tiled windows cover half of the current screen's width. This patch removes this restriction, and adds code to track the tiled window size isolated from the actual window size, using the following heuristics: * If the window was not tiled, cover 1/2 of the screen. * If the window was tiled, use the complement of the current width to cover the "hole" in the screen. * When resizing a tiled window to the oposite border, maximize the window. Windows with client-side decoration does not follow this behavior for the moment, and patches for GTK+ shall be crafted to fix this in the client side. To make the current code work with the tile constraint, the constraint had to ignore the width and x positions of the window, because now these axis are not constrained. Long term, the best way to handle it is using constrained edges rather than tile modes themselves. Constrained edges are more generic and are better suited to the future quarter tiling. With constrained edges, we can isolate the tiling logic from the CSD implementations.
Created attachment 357940 [details] [review] window: Tile and resize considering the tile match After the introduction of the possibility to resize tiled windows, it is a sensible decision to make windows aware of their tiling match. A tiling match is another window that is tiled in such a way that is the complement of the current window. The newly introduced behavior attepts to make tiling as smooth as possible, with the following rules: * Windows now compute their tile match when tiling and, if there's a match, they automatically complement the sibling's width. * Resizing a window with a sibling automatically resizes the sibling too to be the complement of the window's width. * It is not possible to resize below windows' minimum widths.
Created attachment 357941 [details] [review] edge-resistance: Add snapping for tiled windows When windows are tiled, it improves the interaction with them when they have a set of snapping edges relative to the monitor. For example, when there's a document editor and a PDF file opened, I might want to rescale the former to 2/3 of the screen and the latter to 1/3. These snapping sections are not really tied to any other window, and only depend on the current work area of the window. Thus, it is not necessary to adapt the current snapping edge detection algorithm. This patch adds the necessary code in edge-resistance.c to special-case tiled windows and allow them to cover 1/4, 1/3 and 1/2 (horizontally) of the screen. These values are hardcoded.
Created attachment 357942 [details] [review] edge-resistance: Remove useless variable There is a variable in meta_window_edge_resistance_for_resize that isn't really helpful: it just assumes TRUE, and is passed to apply_edge_resistance_to_each_side. This patch removes that useless variable and simply pass TRUE instead.
Created attachment 357943 [details] [review] window: Raise and lower tile match in tandem When a pair of tiled windows are grouped together, they are treated as parts of a whole and interacting with one affects the other. Following the idea that sibling tiled windows are treated as part of the same group, they should also be raised and lowered together. It is still possible to break tiled windows grouping by simply untiling the window with the keyboard or by grabbing and resizing or moving the window with the cursor. This patch makes sibling tiled windows be lowered and raised in tandem. For future reference, this behavior is documented in [1]. [1] https://wiki.gnome.org/GeorgesNeto/MinutesOfFeaneron/Tiling
Created attachment 357944 [details] [review] window: Also consider touching edges for matching tiled windows When computing a potential match for a tiled window, there is a chance we face the case where 2 windows really complement each other's tile mode (i.e. left and right) but they have different sizes, and their borders don't really touch each other. In that case, the current code would mistakenly assume they're tile matches, and would resize them with either a hole or an overlapping area between windows. This is clearly a misbehavior that is a consequence of the previous assumptions pre-resizable tiles. This patch adapts the tile match algorithm to also consider the touching edges when computing the matching tile. The touching edges, however, are not always considered. They obey the following rules: * After successfully resizing or moving, touching edges are considered. * When previewing the tile (i.e. when dragging the window to a corner), touching borders are ignored. * When actually tiling the window, touching edges are also ignored.
Created attachment 357945 [details] [review] constraints: Add percentage constraint In the past, the tiling constraint was used to enforce that windows would have 50% of the workarea, even when the monitor changes. Now that windows can be resized when tiled, this aspect of the tiling constraint was lost. Its purpose, now, is to keep the tiled windows in the position we expect them to be, but now, tiled windows have a slightly mistuned behavior when changing monitors: they keep their widths, not the percentage of window covered. Fix that by adding a new percentage constraint. This new constraint enforces that, when windows are tiled, they keep the same percentage of the screen.
Created attachment 357955 [details] [review] constraints: Add percentage constraint Second version with many improvements.
Created attachment 358040 [details] [review] constraints: Add percentage constraint Only update percentage when action was resize.
The constraints didn't work for me in a quick test - I don't have access to an external monitor at the moment, so this is what I did: - open two windows, tile left and right - open display settings, change resolution The expectation is that the two windows remain tiled as before, without gaps or overlaps, however they just keep their previous size.
(In reply to Georges Basile Stavracas Neto from comment #94) > Only update percentage when action was resize. I suspect that you need to restrict this to user actions as well (META_MOVE_RESIZE_USER_ACTION), but didn't test.
Created attachment 358590 [details] [review] constraints: Add percentage constraint Thanks for testing it out. I could verify the issue you pointed, and the suggested solution (checking for USER_ACTION) did solve the issue for me. Could you please try it again?
(In reply to Georges Basile Stavracas Neto from comment #97) > Thanks for testing it out. I could verify the issue you pointed, and the > suggested solution (checking for USER_ACTION) did solve the issue for me. > > Could you please try it again? I can repeat the earlier test tonight, but on second thought the user action flag is not enough. Moving a window to another monitor (via overview or keybinding) is a user action, but it should not change the "percentage" (no big fan of that name btw). Unfortunately I won't have access to an external monitor until Saturday, so I can't actually confirm this for now.
Created attachment 359415 [details] [review] constraints: Preserve window ratio in tile constraint Instead of adding a new constraint, just reuse the tiling one and reduce the bug surface. And yes, it works on multimonitor setup. See https://cloud.gnome.org/index.php/s/I2vvog8vcS0preX .
As discussed on IRC, I don't like how the first patch turns tiling into a move-resize operation. I've done a replacement that keeps the current constraint-based approach and rebased the other patches on top.
Created attachment 360851 [details] [review] window: Remove obsolete code Commit 91b7dedf368c6f7 removed the ability to temporarily break out of maximization/tiling during grab operations, so this code is no longer necessary.
Created attachment 360852 [details] [review] window: Update tile monitor before move The actual move may involve the tile monitor, so make sure to not use an outdated value by setting it before calling move_between_rects().
Created attachment 360853 [details] [review] window: Split out preview_tile_mode The existing semantics of the tile_mode property are terribly confusing, as it depends on some other property whether it represents the requested or current mode. Clear this up by just using separate variables for the two. As it is unlikely that we will ever support more than one tile preview, we can track the requested mode globally instead of adding another per-window variable.
Created attachment 360854 [details] [review] window: Pass mode as parameter to tile() operation Now that the preview tile mode has been split from the window's tile_mode property, it is much more natural to pass the requested tile_mode to the tile() function instead of setting it externally and calling the function to apply the state.
Created attachment 360855 [details] [review] window: Allow resizing of tiled windows Currently tiled windows are not resizable and their size is fixed to half the screen width. Adjust the code to work with fractions other than half, and allow users to adjust the split by dragging the window edge that is not constrained by a monitor edge. Follow-up patches will improve on that by resizing neighboring tiled windows by a shared edge, and making the functionality available to client-side decorated windows implementing the new edge constraints protocol.
Created attachment 360856 [details] [review] window: Maximize tiled windows when resizing to work area Now that tiled windows are resizable, the user may grow a tiled windows until it covers the entire work area. As this makes the window state mostly indistinguishable from maximization, avoid subtle differences by properly maximizing the window in that case.
Created attachment 360857 [details] [review] window: Tile and resize considering the tile match After the introduction of the possibility to resize tiled windows, it is a sensible decision to make windows aware of their tiling match. A tiling match is another window that is tiled in such a way that is the complement of the current window. The newly introduced behavior attepts to make tiling as smooth as possible, with the following rules: * Windows now compute their tile match when tiling and, if there's a match, they automatically complement the sibling's width. * Resizing a window with a sibling automatically resizes the sibling too to be the complement of the window's width. * It is not possible to resize below windows' minimum widths.
Created attachment 360858 [details] [review] edge-resistance: Add snapping for tiled windows When windows are tiled, it improves the interaction with them when they have a set of snapping edges relative to the monitor. For example, when there's a document editor and a PDF file opened, I might want to rescale the former to 2/3 of the screen and the latter to 1/3. These snapping sections are not really tied to any other window, and only depend on the current work area of the window. Thus, it is not necessary to adapt the current snapping edge detection algorithm. This patch adds the necessary code in edge-resistance.c to special-case tiled windows and allow them to cover 1/4, 1/3 and 1/2 (horizontally) of the screen. These values are hardcoded.
Created attachment 360859 [details] [review] edge-resistance: Remove useless variable There is a variable in meta_window_edge_resistance_for_resize that isn't really helpful: it just assumes TRUE, and is passed to apply_edge_resistance_to_each_side. This patch removes that useless variable and simply pass TRUE instead.
Created attachment 360860 [details] [review] window: Raise and lower tile match in tandem When a pair of tiled windows are grouped together, they are treated as parts of a whole and interacting with one affects the other. Following the idea that sibling tiled windows are treated as part of the same group, they should also be raised and lowered together. It is still possible to break tiled windows grouping by simply untiling the window with the keyboard or by grabbing and resizing or moving the window with the cursor. This patch makes sibling tiled windows be lowered and raised in tandem. For future reference, this behavior is documented in [1]. [1] https://wiki.gnome.org/GeorgesNeto/MinutesOfFeaneron/Tiling
Created attachment 360861 [details] [review] window: Also consider touching edges for matching tiled windows When computing a potential match for a tiled window, there is a chance we face the case where 2 windows really complement each other's tile mode (i.e. left and right) but they have different sizes, and their borders don't really touch each other. In that case, the current code would mistakenly assume they're tile matches, and would resize them with either a hole or an overlapping area between windows. This is clearly a misbehavior that is a consequence of the previous assumptions pre-resizable tiles. This patch adapts the tile match algorithm to also consider the touching edges when computing the matching tile, unless: * the window is not currently tiled (for example when computing the tile preview) * the window is currently resized in tandem with an existing tile match https://bugzilla.gnome.org/show_bug.cgi?id=645153 bar
Review of attachment 360851 [details] [review]: ++
Review of attachment 360858 [details] [review]: LGTM
Review of attachment 360859 [details] [review]: The variable is not completely useless, as do_something (is_resize) is clearer to read than do_something (TRUE) but other functions in the file already pass bool literals, so *shrug* (the function is question is also in the same file, so looking up the parameter meaning is easy enough)
Review of attachment 360853 [details] [review]: Better than having one tile preview field per window, indeed.
Review of attachment 360860 [details] [review]: ::: src/core/window.c @@ +4870,3 @@ + /* If the window has a tile sibling, raise it before raising the window itself */ + if (window->tile_match) + meta_stack_raise (window->tile_match->screen->stack, window->tile_match); We only support one screen, so window->screen->stack is the same as window->tile_match->screen->stack ...
Review of attachment 360854 [details] [review]: Ok
Review of attachment 360855 [details] [review]: Looks good ::: src/core/window.c @@ +2982,3 @@ + else + *fraction = .5; +} Nitpick: why not return the fraction, instead if passing a pointer to a double?
(In reply to Georges Basile Stavracas Neto from comment #119) > > Nitpick: why not return the fraction, instead if passing a pointer to a > double? The idea was that there'll be a second fraction when we do quarter-tiling, but yeah, for now a return value makes more sense ...
Review of attachment 360856 [details] [review]: LGTM - I'd like you to take a second look though, as I did some minor changes when rebasing it on top of the resize patch
Review of attachment 360852 [details] [review]: LGTM
Review of attachment 360856 [details] [review]: Looks good (and the smaller patch size is superb)
Review of attachment 360861 [details] [review]: LGTM, but again I'd like a second opinion: I changed the original patch to figure out when to take gaps/overlaps into account from the existing window state, rather than passing an additional parameter.
Review of attachment 360861 [details] [review]: It works as expected, and it make sense (although it took me a while to understand the conditions inside if())
Review of attachment 360857 [details] [review]: Looks good
Attachment 360851 [details] pushed as 30a205c - window: Remove obsolete code Attachment 360852 [details] pushed as 56f1da5 - window: Update tile monitor before move Attachment 360853 [details] pushed as 8f2c86d - window: Split out preview_tile_mode Attachment 360856 [details] pushed as 57e58ea - window: Maximize tiled windows when resizing to work area Attachment 360857 [details] pushed as 6fe71ec - window: Tile and resize considering the tile match Attachment 360858 [details] pushed as 1dbf6b0 - edge-resistance: Add snapping for tiled windows Attachment 360859 [details] pushed as 8307d9c - edge-resistance: Remove useless variable Attachment 360860 [details] pushed as e76a0f5 - window: Raise and lower tile match in tandem Attachment 360861 [details] pushed as a1c39e1 - window: Also consider touching edges for matching tiled windows