Skip to content

Add Feature: Tiling option menu - #452

Merged
3v1n0 merged 30 commits into
ubuntu:mainfrom
ochi12:tiling-option-menu
Sep 20, 2026
Merged

3v1n0 merged 30 commits into
ubuntu:mainfrom
ochi12:tiling-option-menu

Conversation

@ochi12

@ochi12 ochi12 commented May 13, 2026

Copy link
Copy Markdown
Contributor
  • Tested for multimonitor using mutter devkit
  • Basic pop up animation implemented
  • prefs option to turn it off?

closes #451

@ochi12

ochi12 commented May 18, 2026

Copy link
Copy Markdown
Contributor Author

@3v1n0 any thoughts on this?

@3v1n0

3v1n0 commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

@3v1n0 any thoughts on this?

Very nice and a welcome addition, thanks!

Will do a proper review soon!

@3v1n0
3v1n0 force-pushed the tiling-option-menu branch 2 times, most recently from 4002bcc to 476e5e1 Compare September 20, 2026 02:09
@3v1n0

3v1n0 commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator

I've reviewed it, adjusted few minor things, but overall looks great, thanks!

@3v1n0
3v1n0 force-pushed the tiling-option-menu branch from 4769cd7 to cbd4384 Compare September 20, 2026 03:28
ochi12 and others added 22 commits September 20, 2026 05:32
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
3v1n0 force-pushed the tiling-option-menu branch from cbd4384 to 4c6ab2d Compare September 20, 2026 03:41
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.
@3v1n0
3v1n0 merged commit 770023f into ubuntu:main Sep 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Popup menu to select window tiling

2 participants