Add Feature: Tiling option menu - #452
Merged
Merged
Conversation
Contributor
Author
|
@3v1n0 any thoughts on this? |
Collaborator
Very nice and a welcome addition, thanks! Will do a proper review soon! |
3v1n0
force-pushed
the
tiling-option-menu
branch
2 times, most recently
from
September 20, 2026 02:09
4002bcc to
476e5e1
Compare
Collaborator
|
I've reviewed it, adjusted few minor things, but overall looks great, thanks! |
3v1n0
force-pushed
the
tiling-option-menu
branch
from
September 20, 2026 03:28
4769cd7 to
cbd4384
Compare
this file exports LayoutPicker. A widget where user can hover-select a tile layout. Its current state is purely visual and is not yet integrated with moveHandler.js.
instantiated in TilingMoveHandler class. This commit does not fully integrate layout picker yet but window drag movement is already integrated in this commit.
In this commit window snap now works from layout picker. This commit also includes blocking some snapping behavior when currently picking from the layout picker.
this commit also includes problems fixed which are not shown when animation is not yet implemented, such as layoutPicker shown in random place initially and incorrect visibility trigger bounds. animation focused on translation_y instead of moving the object itself to a new position.
Initially, the main signal triggering update allocation was window-entered-monitor. It was initially thought to be reliable, but this was overlooked. When windows are opened on the same monitor and one is dragged into another monitor, it actually updates the picker position to the other monitor. When I dragged the window left on the first monitor, the picker was still actually placed in the second monitor area.
The tile type is only recomputed while the picker classifies the pointer position, but it was never cleared once a move ended. So after picking a tile, the stale type was still reported as the current one (and its icon kept being shown) until the next move happened to reclassify it. Clear the type and restore the default icons both when a move starts and when it ends so the picker never exposes a stale selection.
The top/bottom classification of the vertical icon was based on the horizontal icon's position and size instead of the vertical icon's own. The two icons currently share the same row, so the outcome is the same, but that is accidental and would silently break as soon as the layout changes. Use the vertical icon's own geometry.
The quarter detection was OR-ing the picker's tile type with the pointer/window edge detection, so a physically detected edge could override the type the user explicitly selected in the picker. For example hovering the picker's right-half icon near the top of the screen could still preview the top-right quarter. Give the picker's selection precedence and only fall back to the edge detection when nothing is being picked. While at it drop the comment that described this as an unresolved issue and declare the pointer edge variables as constants, since they are never reassigned.
The picker positioned itself on the monitor under the pointer, while the move handler can deliberately keep tiling on the previous monitor for a short grace period when the pointer crosses a monitor edge. On multi-monitor setups this placed the picker on a different monitor than the one the tile preview was being computed for. Let the caller pass the monitor the move is being handled for, falling back to the pointer monitor when it is not given.
The picker is meant to be driven by the pointer, but it was also shown for Meta.GrabOp.KEYBOARD_MOVING, where the pointer is unrelated to the window being moved. Skip it for those grabs.
The pointer position was classified on every move, even while the picker was merely peeking or hidden. During the reveal animation the icons can already overlap the pointer, so a tile type could be reported before the picker was actually usable. Only classify once the picker is fully shown and clear the selection otherwise.
Destroying the container manually before calling super.destroy() is redundant, since St.Bin already destroys its child as part of the actor destruction. Drop it and follow what the rest of the extension does.
The picker changes the behavior of every window drag, so give users a way to turn it off. Default it to enabled to preserve the current behavior and expose it as a switch in the 'Other' group of the General preferences.
The move handler had to remember to call onMoveFinished() from every code path that can end a move. Have the picker hide itself when the grab ends instead, and turn the tile type into a regular GObject property that the move handler keeps reading directly. This removes the duplicated lifecycle bookkeeping and the custom getter. The restore path still hides the picker explicitly, since the grab is not released while the tiled window's size is being restored.
The picker is going to grow more options, so give it a dedicated group instead of leaving the switch in the 'Other' section, and place it first in the General preferences.
Keeping the pointer at the top edge made the preview toggle between maximize and the top-half tile after a short timeout. Now that the layout picker can select the top half explicitly, just propose maximize when the picker is enabled and let the user pick the top half from the picker. The toggle and the hold-maximize-inverse settings are kept when the picker is disabled.
3v1n0
force-pushed
the
tiling-option-menu
branch
from
September 20, 2026 03:41
cbd4384 to
4c6ab2d
Compare
GNOME Shell doesn't disable extensions when shutting down, so the monitors-changed and workareas-changed handlers kept running while the monitors are being torn down, eventually reading a monitor that is already gone. Disconnect them as soon as the shell starts shutting down.
monitors-changed can be emitted after the last monitor was removed while get_current_monitor() still reports it, e.g. when shutting down. Passing that number to get_work_area_for_monitor() trips a Mutter assertion, so bail out early when the monitor no longer exists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #451