mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-15 15:45:20 -04:00
refactor: implement keyboard focus management
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
|
||||
@@ -50,6 +51,24 @@ Item {
|
||||
readonly property var contentLoader: impl.item ? impl.item.contentLoader : _fallbackContentLoader
|
||||
readonly property var overlayLoader: impl.item ? impl.item.overlayLoader : _fallbackOverlayLoader
|
||||
readonly property var backgroundWindow: impl.item ? impl.item.backgroundWindow : null
|
||||
readonly property var contentWindow: impl.item ? impl.item.contentWindow : null
|
||||
|
||||
// On Hyprland the OnDemand content surface only receives keyboard focus
|
||||
// through a grab; everywhere else Exclusive focus covers this. Both
|
||||
// popout windows plus every bar are whitelisted so clicks on them are
|
||||
// delivered normally (dismiss MouseAreas, widget-to-widget transfer)
|
||||
// instead of being consumed clearing the grab.
|
||||
HyprlandFocusGrab {
|
||||
windows: {
|
||||
const list = [];
|
||||
if (root.contentWindow)
|
||||
list.push(root.contentWindow);
|
||||
if (root.backgroundWindow && root.backgroundWindow !== root.contentWindow)
|
||||
list.push(root.backgroundWindow);
|
||||
return list.concat(KeyboardFocus.barWindows);
|
||||
}
|
||||
active: KeyboardFocus.wantsGrab(root.shouldBeVisible, root.customKeyboardFocus)
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: _fallbackContentLoader
|
||||
|
||||
@@ -17,6 +17,7 @@ Item {
|
||||
property Component overlayContent: null
|
||||
property alias overlayLoader: overlayLoader
|
||||
readonly property alias backgroundWindow: contentWindow
|
||||
readonly property alias contentWindow: contentWindow
|
||||
property real popupWidth: 400
|
||||
property real popupHeight: 300
|
||||
property real triggerX: 0
|
||||
@@ -758,31 +759,21 @@ Item {
|
||||
}
|
||||
})(), dpr)
|
||||
|
||||
readonly property real triggeringBarLeftExclusion: (effectiveBarPosition === SettingsData.Position.Left && barWidth > 0) ? Math.max(0, barX + barWidth) : 0
|
||||
readonly property real triggeringBarTopExclusion: (effectiveBarPosition === SettingsData.Position.Top && barHeight > 0) ? Math.max(0, barY + barHeight) : 0
|
||||
readonly property real triggeringBarRightExclusion: (effectiveBarPosition === SettingsData.Position.Right && barWidth > 0) ? Math.max(0, screenWidth - barX) : 0
|
||||
readonly property real triggeringBarBottomExclusion: (effectiveBarPosition === SettingsData.Position.Bottom && barHeight > 0) ? Math.max(0, screenHeight - barY) : 0
|
||||
readonly property real maskX: _dismissZone.x
|
||||
readonly property real maskY: _dismissZone.y
|
||||
readonly property real maskWidth: _dismissZone.width
|
||||
readonly property real maskHeight: _dismissZone.height
|
||||
|
||||
readonly property real maskX: {
|
||||
const adjacentLeftBar = adjacentBarInfo?.leftBar ?? 0;
|
||||
return Math.max(triggeringBarLeftExclusion, adjacentLeftBar);
|
||||
}
|
||||
|
||||
readonly property real maskY: {
|
||||
const adjacentTopBar = adjacentBarInfo?.topBar ?? 0;
|
||||
return Math.max(triggeringBarTopExclusion, adjacentTopBar);
|
||||
}
|
||||
|
||||
readonly property real maskWidth: {
|
||||
const adjacentRightBar = adjacentBarInfo?.rightBar ?? 0;
|
||||
const rightExclusion = Math.max(triggeringBarRightExclusion, adjacentRightBar);
|
||||
return Math.max(100, screenWidth - maskX - rightExclusion);
|
||||
}
|
||||
|
||||
readonly property real maskHeight: {
|
||||
const adjacentBottomBar = adjacentBarInfo?.bottomBar ?? 0;
|
||||
const bottomExclusion = Math.max(triggeringBarBottomExclusion, adjacentBottomBar);
|
||||
return Math.max(100, screenHeight - maskY - bottomExclusion);
|
||||
DismissZone {
|
||||
id: _dismissZone
|
||||
barPosition: root.effectiveBarPosition
|
||||
barX: root.barX
|
||||
barY: root.barY
|
||||
barWidth: root.barWidth
|
||||
barHeight: root.barHeight
|
||||
screenWidth: root.screenWidth
|
||||
screenHeight: root.screenHeight
|
||||
adjacentBarInfo: root.adjacentBarInfo
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
@@ -814,17 +805,7 @@ Item {
|
||||
WlrLayershell.namespace: root.layerNamespace
|
||||
WlrLayershell.layer: root.effectivePopoutLayer
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: {
|
||||
if (PopoutManager.screenshotActive)
|
||||
return WlrKeyboardFocus.None;
|
||||
if (customKeyboardFocus !== null)
|
||||
return customKeyboardFocus;
|
||||
if (!shouldBeVisible)
|
||||
return WlrKeyboardFocus.None;
|
||||
if (CompositorService.useHyprlandFocusGrab)
|
||||
return WlrKeyboardFocus.OnDemand;
|
||||
return WlrKeyboardFocus.Exclusive;
|
||||
}
|
||||
WlrLayershell.keyboardFocus: KeyboardFocus.keyboardFocus(shouldBeVisible, customKeyboardFocus)
|
||||
|
||||
readonly property bool _fullHeight: root.fullHeightSurface
|
||||
anchors {
|
||||
|
||||
@@ -18,6 +18,7 @@ Item {
|
||||
property Component overlayContent: null
|
||||
property alias overlayLoader: overlayLoader
|
||||
readonly property alias backgroundWindow: backgroundWindow
|
||||
readonly property alias contentWindow: contentWindow
|
||||
property real popupWidth: 400
|
||||
property real popupHeight: 300
|
||||
property real triggerX: 0
|
||||
@@ -494,31 +495,21 @@ Item {
|
||||
}
|
||||
})(), dpr)
|
||||
|
||||
readonly property real triggeringBarLeftExclusion: (effectiveBarPosition === SettingsData.Position.Left && barWidth > 0) ? Math.max(0, barX + barWidth) : 0
|
||||
readonly property real triggeringBarTopExclusion: (effectiveBarPosition === SettingsData.Position.Top && barHeight > 0) ? Math.max(0, barY + barHeight) : 0
|
||||
readonly property real triggeringBarRightExclusion: (effectiveBarPosition === SettingsData.Position.Right && barWidth > 0) ? Math.max(0, screenWidth - barX) : 0
|
||||
readonly property real triggeringBarBottomExclusion: (effectiveBarPosition === SettingsData.Position.Bottom && barHeight > 0) ? Math.max(0, screenHeight - barY) : 0
|
||||
readonly property real maskX: _dismissZone.x
|
||||
readonly property real maskY: _dismissZone.y
|
||||
readonly property real maskWidth: _dismissZone.width
|
||||
readonly property real maskHeight: _dismissZone.height
|
||||
|
||||
readonly property real maskX: {
|
||||
const adjacentLeftBar = adjacentBarInfo?.leftBar ?? 0;
|
||||
return Math.max(triggeringBarLeftExclusion, adjacentLeftBar);
|
||||
}
|
||||
|
||||
readonly property real maskY: {
|
||||
const adjacentTopBar = adjacentBarInfo?.topBar ?? 0;
|
||||
return Math.max(triggeringBarTopExclusion, adjacentTopBar);
|
||||
}
|
||||
|
||||
readonly property real maskWidth: {
|
||||
const adjacentRightBar = adjacentBarInfo?.rightBar ?? 0;
|
||||
const rightExclusion = Math.max(triggeringBarRightExclusion, adjacentRightBar);
|
||||
return Math.max(100, screenWidth - maskX - rightExclusion);
|
||||
}
|
||||
|
||||
readonly property real maskHeight: {
|
||||
const adjacentBottomBar = adjacentBarInfo?.bottomBar ?? 0;
|
||||
const bottomExclusion = Math.max(triggeringBarBottomExclusion, adjacentBottomBar);
|
||||
return Math.max(100, screenHeight - maskY - bottomExclusion);
|
||||
DismissZone {
|
||||
id: _dismissZone
|
||||
barPosition: root.effectiveBarPosition
|
||||
barX: root.barX
|
||||
barY: root.barY
|
||||
barWidth: root.barWidth
|
||||
barHeight: root.barHeight
|
||||
screenWidth: root.screenWidth
|
||||
screenHeight: root.screenHeight
|
||||
adjacentBarInfo: root.adjacentBarInfo
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
@@ -612,17 +603,7 @@ Item {
|
||||
WlrLayershell.namespace: root.layerNamespace
|
||||
WlrLayershell.layer: root.effectivePopoutLayer
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: {
|
||||
if (PopoutManager.screenshotActive)
|
||||
return WlrKeyboardFocus.None;
|
||||
if (customKeyboardFocus !== null)
|
||||
return customKeyboardFocus;
|
||||
if (!shouldBeVisible)
|
||||
return WlrKeyboardFocus.None;
|
||||
if (CompositorService.useHyprlandFocusGrab)
|
||||
return WlrKeyboardFocus.OnDemand;
|
||||
return WlrKeyboardFocus.Exclusive;
|
||||
}
|
||||
WlrLayershell.keyboardFocus: KeyboardFocus.keyboardFocus(shouldBeVisible, customKeyboardFocus)
|
||||
|
||||
anchors {
|
||||
left: true
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
|
||||
// Defines the screen area (excluding bars) that dismisses popouts
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property int barPosition: 0
|
||||
property real barX: 0
|
||||
property real barY: 0
|
||||
property real barWidth: 0
|
||||
property real barHeight: 0
|
||||
property real screenWidth: 0
|
||||
property real screenHeight: 0
|
||||
property var adjacentBarInfo: null
|
||||
|
||||
readonly property real _leftExclusion: (barPosition === SettingsData.Position.Left && barWidth > 0) ? Math.max(0, barX + barWidth) : 0
|
||||
readonly property real _topExclusion: (barPosition === SettingsData.Position.Top && barHeight > 0) ? Math.max(0, barY + barHeight) : 0
|
||||
readonly property real _rightExclusion: (barPosition === SettingsData.Position.Right && barWidth > 0) ? Math.max(0, screenWidth - barX) : 0
|
||||
readonly property real _bottomExclusion: (barPosition === SettingsData.Position.Bottom && barHeight > 0) ? Math.max(0, screenHeight - barY) : 0
|
||||
|
||||
readonly property real x: Math.max(_leftExclusion, adjacentBarInfo?.leftBar ?? 0)
|
||||
readonly property real y: Math.max(_topExclusion, adjacentBarInfo?.topBar ?? 0)
|
||||
readonly property real width: Math.max(100, screenWidth - x - Math.max(_rightExclusion, adjacentBarInfo?.rightBar ?? 0))
|
||||
readonly property real height: Math.max(100, screenHeight - y - Math.max(_bottomExclusion, adjacentBarInfo?.bottomBar ?? 0))
|
||||
}
|
||||
Reference in New Issue
Block a user