fix: avoid pointer grab stuck on button press (Wayland)#1428
Open
KonTy wants to merge 1 commit into
Open
Conversation
When a button's onclick command opens a window (e.g. a launcher, popup, or overlay) that steals Wayland focus before the button_release_event arrives back at the EWW bar, GTK's internal pointer grab is never released. This causes the entire bar to get 'stuck': hover highlighting stops working on all other buttons, and clicks either do nothing or re-trigger the originally grabbed button. The user must wiggle the mouse to break free. Root cause: emit_activate() on button_press_event triggers GTK's built-in Button activation, which includes an implicit pointer grab (GDK seat grab). If the release event is intercepted by another layer-shell surface, the grab is never freed. Fix: Replace emit_activate() with manual :active CSS state management. On press, set StateFlags::ACTIVE for visual feedback. On release, clear it and run the command. Also handle grab_broken_event as a safety net to clear the :active state if the grab is stolen. This preserves the button press/release animation while eliminating the pointer grab that causes the stuck state. Fixes: elkowar#1008 Fixes: elkowar#1022
KonTy
pushed a commit
to smpl-os/smplos
that referenced
this pull request
Mar 21, 2026
- Revert 'sleep 0.05 &&' from all 9 tray button onclick handlers (no longer needed with patched EWW binary that avoids emit_activate) - Add migration to auto-clean sleep workarounds on existing installs - Fix smplos-refresh-config to search src/shared/ for eww configs - Patched EWW binary (eww-0.6.0-2) in build/prebuilt/ for ISO builds Root cause: GTK button_press_event -> emit_activate() grabs the pointer; if onclick spawns a window that steals Wayland focus before button_release, the grab is never freed. Fix: replace emit_activate() with manual :active CSS state management (StateFlags::ACTIVE). PR: elkowar/eww#1428 Fork: https://github.com/smpl-os/eww (branch: fix/button-pointer-grab)
Rellotscrewdriver
added a commit
to Rellotscrewdriver/CustomEww
that referenced
this pull request
May 20, 2026
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.
Problem
When a button's
onclickcommand opens a window (e.g. a launcher, popup, or overlay) that steals Wayland focus before thebutton_release_eventarrives back at the EWW bar, GTK's internal pointer grab is never released. This causes the entire bar to get "stuck":This affects every EWW user on Hyprland/Wayland whose bar buttons open external windows. The community workaround has been adding
sleep 0.1before commands.Root Cause
emit_activate()onbutton_press_event(line 542 ofwidget_definitions.rs) triggers GTK's built-inButtonactivation, which includes an implicit pointer grab via GDK seat grab. If thebutton_release_eventis intercepted by another layer-shell surface that opens before the release arrives, the grab is never freed.As @Rayzeq analyzed in #1022:
Fix
Replace
emit_activate()with manual:activeCSS state management (the same patterneventboxalready uses):StateFlags::ACTIVEfor visual feedback (preserves the button animation)ACTIVEand run the command (unchanged behavior)ACTIVEas a safety net if the grab is stolen by another surfaceThis preserves the press/release visual animation while eliminating the pointer grab that causes the stuck state. No user-facing API changes.
Testing
widget_definitions.rsFixes #1008
Fixes #1022