Repository navigation
fix(gnome-shell): move-sync tag decodes against the main surface by its texture, not the largest actor (extension v12) - #1856
Conversation
…ts texture, not the largest actor (extension v12) _readTag took the LARGEST surface actor of the window as the main surface and decoded the 1x1 tag as its offset from it. Under libdecor-gtk — GLFW 3.4's and SDL2/SDL3's stock decorations on GNOME — the shadow subsurface is larger than the content, so every tag decoded against the shadow's origin, no frame ever resolved against the window's position history, and the hold timed out on every title-bar drag: stale frames and visible 3D stutter. Found by the LeiaSR session on its OpenGL example (SR PR 447 hardware pass); the same drag was smooth with libdecor disabled. Apps that draw their own chrome (the test apps, the browser) never hit it. The main surface is now found structurally: MetaWindowActor.get_texture() is the toplevel surface's MetaShapedTexture, and mutter sets that same object as the surface actor's content, so the actor whose content is the texture is the toplevel's own surface — the one the tag is a subsurface of for the runtime and for the browser's present-owner tag alike. The pick is a pure function (MoveSyncChoice.pick), unit-tested with the libdecor layout; the size rule remains the fallback without a texture (the 9-11 behaviour). Positions are summed down the actor tree so a nested tree decodes the same as mutter 45-50's flat one. A debug log names which rule applied. Verified on the §9.7 headless GNOME Shell 50.1 harness (scale 2, slow_h / fast_h / reverse): "main surface found by its texture", 0 mismatch, 0 timeouts, every drag settled. The libdecor case itself needs a hardware pass with a GLFW/SDL app after the extension is reloaded (login cycle). Spec §9.2 / §9.8 and the README version log updated; lint comment too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Hardware confirmation (2026-10-09, ds1-linux, GNOME Shell 50 Wayland, Acer DS1 on HDMI-1 at 200 %) — the libdecor case this PR fixes now passes on the real panel. Extension v12 live (
Before this fix (2026-10-07, v11) every title-bar drag of the same app timed out because the tag was decoded against the libdecor shadow actor. The same evening's v11 run with libdecor off also passed (366/366), so the delta is the texture-based main-surface pick. Not verified: the one-time |
Bug
_readTagincontrib/gnome-shell/window-geometry@displayxr.org/lib.jstook the largest surface actor of a window as the main surface and decoded the 1x1 move-sync tag as its offset from it. Under libdecor-gtk (GLFW 3.4's and SDL2/SDL3's stock decorations on GNOME) the shadow subsurface is larger than the content, so every tag decoded against the shadow's origin, nothing resolved against the window's position history, and the move-sync hold timed out on every title-bar drag: stale frames and visible 3D stutter.Found by the LeiaSR session's PR 447 hardware pass on this laptop (OpenGL example, windowed native Wayland): with libdecor disabled in the app the same drag was smooth (274 weaves at 19 ms mean, 164 position advances). Apps that draw their own chrome in a smaller subsurface, the test apps and the browser among them, were never affected.
Fix (extension version 12, no interface change)
MetaWindowActor.get_texture()is the toplevel surface'sMetaShapedTexture, and mutter sets that same object as the surface actor's content, so the actor whose content is that texture is the toplevel's own surface — the one the tag is a subsurface of for the runtime and for the browser's present-owner tag alike (browser-pvt patch 0317 parents the tag on the root surface).MoveSyncChoice.pick(surfaces, texture), exported and unit-tested with the libdecor layout (new section 8 ofscripts/test_gnome_extension_move_sync.js). The size rule stays as the fallback without a texture (the version 9-11 behaviour).DISPLAYXR_DEBUG=1a one-line log names which rule applied.Verification
gjs scripts/test_gnome_extension_move_sync.js(8 sections), lattice / pointer-drag / stage-scale tests,scripts/check_gnome_extension.py --require-gjs: all pass.scripts/linux/move_sync/run.sh default 2 … slow_h fast_h reverse, this extension viaEXT_SRC): shell logmove sync: main surface found by its texture (4 surface actors); analyze.py 0.0 % mismatch on all three drags,move-sync timeouts: 0, every hold settled.SR_WEAVER_MOTION_TRACE=1).🤖 Generated with Claude Code