Repository navigation
Wayland: always rebind global shortcuts on startup - #3678
Conversation
ListShortcuts() only reports previously-approved shortcuts; it does not
re-establish the compositor-side key grab. Its documentation is explicit
about this: it "returns the shortcuts that were successfully bound in a
previous session by this application".
When CopyQ exits, its portal session is closed and the live grab goes with
it, but the persisted "approved" record in kglobalaccel remains. On the
next start CopyQ saw a non-empty ListShortcuts() result matching the wanted
shortcuts and skipped BindShortcuts() entirely, leaving the shortcuts
listed as registered in System Settings but non-functional until the
kglobalaccel component was purged manually.
BindShortcuts() may be called once per session, and a new session is
created on each start. Rebinding an unchanged, already approved set is
silent in xdg-desktop-portal-kde since merge request !368 ("Improve the
global shortcuts workflow"), so call it unconditionally on every session
start instead of only when ListShortcuts() returns an empty list.
The set comparison is kept for repeated bind requests within a single
session, so an unchanged set still does not trigger a spurious
"restart needed" notification.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnE5yttm5XHCE2VHfr1DnG
There was a problem hiding this comment.
Pull request overview
This pull request fixes a Wayland (portal-based) global-shortcut regression where shortcuts can appear âregisteredâ after a CopyQ restart but remain inactive because the portal key grab is not re-established for the new session.
Changes:
- Always call
BindShortcutson portal session startup (when there are enabled shortcuts), even ifListShortcuts()reports the same set from a previous session. - Preserve the existing âbind only once per sessionâ behavior by short-circuiting repeat binds within the same session when the set is unchanged.
- Add detailed in-code rationale documenting portal semantics and backend behavior expectations.
ðĄ Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Reportâ Patch coverage is
â Your patch check has failed because the patch coverage (0.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## master #3678 +/- ##
==========================================
+ Coverage 74.58% 74.60% +0.02%
==========================================
Files 256 256
Lines 37968 37970 +2
Branches 5122 5119 -3
==========================================
+ Hits 28318 28328 +10
+ Misses 9650 9642 -8 â View full report in Codecov by Harness. ð New features to boost your workflow:
|
|
Thanks! I was having the same issue (#3680). Let me merge this now, I need to fix the CI afterwards. |
Problem
On Wayland (KDE Plasma), global shortcuts stop working after a plain restart of CopyQ â no reboot, no logout, same KWin/portal session:
No error is shown, and the entry in System Settings â Shortcuts â Applications still looks perfectly normal â the shortcuts are simply dead.
With
COPYQ_LOG_LEVEL=DEBUGthe log stops right after listing:There is no
Binding portal global shortcuts:line after it.xdg-desktop-portal-kdeconfirms it from the other side âCreateSessionandListShortcutsare called, butBindShortcutsnever is.Wiping the registration with
qdbus6 org.kde.kglobalaccel /component/com_github_hluk_copyq org.kde.kglobalaccel.Component.cleanUpand restarting makes everything work again, because
ListShortcutsthen comes back empty.Cause
bindPortalGlobalShortcuts()treated a non-emptyListShortcuts()result as "nothing to do":But
ListShortcutsis a read-only query and does not establish anything. The portal interface documentation says so directly:When the previous CopyQ process exits, its portal session â and the live grab with it â is closed, while the persisted "approved" record in kglobalaccel remains. So on the next start
ListShortcutskeeps happily reporting the shortcuts as registered even though nothing is actually grabbing keys, and CopyQ skippedBindShortcutson that basis.The one-bind-per-session limit is per session, not per application lifetime, and a new session is created on every start:
Fix
Call
BindShortcutsunconditionally on every session start, regardless of whatListShortcutsreturns. TheListShortcutsresult is still used â for the existingOBSOLETE||override workaround and for the debug log â it just no longer decides whether to bind.The set comparison is kept for repeat bind requests within one session, so re-applying an unchanged configuration still does not produce a spurious "restart needed" notification.
Rebinding an unchanged, already-approved set is silent:
xdg-desktop-portal-kdeskips the confirmation dialog in that case since MR !368 "Improve the global shortcuts workflow".Testing
Tested on KDE Plasma Wayland,
xdg-desktop-portal1.22.1 /xdg-desktop-portal-kde6.7.4, using an isolated app id so an existing CopyQ registration was not touched. Both a pre-fix and a post-fix build were run through the same scenario.Restarting with an unchanged shortcut set:
BindShortcutsreaches the portalkglobalaccelComponent.isActive()falsetruecopyq exit+ restart, same set â no dialog,BindShortcutscalled silently, shortcuts keep working. This is the case that was broken.OBSOLETE||entry for the removed trigger, and the new trigger works.Shortcut activation was driven through
org.kde.kglobalaccel.Component.invokeShortcutand verified by thePortal global shortcut activated:log line.Not tested on other portal backends. Idempotent rebinding of an approved set is the specified behaviour, but I have only verified it live against
xdg-desktop-portal-kdeâ I have no GNOME or wlroots/Hyprland setup to check. Should a backend re-prompt on every start, that is still better than the current situation, where shortcuts are listed as registered but completely inactive. This is noted in a comment next to the change.The X11 path is untouched.