Hyprland: fix keyboard focus for launcher and other panels with direct text input

This commit is contained in:
Lemmy
2026-01-03 09:51:26 -05:00
parent ba02fcbcb4
commit dd4ebda55d
2 changed files with 33 additions and 3 deletions
+9 -3
View File
@@ -50,11 +50,17 @@ PanelWindow {
return WlrKeyboardFocus.None;
}
// Panel open on THIS screen: use panel's preferred focus mode
// Exception: Hyprland's Exclusive captures all input globally, preventing
// click-to-close from working on other monitors, so always use OnDemand
if (root.isPanelOpen && !CompositorService.isHyprland) {
if (root.isPanelOpen) {
// Hyprland's Exclusive captures ALL input globally (including pointer),
// preventing click-to-close from working on other monitors.
// Workaround: briefly use Exclusive when panel opens (for text input focus),
// then switch to OnDemand (for click-to-close on other screens).
if (CompositorService.isHyprland) {
return PanelService.isInitializingKeyboard ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.OnDemand;
}
return PanelService.openedPanel.exclusiveKeyboard ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.OnDemand;
}
// Panel open on ANOTHER screen: OnDemand allows receiving pointer events for click-to-close
return WlrKeyboardFocus.OnDemand;
}
+24
View File
@@ -1,5 +1,6 @@
pragma Singleton
import QtQuick
import Quickshell
import qs.Commons
@@ -14,6 +15,9 @@ Singleton {
property var openedPanel: null
property var closingPanel: null
property bool closedImmediately: false
// Brief window after panel opens where Exclusive keyboard is allowed on Hyprland
// This allows text inputs to receive focus, then switches to OnDemand for click-to-close
property bool isInitializingKeyboard: false
signal willOpen
signal didClose
@@ -87,6 +91,16 @@ Singleton {
return name in registeredPanels;
}
// Timer to switch from Exclusive to OnDemand keyboard focus on Hyprland
Timer {
id: keyboardInitTimer
interval: 100
repeat: false
onTriggered: {
root.isInitializingKeyboard = false;
}
}
// Helper to keep only one panel open at any time
function willOpenPanel(panel) {
if (openedPanel && openedPanel !== panel) {
@@ -100,6 +114,12 @@ Singleton {
openedPanel = panel;
assignToSlot(0, panel);
// Start keyboard initialization period (for Hyprland workaround)
if (panel.exclusiveKeyboard) {
isInitializingKeyboard = true;
keyboardInitTimer.restart();
}
// emit signal
willOpen();
}
@@ -115,6 +135,10 @@ Singleton {
assignToSlot(1, null);
}
// Reset keyboard init state
isInitializingKeyboard = false;
keyboardInitTimer.stop();
// emit signal
didClose();
}