From d8a4ffe47bdaf26d351f0f87ade0f0151d9feb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Thi=E1=BB=87n=20L=E1=BB=99c?= Date: Tue, 13 Oct 2026 10:20:38 +0700 Subject: [PATCH] feat(bar): support auto-hide for island in overlay mode (#3772) * feat(bar): support auto-hide for island in overlay mode * fix(settings): restore selectedIslandDocked scope for overlay islands * fix(bar): keep edge hover strip while island auto-hide is revealed --- quickshell/Modules/DBar/DBarBody.qml | 6 ++++-- quickshell/Modules/DBar/DBarWindow.qml | 13 ++++++++----- quickshell/Modules/Settings/DBarTab.qml | 9 +++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/quickshell/Modules/DBar/DBarBody.qml b/quickshell/Modules/DBar/DBarBody.qml index c46b791b3..4539ec384 100644 --- a/quickshell/Modules/DBar/DBarBody.qml +++ b/quickshell/Modules/DBar/DBarBody.qml @@ -21,6 +21,7 @@ Item { property var rightWidgetsModel readonly property bool barRevealed: inputMask.showing + readonly property bool autoHideActive: topBarCore.autoHide readonly property bool isIsland: barConfig?.island === true // Resolver-owned so the body, the frame and the dismiss window agree during the frame latch. @@ -32,6 +33,7 @@ Item { property real hostOffsetY: 0 // A free island's pill lives in IslandFreeHostWindow; this window only carries its satellites. readonly property bool islandFree: isIsland && SettingsData.islandFreePlacement(barConfig) + readonly property bool islandOverlay: isIsland && (islandHost?.floating ?? SettingsData.islandSetting(barConfig, "islandFloating")) && !islandFree readonly property var islandHost: islandLoader.item readonly property real islandStripThickness: isIsland ? SettingsData.islandStripThickness(barConfig) : 0 readonly property string islandSatellitePosition: isIsland ? SettingsData.islandSetting(barConfig, "islandSatellitePosition") : "edges" @@ -884,7 +886,7 @@ Item { anchors.fill: parent layer.enabled: false - property bool autoHide: !barWindow.isIsland && (barConfig?.autoHide ?? false) + property bool autoHide: (!barWindow.isIsland || barWindow.islandOverlay) && (barConfig?.autoHide ?? false) property bool revealSticky: false // In click-through mode the hidden bar's input mask covers the full // band while the revealed bar's mask covers only the widget sections, @@ -998,7 +1000,7 @@ Item { readonly property var rootWindowBarConfig: rootWindow.barConfig onRootWindowBarConfigChanged: { - autoHide = !barWindow.isIsland && (barConfig?.autoHide ?? false); + autoHide = (!barWindow.isIsland || barWindow.islandOverlay) && (barConfig?.autoHide ?? false); evaluateReveal(); } diff --git a/quickshell/Modules/DBar/DBarWindow.qml b/quickshell/Modules/DBar/DBarWindow.qml index a62f17726..535e84399 100644 --- a/quickshell/Modules/DBar/DBarWindow.qml +++ b/quickshell/Modules/DBar/DBarWindow.qml @@ -139,12 +139,15 @@ PanelWindow { item: barWindow.sectionMasked && body.barRevealed ? body._rightSection : null } + // Kept as a 1px edge strip while revealed under auto-hide so a pointer resting on the screen edge + // stays inside the window; otherwise reveal/hide would toggle the mask and flicker. Region { - readonly property bool active: body.clickThroughEnabled && !body.inputMaskItem.showing - x: active ? body.inputMaskItem.x : 0 - y: active ? body.inputMaskItem.y : 0 - width: active ? body.inputMaskItem.width : 0 - height: active ? body.inputMaskItem.height : 0 + readonly property bool active: (body.clickThroughEnabled || isIsland) && (!body.inputMaskItem.showing || body.autoHideActive) + readonly property bool farEdge: body.barPos === SettingsData.Position.Bottom || body.barPos === SettingsData.Position.Right + x: active ? (barWindow.isVertical ? (farEdge ? body.width - 1 : 0) : body.inputMaskItem.x) : 0 + y: active ? (barWindow.isVertical ? body.inputMaskItem.y : (farEdge ? body.height - 1 : 0)) : 0 + width: active ? (barWindow.isVertical ? 1 : body.inputMaskItem.width) : 0 + height: active ? (barWindow.isVertical ? body.inputMaskItem.height : 1) : 0 } // The slide transform lives on an ancestor, so a hidden bar's pill would otherwise keep its input hole in place. diff --git a/quickshell/Modules/Settings/DBarTab.qml b/quickshell/Modules/Settings/DBarTab.qml index cdb3e8087..0190210d2 100644 --- a/quickshell/Modules/Settings/DBarTab.qml +++ b/quickshell/Modules/Settings/DBarTab.qml @@ -19,6 +19,7 @@ Item { readonly property bool selectedIslandEnabled: bar.selectedBarIsIsland && (bar.selectedBarConfig?.enabled ?? false) readonly property string clickThroughHint: I18n.tr("Disabled by Click through", "bar hover popouts card, Click through is the Advanced toggle name") readonly property bool selectedIslandFree: bar.selectedBarIsIsland && SettingsData.islandFreePlacement(bar.selectedBarConfig) + readonly property bool selectedIslandOverlay: bar.selectedBarIsIsland && bar.islandSetting("islandFloating") && !selectedIslandFree readonly property bool selectedIslandDocked: bar.selectedBarIsIsland && !selectedIslandFree readonly property bool popupGapsZeroed: SettingsData.barUsesConnectedFrameStyle(bar.selectedBarConfig) && !(bar.selectedBarConfig?.useOverlayLayer ?? false) readonly property int placementIndex: !bar.islandSetting("islandFloating") ? 0 : (bar.islandSetting("islandPlacement") === "free" ? 2 : 1) @@ -233,7 +234,7 @@ Item { settingKey: "barVisibility" collapsible: true expanded: false - visible: (bar.selectedBarConfig?.enabled ?? false) && !bar.selectedBarIsIsland + visible: (bar.selectedBarConfig?.enabled ?? false) && (!bar.selectedBarIsIsland || dankBarTab.selectedIslandOverlay) SettingsRow { iconName: "info" @@ -247,7 +248,7 @@ Item { resetStore: bar settingKey: "barAutoHide" tags: ["autohide", "auto-hide", "reveal", "intellihide", "delay", "hide"] - visible: !bar.islandOwnsSelectedBarTop + visible: !bar.islandShadowsSelectedBar && (!bar.selectedBarIsIsland || dankBarTab.selectedIslandOverlay) text: I18n.tr("Auto-hide", "toggle to automatically hide the bar or dock") valueKeys: ["autoHideDelay"] checked: bar.selectedBarConfig?.autoHide ?? false @@ -268,7 +269,7 @@ Item { SettingsToggleRow { settingKey: "barAutoHideStrict" - visible: (bar.selectedBarConfig?.autoHide ?? false) && !bar.islandOwnsSelectedBarTop + visible: (bar.selectedBarConfig?.autoHide ?? false) && !bar.islandShadowsSelectedBar && (!bar.selectedBarIsIsland || dankBarTab.selectedIslandOverlay) tags: ["autohide", "strict", "popout"] text: I18n.tr("Strict auto-hide", "Dank bar setting: hide the bar when the pointer leaves even if a menu or bar popover is still open") description: I18n.tr("Hides even while a bar popout or menu is open", "bar strict auto-hide toggle description") @@ -284,7 +285,7 @@ Item { SettingsToggleRow { settingKey: "barHideWhenWindowsOpen" tags: ["hide", "windows", "empty", "workspace"] - visible: (bar.selectedBarConfig?.autoHide ?? false) && !bar.islandOwnsSelectedBarTop && CompositorService.supportsBarAutoHideReveal + visible: (bar.selectedBarConfig?.autoHide ?? false) && !bar.islandShadowsSelectedBar && (!bar.selectedBarIsIsland || dankBarTab.selectedIslandOverlay) && CompositorService.supportsBarAutoHideReveal text: I18n.tr("Hide when windows open") description: I18n.tr("Stays visible while the workspace has no windows", "bar hide when windows open toggle description") checked: bar.selectedBarConfig?.showOnWindowsOpen ?? false