Fix desktop zoom scrolling the window under the pointer, and Super opening the menu after zooming - #854
Open
AlexB7 wants to merge 2 commits into
Open
Fix desktop zoom scrolling the window under the pointer, and Super opening the menu after zooming#854AlexB7 wants to merge 2 commits into
AlexB7 wants to merge 2 commits into
Conversation
Scroll events consumed for the a11y mouse-wheel zoom bypass meta_keybindings_process_event entirely, so nothing cleared the modifier-only key state: pressing Super, zooming with the wheel and releasing Super still looked like a bare modifier tap and activated the overlay-key binding, popping up the Cinnamon menu after every zoom. Cancel the pending modifier-only state when a zoom scroll is consumed, and treat scroll events like button presses and touches when tracking modifier-only key state. Ref: linuxmint#695 Ref: linuxmint/cinnamon#12587 Co-Authored-By: Claude Fable 5
The a11y mouse-wheel zoom relies on passive button 4/5 grabs, which only intercept the emulated legacy scroll button events. XInput2-aware clients (GTK3 apps, Chromium/Electron, Firefox with MOZ_USE_XINPUT2=1) scroll with the smooth-scroll XI_Motion valuator events instead, and those are delivered to the client before any passive button grab can activate. As a result, zooming also scrolled the window under the pointer. Take an active grab on the virtual core pointer when a zoom scroll is consumed and hold it for the duration of the scroll burst; it is released after a short idle timeout, on a button press, or as soon as the zoom modifier is released (tracked via XkbStateNotify). While the grab is held, the smooth-scroll motion events are routed to muffin and can no longer leak to the client. The grab is deliberately not held for the whole time the modifier is down: modifier+click interactions (Shift+click selection, Ctrl+click) must keep working, and a click swallowed by an active grab cannot be re-injected - the physical press has already registered in the master device's button state, so a synthetic press is discarded by the server as a duplicate. The only remaining leak is the first scroll event of a burst, which has been processed by the time the grab can engage. Wayland sessions are unaffected: muffin sees all events there and already consumes them before delivery to the client. Fixes linuxmint#695 Ref: linuxmint/cinnamon#12587 Co-Authored-By: Claude Fable 5
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.
Fixes #695
Addresses linuxmint/cinnamon#12587 (and the long lineage behind it: linuxmint/cinnamon#5163, #10084, #10148, #11728)
The bugs
With Accessibility → Zoom enabled and a mouse-wheel modifier set, two things go wrong on X11:
MOZ_USE_XINPUT2=1), which is by now nearly everything.Note:
Root causes
Passthrough: muffin's zoom capture uses passive
XIGrabButtongrabs on buttons 4/5. Those only ever intercept the emulated legacy scroll button events. With XI 2.1 smooth scrolling, the X server delivers the smooth-scrollXI_Motionvaluator event to the client under the pointer before the emulated button event activates the passive grab — motion events cannot trigger a passive button grab. So muffin gets the button event (zoom works) and the client gets the motion event (window scrolls). This was confirmed withxevvsxinput test-xi2, and with Firefox/Emacs XInput2 on/off builds (see #695).Menu popup: scroll events consumed by the zoom branch in
events.cbypassmeta_keybindings_process_event, so the modifier-only ("overlay key") state is never cancelled; Super-press → zoom → Super-release looks like a bare Super tap.The fix
Commit 1 cancels the pending modifier-only state when a zoom scroll is consumed (and on scroll events generally, matching the existing button/touch behavior). Fixes the menu popup on both X11 and Wayland.
Commit 2 takes an active grab on the virtual core pointer for the duration of a zoom scroll burst. The first consumed zoom scroll engages the grab (via the existing
meta_backend_grab_device()); each further scroll refreshes a 1 s idle timer. The grab is released on timeout, on a button press, or as soon as the zoom modifier is released (tracked throughXkbStateNotify, which muffin already receives — no key grabs involved). While the grab is held, smooth-scroll motion events route to muffin and cannot reach the client.The grab is intentionally not held for the whole time the modifier is down. Modifier+click interactions (Shift+click selection, Ctrl+click) must keep working, and re-injecting a swallowed click via XTest is not possible: the physical press has already registered in the master device's button state, so the synthetic press is discarded by the server as a duplicate (verified with
xev: noButtonPressdelivered,EnterNotify state 0x111).Wayland is unaffected by commit 2 (guarded, and not needed — muffin consumes the events before delivery there).
Known limitations
AlreadyGrabbed) if another client holds a pointer grab (open menu, button held); it retries on the next scroll event and zoom itself keeps working through the passive grabs.Testing this PR on the stable 6.6.x series (Mint 22.3)
This PR targets master, but the patches apply cleanly to the current stable release, so anyone affected can try them on a test installation of Linux Mint 22.x / muffin 6.6.x:
Pre-rebased branch (easiest): a backport onto the
6.6.3tag is atAlexB7/muffinbranchzoom-fix-6.6.3:Or apply this PR's commits yourself:
Either way, install the full package set (the fix lives in
libmuffin0) and log out/in afterwards. To verify: enable Accessibility → Zoom with a mouse wheel modifier, hold the modifier and scroll over Chromium or any GTK3 app — the window content should no longer scroll while zooming (apart from at most the first tick of a burst), and with Super as the modifier the menu should no longer open when you release the key.Reverting: the locally built version (
6.6.3) sorts below the distro's (6.6.3+<codename>), so going back to stock is justand a log out/in. For the same reason, Update Manager will offer to replace the patched build with the stock package at the next update — hold the packages (
sudo apt-mark hold muffin libmuffin0 muffin-common gir1.2-meta-muffin-0.0) if you want to keep testing through updates, andunholdwhen done.Testing done
On Linux Mint 22.3, muffin 6.6.3 + these patches, X11:
MOZ_USE_XINPUT2=1Firefox: zoom works, window content no longer scrolls (previously reproduced reliably in all three).🤖 Generated with Claude Code