diff --git a/quickshell/Common/KeybindActions.js b/quickshell/Common/KeybindActions.js index 10a6208c3..620d2af09 100644 --- a/quickshell/Common/KeybindActions.js +++ b/quickshell/Common/KeybindActions.js @@ -21,6 +21,16 @@ const DMS_ACTIONS = [ { id: "spawn dms ipc call island open notificationcenter", label: "DankIsland: Open Notification Center" }, { id: "spawn dms ipc call island cycle", label: "DankIsland: Cycle Activity" }, { id: "spawn dms ipc call island close", label: "DankIsland: Close" }, + { id: "spawn dms ipc call dot toggle home", label: "DankDot: Toggle" }, + { id: "spawn dms ipc call dot open home", label: "DankDot: Open Clock" }, + { id: "spawn dms ipc call dot open media", label: "DankDot: Open Media" }, + { id: "spawn dms ipc call dot open launcher", label: "DankDot: Open Launcher" }, + { id: "spawn dms ipc call dot open controlcenter", label: "DankDot: Open Control Center" }, + { id: "spawn dms ipc call dot open wallpaper", label: "DankDot: Open Wallpapers" }, + { id: "spawn dms ipc call dot open weather", label: "DankDot: Open Weather" }, + { id: "spawn dms ipc call dot open notificationcenter", label: "DankDot: Open Notification Center" }, + { id: "spawn dms ipc call dot cycle", label: "DankDot: Cycle Activity" }, + { id: "spawn dms ipc call dot close", label: "DankDot: Close" }, { id: "spawn dms ipc call defaultApp browser", label: "Default Web Browser: Open" }, { id: "spawn dms ipc call defaultApp fileManager", label: "Default File Manager: Open" }, { id: "spawn dms ipc call defaultApp mail", label: "Default Mail: Open" }, diff --git a/quickshell/Common/LayoutResolver.js b/quickshell/Common/LayoutResolver.js index 21d19af1d..82435805a 100644 --- a/quickshell/Common/LayoutResolver.js +++ b/quickshell/Common/LayoutResolver.js @@ -77,9 +77,13 @@ function resolveScreen(inputs, screen, options) { // Free islands and dots float anywhere on the screen, so they never join an edge band. const isFree = input => input.config.dot === true || (isIsland(input.config) && (input.islandPlacement ?? input.config.islandPlacement) === "free"); for (const input of enabled.filter(isFree)) { + const dot = input.config.dot === true; + // A free island keeps its satellites in a bar window on its configured edge; that band never reserves or shadows. + const satellites = !dot && (input.islandSatellites ?? input.config.islandSatellitesEnabled ?? true); instances.push({ key: JSON.stringify([screen.name, input.config.id]), screenName: screen.name, - barId: input.config.id, configOrder: inputs.indexOf(input), edge: "", kind: "island", free: true, dot: input.config.dot === true, + barId: input.config.id, configOrder: inputs.indexOf(input), edge: "", kind: "island", free: true, dot, + satelliteEdge: satellites ? edgeName(input.config.position ?? 0) || "top" : "", row: 0, rowThickness: 0, rowOffset: 0, reservation: 0, exclusiveZone: -1, exclusionSize: 0, paintedBounds: { x: 0, y: 0, width: 0, height: 0 }, margins: { top: 0, bottom: 0, left: 0, right: 0 } }); @@ -185,6 +189,10 @@ function resolveScreen(inputs, screen, options) { }; } +function hostsBarWindow(instance) { + return instance.free ? !!instance.satelliteEdge : instance.kind === "bar" || instance.kind === "island"; +} + function adjacentBar(layout, edge, config) { if (!layout || config?.autoHide) return null; diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 8583d12b3..aa9d7aa17 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -834,6 +834,7 @@ Singleton { property var lastUsedBarByScreen: ({}) // One slot per edge; a dot floats, so it never takes one. readonly property int edgeBarConfigCount: (barConfigs || []).filter(cfg => cfg && !isDotBarConfig(cfg)).length + readonly property var dotBarConfig: (barConfigs || []).find(cfg => isDotBarConfig(cfg)) ?? null readonly property var islandDefaults: ({ "islandFloating": false, "islandPlacement": "edge", @@ -2470,6 +2471,38 @@ Singleton { return !!bc && bc.dot === true; } + // The dot is a companion, not a layout: the first enable clones the base bar so it inherits its look. + function setDotEnabled(enabled, baseId) { + const existing = dotBarConfig; + if (existing) { + if ((existing.enabled ?? false) !== enabled) + updateBarConfig(existing.id, { + enabled + }); + return; + } + if (!enabled) + return; + const base = getBarConfig(baseId); + const source = base && !isDotBarConfig(base) ? base : getBarConfig("default"); + if (!source) + return; + const config = Object.assign(JSON.parse(JSON.stringify(source)), { + id: "dot" + Date.now(), + name: I18n.tr("Dot", "bar layout: free-floating dot that opens island activities"), + enabled: true, + island: false, + dot: true, + screenPreferences: ["all"], + showOnLastDisplay: true, + followInterfaceStyle: false, + transparency: barTransparency(source) + }); + // An inherited "always here" would make the base island and the dot fight by config order. + delete config.islandSharedRouting; + addBarConfig(config); + } + function islandFreePlacement(bc) { return isDotBarConfig(bc) || (islandSetting(bc, "islandFloating") && islandSetting(bc, "islandPlacement") === "free"); } diff --git a/quickshell/Common/SettingsTabs.qml b/quickshell/Common/SettingsTabs.qml index 48fa6ae16..924d63fda 100644 --- a/quickshell/Common/SettingsTabs.qml +++ b/quickshell/Common/SettingsTabs.qml @@ -86,11 +86,13 @@ Singleton { "id": "dankbar", "text": I18n.tr("Bar"), "icon": "toolbar", - "hint": I18n.tr("Position, appearance, island"), + "aliases": ["dot", "dankdot"], + "hint": I18n.tr("Layout, position, appearance", "settings hub hint for the bar pages"), "hubHeader": "BarHubHeader", "children": [ { "id": "dankbar_settings", + "aliases": ["dank_island", "island"], "text": I18n.tr("General", "adjective, settings page and section title for general options"), "icon": "tune", "tabIndex": 3, @@ -98,28 +100,19 @@ Singleton { }, { "id": "dankbar_appearance", + "aliases": ["frame"], "text": I18n.tr("Appearance", "settings page and section title for visual options"), "icon": "palette", "tabIndex": 6, "hint": I18n.tr("Background, corners, spacing, widget style") }, { - "id": "dank_island", - "text": I18n.tr("Island", "noun, dank island feature, settings page and layout option"), - "icon": "view_in_ar", - "tabIndex": 46, - "islandOnly": true, - "titleFrom": "selectedIslandTitle", - "hintFrom": "selectedIslandHint", - "hint": I18n.tr("Home layout, notifications, satellites") - }, - { - "id": "frame", - "text": I18n.tr("Frame", "noun, screen frame feature, settings page and layout option"), - "icon": "frame_source", - "tabIndex": 33, - "frameOnly": true, - "hint": I18n.tr("Border, connected mode, arcs") + "id": "dankbar_advanced", + "advanced": true, + "text": I18n.tr("Advanced"), + "icon": "settings", + "tabIndex": 64, + "hint": I18n.tr("Layers, fullscreen, exclusive zone") } ] }, @@ -754,10 +747,6 @@ Singleton { return false; if (entry.autostartOnly && !DesktopService.autostartAvailable) return false; - if (entry.frameOnly && !SettingsData.frameEnabled) - return false; - if (entry.islandOnly && !SettingsData.isIslandBarConfig(SettingsData.getBarConfig(SettingsUiState.selectedBarId))) - return false; if (entry.cellularOnly && (NetworkService.cellularDevices?.length ?? 0) === 0) return false; if (entry.kind === "hub" && !entry.hubHeader && visibleLeaves(entry.id).length === 0) diff --git a/quickshell/Common/SettingsUiState.qml b/quickshell/Common/SettingsUiState.qml index a525281ef..907b8239a 100644 --- a/quickshell/Common/SettingsUiState.qml +++ b/quickshell/Common/SettingsUiState.qml @@ -20,9 +20,6 @@ Singleton { property string selectedWidgetTitle: "" property string selectedWidgetDescription: "" property string selectedWidgetIcon: "" - readonly property bool selectedBarIsDot: SettingsData.isDotBarConfig(SettingsData.getBarConfig(selectedBarId)) - readonly property string selectedIslandTitle: selectedBarIsDot ? I18n.tr("Dot", "bar layout: free-floating dot that opens island activities") : I18n.tr("Island", "noun, dank island feature, settings page and layout option") - readonly property string selectedIslandHint: selectedBarIsDot ? I18n.tr("Popups, expand, badge", "settings hub hint for the dot island page") : I18n.tr("Home layout, notifications, satellites") function normalizeSelectedBar() { if (SettingsData.getBarConfig(selectedBarId)) diff --git a/quickshell/Common/ShellLayout.qml b/quickshell/Common/ShellLayout.qml index 9978e7dc3..dd14081e0 100644 --- a/quickshell/Common/ShellLayout.qml +++ b/quickshell/Common/ShellLayout.qml @@ -26,7 +26,8 @@ Singleton { popupThickness: Theme.barThickness(Resolver.option(config, "innerPadding", root.primaryBar, 4), screen.scale), islandThickness: Resolver.islandThickness(config, SettingsData.islandDefaults), islandFloating: SettingsData.islandSetting(config, "islandFloating"), - islandPlacement: SettingsData.islandFreePlacement(config) ? "free" : "edge" + islandPlacement: SettingsData.islandFreePlacement(config) ? "free" : "edge", + islandSatellites: SettingsData.islandSetting(config, "islandSatellitesEnabled") })), screen, { screens: root.screens, displayNameMode: SettingsData.displayNameMode, @@ -78,7 +79,7 @@ Singleton { } function hostedScreens(barId) { - return Quickshell.screens.filter(screen => forScreen(screen)?.instances.some(instance => instance.barId === barId && !instance.free && (instance.kind === "bar" || instance.kind === "island"))); + return Quickshell.screens.filter(screen => forScreen(screen)?.instances.some(instance => instance.barId === barId && Resolver.hostsBarWindow(instance))); } function frameKeys(screen) { diff --git a/quickshell/Modals/Settings/SettingsContent.qml b/quickshell/Modals/Settings/SettingsContent.qml index f33d1601b..2a2ce5ba1 100644 --- a/quickshell/Modals/Settings/SettingsContent.qml +++ b/quickshell/Modals/Settings/SettingsContent.qml @@ -186,6 +186,7 @@ FocusScope { "window_rules": "WindowRulesTab.qml", "dankbar_settings": "DankBarTab.qml", "dankbar_appearance": "DankBarAppearanceTab.qml", + "dankbar_advanced": "DankBarAdvancedTab.qml", "bar_widget": "BarWidgetTab.qml", "compositor_layout": "CompositorLayoutTab.qml", "dock_general": "DockGeneralTab.qml", @@ -222,8 +223,6 @@ FocusScope { "audio": "AudioTab.qml", "locale": "LocaleTab.qml", "multiplexers": "MuxTab.qml", - "frame": "FrameTab.qml", - "dank_island": "DankIslandTab.qml", "users": "UsersTab.qml", "user_create": "CreateUserTab.qml", "greeter_auth": "GreeterAuthTab.qml", @@ -235,7 +234,7 @@ FocusScope { "plugins_manage": "PluginsManageTab.qml" }) - readonly property var pagesWithParentModal: ["dankbar_widgets", "window_rules", "display_config", "users", "time_weather", "weather", "lock_screen", "greeter", "dank_dash", "wallpaper_cycling", "theme_schedule", "surface_shadows", "keybinds", "dankbar_settings", "dankbar_appearance", "bar_widget", "dock_general", "dock_widgets", "dock_appearance", "dock_advanced", "launcher", "theme", "theme_apps", "media_player", "desktop_widgets", "dank_island", "autostart", "compositor_layout"] + readonly property var pagesWithParentModal: ["dankbar_widgets", "window_rules", "display_config", "users", "time_weather", "weather", "lock_screen", "greeter", "dank_dash", "wallpaper_cycling", "theme_schedule", "surface_shadows", "keybinds", "dankbar_settings", "dankbar_appearance", "bar_widget", "dock_general", "dock_widgets", "dock_appearance", "dock_advanced", "launcher", "theme", "theme_apps", "media_player", "desktop_widgets", "autostart", "compositor_layout"] Column { anchors.fill: parent diff --git a/quickshell/Modals/Settings/SettingsModal.qml b/quickshell/Modals/Settings/SettingsModal.qml index b24a4610d..605ba3a3c 100644 --- a/quickshell/Modals/Settings/SettingsModal.qml +++ b/quickshell/Modals/Settings/SettingsModal.qml @@ -181,35 +181,6 @@ DankFloatingWindow { } } - Connections { - target: SettingsData - - function onFrameEnabledChanged() { - if (!SettingsData.frameEnabled && settingsModal.currentPage === "frame") - settingsModal.setPage("dankbar"); - } - - function onIslandBarConfigsChanged() { - settingsModal.leaveIslandPageIfHidden(); - } - } - - function leaveIslandPageIfHidden() { - if (settingsModal.currentPage !== "dank_island") - return; - if (SettingsData.isIslandBarConfig(SettingsData.getBarConfig(SettingsUiState.selectedBarId))) - return; - settingsModal.setPage("dankbar"); - } - - Connections { - target: SettingsUiState - - function onSelectedBarIdChanged() { - settingsModal.leaveIslandPageIfHidden(); - } - } - Connections { target: PluginService diff --git a/quickshell/Modules/DankBar/DankBarBody.qml b/quickshell/Modules/DankBar/DankBarBody.qml index 97f40b351..29da204c1 100644 --- a/quickshell/Modules/DankBar/DankBarBody.qml +++ b/quickshell/Modules/DankBar/DankBarBody.qml @@ -22,6 +22,8 @@ Item { readonly property bool barRevealed: inputMask.showing readonly property bool isIsland: barConfig?.island === true + // A free island's pill lives in IslandFreeHostWindow; this window only carries its satellites. + readonly property bool islandFree: isIsland && SettingsData.islandFreePlacement(barConfig) 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" @@ -29,6 +31,16 @@ Item { readonly property bool islandSatellitesHugIsland: isIsland && islandSatellitePosition === "island" readonly property real islandSatelliteGap: isIsland ? SettingsData.islandSetting(barConfig, "islandSatelliteGap") : 0 readonly property bool islandSatelliteBackground: isIsland && SettingsData.islandSetting(barConfig, "islandSatelliteBackground") + readonly property color islandSurfaceColor: { + if (islandHost) + return islandHost.surfaceColor; + if (!isIsland) + return Theme.hostSurface; + if (SettingsData.islandSetting(barConfig, "islandHighContrast")) + return Theme.surfaceContainerHighest; + const palette = SettingsData.islandSetting(barConfig, "islandPalette"); + return palette === "bright" ? Theme.surfaceBright : palette === "dim" ? Theme.surfaceDim : _hostSurface; + } readonly property real islandChromePad: isIsland ? Theme.snap((barConfig?.innerPadding ?? 4) + Theme.spacingXS, _dpr) : 0 readonly property real islandChromeInset: islandSatelliteBackground ? islandChromePad : 0 readonly property bool islandMotionRunning: islandHost?.motionRunning ?? false @@ -49,8 +61,10 @@ Item { readonly property real contentAlongEnd: (isVertical ? barUnitInset.y + barUnitInset.height - topBarContent.anchors.bottomMargin : barUnitInset.x + barUnitInset.width - topBarContent.anchors.rightMargin) readonly property real leadingSectionSize: _leftSection ? (isVertical ? _leftSection.implicitHeight : _leftSection.implicitWidth) : 0 readonly property real trailingSectionSize: _rightSection ? (isVertical ? _rightSection.implicitHeight : _rightSection.implicitWidth) : 0 - readonly property real islandLeadingOffset: !islandSatellitesHugIsland ? 0 : Math.max(0, islandAlongStart - islandSatelliteGap - islandChromeInset - leadingSectionSize - contentAlongStart) - readonly property real islandTrailingOffset: !islandSatellitesHugIsland ? 0 : Math.max(0, contentAlongEnd - (islandAlongEnd + islandSatelliteGap + islandChromeInset + trailingSectionSize)) + readonly property real freeSatelliteSeparation: leadingSectionSize > 0 && trailingSectionSize > 0 ? islandSatelliteGap + islandChromeInset * 2 : 0 + readonly property real freeSatelliteStart: ((isVertical ? height : width) - leadingSectionSize - freeSatelliteSeparation - trailingSectionSize) / 2 + readonly property real islandLeadingOffset: !islandSatellitesHugIsland ? 0 : Math.max(0, islandFree ? freeSatelliteStart - contentAlongStart : islandAlongStart - islandSatelliteGap - islandChromeInset - leadingSectionSize - contentAlongStart) + readonly property real islandTrailingOffset: !islandSatellitesHugIsland ? 0 : Math.max(0, contentAlongEnd - (islandFree ? freeSatelliteStart + leadingSectionSize + freeSatelliteSeparation + trailingSectionSize : islandAlongEnd + islandSatelliteGap + islandChromeInset + trailingSectionSize)) readonly property var leadingSectionRect: sectionRect(_leftSection, false, _revealProgress + islandLeadingOffset + islandTrailingOffset) readonly property var trailingSectionRect: sectionRect(_rightSection, false, _revealProgress + islandLeadingOffset + islandTrailingOffset) @@ -582,7 +596,7 @@ Item { readonly property bool reserveExclusiveWhenAutoHidden: FrameTransitionState.effectiveFrameEnabled && usesFrameBarChrome && !!barWindow.screen && SettingsData.isScreenInPreferences(barWindow.screen, SettingsData.frameScreenPreferences) - readonly property real surfaceExclusiveZone: isIsland ? ((islandHost?.floating ?? false) ? 0 : islandStripThickness) : (!(barConfig?.visible ?? true) || (topBarCore.autoHide && !barWindow.reserveExclusiveWhenAutoHidden)) ? -1 : (barWindow.effectiveBarThickness + effectiveSpacing + (usesFrameBarChrome ? 0 : (barConfig?.bottomGap ?? 0))) + readonly property real surfaceExclusiveZone: isIsland ? ((islandFree || (islandHost?.floating ?? false)) ? 0 : islandStripThickness) : (!(barConfig?.visible ?? true) || (topBarCore.autoHide && !barWindow.reserveExclusiveWhenAutoHidden)) ? -1 : (barWindow.effectiveBarThickness + effectiveSpacing + (usesFrameBarChrome ? 0 : (barConfig?.bottomGap ?? 0))) readonly property alias inputMaskItem: inputMask @@ -926,7 +940,7 @@ Item { pad: barWindow.islandChromePad sweep: barWindow.isIsland ? SettingsData.islandSetting(barConfig, "islandSatelliteSwoopRadius") : 0 gothEnabled: barWindow.isIsland && SettingsData.islandSetting(barConfig, "islandSatelliteGothCorners") - fillColor: Theme.withAlpha(barWindow.islandHost?.surfaceColor ?? Theme.hostSurface, barWindow.isIsland ? SettingsData.islandSetting(barConfig, "islandSatelliteTransparency") : 1) + fillColor: Theme.withAlpha(barWindow.islandSurfaceColor, barWindow.isIsland ? SettingsData.islandSetting(barConfig, "islandSatelliteTransparency") : 1) } SectionSurface { @@ -942,7 +956,7 @@ Item { pad: barWindow.islandChromePad sweep: barWindow.isIsland ? SettingsData.islandSetting(barConfig, "islandSatelliteSwoopRadius") : 0 gothEnabled: barWindow.isIsland && SettingsData.islandSetting(barConfig, "islandSatelliteGothCorners") - fillColor: Theme.withAlpha(barWindow.islandHost?.surfaceColor ?? Theme.hostSurface, barWindow.isIsland ? SettingsData.islandSetting(barConfig, "islandSatelliteTransparency") : 1) + fillColor: Theme.withAlpha(barWindow.islandSurfaceColor, barWindow.isIsland ? SettingsData.islandSetting(barConfig, "islandSatelliteTransparency") : 1) } MouseArea { @@ -1002,7 +1016,7 @@ Item { Loader { id: islandLoader anchors.fill: parent - active: barWindow.isIsland + active: barWindow.isIsland && !barWindow.islandFree sourceComponent: IslandBarHost { barConfig: barWindow.barConfig screen: barWindow.screen diff --git a/quickshell/Modules/DankIsland/IslandBarHost.qml b/quickshell/Modules/DankIsland/IslandBarHost.qml index 88d0105d4..a4025e148 100644 --- a/quickshell/Modules/DankIsland/IslandBarHost.qml +++ b/quickshell/Modules/DankIsland/IslandBarHost.qml @@ -62,7 +62,7 @@ Item { readonly property real freeMargin: Math.max(0, Math.min(64, root.setting("islandFreeEdgeMargin"))) readonly property int compactThickness: root.dotMode ? Math.max(24, Math.min(72, root.dotSize)) : root.islandMetrics.compact readonly property bool floating: root.setting("islandFloating") - readonly property bool usesOverlayLayer: CompositorService.framePeerSurfacesUseOverlayForScreen(root.screen) || LayerShell.envUsesOverlay("DMS_DANKISLAND_LAYER", root.setting("islandUseOverlayLayer")) + readonly property bool usesOverlayLayer: root.dotMode || CompositorService.framePeerSurfacesUseOverlayForScreen(root.screen) || LayerShell.envUsesOverlay("DMS_DANKISLAND_LAYER", root.setting("islandUseOverlayLayer")) // A free island's position only picks the orientation; a dot is always a circle. readonly property bool isVertical: !root.dotMode && SettingsData.islandVertical(root.barConfig) readonly property string edge: root.freeMode ? (root.isVertical ? "left" : "top") : SettingsData.islandEdge(root.barConfig) diff --git a/quickshell/Modules/Settings/BarHubHeader.qml b/quickshell/Modules/Settings/BarHubHeader.qml index abc1850a9..537014b63 100644 --- a/quickshell/Modules/Settings/BarHubHeader.qml +++ b/quickshell/Modules/Settings/BarHubHeader.qml @@ -13,6 +13,8 @@ Column { property string confirmingRemoveId: "" property string editingBarId: "" property string renameDraft: "" + readonly property bool dotSelected: SettingsData.isDotBarConfig(bar.selectedBarConfig) + readonly property bool dotEnabled: SettingsData.dotBarConfig?.enabled ?? false BarSelectionState { id: bar @@ -54,7 +56,7 @@ Column { delete newBar.island; delete newBar.dot; SettingsData.addBarConfig(newBar); - bar.selectedBarId = newId; + bar.select(newId); } function canDeleteBar(config) { @@ -68,7 +70,7 @@ Column { } confirmingRemoveId = ""; SettingsData.deleteBarConfig(barId); - bar.selectedBarId = "default"; + bar.select("default"); } function canToggleBar(config) { @@ -81,16 +83,28 @@ Column { }); } + function setDotEnabled(enabled) { + SettingsData.setDotEnabled(enabled, bar.selectedBarId); + if (enabled) { + bar.select(SettingsData.dotBarConfig?.id ?? bar.selectedBarId); + return; + } + if (dotSelected) + bar.select(SettingsData.barConfigs.find(config => config.enabled && !SettingsData.isDotBarConfig(config))?.id ?? "default"); + } + + function barTitle(config) { + return config.name || I18n.tr("Bar %1", "numbered name for an unnamed bar, %1 is its position").arg(SettingsData.barConfigs.indexOf(config) + 1); + } + function barSummary(config) { - const parts = SettingsData.islandFreePlacement(config) ? [I18n.tr("Free", "bar summary: island floats anywhere on the display")] : [bar.positionLabel(config.position ?? SettingsData.Position.Top)]; + const parts = SettingsData.islandFreePlacement(config) ? [I18n.tr("Floating", "bar summary: island can be dragged anywhere on the display")] : [bar.positionLabel(config.position ?? SettingsData.Position.Top)]; const prefs = config.screenPreferences || ["all"]; if (prefs.includes("all")) parts.push(I18n.tr("All displays")); else parts.push(prefs.length === 1 ? I18n.tr("%1 display", "singular, bar summary of assigned monitors, %1 is 1").arg(prefs.length) : I18n.tr("%1 displays", "plural, bar summary of assigned monitors, %1 is a count").arg(prefs.length)); - if (SettingsData.isDotBarConfig(config)) - parts.push(I18n.tr("Dot", "bar summary: free-floating dot layout")); - else if (SettingsData.isIslandBarConfig(config)) + if (SettingsData.isIslandBarConfig(config)) parts.push(I18n.tr("Island")); return parts.join(" • "); } @@ -112,22 +126,21 @@ Column { } Repeater { - model: SettingsData.barConfigs + model: SettingsData.barConfigs.filter(config => !SettingsData.isDotBarConfig(config)) delegate: SettingsInstanceRow { required property var modelData - required property int index - title: modelData.name || I18n.tr("Bar %1", "numbered name for an unnamed bar, %1 is its position").arg(index + 1) + title: root.barTitle(modelData) summary: root.barSummary(modelData) selected: bar.selectedBarId === modelData.id checked: modelData.enabled ?? false toggleVisible: root.canToggleBar(modelData) deletable: root.canDeleteBar(modelData) confirmingDelete: root.confirmingRemoveId === modelData.id - onClicked: bar.selectedBarId = modelData.id + onClicked: bar.select(modelData.id) onToggled: checked => { - bar.selectedBarId = modelData.id; + bar.select(modelData.id); root.setBarEnabled(modelData.id, checked); } onDeleteRequested: root.deleteBar(modelData.id) @@ -137,7 +150,7 @@ Column { SettingsRow { title: I18n.tr("Name") subtitle: root.editingBarId ? "" : bar.selectedBarName - visible: !!bar.selectedBarConfig + visible: !!bar.selectedBarConfig && !root.dotSelected DankActionButton { iconName: root.editingBarId ? "check" : "edit" @@ -180,11 +193,25 @@ Column { } } + SettingsInstanceRow { + title: I18n.tr("Dot", "bar layout: free-floating dot that opens island activities") + summary: I18n.tr("A floating companion that works alongside any bar layout", "bar settings: what the dot is") + settingKey: "dotEnabled" + tags: ["dot", "dankdot", "companion", "floating", "island", "enable"] + clickable: root.dotEnabled + selected: root.dotSelected + checked: root.dotEnabled + deletable: false + onClicked: bar.select(SettingsData.dotBarConfig.id) + onToggled: checked => root.setDotEnabled(checked) + } + SettingsCard { iconName: "toolbar" title: I18n.tr("Layout", "noun, settings section title for arrangement options") settingKey: "barLayout" - tags: ["layout", "standard", "frame", "island", "dot", "mode", "bar"] + visible: !root.dotSelected + tags: ["layout", "standard", "frame", "island", "mode", "bar"] SettingsLayoutPicker {} } diff --git a/quickshell/Modules/Settings/BarWidgetOptions/BatteryOptions.qml b/quickshell/Modules/Settings/BarWidgetOptions/BatteryOptions.qml index 56b1ad915..0075809a9 100644 --- a/quickshell/Modules/Settings/BarWidgetOptions/BatteryOptions.qml +++ b/quickshell/Modules/Settings/BarWidgetOptions/BatteryOptions.qml @@ -1,5 +1,6 @@ import QtQuick import qs.Common +import qs.Services import qs.Modules.Settings.Widgets Column { @@ -8,6 +9,14 @@ Column { property var page: null readonly property var styleValues: ["icon", "solid", "outline", "ring"] + readonly property var barConfig: { + SettingsData.barConfigs; + return SettingsData.getBarConfig(page?.barId ?? ""); + } + readonly property var barStore: ({ + "isDefault": keys => keys.every(key => (root.barConfig?.[key] ?? SettingsData.barConfigDefault(key)) === SettingsData.barConfigDefault(key)), + "resetToDefault": keys => SettingsData.updateBarConfig(root.page.barId, Object.fromEntries(keys.map(key => [key, SettingsData.barConfigDefault(key)]))) + }) width: parent?.width ?? 0 spacing: Theme.spacingL @@ -76,5 +85,23 @@ Column { root.page.set("batteryStyle", root.styleValues[index]); } } + + SettingsButtonGroupRow { + settingKey: "batteryColorMode" + tags: ["battery", "color", "level", "theme", "icon", "meter", "indicator", "accent", "green", "red"] + text: I18n.tr("Battery") + visible: BatteryService.batteryAvailable && !(root.page?.dockHosted ?? false) + resetStore: root.barStore + resetKeys: ["batteryColorMode"] + model: [I18n.tr("Theme", "battery settings: theme accent indicator colors"), I18n.tr("Level", "battery settings: charge level indicator colors")] + currentIndex: (root.barConfig?.batteryColorMode ?? "theme") === "level" ? 1 : 0 + onSelectionChanged: (index, selected) => { + if (!selected) + return; + SettingsData.updateBarConfig(root.page.barId, { + batteryColorMode: index === 1 ? "level" : "theme" + }); + } + } } } diff --git a/quickshell/Modules/Settings/BarWidgetOptions/SystemTrayOptions.qml b/quickshell/Modules/Settings/BarWidgetOptions/SystemTrayOptions.qml index ea420fbc0..f8cab5944 100644 --- a/quickshell/Modules/Settings/BarWidgetOptions/SystemTrayOptions.qml +++ b/quickshell/Modules/Settings/BarWidgetOptions/SystemTrayOptions.qml @@ -9,6 +9,7 @@ Column { readonly property bool inlineExpansion: page.value("trayUseInlineExpansion") readonly property bool autoOverflow: page.value("trayAutoOverflow") + readonly property bool trayTinted: ["primary", "secondary"].includes(SettingsData.systemTrayIconTintMode || "none") width: parent?.width ?? 0 spacing: Theme.spacingL @@ -64,5 +65,43 @@ Column { unit: "px" onSliderValueChanged: newValue => root.page.set("trayIconSpacing", newValue) } + + SettingsButtonGroupRow { + readonly property var modes: ["none", "monochrome", "primary", "secondary"] + + settingKey: "trayIconTint" + tags: ["tray", "icon", "tint", "monochrome", "system tray", "color"] + text: I18n.tr("Tray icon tint") + resetKeys: ["systemTrayIconTintMode"] + model: [I18n.tr("None"), I18n.tr("Monochrome"), I18n.tr("Primary"), I18n.tr("Secondary")] + currentIndex: Math.max(0, modes.indexOf(SettingsData.systemTrayIconTintMode || "none")) + onSelectionChanged: (index, selected) => { + if (!selected) + return; + SettingsData.set("systemTrayIconTintMode", modes[index]); + } + } + + SettingsSliderRow { + text: I18n.tr("Tint saturation") + tags: ["tray", "tint", "saturation"] + visible: root.trayTinted + resetKeys: ["systemTrayIconTintSaturation"] + value: SettingsData.systemTrayIconTintSaturation ?? 50 + minimum: 0 + maximum: 100 + onSliderDragFinished: finalValue => SettingsData.set("systemTrayIconTintSaturation", finalValue) + } + + SettingsSliderRow { + text: I18n.tr("Tint strength") + tags: ["tray", "tint", "strength"] + visible: root.trayTinted + resetKeys: ["systemTrayIconTintStrength"] + value: SettingsData.systemTrayIconTintStrength ?? 135 + minimum: 0 + maximum: 200 + onSliderDragFinished: finalValue => SettingsData.set("systemTrayIconTintStrength", finalValue) + } } } diff --git a/quickshell/Modules/Settings/DankBarAdvancedTab.qml b/quickshell/Modules/Settings/DankBarAdvancedTab.qml new file mode 100644 index 000000000..45463f928 --- /dev/null +++ b/quickshell/Modules/Settings/DankBarAdvancedTab.qml @@ -0,0 +1,192 @@ +import QtQuick +import qs.Common +import qs.Services +import qs.Modules.Settings.Widgets + +Item { + id: root + + LayoutMirroring.enabled: I18n.isRtl + LayoutMirroring.childrenInherit: true + + readonly property bool isDot: SettingsData.isDotBarConfig(bar.selectedBarConfig) + + BarSelectionState { + id: bar + } + + SettingsPage { + id: mainColumn + + SettingsCard { + iconName: "tune" + title: I18n.tr("Behavior") + settingKey: "barAdvanced" + tags: ["bar", "advanced", "overlay", "layer", "click", "through", "maximize", "island", "spring", "motion"] + visible: bar.selectedBarConfig?.enabled ?? false + + SettingsToggleRow { + settingKey: "barClickThrough" + resetStore: bar + resetKeys: ["clickThrough"] + tags: ["clickthrough", "click", "through", "mouse", "input", "mask", "passthrough"] + visible: !bar.islandOwnsSelectedBarTop + text: I18n.tr("Click through") + checked: bar.selectedBarConfig?.clickThrough ?? false + onToggled: toggled => SettingsData.updateBarConfig(bar.selectedBarId, { + clickThrough: toggled + }) + } + + SettingsToggleRow { + settingKey: "barUseOverlayLayer" + resetStore: bar + resetKeys: ["useOverlayLayer"] + tags: ["bar", "fullscreen", "overlay", "layer"] + visible: !bar.islandOwnsSelectedBarTop + text: I18n.tr("Use overlay layer") + checked: bar.selectedBarConfig?.useOverlayLayer ?? false + onToggled: toggled => { + SettingsData.updateBarConfig(bar.selectedBarId, { + useOverlayLayer: toggled + }); + bar.notifyHorizontalBarChange(); + } + } + + SettingsToggleRow { + settingKey: "islandUseOverlayLayer" + tags: ["island", "fullscreen", "overlay", "layer"] + visible: bar.selectedBarIsIsland && !root.isDot + resetStore: bar + resetKeys: ["islandUseOverlayLayer"] + text: I18n.tr("Use overlay layer") + checked: bar.islandSetting("islandUseOverlayLayer") + onToggled: checked => bar.apply("islandUseOverlayLayer", checked) + } + + SettingsToggleRow { + settingKey: "islandReducedMotion" + tags: ["island", "motion", "animation", "reduce", "accessibility", "spring"] + visible: bar.selectedBarIsIsland + resetStore: bar + resetKeys: ["islandReducedMotion"] + text: I18n.tr("Reduce motion") + checked: bar.islandSetting("islandReducedMotion") + onToggled: checked => bar.apply("islandReducedMotion", checked) + } + + SettingsSliderRow { + settingKey: "islandSpringStiffness" + tags: ["island", "motion", "spring", "stiffness", "animation"] + visible: bar.selectedBarIsIsland + resetStore: bar + resetKeys: ["islandSpringStiffness"] + text: I18n.tr("Spring stiffness", "island settings: spring stiffness slider") + unit: "" + minimum: 100 + maximum: 1200 + step: 10 + value: Math.round(bar.islandSetting("islandSpringStiffness")) + enabled: !bar.islandSetting("islandReducedMotion") + onSliderValueChanged: value => bar.apply("islandSpringStiffness", value) + } + + SettingsSliderRow { + settingKey: "islandSpringDamping" + tags: ["island", "motion", "spring", "damping", "bounce", "animation"] + visible: bar.selectedBarIsIsland + resetStore: bar + resetKeys: ["islandSpringDamping"] + text: I18n.tr("Spring damping", "island settings: spring damping slider") + unit: "" + minimum: 10 + maximum: 100 + step: 1 + value: Math.round(bar.islandSetting("islandSpringDamping")) + enabled: !bar.islandSetting("islandReducedMotion") + onSliderValueChanged: value => bar.apply("islandSpringDamping", value) + } + + SettingsSliderRow { + settingKey: "islandSpringMass" + tags: ["island", "motion", "spring", "mass", "inertia", "animation"] + visible: bar.selectedBarIsIsland + resetStore: bar + resetKeys: ["islandSpringMass"] + text: I18n.tr("Spring mass", "island settings: spring mass slider") + minimum: 25 + maximum: 300 + step: 5 + unit: "" + decimals: 2 + value: Math.round(bar.islandSetting("islandSpringMass") * 100) + enabled: !bar.islandSetting("islandReducedMotion") + onSliderValueChanged: value => bar.apply("islandSpringMass", value / 100) + } + + SettingsToggleRow { + settingKey: "barMaximizeDetection" + resetStore: bar + resetKeys: ["maximizeDetection"] + tags: ["maximize", "gaps", "border", "fullscreen"] + visible: CompositorService.supportsBarAutoHideReveal && !root.isDot + text: I18n.tr("Maximize detection") + checked: bar.selectedBarConfig?.maximizeDetection ?? true + onToggled: toggled => SettingsData.updateBarConfig(bar.selectedBarId, { + maximizeDetection: toggled + }) + } + } + + SettingsCard { + iconName: "space_bar" + title: I18n.tr("Gaps") + settingKey: "barAppearanceAdvanced" + tags: ["bar", "advanced", "exclusive", "zone", "popup", "gaps"] + visible: (bar.selectedBarConfig?.enabled ?? false) && !bar.selectedBarFrameStyled && !root.isDot + + SettingsSliderRow { + settingKey: "barExclusiveZone" + tags: ["exclusive", "zone", "reserved", "offset"] + visible: !bar.islandOwnsSelectedBarTop + text: I18n.tr("Exclusive zone offset") + resetStore: bar + resetKeys: ["bottomGap"] + value: bar.selectedBarConfig?.bottomGap ?? 0 + minimum: -50 + maximum: 50 + unit: "px" + onSliderDragFinished: finalValue => SettingsData.updateBarConfig(bar.selectedBarId, { + bottomGap: finalValue + }) + } + + SettingsToggleRow { + text: I18n.tr("Auto popup gaps") + tags: ["popup", "gaps", "auto"] + resetStore: bar + resetKeys: ["popupGapsAuto"] + checked: bar.selectedBarConfig?.popupGapsAuto ?? true + onToggled: checked => SettingsData.updateBarConfig(bar.selectedBarId, { + popupGapsAuto: checked + }) + } + + SettingsSliderRow { + visible: !(bar.selectedBarConfig?.popupGapsAuto ?? true) + text: I18n.tr("Gap size") + tags: ["popup", "gaps", "size"] + resetStore: bar + resetKeys: ["popupGapsManual"] + unit: "px" + value: bar.selectedBarConfig?.popupGapsManual ?? 4 + minimum: 0 + maximum: 50 + onSliderDragFinished: finalValue => SettingsData.updateBarConfig(bar.selectedBarId, { + popupGapsManual: finalValue + }) + } + } + } +} diff --git a/quickshell/Modules/Settings/DankBarAppearanceTab.qml b/quickshell/Modules/Settings/DankBarAppearanceTab.qml index cde147590..fd4182215 100644 --- a/quickshell/Modules/Settings/DankBarAppearanceTab.qml +++ b/quickshell/Modules/Settings/DankBarAppearanceTab.qml @@ -14,11 +14,15 @@ Item { property var parentModal: null readonly property bool widgetBackgroundEnabled: !(bar.selectedBarConfig?.noBackground ?? false) - readonly property bool trayTinted: ["primary", "secondary"].includes(SettingsData.systemTrayIconTintMode || "none") readonly property var outlineColors: ["surfaceText", "secondary", "primary"] readonly property var outlineColorLabels: [I18n.tr("Surface"), I18n.tr("Secondary"), I18n.tr("Primary")] readonly property var paletteValues: ["default", "bright", "dim"] readonly property var batteryStyleValues: ["solid", "outline", "ring"] + readonly property var satellitePositionValues: ["island", "edges"] + readonly property bool isDot: SettingsData.isDotBarConfig(bar.selectedBarConfig) + readonly property bool selectedIslandEnabled: bar.selectedBarIsIsland && (bar.selectedBarConfig?.enabled ?? false) + readonly property bool selectedIslandFree: bar.selectedBarIsIsland && SettingsData.islandFreePlacement(bar.selectedBarConfig) + readonly property int frameInsetPaddingDisplay: Math.round(SettingsData.frameBarContentGap) function valueIndex(values, value, fallback) { const index = values.indexOf(value); @@ -32,12 +36,112 @@ Item { SettingsPage { id: mainColumn + SettingsCard { + iconName: "border_outer" + title: I18n.tr("Frame") + settingKey: "frameBorder" + collapsible: true + visible: !root.isDot && SettingsData.frameEnabled + + SettingsSliderRow { + settingKey: "frameRounding" + tags: ["frame", "border", "rounding", "radius", "corner"] + text: I18n.tr("Radius", "corner radius slider label") + unit: "px" + minimum: 0 + maximum: 100 + step: 1 + value: SettingsData.frameRounding + onSliderDragFinished: v => SettingsData.set("frameRounding", v) + } + + SettingsSliderRow { + settingKey: "frameThickness" + tags: ["frame", "border", "thickness", "size", "width"] + text: I18n.tr("Width") + unit: "px" + minimum: 2 + maximum: 100 + step: 1 + value: SettingsData.frameThickness + onSliderDragFinished: v => SettingsData.set("frameThickness", v) + } + + SettingsSliderRow { + settingKey: "frameBarSize" + tags: ["frame", "bar", "thickness", "size", "height", "width"] + text: I18n.tr("Bar size") + unit: "px" + minimum: 24 + maximum: 100 + step: 1 + value: SettingsData.frameBarSize + onSliderDragFinished: v => SettingsData.set("frameBarSize", v) + } + + SettingsSliderRow { + settingKey: "frameBarInsetPadding" + tags: ["frame", "bar", "edge", "inset", "padding", "corner", "end"] + text: I18n.tr("Bar inset padding") + minimumLabel: I18n.tr("Edge to edge", "slider minimum label, bar touches the screen edges") + unit: "px" + minimum: 0 + maximum: 48 + step: 1 + value: root.frameInsetPaddingDisplay + onSliderDragFinished: v => SettingsData.set("frameBarInsetPadding", v) + } + + SettingsToggleRow { + id: frameBlurToggle + settingKey: "frameBlurEnabled" + tags: ["frame", "blur", "background", "glass", "transparency", "frosted"] + text: I18n.tr("Blur") + checked: SettingsData.frameBlurEnabled + onToggled: checked => SettingsData.set("frameBlurEnabled", checked) + enabled: BlurService.available && SettingsData.blurEnabled + visible: BlurService.available + } + + SettingsRow { + visible: BlurService.available && !SettingsData.blurEnabled + body: Item { + width: parent.width + height: blurToggleNote.height + Theme.spacingM * 2 + + Row { + id: blurToggleNote + x: Theme.spacingM + width: parent.width - Theme.spacingM * 2 + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "blur_on" + size: Theme.fontSizeMedium + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Frame Blur follows Background Blur in Theme & Colors") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + wrapMode: Text.WordWrap + width: parent.width - Theme.fontSizeMedium - Theme.spacingS + } + } + } + } + } + SettingsCard { iconName: "rounded_corner" - title: I18n.tr("Bar") + title: !root.isDot ? I18n.tr("Bar") : I18n.tr("Dot", "bar layout: free-floating dot that opens island activities") settingKey: "barCorners" tags: ["background", "opacity", "corners", "rounded", "goth", "shadow"] - visible: (bar.selectedBarConfig?.enabled ?? false) && !bar.selectedBarFrameStyled + // Frame styling never reaches the dot's surface, which always paints its own palette and background. + visible: (bar.selectedBarConfig?.enabled ?? false) && (root.isDot || !bar.selectedBarFrameStyled) SettingsButtonGroupRow { settingKey: "islandPalette" @@ -71,7 +175,7 @@ Item { resetStore: bar resetKeys: ["islandBatteryStyle"] text: I18n.tr("Battery style", "island settings: battery meter style row") - visible: bar.selectedBarIsIsland && !SettingsData.isDotBarConfig(bar.selectedBarConfig) && SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "status") && BatteryService.batteryAvailable && SettingsData.islandHomeStatusContent(bar.selectedBarConfig) === "battery" + visible: bar.selectedBarIsIsland && !root.isDot && SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "status") && BatteryService.batteryAvailable && SettingsData.islandHomeStatusContent(bar.selectedBarConfig) === "battery" model: [I18n.tr("Solid", "island settings: filled battery meter style"), I18n.tr("Outline", "island settings: outlined battery meter style"), I18n.tr("Circle", "island settings: circular battery meter style")] currentIndex: root.valueIndex(root.batteryStyleValues, bar.islandSetting("islandBatteryStyle"), "solid") onSelectionChanged: (index, selected) => { @@ -80,10 +184,25 @@ Item { } } + SettingsButtonGroupRow { + settingKey: "islandBatteryColorMode" + tags: ["island", "battery", "color", "level", "theme", "meter", "accent", "green", "red"] + resetStore: bar + resetKeys: ["batteryColorMode"] + text: I18n.tr("Battery") + visible: bar.selectedBarIsIsland && !root.isDot && SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "status") && BatteryService.batteryAvailable && SettingsData.islandHomeStatusContent(bar.selectedBarConfig) === "battery" + model: [I18n.tr("Theme", "battery settings: theme accent indicator colors"), I18n.tr("Level", "battery settings: charge level indicator colors")] + currentIndex: (bar.selectedBarConfig?.batteryColorMode ?? "theme") === "level" ? 1 : 0 + onSelectionChanged: (index, selected) => { + if (selected) + bar.apply("batteryColorMode", index === 1 ? "level" : "theme"); + } + } + SurfaceColorRow { settingKey: "barSurfaceColor" tags: ["background", "color", "surface", "bar", "material"] - visible: !bar.selectedBarFrameStyled + visible: root.isDot || !bar.selectedBarFrameStyled resetStore: bar resetKeys: ["surfaceColor", "surfaceCustomColor"] text: I18n.tr("Background") @@ -96,13 +215,46 @@ Item { } SettingsControlledBy { - visible: !bar.selectedBarFrameStyled && !bar.islandOwnsSelectedBarTop + visible: !root.isDot && !bar.selectedBarFrameStyled && !bar.islandOwnsSelectedBarTop target: "surfaces" parentModal: root.parentModal section: "surfaceOpacity_bar_" + bar.selectedBarId settingLabel: I18n.tr("Opacity") } + SettingsSliderRow { + settingKey: "dotOpacity" + tags: ["dot", "opacity", "transparency", "background"] + visible: root.isDot + resetStore: bar + resetKeys: ["transparency"] + text: I18n.tr("Opacity") + minimum: 0 + maximum: 100 + step: 1 + value: Math.round(SettingsData.barTransparency(bar.selectedBarConfig) * 100) + onSliderDragFinished: finalValue => SettingsData.updateBarConfig(bar.selectedBarId, { + followInterfaceStyle: false, + transparency: finalValue / 100 + }) + } + + SettingsSliderRow { + settingKey: "islandFreeIdleOpacity" + tags: ["island", "free", "dot", "idle", "opacity", "fade"] + visible: root.isDot + resetStore: bar + resetKeys: ["islandFreeIdleOpacity"] + text: I18n.tr("Idle opacity", "island settings: dot opacity while idle") + unit: "%" + minimum: 5 + maximum: 100 + step: 1 + value: Math.round(bar.islandSetting("islandFreeIdleOpacity") * 100) + enabled: bar.islandSetting("islandFreeIdleDelay") > 0 + onSliderValueChanged: value => bar.apply("islandFreeIdleOpacity", value / 100) + } + SettingsButtonGroupRow { settingKey: "barCornerStyle" tags: ["rounded", "attached", "square", "corners", "edge", "screen", "flush"] @@ -229,20 +381,73 @@ Item { } } - SettingsControlledBy { - visible: (bar.selectedBarConfig?.enabled ?? false) && bar.selectedBarFrameSanitized && !bar.islandOwnsSelectedBarTop - parentModal: root.parentModal - section: "frameBorder" - settingLabel: I18n.tr("Bar surface and spacing") - reason: SettingsData.connectedFrameModeActive ? I18n.tr("Managed by Frame in Connected Mode") : I18n.tr("Managed by Frame") - } - SettingsCard { iconName: "space_bar" title: I18n.tr("Size & spacing") settingKey: "barSpacing" tags: ["size", "scale", "font", "icon", "spacing", "padding", "inset", "length"] - visible: bar.selectedBarConfig?.enabled ?? false + visible: (bar.selectedBarConfig?.enabled ?? false) && !root.isDot + + SettingsSliderRow { + settingKey: "islandReserveThickness" + tags: ["island", "placement", "reservation", "exclusive", "height", "width", "thickness"] + visible: bar.selectedBarIsIsland && !root.selectedIslandFree + resetStore: bar + resetKeys: ["islandReserveThickness"] + text: bar.selectedBarIsVertical ? I18n.tr("Reserved width", "island settings: reserved strip width slider") : I18n.tr("Reserved height", "island settings: reserved strip height slider") + unit: "px" + minimum: 24 + maximum: 128 + step: 1 + value: bar.islandSetting("islandReserveThickness") + enabled: !bar.islandSetting("islandFloating") + onSliderValueChanged: value => bar.apply("islandReserveThickness", value) + } + + SettingsSliderRow { + settingKey: "islandCompactThickness" + tags: ["island", "placement", "compact", "height", "width", "thickness", "size", "satellite"] + visible: bar.selectedBarIsIsland && !root.selectedIslandFree + resetStore: bar + resetKeys: ["islandCompactThickness"] + text: bar.selectedBarIsVertical ? I18n.tr("Compact width", "island settings: compact pill width slider") : I18n.tr("Compact height", "island settings: compact pill height slider") + unit: "px" + minimum: 24 + maximum: 72 + step: 1 + value: bar.islandSetting("islandCompactThickness") + onSliderValueChanged: value => bar.apply("islandCompactThickness", value) + } + + SettingsSliderRow { + settingKey: "islandOuterGap" + tags: ["island", "placement", "gap", "top", "margin"] + visible: bar.selectedBarIsIsland && !root.selectedIslandFree + resetStore: bar + resetKeys: ["islandOuterGap"] + text: I18n.tr("Outer gap", "island settings: gap between screen edge and island") + unit: "px" + minimum: 0 + maximum: 48 + step: 1 + value: bar.islandSetting("islandOuterGap") + onSliderValueChanged: value => bar.apply("islandOuterGap", value) + } + + SettingsSliderRow { + settingKey: "islandAlongOffset" + tags: ["island", "placement", "horizontal", "vertical", "offset", "center"] + visible: bar.selectedBarIsIsland && !root.selectedIslandFree + resetStore: bar + resetKeys: ["islandAlongOffset"] + text: bar.selectedBarIsVertical ? I18n.tr("Vertical offset", "island settings: vertical offset slider") : I18n.tr("Horizontal offset", "island settings: horizontal offset slider") + unit: "px" + minimum: -600 + maximum: 600 + step: 1 + value: bar.islandSetting("islandAlongOffset") + onSliderValueChanged: value => bar.apply("islandAlongOffset", value) + } SettingsSliderRow { settingKey: "barSize" @@ -385,12 +590,116 @@ Item { } } + SettingsCard { + iconName: "widgets" + title: I18n.tr("Satellites", "island settings: satellite widgets card title") + settingKey: "islandSatellites" + collapsible: true + expanded: true + visible: root.selectedIslandEnabled && !root.isDot + + SettingsToggleRow { + settingKey: "islandSatellitesEnabled" + tags: ["island", "satellite", "widgets", "left", "right"] + resetStore: bar + resetKeys: ["islandSatellitesEnabled"] + text: I18n.tr("Show", "island settings: satellite widgets toggle") + checked: bar.islandSetting("islandSatellitesEnabled") + onToggled: checked => bar.apply("islandSatellitesEnabled", checked) + } + + SettingsButtonGroupRow { + settingKey: "islandSatellitePosition" + tags: ["island", "satellite", "widgets", "position", "edges", "center"] + resetStore: bar + resetKeys: ["islandSatellitePosition"] + text: I18n.tr("Position", "island settings: position card title") + model: [I18n.tr("Near island", "island settings: satellites hug the island"), I18n.tr("Display edges", "island settings: satellites sit at screen edges")] + currentIndex: root.valueIndex(root.satellitePositionValues, bar.islandSetting("islandSatellitePosition"), "island") + enabled: bar.islandSetting("islandSatellitesEnabled") + onSelectionChanged: (index, selected) => { + if (selected) + bar.apply("islandSatellitePosition", root.satellitePositionValues[index] ?? "island"); + } + } + + SettingsToggleRow { + settingKey: "islandSatelliteBackground" + tags: ["island", "satellite", "widgets", "background", "chrome"] + resetStore: bar + resetKeys: ["islandSatelliteBackground"] + text: I18n.tr("Background", "island settings: satellite background toggle") + checked: bar.islandSetting("islandSatelliteBackground") + visible: bar.islandSetting("islandSatellitesEnabled") + onToggled: checked => bar.apply("islandSatelliteBackground", checked) + } + + SettingsToggleRow { + settingKey: "islandSatelliteGothCorners" + tags: ["island", "satellite", "goth", "corners", "wing", "sweep"] + resetStore: bar + resetKeys: ["islandSatelliteGothCorners"] + text: I18n.tr("Goth corners", "island settings: satellite goth corners toggle") + checked: bar.islandSetting("islandSatelliteGothCorners") + visible: bar.islandSetting("islandSatellitesEnabled") + enabled: bar.islandSetting("islandSatelliteBackground") + onToggled: checked => bar.apply("islandSatelliteGothCorners", checked) + } + + SettingsSliderRow { + settingKey: "islandSatelliteSwoopRadius" + tags: ["island", "satellite", "goth", "corners", "radius", "sweep", "size"] + resetStore: bar + resetKeys: ["islandSatelliteSwoopRadius"] + text: I18n.tr("Goth corner radius", "island settings: satellite goth corner radius slider") + unit: "px" + minimum: 4 + maximum: 64 + step: 1 + value: bar.islandSetting("islandSatelliteSwoopRadius") + visible: bar.islandSetting("islandSatellitesEnabled") + enabled: bar.islandSetting("islandSatelliteBackground") && bar.islandSetting("islandSatelliteGothCorners") + onSliderValueChanged: value => bar.apply("islandSatelliteSwoopRadius", value) + } + + SettingsSliderRow { + settingKey: "islandSatelliteTransparency" + tags: ["island", "satellite", "background", "opacity", "transparency", "blur"] + resetStore: bar + resetKeys: ["islandSatelliteTransparency"] + text: I18n.tr("Opacity", "island settings: satellite background opacity slider") + minimum: 0 + maximum: 100 + step: 1 + value: Math.round(bar.islandSetting("islandSatelliteTransparency") * 100) + visible: bar.islandSetting("islandSatellitesEnabled") + enabled: bar.islandSetting("islandSatelliteBackground") + onSliderValueChanged: value => bar.apply("islandSatelliteTransparency", value / 100) + } + + SettingsSliderRow { + settingKey: "islandSatelliteGap" + tags: ["island", "satellite", "widgets", "gap", "spacing"] + resetStore: bar + resetKeys: ["islandSatelliteGap"] + text: I18n.tr("Gap", "island settings: satellite to island gap slider") + unit: "px" + minimum: 4 + maximum: 48 + step: 1 + value: bar.islandSetting("islandSatelliteGap") + visible: bar.islandSetting("islandSatellitesEnabled") + enabled: bar.islandSetting("islandSatellitePosition") !== "edges" + onSliderValueChanged: value => bar.apply("islandSatelliteGap", value) + } + } + SettingsCard { iconName: "widgets" title: I18n.tr("Widgets") settingKey: "barWidgets" tags: ["widget", "style", "pills", "segments", "opacity", "padding", "maximize"] - visible: bar.selectedBarConfig?.enabled ?? false + visible: (bar.selectedBarConfig?.enabled ?? false) && !root.isDot SettingsRow { settingKey: "barWidgetStyle" @@ -492,7 +801,7 @@ Item { settingKey: "barWidgetOutline" iconName: "highlight" title: I18n.tr("Widget outline") - visible: bar.selectedBarConfig?.enabled ?? false + visible: (bar.selectedBarConfig?.enabled ?? false) && !root.isDot enabled: root.widgetBackgroundEnabled resetStore: bar resetKeys: ["widgetOutlineEnabled"] @@ -550,6 +859,7 @@ Item { title: I18n.tr("Widget colors") settingKey: "widgetStyling" tags: ["widget", "background", "color", "colorful", "text", "all", "bars"] + visible: !root.isDot WidgetTextStyleRow {} @@ -561,119 +871,5 @@ Item { enabled: root.widgetBackgroundEnabled } } - - SettingsCard { - iconName: "palette" - title: I18n.tr("Icons") - settingKey: "trayIconTint" - tags: ["icon", "tray", "tint", "battery", "color"] - visible: bar.selectedBarConfig?.enabled ?? false - - SettingsButtonGroupRow { - settingKey: "batteryColorMode" - tags: ["battery", "color", "level", "theme", "icon", "meter", "indicator", "accent", "green", "red"] - text: I18n.tr("Battery") - visible: BatteryService.batteryAvailable - resetStore: bar - resetKeys: ["batteryColorMode"] - model: [I18n.tr("Theme", "battery settings: theme accent indicator colors"), I18n.tr("Level", "battery settings: charge level indicator colors")] - currentIndex: (bar.selectedBarConfig?.batteryColorMode ?? "theme") === "level" ? 1 : 0 - onSelectionChanged: (index, selected) => { - if (!selected) - return; - SettingsData.updateBarConfig(bar.selectedBarId, { - batteryColorMode: index === 1 ? "level" : "theme" - }); - } - } - - SettingsButtonGroupRow { - readonly property var modes: ["none", "monochrome", "primary", "secondary"] - - tags: ["tray", "icon", "tint", "monochrome", "system tray"] - text: I18n.tr("Tray icon tint") - resetKeys: ["systemTrayIconTintMode"] - model: [I18n.tr("None"), I18n.tr("Monochrome"), I18n.tr("Primary"), I18n.tr("Secondary")] - currentIndex: Math.max(0, modes.indexOf(SettingsData.systemTrayIconTintMode || "none")) - onSelectionChanged: (index, selected) => { - if (!selected) - return; - SettingsData.set("systemTrayIconTintMode", modes[index]); - } - } - - SettingsSliderRow { - text: I18n.tr("Tint saturation") - tags: ["tray", "tint", "saturation"] - visible: root.trayTinted - resetKeys: ["systemTrayIconTintSaturation"] - value: SettingsData.systemTrayIconTintSaturation ?? 50 - minimum: 0 - maximum: 100 - onSliderDragFinished: finalValue => SettingsData.set("systemTrayIconTintSaturation", finalValue) - } - - SettingsSliderRow { - text: I18n.tr("Tint strength") - tags: ["tray", "tint", "strength"] - visible: root.trayTinted - resetKeys: ["systemTrayIconTintStrength"] - value: SettingsData.systemTrayIconTintStrength ?? 135 - minimum: 0 - maximum: 200 - onSliderDragFinished: finalValue => SettingsData.set("systemTrayIconTintStrength", finalValue) - } - } - - SettingsCard { - title: I18n.tr("Advanced") - settingKey: "barAppearanceAdvanced" - tags: ["bar", "advanced", "exclusive", "zone", "popup", "gaps"] - collapsible: true - expanded: false - visible: (bar.selectedBarConfig?.enabled ?? false) && !bar.selectedBarFrameStyled - - SettingsSliderRow { - settingKey: "barExclusiveZone" - tags: ["exclusive", "zone", "reserved", "offset"] - visible: !bar.islandOwnsSelectedBarTop - text: I18n.tr("Exclusive zone offset") - resetStore: bar - resetKeys: ["bottomGap"] - value: bar.selectedBarConfig?.bottomGap ?? 0 - minimum: -50 - maximum: 50 - unit: "px" - onSliderDragFinished: finalValue => SettingsData.updateBarConfig(bar.selectedBarId, { - bottomGap: finalValue - }) - } - - SettingsToggleRow { - text: I18n.tr("Auto popup gaps") - tags: ["popup", "gaps", "auto"] - resetStore: bar - resetKeys: ["popupGapsAuto"] - checked: bar.selectedBarConfig?.popupGapsAuto ?? true - onToggled: checked => SettingsData.updateBarConfig(bar.selectedBarId, { - popupGapsAuto: checked - }) - } - - SettingsSliderRow { - visible: !(bar.selectedBarConfig?.popupGapsAuto ?? true) - text: I18n.tr("Gap size") - tags: ["popup", "gaps", "size"] - resetStore: bar - resetKeys: ["popupGapsManual"] - unit: "px" - value: bar.selectedBarConfig?.popupGapsManual ?? 4 - minimum: 0 - maximum: 50 - onSliderDragFinished: finalValue => SettingsData.updateBarConfig(bar.selectedBarId, { - popupGapsManual: finalValue - }) - } - } } } diff --git a/quickshell/Modules/Settings/DankBarTab.qml b/quickshell/Modules/Settings/DankBarTab.qml index bbe0e2850..b6b426ef8 100644 --- a/quickshell/Modules/Settings/DankBarTab.qml +++ b/quickshell/Modules/Settings/DankBarTab.qml @@ -12,18 +12,20 @@ Item { LayoutMirroring.childrenInherit: true property var parentModal: null - BarSelectionState { id: bar } readonly property var interactionModeValues: ["click", "hybrid"] readonly property var routingValues: ["normal", "always", "last-used"] - readonly property var placementValues: ["edge", "free"] - readonly property bool selectedBarIsDot: SettingsData.isDotBarConfig(bar.selectedBarConfig) + readonly property var clockDisplayValues: ["time", "date", "both"] + readonly property var systemLevelDisplayValues: ["icon", "percentage", "both"] + readonly property var statusContentValues: ["battery", "connectivity"] + readonly property bool isDot: SettingsData.isDotBarConfig(bar.selectedBarConfig) + readonly property bool selectedIslandEnabled: bar.selectedBarIsIsland && (bar.selectedBarConfig?.enabled ?? false) readonly property bool selectedIslandFree: bar.selectedBarIsIsland && SettingsData.islandFreePlacement(bar.selectedBarConfig) - readonly property bool selectedIslandEdgeOrFree: bar.selectedBarIsIsland && !selectedBarIsDot - readonly property bool selectedIslandAnywhere: selectedIslandFree && !selectedBarIsDot + readonly property bool selectedIslandFloating: selectedIslandFree && !isDot + readonly property int placementIndex: !bar.islandSetting("islandFloating") ? 0 : (bar.islandSetting("islandPlacement") === "free" ? 2 : 1) function valueIndex(values, value, fallback) { const index = values.indexOf(value); @@ -62,25 +64,10 @@ Item { subtitle: I18n.tr("The Island holds this edge on a display this bar covers, so the bar stays hidden there") } - SettingsDropdownRow { - id: sharedRouting - settingKey: "islandSharedRouting" - tags: ["dot", "island", "routing", "launcher", "dash", "control center", "ipc", "last used"] - visible: bar.selectedBarIsIsland - resetStore: bar - resetKeys: ["islandSharedRouting"] - text: I18n.tr("Shared shortcuts") - description: I18n.tr("Routes launcher, dash, control center and notification shortcuts") - options: [I18n.tr("Normal routing"), I18n.tr("Always here"), I18n.tr("Last used on this screen")] - dropdownWidth: Theme.smallBreakpoint / 2 - currentValue: options[dankBarTab.valueIndex(dankBarTab.routingValues, SettingsData.islandSharedRoutingMode(bar.selectedBarConfig), "normal")] - onValueChanged: value => SettingsData.setIslandSharedRouting(bar.selectedBarId, dankBarTab.routingValues[options.indexOf(value)] ?? "normal") - } - SettingsButtonGroupRow { settingKey: "islandFreeOrientation" tags: ["island", "free", "orientation", "horizontal", "vertical"] - visible: dankBarTab.selectedIslandAnywhere + visible: dankBarTab.selectedIslandFloating text: I18n.tr("Orientation", "island settings: horizontal or vertical row for a free island") model: [I18n.tr("Horizontal", "island settings: free island orientation"), I18n.tr("Vertical", "island settings: free island orientation")] currentIndex: SettingsData.islandVertical(bar.selectedBarConfig) ? 1 : 0 @@ -110,37 +97,30 @@ Item { } } - SettingsToggleRow { - settingKey: "islandFloating" - tags: ["island", "placement", "float", "overlay", "exclusive", "reserve"] - visible: dankBarTab.selectedIslandEdgeOrFree - resetStore: bar - resetKeys: ["islandFloating"] - text: I18n.tr("Float", "island settings: float toggle") - description: I18n.tr("Set floating overlay or enable drag anywhere mode") - checked: bar.islandSetting("islandFloating") - onToggled: checked => bar.apply("islandFloating", checked) - } - SettingsButtonGroupRow { settingKey: "islandPlacement" - tags: ["island", "placement", "free", "floating", "dot", "edge", "drag"] - visible: dankBarTab.selectedIslandEdgeOrFree && bar.islandSetting("islandFloating") + tags: ["island", "placement", "docked", "overlay", "floating", "float", "free", "anywhere", "edge", "drag", "exclusive", "reserve"] + visible: bar.selectedBarIsIsland && !dankBarTab.isDot resetStore: bar - resetKeys: ["islandPlacement"] - text: I18n.tr("Placement", "island settings: edge or free placement row") - model: [I18n.tr("Edge", "island settings: floats along a screen edge"), I18n.tr("Anywhere", "island settings: floats anywhere on the display")] - currentIndex: dankBarTab.valueIndex(dankBarTab.placementValues, bar.islandSetting("islandPlacement"), "edge") + resetKeys: ["islandFloating", "islandPlacement"] + text: I18n.tr("Placement", "island settings: docked, overlay or floating placement row") + model: [I18n.tr("Docked", "island settings: island reserves its edge strip"), I18n.tr("Overlay", "island settings: island floats over windows along its edge without reserving space"), I18n.tr("Floating", "island settings: island can be dragged anywhere on the display")] + currentIndex: dankBarTab.placementIndex onSelectionChanged: (index, selected) => { if (!selected) return; - bar.apply("islandPlacement", dankBarTab.placementValues[index] ?? "edge"); + const patch = { + islandFloating: index > 0 + }; + if (index > 0) + patch.islandPlacement = index === 2 ? "free" : "edge"; + SettingsData.updateBarConfig(bar.selectedBarId, patch); bar.notifyHorizontalBarChange(); } } SettingsRow { - visible: dankBarTab.selectedIslandAnywhere + visible: dankBarTab.selectedIslandFloating body: StyledText { width: parent.width text: I18n.tr("Drag to move, click to open activities", "island settings: free placement hint") @@ -150,71 +130,25 @@ Item { } } - SettingsSliderRow { - settingKey: "islandReserveThickness" - tags: ["island", "placement", "reservation", "exclusive", "height", "width", "thickness"] - visible: bar.selectedBarIsIsland && !dankBarTab.selectedIslandFree + SettingsDropdownRow { + id: sharedRouting + settingKey: "islandSharedRouting" + tags: ["dot", "island", "routing", "launcher", "dash", "control center", "ipc", "last used"] + visible: bar.selectedBarIsIsland resetStore: bar - resetKeys: ["islandReserveThickness"] - text: bar.selectedBarIsVertical ? I18n.tr("Reserved width", "island settings: reserved strip width slider") : I18n.tr("Reserved height", "island settings: reserved strip height slider") - unit: "px" - minimum: 24 - maximum: 128 - step: 1 - value: bar.islandSetting("islandReserveThickness") - enabled: !bar.islandSetting("islandFloating") - onSliderValueChanged: value => bar.apply("islandReserveThickness", value) - } - - SettingsSliderRow { - settingKey: "islandCompactThickness" - tags: ["island", "placement", "compact", "height", "width", "thickness", "size", "satellite"] - visible: bar.selectedBarIsIsland && !dankBarTab.selectedIslandFree - resetStore: bar - resetKeys: ["islandCompactThickness"] - text: bar.selectedBarIsVertical ? I18n.tr("Compact width", "island settings: compact pill width slider") : I18n.tr("Compact height", "island settings: compact pill height slider") - unit: "px" - minimum: 24 - maximum: 72 - step: 1 - value: bar.islandSetting("islandCompactThickness") - onSliderValueChanged: value => bar.apply("islandCompactThickness", value) - } - - SettingsSliderRow { - settingKey: "islandOuterGap" - tags: ["island", "placement", "gap", "top", "margin"] - visible: bar.selectedBarIsIsland && !dankBarTab.selectedIslandFree - resetStore: bar - resetKeys: ["islandOuterGap"] - text: I18n.tr("Outer gap", "island settings: gap between screen edge and island") - unit: "px" - minimum: 0 - maximum: 48 - step: 1 - value: bar.islandSetting("islandOuterGap") - onSliderValueChanged: value => bar.apply("islandOuterGap", value) - } - - SettingsSliderRow { - settingKey: "islandAlongOffset" - tags: ["island", "placement", "horizontal", "vertical", "offset", "center"] - visible: bar.selectedBarIsIsland && !dankBarTab.selectedIslandFree - resetStore: bar - resetKeys: ["islandAlongOffset"] - text: bar.selectedBarIsVertical ? I18n.tr("Vertical offset", "island settings: vertical offset slider") : I18n.tr("Horizontal offset", "island settings: horizontal offset slider") - unit: "px" - minimum: -600 - maximum: 600 - step: 1 - value: bar.islandSetting("islandAlongOffset") - onSliderValueChanged: value => bar.apply("islandAlongOffset", value) + resetKeys: ["islandSharedRouting"] + text: I18n.tr("Shared shortcuts") + description: I18n.tr("Routes launcher, dash, control center and notification shortcuts") + options: [I18n.tr("Normal routing"), I18n.tr("Always here"), I18n.tr("Last used on this screen")] + dropdownWidth: Theme.smallBreakpoint / 2 + currentValue: options[dankBarTab.valueIndex(dankBarTab.routingValues, SettingsData.islandSharedRoutingMode(bar.selectedBarConfig), "normal")] + onValueChanged: value => SettingsData.setIslandSharedRouting(bar.selectedBarId, dankBarTab.routingValues[options.indexOf(value)] ?? "normal") } SettingsSliderRow { settingKey: "islandFreeSize" tags: ["island", "free", "dot", "size", "diameter"] - visible: dankBarTab.selectedBarIsDot + visible: dankBarTab.isDot resetStore: bar resetKeys: ["islandFreeSize"] text: I18n.tr("Dot size", "island settings: free dot diameter slider") @@ -244,7 +178,7 @@ Item { SettingsSliderRow { settingKey: "islandFreeIdleDelay" tags: ["island", "free", "dot", "idle", "delay", "fade", "timeout"] - visible: dankBarTab.selectedBarIsDot + visible: dankBarTab.isDot resetStore: bar resetKeys: ["islandFreeIdleDelay"] text: I18n.tr("Idle delay", "island settings: time before the dot fades, 0 disables idling") @@ -256,26 +190,10 @@ Item { onSliderValueChanged: value => bar.apply("islandFreeIdleDelay", value) } - SettingsSliderRow { - settingKey: "islandFreeIdleOpacity" - tags: ["island", "free", "dot", "idle", "opacity", "fade"] - visible: dankBarTab.selectedBarIsDot - resetStore: bar - resetKeys: ["islandFreeIdleOpacity"] - text: I18n.tr("Idle opacity", "island settings: dot opacity while idle") - unit: "%" - minimum: 5 - maximum: 100 - step: 1 - value: Math.round(bar.islandSetting("islandFreeIdleOpacity") * 100) - enabled: bar.islandSetting("islandFreeIdleDelay") > 0 - onSliderValueChanged: value => bar.apply("islandFreeIdleOpacity", value / 100) - } - SettingsSliderRow { settingKey: "islandFreeIdleScale" tags: ["island", "free", "dot", "idle", "shrink", "scale"] - visible: dankBarTab.selectedBarIsDot + visible: dankBarTab.isDot resetStore: bar resetKeys: ["islandFreeIdleScale"] text: I18n.tr("Idle size", "island settings: how far the dot shrinks while idle") @@ -308,6 +226,104 @@ Item { } } + SettingsCard { + iconName: "tune" + title: I18n.tr("Frame") + settingKey: "frameEnabled" + tags: ["frame", "mode", "bar", "overview"] + visible: !dankBarTab.isDot && SettingsData.frameEnabled + + SettingsButtonGroupRow { + settingKey: "frameModeSelector" + tags: ["frame", "mode", "connected", "separate", "popout", "flush", "float"] + resetKeys: ["frameMode"] + text: I18n.tr("Surfaces") + model: [I18n.tr("Separate", "adjective, frame surfaces mode option, opposite of connected"), I18n.tr("Connected")] + currentIndex: SettingsData.frameMode === "connected" ? 1 : 0 + onSelectionChanged: (index, selected) => { + if (!selected) + return; + switch (index) { + case 1: + SettingsData.set("frameMode", "connected"); + break; + default: + SettingsData.set("frameMode", "separate"); + break; + } + } + } + + SettingsToggleRow { + settingKey: "frameShowOnOverview" + tags: ["frame", "overview", "show", "hide", "niri"] + text: I18n.tr("Show on overview") + visible: CompositorService.supportsNativeOverview + checked: SettingsData.frameShowOnOverview + onToggled: checked => SettingsData.set("frameShowOnOverview", checked) + } + } + + SettingsCard { + iconName: "blur_linear" + title: I18n.tr("Connected") + settingKey: "frameConnectedOptions" + collapsible: true + expanded: true + visible: !dankBarTab.isDot && SettingsData.frameEnabled && SettingsData.frameMode === "connected" + + SettingsToggleRow { + settingKey: "frameCloseGaps" + tags: ["frame", "connected", "gap", "edge", "curves", "arcs", "expose", "popout", "notification"] + text: I18n.tr("Expose the arcs") + checked: !SettingsData.frameCloseGaps + onToggled: checked => SettingsData.set("frameCloseGaps", !checked) + } + + SettingsButtonGroupRow { + settingKey: "frameLauncherEmergeSide" + tags: ["frame", "connected", "launcher", "modal", "emerge", "direction", "bottom", "top"] + text: I18n.tr("Launcher emerge side") + model: [I18n.tr("Bottom"), I18n.tr("Top")] + currentIndex: SettingsData.frameLauncherEmergeSide === "top" ? 1 : 0 + onSelectionChanged: (index, selected) => { + if (!selected) + return; + SettingsData.set("frameLauncherEmergeSide", index === 1 ? "top" : "bottom"); + } + } + + SettingsToggleRow { + settingKey: "frameLauncherArcExtender" + tags: ["frame", "connected", "launcher", "arc", "extender", "center"] + text: I18n.tr("Arc extender") + checked: SettingsData.frameLauncherArcExtender + onToggled: checked => SettingsData.set("frameLauncherArcExtender", checked) + } + + SettingsToggleRow { + settingKey: "frameLauncherEdgeHover" + tags: ["frame", "connected", "launcher", "hover", "edge", "reveal"] + text: I18n.tr("Edge hover reveal") + checked: SettingsData.frameLauncherEdgeHover + onToggled: checked => SettingsData.set("frameLauncherEdgeHover", checked) + } + } + + SettingsCard { + iconName: "monitor" + title: I18n.tr("Frame displays", "settings card title: displays that draw the frame") + settingKey: "frameDisplays" + collapsible: true + expanded: false + visible: !dankBarTab.isDot && SettingsData.frameEnabled + + SettingsDisplayPicker { + displayPreferences: SettingsData.frameScreenPreferences + onPreferencesChanged: prefs => SettingsData.set("frameScreenPreferences", prefs) + } + } + SettingsCard { iconName: "visibility" title: I18n.tr("Visibility", "settings card title for bar or dock show and hide behavior") @@ -493,6 +509,152 @@ Item { } } + SettingsCard { + iconName: "home" + title: I18n.tr("Home compact", "island settings: home face card title") + settingKey: "islandActivities" + visible: dankBarTab.selectedIslandEnabled && !dankBarTab.isDot + + IslandHomeLayoutEditor { + width: parent.width + barId: bar.selectedBarIsIsland ? bar.selectedBarId : "" + } + + SettingsButtonGroupRow { + settingKey: "islandHomeClockDisplay" + tags: ["island", "home", "compact", "clock", "time", "date"] + resetStore: bar + resetKeys: ["islandHomeClockDisplay"] + text: I18n.tr("Clock style", "island settings: clock display mode row") + model: [I18n.tr("Time", "island settings: clock shows time only"), I18n.tr("Date", "island settings: clock shows date only"), I18n.tr("Both", "island settings: clock shows time and date")] + currentIndex: dankBarTab.valueIndex(dankBarTab.clockDisplayValues, bar.islandSetting("islandHomeClockDisplay"), "both") + onSelectionChanged: (index, selected) => { + if (selected) + bar.apply("islandHomeClockDisplay", dankBarTab.clockDisplayValues[index] ?? "both"); + } + } + + SettingsButtonGroupRow { + settingKey: "islandHomeVolumeDisplay" + tags: ["island", "home", "compact", "volume", "icon", "percentage"] + resetStore: bar + resetKeys: ["islandHomeVolumeDisplay"] + text: I18n.tr("Volume style", "island settings: volume display mode row") + visible: SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "volume") + model: [I18n.tr("Icon", "island settings: level shown as icon only"), I18n.tr("Percentage", "island settings: level shown as percentage only"), I18n.tr("Both", "island settings: level shown as icon and percentage")] + currentIndex: dankBarTab.valueIndex(dankBarTab.systemLevelDisplayValues, bar.islandSetting("islandHomeVolumeDisplay"), "both") + onSelectionChanged: (index, selected) => { + if (selected) + bar.apply("islandHomeVolumeDisplay", dankBarTab.systemLevelDisplayValues[index] ?? "both"); + } + } + + SettingsButtonGroupRow { + settingKey: "islandHomeBrightnessDisplay" + tags: ["island", "home", "compact", "brightness", "icon", "percentage"] + resetStore: bar + resetKeys: ["islandHomeBrightnessDisplay"] + text: I18n.tr("Brightness style", "island settings: brightness display mode row") + visible: SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "brightness") + model: [I18n.tr("Icon", "island settings: level shown as icon only"), I18n.tr("Percentage", "island settings: level shown as percentage only"), I18n.tr("Both", "island settings: level shown as icon and percentage")] + currentIndex: dankBarTab.valueIndex(dankBarTab.systemLevelDisplayValues, bar.islandSetting("islandHomeBrightnessDisplay"), "both") + onSelectionChanged: (index, selected) => { + if (selected) + bar.apply("islandHomeBrightnessDisplay", dankBarTab.systemLevelDisplayValues[index] ?? "both"); + } + } + + SettingsButtonGroupRow { + settingKey: "islandHomeStatusContent" + tags: ["island", "home", "compact", "status", "battery", "wifi", "bluetooth", "connectivity"] + text: I18n.tr("Control Center", "island settings: status group content row") + visible: SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "status") + model: [I18n.tr("Battery", "island settings: status group battery content"), I18n.tr("Wi-Fi & Bluetooth", "island settings: status group connectivity content")] + currentIndex: dankBarTab.valueIndex(dankBarTab.statusContentValues, SettingsData.islandHomeStatusContent(bar.selectedBarConfig), "battery") + onSelectionChanged: (index, selected) => { + if (selected) + bar.apply("islandHomeStatusContent", dankBarTab.statusContentValues[index] ?? "battery"); + } + } + + SettingsToggleRow { + settingKey: "islandHomeCompactTight" + tags: ["island", "home", "compact", "narrow", "width", "height", "clock"] + resetStore: bar + resetKeys: ["islandHomeCompactTight"] + text: I18n.tr("Compact pill", "island settings: tighter home pill toggle") + checked: bar.islandSetting("islandHomeCompactTight") + onToggled: checked => bar.apply("islandHomeCompactTight", checked) + } + + SettingsRow { + body: Flow { + width: parent.width + spacing: Theme.spacingS + + DankButton { + text: I18n.tr("Launcher", "island settings: button to launcher tab") + iconName: "grid_view" + onClicked: { + if (!dankBarTab.parentModal) + return; + SettingsSearchService.navigateToSection("launcherStyle"); + dankBarTab.parentModal.navigateTo("launcher"); + } + } + + DankButton { + text: I18n.tr("Time & weather", "island settings: button to weather tab") + iconName: "cloud" + onClicked: { + if (!dankBarTab.parentModal) + return; + SettingsSearchService.navigateToSection("weatherEnabled"); + dankBarTab.parentModal.navigateTo("time_weather"); + } + } + } + } + } + + SettingsCard { + iconName: "notifications" + title: I18n.tr("Notifications", "island settings: notifications card title") + settingKey: "islandNotifications" + visible: dankBarTab.selectedIslandEnabled + + SettingsToggleRow { + settingKey: "islandNotificationPopups" + tags: ["island", "notifications", "popup", "standard", "bar", "stack", "arrival"] + resetStore: bar + resetKeys: ["islandNotificationPopups"] + text: I18n.tr("Use standard popups", "island settings: show arriving notifications as stacked popups instead of in the island") + checked: bar.islandSetting("islandNotificationPopups") + onToggled: checked => bar.apply("islandNotificationPopups", checked) + } + + SettingsToggleRow { + settingKey: "islandNotificationExpand" + tags: ["island", "notifications", "expand", "arrival", "size"] + resetStore: bar + resetKeys: ["islandNotificationExpand"] + text: I18n.tr("Expand by default", "island settings: expanded notification toggle") + checked: bar.islandSetting("islandNotificationExpand") + onToggled: checked => bar.apply("islandNotificationExpand", checked) + } + + SettingsToggleRow { + settingKey: "islandNotificationBadgeClearOnOpen" + tags: ["island", "home", "notifications", "badge", "unread", "clear", "dismiss", "open"] + resetStore: bar + resetKeys: ["islandNotificationBadgeClearOnOpen"] + text: I18n.tr("Clear badge on open", "island settings: clear the notification badge when the center opens") + checked: bar.islandSetting("islandNotificationBadgeClearOnOpen") + enabled: dankBarTab.isDot || SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "notifications") + onToggled: checked => bar.apply("islandNotificationBadgeClearOnOpen", checked) + } + } + SettingsToggleCard { settingKey: "hoverPopouts" resetStore: bar @@ -500,7 +662,7 @@ Item { tags: ["bar", "hover", "popout", "reveal", "widget", "delay"] iconName: "touch_app" title: I18n.tr("Hover popouts") - visible: bar.selectedBarConfig?.enabled ?? false + visible: (bar.selectedBarConfig?.enabled ?? false) && !dankBarTab.isDot enabled: !(bar.selectedBarConfig?.clickThrough ?? false) opacity: (bar.selectedBarConfig?.clickThrough ?? false) ? 0.5 : 1.0 checked: bar.selectedBarConfig?.hoverPopouts ?? false @@ -621,127 +783,5 @@ Item { } } } - - SettingsCard { - title: I18n.tr("Advanced") - settingKey: "barAdvanced" - tags: ["bar", "advanced", "overlay", "layer", "click", "through", "maximize", "island", "spring", "motion"] - collapsible: true - expanded: false - visible: bar.selectedBarConfig?.enabled ?? false - - SettingsToggleRow { - settingKey: "barClickThrough" - resetStore: bar - resetKeys: ["clickThrough"] - tags: ["clickthrough", "click", "through", "mouse", "input", "mask", "passthrough"] - visible: !bar.islandOwnsSelectedBarTop - text: I18n.tr("Click through") - checked: bar.selectedBarConfig?.clickThrough ?? false - onToggled: toggled => SettingsData.updateBarConfig(bar.selectedBarId, { - clickThrough: toggled - }) - } - - SettingsToggleRow { - settingKey: "barUseOverlayLayer" - resetStore: bar - resetKeys: ["useOverlayLayer"] - tags: ["bar", "fullscreen", "overlay", "layer"] - visible: !bar.islandOwnsSelectedBarTop - text: I18n.tr("Use overlay layer") - checked: bar.selectedBarConfig?.useOverlayLayer ?? false - onToggled: toggled => { - SettingsData.updateBarConfig(bar.selectedBarId, { - useOverlayLayer: toggled - }); - bar.notifyHorizontalBarChange(); - } - } - - SettingsToggleRow { - settingKey: "islandUseOverlayLayer" - tags: ["island", "fullscreen", "overlay", "layer"] - visible: bar.selectedBarIsIsland - resetStore: bar - resetKeys: ["islandUseOverlayLayer"] - text: I18n.tr("Use overlay layer") - checked: bar.islandSetting("islandUseOverlayLayer") - onToggled: checked => bar.apply("islandUseOverlayLayer", checked) - } - - SettingsToggleRow { - settingKey: "islandReducedMotion" - tags: ["island", "motion", "animation", "reduce", "accessibility", "spring"] - visible: bar.selectedBarIsIsland - resetStore: bar - resetKeys: ["islandReducedMotion"] - text: I18n.tr("Reduce motion") - checked: bar.islandSetting("islandReducedMotion") - onToggled: checked => bar.apply("islandReducedMotion", checked) - } - - SettingsSliderRow { - settingKey: "islandSpringStiffness" - tags: ["island", "motion", "spring", "stiffness", "animation"] - visible: bar.selectedBarIsIsland - resetStore: bar - resetKeys: ["islandSpringStiffness"] - text: I18n.tr("Spring stiffness", "island settings: spring stiffness slider") - unit: "" - minimum: 100 - maximum: 1200 - step: 10 - value: Math.round(bar.islandSetting("islandSpringStiffness")) - enabled: !bar.islandSetting("islandReducedMotion") - onSliderValueChanged: value => bar.apply("islandSpringStiffness", value) - } - - SettingsSliderRow { - settingKey: "islandSpringDamping" - tags: ["island", "motion", "spring", "damping", "bounce", "animation"] - visible: bar.selectedBarIsIsland - resetStore: bar - resetKeys: ["islandSpringDamping"] - text: I18n.tr("Spring damping", "island settings: spring damping slider") - unit: "" - minimum: 10 - maximum: 100 - step: 1 - value: Math.round(bar.islandSetting("islandSpringDamping")) - enabled: !bar.islandSetting("islandReducedMotion") - onSliderValueChanged: value => bar.apply("islandSpringDamping", value) - } - - SettingsSliderRow { - settingKey: "islandSpringMass" - tags: ["island", "motion", "spring", "mass", "inertia", "animation"] - visible: bar.selectedBarIsIsland - resetStore: bar - resetKeys: ["islandSpringMass"] - text: I18n.tr("Spring mass", "island settings: spring mass slider") - minimum: 25 - maximum: 300 - step: 5 - unit: "" - decimals: 2 - value: Math.round(bar.islandSetting("islandSpringMass") * 100) - enabled: !bar.islandSetting("islandReducedMotion") - onSliderValueChanged: value => bar.apply("islandSpringMass", value / 100) - } - - SettingsToggleRow { - settingKey: "barMaximizeDetection" - resetStore: bar - resetKeys: ["maximizeDetection"] - tags: ["maximize", "gaps", "border", "fullscreen"] - visible: CompositorService.supportsBarAutoHideReveal - text: I18n.tr("Maximize detection") - checked: bar.selectedBarConfig?.maximizeDetection ?? true - onToggled: toggled => SettingsData.updateBarConfig(bar.selectedBarId, { - maximizeDetection: toggled - }) - } - } } } diff --git a/quickshell/Modules/Settings/DankIslandTab.qml b/quickshell/Modules/Settings/DankIslandTab.qml deleted file mode 100644 index 70a909283..000000000 --- a/quickshell/Modules/Settings/DankIslandTab.qml +++ /dev/null @@ -1,292 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Common -import qs.Modules.Settings.Widgets -import qs.Services -import qs.Widgets - -Item { - id: root - - property var parentModal: null - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - BarSelectionState { - id: bar - } - - readonly property string selectedIslandId: bar.selectedBarIsIsland ? bar.selectedBarId : "" - readonly property var config: bar.selectedBarConfig - readonly property bool islandEnabled: bar.selectedBarIsIsland && (bar.selectedBarConfig?.enabled ?? false) - readonly property bool isDot: SettingsData.isDotBarConfig(root.config) - readonly property bool isFree: SettingsData.islandFreePlacement(root.config) - - readonly property var clockDisplayValues: ["time", "date", "both"] - readonly property var systemLevelDisplayValues: ["icon", "percentage", "both"] - readonly property var statusContentValues: ["battery", "connectivity"] - readonly property var satellitePositionValues: ["island", "edges"] - - function valueIndex(values, value, fallback) { - const index = values.indexOf(value); - return index >= 0 ? index : Math.max(0, values.indexOf(fallback)); - } - - SettingsPage { - id: mainColumn - - SettingsCard { - width: parent.width - iconName: "home" - title: I18n.tr("Home compact", "island settings: home face card title") - settingKey: "islandActivities" - visible: root.islandEnabled && !root.isDot - - IslandHomeLayoutEditor { - width: parent.width - barId: root.selectedIslandId - } - - SettingsButtonGroupRow { - settingKey: "islandHomeClockDisplay" - tags: ["island", "home", "compact", "clock", "time", "date"] - resetStore: bar - resetKeys: ["islandHomeClockDisplay"] - text: I18n.tr("Clock style", "island settings: clock display mode row") - model: [I18n.tr("Time", "island settings: clock shows time only"), I18n.tr("Date", "island settings: clock shows date only"), I18n.tr("Both", "island settings: clock shows time and date")] - currentIndex: root.valueIndex(root.clockDisplayValues, bar.islandSetting("islandHomeClockDisplay"), "both") - onSelectionChanged: (index, selected) => { - if (selected) - bar.apply("islandHomeClockDisplay", root.clockDisplayValues[index] ?? "both"); - } - } - - SettingsButtonGroupRow { - settingKey: "islandHomeVolumeDisplay" - tags: ["island", "home", "compact", "volume", "icon", "percentage"] - resetStore: bar - resetKeys: ["islandHomeVolumeDisplay"] - text: I18n.tr("Volume style", "island settings: volume display mode row") - visible: SettingsData.islandHomeGroupEnabled(root.config, "volume") - model: [I18n.tr("Icon", "island settings: level shown as icon only"), I18n.tr("Percentage", "island settings: level shown as percentage only"), I18n.tr("Both", "island settings: level shown as icon and percentage")] - currentIndex: root.valueIndex(root.systemLevelDisplayValues, bar.islandSetting("islandHomeVolumeDisplay"), "both") - onSelectionChanged: (index, selected) => { - if (selected) - bar.apply("islandHomeVolumeDisplay", root.systemLevelDisplayValues[index] ?? "both"); - } - } - - SettingsButtonGroupRow { - settingKey: "islandHomeBrightnessDisplay" - tags: ["island", "home", "compact", "brightness", "icon", "percentage"] - resetStore: bar - resetKeys: ["islandHomeBrightnessDisplay"] - text: I18n.tr("Brightness style", "island settings: brightness display mode row") - visible: SettingsData.islandHomeGroupEnabled(root.config, "brightness") - model: [I18n.tr("Icon", "island settings: level shown as icon only"), I18n.tr("Percentage", "island settings: level shown as percentage only"), I18n.tr("Both", "island settings: level shown as icon and percentage")] - currentIndex: root.valueIndex(root.systemLevelDisplayValues, bar.islandSetting("islandHomeBrightnessDisplay"), "both") - onSelectionChanged: (index, selected) => { - if (selected) - bar.apply("islandHomeBrightnessDisplay", root.systemLevelDisplayValues[index] ?? "both"); - } - } - - SettingsButtonGroupRow { - settingKey: "islandHomeStatusContent" - tags: ["island", "home", "compact", "status", "battery", "wifi", "bluetooth", "connectivity"] - text: I18n.tr("Control Center", "island settings: status group content row") - visible: SettingsData.islandHomeGroupEnabled(root.config, "status") - model: [I18n.tr("Battery", "island settings: status group battery content"), I18n.tr("Wi-Fi & Bluetooth", "island settings: status group connectivity content")] - currentIndex: root.valueIndex(root.statusContentValues, SettingsData.islandHomeStatusContent(root.config), "battery") - onSelectionChanged: (index, selected) => { - if (selected) - bar.apply("islandHomeStatusContent", root.statusContentValues[index] ?? "battery"); - } - } - - SettingsToggleRow { - settingKey: "islandHomeCompactTight" - tags: ["island", "home", "compact", "narrow", "width", "height", "clock"] - resetStore: bar - resetKeys: ["islandHomeCompactTight"] - text: I18n.tr("Compact pill", "island settings: tighter home pill toggle") - checked: bar.islandSetting("islandHomeCompactTight") - onToggled: checked => bar.apply("islandHomeCompactTight", checked) - } - - SettingsRow { - body: Flow { - width: parent.width - spacing: Theme.spacingS - - DankButton { - text: I18n.tr("Launcher", "island settings: button to launcher tab") - iconName: "grid_view" - onClicked: { - if (!root.parentModal) - return; - SettingsSearchService.navigateToSection("launcherStyle"); - root.parentModal.navigateTo("launcher"); - } - } - - DankButton { - text: I18n.tr("Time & weather", "island settings: button to weather tab") - iconName: "cloud" - onClicked: { - if (!root.parentModal) - return; - SettingsSearchService.navigateToSection("weatherEnabled"); - root.parentModal.navigateTo("time_weather"); - } - } - } - } - } - - SettingsCard { - width: parent.width - iconName: "notifications" - title: I18n.tr("Notifications", "island settings: notifications card title") - settingKey: "islandNotifications" - visible: root.islandEnabled - - SettingsToggleRow { - settingKey: "islandNotificationPopups" - tags: ["island", "notifications", "popup", "standard", "bar", "stack", "arrival"] - resetStore: bar - resetKeys: ["islandNotificationPopups"] - text: I18n.tr("Use standard popups", "island settings: show arriving notifications as stacked popups instead of in the island") - checked: bar.islandSetting("islandNotificationPopups") - onToggled: checked => bar.apply("islandNotificationPopups", checked) - } - - SettingsToggleRow { - settingKey: "islandNotificationExpand" - tags: ["island", "notifications", "expand", "arrival", "size"] - resetStore: bar - resetKeys: ["islandNotificationExpand"] - text: I18n.tr("Expand by default", "island settings: expanded notification toggle") - checked: bar.islandSetting("islandNotificationExpand") - onToggled: checked => bar.apply("islandNotificationExpand", checked) - } - - SettingsToggleRow { - settingKey: "islandNotificationBadgeClearOnOpen" - tags: ["island", "home", "notifications", "badge", "unread", "clear", "dismiss", "open"] - resetStore: bar - resetKeys: ["islandNotificationBadgeClearOnOpen"] - text: I18n.tr("Clear badge on open", "island settings: clear the notification badge when the center opens") - checked: bar.islandSetting("islandNotificationBadgeClearOnOpen") - enabled: root.isDot || SettingsData.islandHomeGroupEnabled(root.config, "notifications") - onToggled: checked => bar.apply("islandNotificationBadgeClearOnOpen", checked) - } - } - - SettingsCard { - width: parent.width - iconName: "widgets" - title: I18n.tr("Satellites", "island settings: satellite widgets card title") - settingKey: "islandSatellites" - collapsible: true - expanded: true - visible: root.islandEnabled && !root.isFree - - SettingsToggleRow { - settingKey: "islandSatellitesEnabled" - tags: ["island", "satellite", "widgets", "left", "right"] - resetStore: bar - resetKeys: ["islandSatellitesEnabled"] - text: I18n.tr("Show", "island settings: satellite widgets toggle") - checked: bar.islandSetting("islandSatellitesEnabled") - onToggled: checked => bar.apply("islandSatellitesEnabled", checked) - } - - SettingsButtonGroupRow { - settingKey: "islandSatellitePosition" - tags: ["island", "satellite", "widgets", "position", "edges", "center"] - resetStore: bar - resetKeys: ["islandSatellitePosition"] - text: I18n.tr("Position", "island settings: position card title") - model: [I18n.tr("Near island", "island settings: satellites hug the island"), I18n.tr("Display edges", "island settings: satellites sit at screen edges")] - currentIndex: root.valueIndex(root.satellitePositionValues, bar.islandSetting("islandSatellitePosition"), "island") - enabled: bar.islandSetting("islandSatellitesEnabled") - onSelectionChanged: (index, selected) => { - if (selected) - bar.apply("islandSatellitePosition", root.satellitePositionValues[index] ?? "island"); - } - } - - SettingsToggleRow { - settingKey: "islandSatelliteBackground" - tags: ["island", "satellite", "widgets", "background", "chrome"] - resetStore: bar - resetKeys: ["islandSatelliteBackground"] - text: I18n.tr("Background", "island settings: satellite background toggle") - checked: bar.islandSetting("islandSatelliteBackground") - visible: bar.islandSetting("islandSatellitesEnabled") - onToggled: checked => bar.apply("islandSatelliteBackground", checked) - } - - SettingsToggleRow { - settingKey: "islandSatelliteGothCorners" - tags: ["island", "satellite", "goth", "corners", "wing", "sweep"] - resetStore: bar - resetKeys: ["islandSatelliteGothCorners"] - text: I18n.tr("Goth corners", "island settings: satellite goth corners toggle") - checked: bar.islandSetting("islandSatelliteGothCorners") - visible: bar.islandSetting("islandSatellitesEnabled") - enabled: bar.islandSetting("islandSatelliteBackground") - onToggled: checked => bar.apply("islandSatelliteGothCorners", checked) - } - - SettingsSliderRow { - settingKey: "islandSatelliteSwoopRadius" - tags: ["island", "satellite", "goth", "corners", "radius", "sweep", "size"] - resetStore: bar - resetKeys: ["islandSatelliteSwoopRadius"] - text: I18n.tr("Goth corner radius", "island settings: satellite goth corner radius slider") - unit: "px" - minimum: 4 - maximum: 64 - step: 1 - value: bar.islandSetting("islandSatelliteSwoopRadius") - visible: bar.islandSetting("islandSatellitesEnabled") - enabled: bar.islandSetting("islandSatelliteBackground") && bar.islandSetting("islandSatelliteGothCorners") - onSliderValueChanged: value => bar.apply("islandSatelliteSwoopRadius", value) - } - - SettingsSliderRow { - settingKey: "islandSatelliteTransparency" - tags: ["island", "satellite", "background", "opacity", "transparency", "blur"] - resetStore: bar - resetKeys: ["islandSatelliteTransparency"] - text: I18n.tr("Opacity", "island settings: satellite background opacity slider") - minimum: 0 - maximum: 100 - step: 1 - value: Math.round(bar.islandSetting("islandSatelliteTransparency") * 100) - visible: bar.islandSetting("islandSatellitesEnabled") - enabled: bar.islandSetting("islandSatelliteBackground") - onSliderValueChanged: value => bar.apply("islandSatelliteTransparency", value / 100) - } - - SettingsSliderRow { - settingKey: "islandSatelliteGap" - tags: ["island", "satellite", "widgets", "gap", "spacing"] - resetStore: bar - resetKeys: ["islandSatelliteGap"] - text: I18n.tr("Gap", "island settings: satellite to island gap slider") - unit: "px" - minimum: 4 - maximum: 48 - step: 1 - value: bar.islandSetting("islandSatelliteGap") - visible: bar.islandSetting("islandSatellitesEnabled") - enabled: bar.islandSetting("islandSatellitePosition") !== "edges" - onSliderValueChanged: value => bar.apply("islandSatelliteGap", value) - } - } - } -} diff --git a/quickshell/Modules/Settings/FrameTab.qml b/quickshell/Modules/Settings/FrameTab.qml deleted file mode 100644 index 4b84d8674..000000000 --- a/quickshell/Modules/Settings/FrameTab.qml +++ /dev/null @@ -1,222 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets -import qs.Modules.Settings.Widgets - -Item { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - // Bar Inset Padding: resolve the "auto" sentinel (stored < 0) to the frame thickness for the slider display. - readonly property int frameInsetPaddingDisplay: Math.round(SettingsData.frameBarContentGap) - - SettingsPage { - id: mainColumn - - SettingsCard { - width: parent.width - iconName: "tune" - title: I18n.tr("Behavior") - settingKey: "frameEnabled" - tags: ["frame", "mode", "bar", "overview"] - visible: SettingsData.frameEnabled - - SettingsButtonGroupRow { - settingKey: "frameModeSelector" - tags: ["frame", "mode", "connected", "separate", "popout", "flush", "float"] - resetKeys: ["frameMode"] - text: I18n.tr("Surfaces") - model: [I18n.tr("Separate", "adjective, frame surfaces mode option, opposite of connected"), I18n.tr("Connected")] - currentIndex: SettingsData.frameMode === "connected" ? 1 : 0 - onSelectionChanged: (index, selected) => { - if (!selected) - return; - switch (index) { - case 1: - SettingsData.set("frameMode", "connected"); - break; - default: - SettingsData.set("frameMode", "separate"); - break; - } - } - } - - SettingsToggleRow { - settingKey: "frameShowOnOverview" - tags: ["frame", "overview", "show", "hide", "niri"] - text: I18n.tr("Show on overview") - visible: CompositorService.supportsNativeOverview - checked: SettingsData.frameShowOnOverview - onToggled: checked => SettingsData.set("frameShowOnOverview", checked) - } - } - - SettingsCard { - width: parent.width - iconName: "border_outer" - title: I18n.tr("Border") - settingKey: "frameBorder" - collapsible: true - visible: SettingsData.frameEnabled - - SettingsSliderRow { - settingKey: "frameRounding" - tags: ["frame", "border", "rounding", "radius", "corner"] - text: I18n.tr("Radius", "corner radius slider label") - unit: "px" - minimum: 0 - maximum: 100 - step: 1 - value: SettingsData.frameRounding - onSliderDragFinished: v => SettingsData.set("frameRounding", v) - } - - SettingsSliderRow { - settingKey: "frameThickness" - tags: ["frame", "border", "thickness", "size", "width"] - text: I18n.tr("Width") - unit: "px" - minimum: 2 - maximum: 100 - step: 1 - value: SettingsData.frameThickness - onSliderDragFinished: v => SettingsData.set("frameThickness", v) - } - - SettingsSliderRow { - settingKey: "frameBarSize" - tags: ["frame", "bar", "thickness", "size", "height", "width"] - text: I18n.tr("Bar size") - unit: "px" - minimum: 24 - maximum: 100 - step: 1 - value: SettingsData.frameBarSize - onSliderDragFinished: v => SettingsData.set("frameBarSize", v) - } - - SettingsSliderRow { - settingKey: "frameBarInsetPadding" - tags: ["frame", "bar", "edge", "inset", "padding", "corner", "end"] - text: I18n.tr("Bar inset padding") - minimumLabel: I18n.tr("Edge to edge", "slider minimum label, bar touches the screen edges") - unit: "px" - minimum: 0 - maximum: 48 - step: 1 - value: root.frameInsetPaddingDisplay - onSliderDragFinished: v => SettingsData.set("frameBarInsetPadding", v) - } - - SettingsToggleRow { - id: frameBlurToggle - settingKey: "frameBlurEnabled" - tags: ["frame", "blur", "background", "glass", "transparency", "frosted"] - text: I18n.tr("Blur") - checked: SettingsData.frameBlurEnabled - onToggled: checked => SettingsData.set("frameBlurEnabled", checked) - enabled: BlurService.available && SettingsData.blurEnabled - visible: BlurService.available - } - - SettingsRow { - visible: BlurService.available && !SettingsData.blurEnabled - body: Item { - width: parent.width - height: blurToggleNote.height + Theme.spacingM * 2 - - Row { - id: blurToggleNote - x: Theme.spacingM - width: parent.width - Theme.spacingM * 2 - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - DankIcon { - name: "blur_on" - size: Theme.fontSizeMedium - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Frame Blur follows Background Blur in Theme & Colors") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - wrapMode: Text.WordWrap - width: parent.width - Theme.fontSizeMedium - Theme.spacingS - } - } - } - } - } - - SettingsCard { - width: parent.width - iconName: "blur_linear" - title: I18n.tr("Connected") - settingKey: "frameConnectedOptions" - collapsible: true - expanded: true - visible: SettingsData.frameEnabled && SettingsData.frameMode === "connected" - - SettingsToggleRow { - settingKey: "frameCloseGaps" - tags: ["frame", "connected", "gap", "edge", "curves", "arcs", "expose", "popout", "notification"] - text: I18n.tr("Expose the arcs") - checked: !SettingsData.frameCloseGaps - onToggled: checked => SettingsData.set("frameCloseGaps", !checked) - } - - SettingsButtonGroupRow { - settingKey: "frameLauncherEmergeSide" - tags: ["frame", "connected", "launcher", "modal", "emerge", "direction", "bottom", "top"] - text: I18n.tr("Launcher emerge side") - model: [I18n.tr("Bottom"), I18n.tr("Top")] - currentIndex: SettingsData.frameLauncherEmergeSide === "top" ? 1 : 0 - onSelectionChanged: (index, selected) => { - if (!selected) - return; - SettingsData.set("frameLauncherEmergeSide", index === 1 ? "top" : "bottom"); - } - } - - SettingsToggleRow { - settingKey: "frameLauncherArcExtender" - tags: ["frame", "connected", "launcher", "arc", "extender", "center"] - text: I18n.tr("Arc extender") - checked: SettingsData.frameLauncherArcExtender - onToggled: checked => SettingsData.set("frameLauncherArcExtender", checked) - } - - SettingsToggleRow { - settingKey: "frameLauncherEdgeHover" - tags: ["frame", "connected", "launcher", "hover", "edge", "reveal"] - text: I18n.tr("Edge hover reveal") - checked: SettingsData.frameLauncherEdgeHover - onToggled: checked => SettingsData.set("frameLauncherEdgeHover", checked) - } - } - - SettingsCard { - width: parent.width - iconName: "monitor" - title: I18n.tr("Displays") - settingKey: "frameDisplays" - collapsible: true - expanded: false - visible: SettingsData.frameEnabled - - SettingsDisplayPicker { - displayPreferences: SettingsData.frameScreenPreferences - onPreferencesChanged: prefs => SettingsData.set("frameScreenPreferences", prefs) - } - } - } -} diff --git a/quickshell/Modules/Settings/SettingsHubPage.qml b/quickshell/Modules/Settings/SettingsHubPage.qml index 3f7b0ec57..3f577e726 100644 --- a/quickshell/Modules/Settings/SettingsHubPage.qml +++ b/quickshell/Modules/Settings/SettingsHubPage.qml @@ -38,8 +38,8 @@ FocusScope { required property var modelData iconName: modelData.icon - title: (modelData.titleFrom ? SettingsUiState[modelData.titleFrom] : "") || modelData.text - hint: (modelData.hintFrom ? SettingsUiState[modelData.hintFrom] : "") || (modelData.hint ?? "") + title: modelData.text + hint: modelData.hint ?? "" trailingBadge: modelData.kind === "plugin" && PluginService.loadedPlugins[modelData.pluginId] === undefined ? I18n.tr("Disabled") : "" onClicked: root.parentModal?.navigateTo(modelData.id) } diff --git a/quickshell/Modules/Settings/ShadowsTab.qml b/quickshell/Modules/Settings/ShadowsTab.qml index 7fc49db31..50fa300c6 100644 --- a/quickshell/Modules/Settings/ShadowsTab.qml +++ b/quickshell/Modules/Settings/ShadowsTab.qml @@ -234,7 +234,7 @@ Item { visible: shadowCard.bars.length > 1 options: shadowCard.bars.map(config => config.name || config.id) currentValue: bar.selectedBarConfig?.name || bar.selectedBarConfig?.id || "" - onValueChanged: value => bar.selectedBarId = shadowCard.bars.find(config => (config.name || config.id) === value)?.id ?? bar.selectedBarId + onValueChanged: value => bar.select(shadowCard.bars.find(config => (config.name || config.id) === value)?.id ?? bar.selectedBarId) } SettingsToggleRow { diff --git a/quickshell/Modules/Settings/ThemeSurfacesTab.qml b/quickshell/Modules/Settings/ThemeSurfacesTab.qml index 23fc2878b..e89c949e4 100644 --- a/quickshell/Modules/Settings/ThemeSurfacesTab.qml +++ b/quickshell/Modules/Settings/ThemeSurfacesTab.qml @@ -29,7 +29,7 @@ Column { readonly property var opacityTargets: { SettingsData.barConfigs; SettingsData.dockConfigs; - const bars = SettingsData.barConfigs.map(config => ({ + const bars = SettingsData.barConfigs.filter(config => !SettingsData.isDotBarConfig(config)).map(config => ({ kind: "bar", id: config.id, name: config.name || config.id, diff --git a/quickshell/Modules/Settings/Widgets/BarSelectionState.qml b/quickshell/Modules/Settings/Widgets/BarSelectionState.qml index f4562e80c..42336804b 100644 --- a/quickshell/Modules/Settings/Widgets/BarSelectionState.qml +++ b/quickshell/Modules/Settings/Widgets/BarSelectionState.qml @@ -6,27 +6,15 @@ import qs.Services Item { id: root - property string selectedBarId: SettingsUiState.selectedBarId + readonly property string selectedBarId: SettingsUiState.selectedBarId - onSelectedBarIdChanged: { - if (SettingsUiState.selectedBarId !== selectedBarId) - SettingsUiState.selectedBarId = selectedBarId; + function select(id) { + SettingsUiState.selectedBarId = id; } - Connections { - target: SettingsUiState - - function onSelectedBarIdChanged() { - if (root.selectedBarId !== SettingsUiState.selectedBarId) - root.selectedBarId = SettingsUiState.selectedBarId; - } - } - - property var selectedBarConfig: { - selectedBarId; + readonly property var selectedBarConfig: { SettingsData.barConfigs; - const index = SettingsData.barConfigs.findIndex(cfg => cfg.id === selectedBarId); - return index !== -1 ? SettingsData.barConfigs[index] : SettingsData.barConfigs[0]; + return SettingsData.getBarConfig(selectedBarId) ?? SettingsData.barConfigs[0] ?? null; } readonly property string selectedBarName: { selectedBarId; diff --git a/quickshell/Modules/Settings/Widgets/SettingsControlledBy.qml b/quickshell/Modules/Settings/Widgets/SettingsControlledBy.qml index 47da568a6..62a446ad2 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsControlledBy.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsControlledBy.qml @@ -17,11 +17,9 @@ StyledRect { property string reason: "" property var parentModal: null - readonly property string resolvedTarget: target || (SettingsData.frameEnabled ? "frame" : "island") + readonly property string resolvedTarget: target || "frame" readonly property string iconName: { switch (resolvedTarget) { - case "island": - return "view_in_ar"; case "surfaces": return "layers"; case "shadows": @@ -32,8 +30,6 @@ StyledRect { } readonly property string buttonText: { switch (resolvedTarget) { - case "island": - return I18n.tr("Open Island", "settings: button that opens the Dank Island tab"); case "surfaces": return I18n.tr("Interface style"); case "shadows": @@ -44,14 +40,12 @@ StyledRect { } readonly property string tabName: { switch (resolvedTarget) { - case "island": - return "dank_island"; case "surfaces": return "theme_surfaces"; case "shadows": return "surface_shadows"; default: - return "frame"; + return section === "frameConnectedOptions" ? "dankbar_settings" : "dankbar_appearance"; } } diff --git a/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml b/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml index 0459cd64b..a2c0a2c10 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml @@ -31,10 +31,6 @@ GridLayout { { "key": "island", "label": I18n.tr("Island") - }, - { - "key": "dot", - "label": I18n.tr("Dot", "bar layout: free-floating dot that opens island activities") } ] readonly property real cardHeightRatio: 7.5 @@ -44,13 +40,6 @@ GridLayout { readonly property real previewIslandRatio: 0.42 readonly property real previewWidth: Math.round(Theme.iconSize * previewWidthRatio) readonly property real minimumCardWidth: previewWidth + Theme.spacingL * 2 - // The dot is a companion, not a mode: its card toggles a dot config alongside whatever the selected bar is. - readonly property var dotConfig: { - SettingsData.barConfigs; - return (SettingsData.barConfigs || []).find(cfg => SettingsData.isDotBarConfig(cfg)) ?? null; - } - readonly property bool dotActive: root.dotConfig?.enabled ?? false - readonly property bool dotSelected: !root.edgePlacement && !root.widgetStyle && SettingsData.isDotBarConfig(SettingsData.getBarConfig(SettingsUiState.selectedBarId)) readonly property var targetConfig: { SettingsData.barConfigs; SettingsUiState.selectedBarId; @@ -60,40 +49,9 @@ GridLayout { } readonly property string activeBarMode: SettingsData.frameEnabled ? "frame" : (SettingsData.isIslandBarConfig(root.targetConfig) ? "island" : "standard") - function toggleDot() { - const existing = root.dotConfig; - if (existing) { - SettingsData.updateBarConfig(existing.id, { - enabled: !existing.enabled - }); - SettingsUiState.selectedBarId = existing.enabled ? (root.targetConfig?.id ?? "default") : existing.id; - return; - } - const base = root.targetConfig ?? SettingsData.getBarConfig("default"); - if (!base) - return; - const id = "dot" + Date.now(); - const config = Object.assign(JSON.parse(JSON.stringify(base)), { - id, - name: I18n.tr("Dot", "bar layout: free-floating dot that opens island activities"), - enabled: true, - island: false, - dot: true, - screenPreferences: ["all"], - showOnLastDisplay: true - }); - // An inherited "always here" would make the base island and the dot fight by config order. - delete config.islandSharedRouting; - SettingsData.addBarConfig(config); - SettingsUiState.selectedBarId = id; - } - function applyBarMode(mode) { const target = root.targetConfig; switch (mode) { - case "dot": - root.toggleDot(); - return; case "frame": if (SettingsData.frameEnabled) return; @@ -130,10 +88,10 @@ GridLayout { Rectangle { id: modeCard required property var modelData - enabled: (modelData.enabled ?? true) && (modelData.key === "dot" || !root.dotSelected) + enabled: modelData.enabled ?? true opacity: enabled ? 1 : SettingsMetrics.disabledOpacity - readonly property bool isActive: modelData.key === "dot" && !root.edgePlacement && !root.widgetStyle ? root.dotActive : root.selectedKey === modelData.key + readonly property bool isActive: root.selectedKey === modelData.key Layout.fillWidth: true Layout.fillHeight: true @@ -146,7 +104,7 @@ GridLayout { border.color: isActive ? Theme.primary : Theme.outlineMedium activeFocusOnTab: true - Accessible.role: modelData.key === "dot" ? Accessible.CheckBox : Accessible.RadioButton + Accessible.role: Accessible.RadioButton Accessible.name: modelData.label Accessible.checked: isActive Accessible.onPressAction: root.selected(modelData.key) @@ -247,16 +205,6 @@ GridLayout { color: Theme.primary } - Rectangle { - visible: !root.widgetStyle && modeCard.modelData.key === "dot" - x: Math.round(parent.width * 0.62) - y: Math.round(parent.height * 0.3) - width: Math.round(screenPreview.stripSize * 1.6) - height: width - radius: width / 2 - color: Theme.primary - } - Rectangle { visible: !root.widgetStyle && modeCard.modelData.key === "island" anchors.top: parent.top diff --git a/quickshell/tests/layout-resolver.test.mjs b/quickshell/tests/layout-resolver.test.mjs index 6b8e6ce1a..f9075a713 100644 --- a/quickshell/tests/layout-resolver.test.mjs +++ b/quickshell/tests/layout-resolver.test.mjs @@ -167,7 +167,7 @@ test("free islands and dots keep their key but leave every band, reservation and for (const options of [{}, { effectiveFrameEnabled: true }, { effectiveFrameEnabled: true, effectiveConnected: true }]) { const layout = resolve(configs, options); const dot = layout.instances.find(instance => instance.barId === "dot"); - assert.deepEqual(plain({ ...dot, paintedBounds: undefined, margins: undefined }), { key: JSON.stringify(["DP-1", "dot"]), screenName: "DP-1", barId: "dot", configOrder: 1, edge: "", kind: "island", free: true, dot: true, row: 0, rowThickness: 0, rowOffset: 0, reservation: 0, exclusiveZone: -1, exclusionSize: 0 }); + assert.deepEqual(plain({ ...dot, paintedBounds: undefined, margins: undefined }), { key: JSON.stringify(["DP-1", "dot"]), screenName: "DP-1", barId: "dot", configOrder: 1, edge: "", kind: "island", free: true, dot: true, satelliteEdge: "", row: 0, rowThickness: 0, rowOffset: 0, reservation: 0, exclusiveZone: -1, exclusionSize: 0 }); assert.equal(layout.instances.find(instance => instance.barId === "free").dot, false); assert.equal(layout.edges.top.island, null); assert.equal(layout.edges.top.islandThickness, 0); @@ -180,3 +180,26 @@ test("free islands and dots keep their key but leave every band, reservation and assert.deepEqual(plain(layout.instances.filter(instance => instance.free).map(instance => instance.barId)), ["dot", "free"]); assert.equal(resolver.adjacentInfo(layout, configs[0], configs[0]).topBar, 0); }); + +test("a free island keeps a bar window for its satellites on its edge without reserving or shadowing it", () => { + const top = bar("top"); + const free = values => bar("free", 1, { island: true, islandFloating: true, islandPlacement: "free", ...values }); + for (const options of [{}, { effectiveFrameEnabled: true }, { effectiveFrameEnabled: true, effectiveConnected: true }]) { + const baseline = resolve([top], options); + const layout = resolve([top, free({}), bar("dot", 1, { dot: true })], options); + const instance = layout.instances.find(instance => instance.barId === "free"); + assert.equal(instance.satelliteEdge, "bottom"); + assert.equal(instance.edge, ""); + assert.equal(instance.reservation, 0); + assert.equal(instance.exclusiveZone, -1); + assert.equal(resolver.hostsBarWindow(instance), true); + assert.equal(resolver.hostsBarWindow(layout.instances.find(instance => instance.barId === "dot")), false); + assert.equal(layout.edges.bottom.island, null); + assert.equal(layout.edges.bottom.islandThickness, 0); + assert.deepEqual(plain(layout.edges), plain(resolve([top, bar("dot", 1, { dot: true })], options).edges)); + assert.equal(layout.edges.top.occupancy, baseline.edges.top.occupancy); + assert.equal(layout.manualPlacement, false); + const off = resolve([top, free({ islandSatellitesEnabled: false })], options).instances.find(instance => instance.barId === "free"); + assert.equal(resolver.hostsBarWindow(off), false); + } +}); diff --git a/quickshell/tests/qml/island-free.qml b/quickshell/tests/qml/island-free.qml index a9a0e7baa..eb1b7f57a 100644 --- a/quickshell/tests/qml/island-free.qml +++ b/quickshell/tests/qml/island-free.qml @@ -2,6 +2,7 @@ import QtQuick import Quickshell import qs.Common import qs.Services +import qs.Modules.DankBar import qs.Modules.DankIsland import qs.DankCommon.Common as DC @@ -9,6 +10,7 @@ ShellRoot { id: root property var hosts: [] + property bool hostsChecked: false Component { id: hostComponent @@ -34,7 +36,7 @@ ShellRoot { SettingsData.frameEnabled = false; SettingsData.barConfigs = [ { id: "dot", enabled: true, visible: true, dot: true, position: 0 }, - { id: "vertical", enabled: true, visible: true, island: true, islandFloating: true, islandPlacement: "free", position: 2 } + { id: "vertical", enabled: true, visible: true, island: true, islandFloating: true, islandPlacement: "free", position: 2, islandSatellitePosition: "island", leftWidgets: ["clock"], rightWidgets: ["clock"] } ]; root.hosts = SettingsData.barConfigs.map(config => hostComponent.createObject(root, { barId: config.id, screen: Quickshell.screens[0] })); } @@ -65,6 +67,39 @@ ShellRoot { surface.surfaceMotion.settle(); root.check(!surface.motionRunning, "idle motion stops"); } + root.hostsChecked = true; + } catch (error) { + console.error("FIXTURE_FAIL", error.message); + Qt.quit(); + } + } + } + + Item { + Repeater { + id: bars + model: root.hostsChecked ? SettingsData.barConfigs : [] + delegate: DankBar { + required property var modelData + barConfig: modelData + } + } + } + + Timer { + interval: 0 + readonly property var band: bars.count === 2 ? bars.itemAt(1).barVariants.instances[0] ?? null : null + running: !!band && band.height === band.screen.height && band.width < band.height + onTriggered: { + try { + root.check(bars.itemAt(0).barVariants.instances.length === 0, "a dot has no satellite window"); + const band = bars.itemAt(1).barVariants.instances[0]; + root.check(bars.itemAt(1).barVariants.instances.length === 1 && !band.islandHost, "a free island keeps one satellite window without a pill"); + root.check(band.exclusiveZone <= 0, "the satellite window reserves nothing"); + const leading = band.leadingSectionRect; + const trailing = band.trailingSectionRect; + root.check(leading.y + leading.h <= trailing.y, "near island keeps left before right"); + root.check(Math.abs((leading.y + trailing.y + trailing.h) / 2 - band.height / 2) <= 2, "near island gathers at the edge centre"); console.log("FIXTURE_PASS"); } catch (error) { console.error("FIXTURE_FAIL", error.message); diff --git a/quickshell/tests/run-surface-fixture.py b/quickshell/tests/run-surface-fixture.py index 609a43d81..e0c924c86 100644 --- a/quickshell/tests/run-surface-fixture.py +++ b/quickshell/tests/run-surface-fixture.py @@ -139,7 +139,7 @@ with tempfile.TemporaryDirectory(prefix="dms-surface-test-") as temporary: if mpris: start_dbus(fixture_env, processes) processes.append(subprocess.Popen([sys.executable, str(repo / "quickshell/tests/fixtures/mpris_player.py")] + (["--artwork"] if "--artwork" in sys.argv else []), env=fixture_env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)) - result = subprocess.run(["qs", "-p", str(home / "qml")], env=fixture_env, capture_output=True, text=True, timeout=60) + result = subprocess.run(["qs", "-p", str(home / "qml")], env=fixture_env, capture_output=True, text=True, timeout=180) output = result.stdout + result.stderr failed = bool(result.returncode) or "FIXTURE_PASS" not in output or "FIXTURE_FAIL" in output except subprocess.TimeoutExpired as expired: diff --git a/quickshell/translations/extract_settings_index.py b/quickshell/translations/extract_settings_index.py index ed09f32a5..5fa25124c 100644 --- a/quickshell/translations/extract_settings_index.py +++ b/quickshell/translations/extract_settings_index.py @@ -99,7 +99,6 @@ TAB_INDEX_MAP = { "KeybindsTab.qml": 2, "DankBarTab.qml": 3, "DankDashTab.qml": 43, - "DankIslandTab.qml": 46, "CompositorLayoutTab.qml": 37, "WindowRulesTab.qml": 38, "DockGeneralTab.qml": 5, @@ -107,6 +106,7 @@ TAB_INDEX_MAP = { "DockAppearanceTab.qml": 58, "DockAdvancedTab.qml": 59, "DankBarAppearanceTab.qml": 6, + "DankBarAdvancedTab.qml": 64, "NetworkStatusTab.qml": 7, "NetworkEthernetTab.qml": 39, "NetworkWifiTab.qml": 40, @@ -141,7 +141,6 @@ TAB_INDEX_MAP = { "LocaleTab.qml": 30, "GreeterTab.qml": 31, "MuxTab.qml": 32, - "FrameTab.qml": 33, "DefaultAppsTab.qml": 34, "UsersTab.qml": 35, "UserAccountsTab.qml": 60, @@ -165,8 +164,6 @@ SIDEBAR_GATE_CONDITIONS = [ ("pointerCapable", "pointerCapable"), ("windowRulesCapable", "windowRulesCapable"), ("layoutCapable", "layoutCapable"), - ("frameOnly", "frameEnabled"), - ("islandOnly", "islandEnabled"), ("cellularOnly", "cellularAvailable"), ] @@ -183,6 +180,9 @@ FILE_PAGE_MAP = { TAB_META_DEFAULT = ("Settings", None, None) +# Frame and island rows live on the bar pages; ungated ones still need their feature on. +BAR_TAB_FILES = {"DankBarTab.qml", "DankBarAppearanceTab.qml", "DankBarAdvancedTab.qml"} + SEARCHABLE_COMPONENTS = [ "SettingsCard", "SettingsToggleRow", @@ -383,7 +383,7 @@ def find_settings_components(content, filename, wrappers, tab_meta, hub_meta): if tags_raw: tags = extract_tags(tags_raw) - desc_raw = extract_property(block, "description") or defaults.get("description") + desc_raw = extract_property(block, "description") or extract_property(block, "summary") or defaults.get("description") description = None if desc_raw: description = extract_i18n_string(desc_raw) @@ -435,6 +435,11 @@ def find_settings_components(content, filename, wrappers, tab_meta, hub_meta): condition_key = "dmsConnected" elif "Theme.matugenAvailable" in visible_raw: condition_key = "matugenAvailable" + if filename in BAR_TAB_FILES and not condition_key: + if setting_key.startswith("frame"): + condition_key = "frameEnabled" + elif setting_key.startswith("island"): + condition_key = "islandEnabled" category, parent_label, _ = page_meta if page_meta else tab_meta.get(tab_index, TAB_META_DEFAULT) enriched_keywords = enrich_keywords(label, description, category, tags, parent_label) @@ -679,12 +684,12 @@ def extract_settings_index(root_dir, tab_meta, hub_meta): ) if "islandHomeLayout" not in seen_keys: - category, parent_label, _ = tab_meta.get(46, TAB_META_DEFAULT) + category, parent_label, _ = tab_meta.get(3, TAB_META_DEFAULT) all_entries.append( { "section": "islandHomeLayout", "label": "Home Layout", - "tabIndex": 46, + "tabIndex": 3, "category": category, "parentLabel": parent_label, "keywords": enrich_keywords( diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index d745f0e11..d793fc9af 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -289,11 +289,11 @@ "page": "dankbar", "category": "Bar", "keywords": [ + "advanced", "appearance", "bar", - "frame", "general", - "island", + "layout", "panel", "position", "statusbar", @@ -954,6 +954,30 @@ "page": "dock", "icon": "dock_to_bottom" }, + { + "section": "dotEnabled", + "label": "Dot", + "tabIndex": -1, + "category": "Bar", + "keywords": [ + "alongside", + "bar", + "companion", + "dankdot", + "dot", + "enable", + "floating", + "island", + "layout", + "panel", + "statusbar", + "taskbar", + "topbar", + "works" + ], + "page": "dankbar", + "description": "A floating companion that works alongside any bar layout" + }, { "section": "wallpaperFillMode", "label": "Fill mode", @@ -1372,7 +1396,6 @@ "category": "Bar", "keywords": [ "bar", - "dot", "frame", "island", "layout", @@ -2800,28 +2823,26 @@ "conditionKey": "keybindsAvailable" }, { - "section": "barAdvanced", - "label": "Advanced", + "section": "frameLauncherArcExtender", + "label": "Arc extender", "tabIndex": 3, "category": "General", "keywords": [ - "advanced", + "arc", "bar", - "click", + "center", + "connected", + "extender", + "frame", "general", - "island", - "layer", - "maximize", - "motion", - "overlay", + "launcher", "panel", - "spring", "statusbar", "taskbar", - "through", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "frameEnabled" }, { "section": "barAutoHide", @@ -2894,52 +2915,158 @@ "topbar" ], "parentLabel": "Bar", - "icon": "touch_app" + "icon": "touch_app", + "conditionKey": "islandEnabled" }, { - "section": "barClickThrough", - "label": "Click through", + "section": "islandHomeBrightnessDisplay", + "label": "Brightness style", "tabIndex": 3, "category": "General", "keywords": [ + "backlight", "bar", - "click", - "clickthrough", + "bright", + "brightness", + "compact", + "dim", "general", - "input", - "mask", - "mouse", + "home", + "icon", + "island", "panel", - "passthrough", + "percentage", "statusbar", + "style", "taskbar", - "through", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { - "section": "islandCompactThickness", - "label": "Compact width", + "section": "islandNotificationBadgeClearOnOpen", + "label": "Clear badge on open", + "tabIndex": 3, + "category": "General", + "keywords": [ + "badge", + "bar", + "clear", + "dismiss", + "general", + "home", + "island", + "notifications", + "open", + "panel", + "statusbar", + "taskbar", + "topbar", + "unread" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandHomeClockDisplay", + "label": "Clock style", "tabIndex": 3, "category": "General", "keywords": [ "bar", + "clock", + "compact", + "date", + "general", + "home", + "island", + "panel", + "statusbar", + "style", + "taskbar", + "time", + "topbar", + "watch" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandHomeCompactTight", + "label": "Compact pill", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "clock", "compact", "general", "height", + "home", "island", + "narrow", "panel", - "placement", - "satellite", - "size", + "pill", "statusbar", "taskbar", - "thickness", "topbar", "width" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "frameConnectedOptions", + "label": "Connected", + "tabIndex": 3, + "category": "General", + "keywords": [ + "arcs", + "bar", + "connected", + "curves", + "edge", + "expose", + "frame", + "gap", + "general", + "notification", + "panel", + "popout", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "icon": "blur_linear", + "conditionKey": "frameEnabled" + }, + { + "section": "islandHomeStatusContent", + "label": "Control Center", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "battery", + "bluetooth", + "center", + "compact", + "connectivity", + "control", + "general", + "home", + "island", + "panel", + "status", + "statusbar", + "taskbar", + "topbar", + "wifi" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "barDisplay", @@ -2982,7 +3109,30 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "frameLauncherEdgeHover", + "label": "Edge hover reveal", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "connected", + "edge", + "frame", + "general", + "hover", + "launcher", + "panel", + "reveal", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" }, { "section": "islandFreeEdgeMargin", @@ -3003,7 +3153,30 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandNotificationExpand", + "label": "Expand by default", + "tabIndex": 3, + "category": "General", + "keywords": [ + "arrival", + "bar", + "default", + "expand", + "general", + "island", + "notifications", + "panel", + "size", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "islandInteractionMode", @@ -3025,34 +3198,78 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { - "section": "islandFloating", - "label": "Float", + "section": "frameCloseGaps", + "label": "Expose the arcs", "tabIndex": 3, "category": "General", "keywords": [ - "anywhere", + "arcs", "bar", - "drag", - "enable", - "exclusive", - "float", - "floating", + "connected", + "curves", + "edge", + "expose", + "frame", + "gap", "general", - "island", - "mode", - "overlay", + "notification", "panel", - "placement", - "reserve", + "popout", "statusbar", "taskbar", "topbar" ], "parentLabel": "Bar", - "description": "Set floating overlay or enable drag anywhere mode" + "conditionKey": "frameEnabled" + }, + { + "section": "frameEnabled", + "label": "Frame", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "frame", + "general", + "mode", + "overview", + "panel", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "icon": "tune", + "conditionKey": "frameEnabled" + }, + { + "section": "frameDisplays", + "label": "Frame displays", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "displays", + "frame", + "general", + "monitor", + "monitors", + "output", + "outputs", + "panel", + "screen", + "screens", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "icon": "monitor", + "conditionKey": "frameEnabled" }, { "section": "islandHoverCloseDelay", @@ -3073,7 +3290,8 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "barHideWhenWindowsOpen", @@ -3096,6 +3314,69 @@ "parentLabel": "Bar", "conditionKey": "windowRulesCapable" }, + { + "section": "islandHomeLayout", + "label": "Home Layout", + "tabIndex": 3, + "category": "General", + "parentLabel": "Bar", + "keywords": [ + "around", + "badge", + "bar", + "battery", + "brightness", + "clock", + "general", + "groups", + "hidden", + "hide", + "home", + "island", + "launcher", + "layout", + "left", + "media", + "notifications", + "order", + "panel", + "reorder", + "right", + "statusbar", + "taskbar", + "time", + "topbar", + "volume", + "watch", + "weather" + ], + "icon": "home", + "description": "Order and hide the groups around the island clock", + "conditionKey": "islandEnabled" + }, + { + "section": "islandActivities", + "label": "Home compact", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "clock", + "compact", + "date", + "general", + "home", + "island", + "panel", + "statusbar", + "taskbar", + "time", + "topbar" + ], + "parentLabel": "Bar", + "icon": "home", + "conditionKey": "islandEnabled" + }, { "section": "hoverPopouts", "label": "Hover popouts", @@ -3141,32 +3422,8 @@ "timeout", "topbar" ], - "parentLabel": "Bar" - }, - { - "section": "islandFreeIdleOpacity", - "label": "Idle opacity", - "tabIndex": 3, - "category": "General", - "keywords": [ - "afk", - "bar", - "dot", - "fade", - "free", - "general", - "idle", - "inactive", - "island", - "opacity", - "panel", - "screensaver", - "statusbar", - "taskbar", - "timeout", - "topbar" - ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "islandFreeIdleScale", @@ -3192,7 +3449,8 @@ "timeout", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "islandMediaClockVisible", @@ -3214,7 +3472,37 @@ "topbar", "watch" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "frameLauncherEmergeSide", + "label": "Launcher emerge side", + "tabIndex": 3, + "category": "General", + "keywords": [ + "app drawer", + "app menu", + "applications", + "bar", + "bottom", + "connected", + "direction", + "emerge", + "frame", + "general", + "launcher", + "modal", + "panel", + "side", + "start menu", + "statusbar", + "taskbar", + "top", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" }, { "section": "barManualVisibility", @@ -3237,25 +3525,31 @@ "parentLabel": "Bar" }, { - "section": "barMaximizeDetection", - "label": "Maximize detection", + "section": "islandNotifications", + "label": "Notifications", "tabIndex": 3, "category": "General", "keywords": [ + "alert", + "alerts", + "arrival", "bar", - "border", - "detection", - "fullscreen", - "gaps", "general", - "maximize", + "island", + "notif", + "notifications", + "notifs", "panel", + "popup", + "stack", + "standard", "statusbar", "taskbar", "topbar" ], "parentLabel": "Bar", - "conditionKey": "windowRulesCapable" + "icon": "notifications", + "conditionKey": "islandEnabled" }, { "section": "islandHoverOpenDelay", @@ -3275,7 +3569,8 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "islandFreeOrientation", @@ -3295,28 +3590,8 @@ "topbar", "vertical" ], - "parentLabel": "Bar" - }, - { - "section": "islandOuterGap", - "label": "Outer gap", - "tabIndex": 3, - "category": "General", - "keywords": [ - "bar", - "gap", - "general", - "island", - "margin", - "outer", - "panel", - "placement", - "statusbar", - "taskbar", - "top", - "topbar" - ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "islandPlacement", @@ -3324,21 +3599,27 @@ "tabIndex": 3, "category": "General", "keywords": [ + "anywhere", "bar", - "dot", + "docked", "drag", "edge", + "exclusive", + "float", "floating", "free", "general", "island", + "overlay", "panel", "placement", + "reserve", "statusbar", "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "barPosition", @@ -3353,74 +3634,29 @@ "bar", "center", "control", - "control center", "dash", - "dot", + "free", "general", - "ipc", + "horizontal", "island", - "last used", "launcher", "notif", "notification", + "orientation", "panel", "position", "routes", - "routing", "shortcuts", "start menu", "statusbar", "taskbar", - "topbar" + "topbar", + "vertical" ], "parentLabel": "Bar", "icon": "vertical_align_center", "description": "Routes launcher, dash, control center and notification shortcuts" }, - { - "section": "islandReducedMotion", - "label": "Reduce motion", - "tabIndex": 3, - "category": "General", - "keywords": [ - "accessibility", - "animation", - "bar", - "general", - "island", - "motion", - "panel", - "reduce", - "spring", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar" - }, - { - "section": "islandReserveThickness", - "label": "Reserved width", - "tabIndex": 3, - "category": "General", - "keywords": [ - "bar", - "exclusive", - "general", - "height", - "island", - "panel", - "placement", - "reservation", - "reserved", - "statusbar", - "taskbar", - "thickness", - "topbar", - "width" - ], - "parentLabel": "Bar" - }, { "section": "barScrollWheel", "label": "Scroll wheel", @@ -3476,7 +3712,8 @@ "topbar" ], "parentLabel": "Bar", - "description": "Routes launcher, dash, control center and notification shortcuts" + "description": "Routes launcher, dash, control center and notification shortcuts", + "conditionKey": "islandEnabled" }, { "section": "barOpenOnOverview", @@ -3499,66 +3736,25 @@ "conditionKey": "nativeOverviewCapable" }, { - "section": "islandSpringDamping", - "label": "Spring damping", + "section": "frameShowOnOverview", + "label": "Show on overview", "tabIndex": 3, "category": "General", "keywords": [ - "animation", "bar", - "bounce", - "damping", + "frame", "general", - "island", - "motion", + "hide", + "niri", + "overview", "panel", - "spring", + "show", "statusbar", "taskbar", "topbar" ], - "parentLabel": "Bar" - }, - { - "section": "islandSpringMass", - "label": "Spring mass", - "tabIndex": 3, - "category": "General", - "keywords": [ - "animation", - "bar", - "general", - "inertia", - "island", - "mass", - "motion", - "panel", - "spring", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar" - }, - { - "section": "islandSpringStiffness", - "label": "Spring stiffness", - "tabIndex": 3, - "category": "General", - "keywords": [ - "animation", - "bar", - "general", - "island", - "motion", - "panel", - "spring", - "statusbar", - "stiffness", - "taskbar", - "topbar" - ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "nativeOverviewCapable" }, { "section": "barAutoHideStrict", @@ -3581,62 +3777,51 @@ "parentLabel": "Bar" }, { - "section": "barUseOverlayLayer", - "label": "Use overlay layer", + "section": "frameModeSelector", + "label": "Surfaces", "tabIndex": 3, "category": "General", "keywords": [ "bar", - "fullscreen", + "connected", + "float", + "flush", + "frame", "general", - "layer", - "overlay", + "mode", "panel", + "popout", + "separate", + "statusbar", + "surfaces", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" + }, + { + "section": "islandNotificationPopups", + "label": "Use standard popups", + "tabIndex": 3, + "category": "General", + "keywords": [ + "arrival", + "bar", + "general", + "island", + "notifications", + "panel", + "popup", + "popups", + "stack", + "standard", "statusbar", "taskbar", "topbar" ], - "parentLabel": "Bar" - }, - { - "section": "islandUseOverlayLayer", - "label": "Use overlay layer", - "tabIndex": 3, - "category": "General", - "keywords": [ - "bar", - "fullscreen", - "general", - "island", - "layer", - "overlay", - "panel", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar" - }, - { - "section": "islandAlongOffset", - "label": "Vertical offset", - "tabIndex": 3, - "category": "General", - "keywords": [ - "bar", - "center", - "general", - "horizontal", - "island", - "offset", - "panel", - "placement", - "statusbar", - "taskbar", - "topbar", - "vertical" - ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "barVisibility", @@ -3663,6 +3848,33 @@ "parentLabel": "Bar", "icon": "visibility" }, + { + "section": "islandHomeVolumeDisplay", + "label": "Volume style", + "tabIndex": 3, + "category": "General", + "keywords": [ + "audio", + "bar", + "compact", + "general", + "home", + "icon", + "island", + "loudness", + "panel", + "percentage", + "sound", + "speaker", + "statusbar", + "style", + "taskbar", + "topbar", + "volume" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "dockAutoHide", "label": "Auto-hide", @@ -3835,26 +4047,6 @@ "parentLabel": "Dock", "icon": "visibility_off" }, - { - "section": "barAppearanceAdvanced", - "label": "Advanced", - "tabIndex": 6, - "category": "Appearance", - "keywords": [ - "advanced", - "appearance", - "bar", - "exclusive", - "gaps", - "panel", - "popup", - "statusbar", - "taskbar", - "topbar", - "zone" - ], - "parentLabel": "Bar" - }, { "section": "barNoBackground", "label": "Background", @@ -3892,6 +4084,27 @@ ], "parentLabel": "Bar" }, + { + "section": "islandSatelliteBackground", + "label": "Background", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "background", + "bar", + "chrome", + "island", + "panel", + "satellite", + "statusbar", + "taskbar", + "topbar", + "widgets" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "widgetBackgroundColor", "label": "Background", @@ -3934,6 +4147,49 @@ "parentLabel": "Bar", "icon": "rounded_corner" }, + { + "section": "frameBarInsetPadding", + "label": "Bar inset padding", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "corner", + "edge", + "end", + "frame", + "inset", + "padding", + "panel", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" + }, + { + "section": "frameBarSize", + "label": "Bar size", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "frame", + "height", + "panel", + "size", + "statusbar", + "taskbar", + "thickness", + "topbar", + "width" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" + }, { "section": "_tab_6", "label": "Bar: Appearance", @@ -3965,7 +4221,7 @@ "description": "Background, corners, spacing, widget style" }, { - "section": "batteryColorMode", + "section": "islandBatteryColorMode", "label": "Battery", "tabIndex": 6, "category": "Appearance", @@ -3978,8 +4234,7 @@ "charging", "color", "green", - "icon", - "indicator", + "island", "level", "meter", "panel", @@ -3990,7 +4245,8 @@ "theme", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "islandBatteryStyle", @@ -4016,7 +4272,30 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "frameBlurEnabled", + "label": "Blur", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "background", + "bar", + "blur", + "frame", + "frosted", + "glass", + "panel", + "statusbar", + "taskbar", + "topbar", + "transparency" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" }, { "section": "barBorder", @@ -4035,6 +4314,30 @@ "parentLabel": "Bar", "icon": "border_style" }, + { + "section": "islandCompactThickness", + "label": "Compact width", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "compact", + "height", + "island", + "panel", + "placement", + "satellite", + "size", + "statusbar", + "taskbar", + "thickness", + "topbar", + "width" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "barCornerStyle", "label": "Corner style", @@ -4081,25 +4384,6 @@ ], "parentLabel": "Bar" }, - { - "section": "barExclusiveZone", - "label": "Exclusive zone offset", - "tabIndex": 6, - "category": "Appearance", - "keywords": [ - "appearance", - "bar", - "exclusive", - "offset", - "panel", - "reserved", - "statusbar", - "taskbar", - "topbar", - "zone" - ], - "parentLabel": "Bar" - }, { "section": "barFontScale", "label": "Font scale", @@ -4119,6 +4403,75 @@ ], "parentLabel": "Bar" }, + { + "section": "frameBorder", + "label": "Frame", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "border", + "corner", + "frame", + "panel", + "radius", + "rounding", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "icon": "border_outer", + "conditionKey": "frameEnabled" + }, + { + "section": "islandSatelliteGap", + "label": "Gap", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "gap", + "island", + "panel", + "satellite", + "spacing", + "statusbar", + "taskbar", + "topbar", + "widgets" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSatelliteSwoopRadius", + "label": "Goth corner radius", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "corner", + "corners", + "goth", + "island", + "panel", + "radius", + "round", + "rounded", + "satellite", + "size", + "statusbar", + "sweep", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "barGothCorners", "label": "Goth corners", @@ -4141,6 +4494,31 @@ ], "parentLabel": "Bar" }, + { + "section": "islandSatelliteGothCorners", + "label": "Goth corners", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "corners", + "goth", + "island", + "panel", + "radius", + "round", + "rounded", + "satellite", + "statusbar", + "sweep", + "taskbar", + "topbar", + "wing" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "barLengthMode", "label": "Height", @@ -4185,7 +4563,8 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "barIconScale", @@ -4206,26 +4585,30 @@ "parentLabel": "Bar" }, { - "section": "trayIconTint", - "label": "Icons", + "section": "islandFreeIdleOpacity", + "label": "Idle opacity", "tabIndex": 6, "category": "Appearance", "keywords": [ + "afk", "appearance", "bar", - "battery", - "color", - "icon", - "icons", + "dot", + "fade", + "free", + "idle", + "inactive", + "island", + "opacity", "panel", + "screensaver", "statusbar", "taskbar", - "tint", - "topbar", - "tray" + "timeout", + "topbar" ], "parentLabel": "Bar", - "icon": "palette" + "conditionKey": "islandEnabled" }, { "section": "barLengthPadding", @@ -4285,6 +4668,69 @@ ], "parentLabel": "Bar" }, + { + "section": "dotOpacity", + "label": "Opacity", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "background", + "bar", + "dot", + "opacity", + "panel", + "statusbar", + "taskbar", + "topbar", + "transparency" + ], + "parentLabel": "Bar" + }, + { + "section": "islandSatelliteTransparency", + "label": "Opacity", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "background", + "bar", + "blur", + "island", + "opacity", + "panel", + "satellite", + "statusbar", + "taskbar", + "topbar", + "transparency" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandOuterGap", + "label": "Outer gap", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "gap", + "island", + "margin", + "outer", + "panel", + "placement", + "statusbar", + "taskbar", + "top", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "islandPalette", "label": "Palette", @@ -4303,7 +4749,8 @@ "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "islandEnabled" }, { "section": "barLengthPercent", @@ -4326,6 +4773,118 @@ ], "parentLabel": "Bar" }, + { + "section": "islandSatellitePosition", + "label": "Position", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "center", + "edges", + "island", + "panel", + "position", + "satellite", + "statusbar", + "taskbar", + "topbar", + "widgets" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "frameRounding", + "label": "Radius", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "border", + "corner", + "frame", + "panel", + "radius", + "rounding", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" + }, + { + "section": "islandReserveThickness", + "label": "Reserved width", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "exclusive", + "height", + "island", + "panel", + "placement", + "reservation", + "reserved", + "statusbar", + "taskbar", + "thickness", + "topbar", + "width" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSatellites", + "label": "Satellites", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "island", + "left", + "panel", + "right", + "satellite", + "satellites", + "statusbar", + "taskbar", + "topbar", + "widgets" + ], + "parentLabel": "Bar", + "icon": "widgets", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSatellitesEnabled", + "label": "Show", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "island", + "left", + "panel", + "right", + "satellite", + "show", + "statusbar", + "taskbar", + "topbar", + "widgets" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "barSize", "label": "Size", @@ -4395,6 +4954,28 @@ ], "parentLabel": "Bar" }, + { + "section": "islandAlongOffset", + "label": "Vertical offset", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "center", + "horizontal", + "island", + "offset", + "panel", + "placement", + "statusbar", + "taskbar", + "topbar", + "vertical" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "widgetStyling", "label": "Widget colors", @@ -4490,6 +5071,27 @@ "parentLabel": "Bar", "icon": "widgets" }, + { + "section": "frameThickness", + "label": "Width", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "border", + "frame", + "panel", + "size", + "statusbar", + "taskbar", + "thickness", + "topbar", + "width" + ], + "parentLabel": "Bar", + "conditionKey": "frameEnabled" + }, { "section": "networkStatus", "label": "Backend", @@ -8397,6 +8999,14 @@ "icon": "widgets", "description": "Add, remove, reorder and configure" }, + { + "section": "barWidgetOption:BatteryOptions.qml:7", + "label": "Battery", + "tabIndex": 22, + "keywords": [], + "runtimeType": "barWidgetOption", + "optionFile": "BatteryOptions.qml" + }, { "section": "barWidgetOption:BatteryOptions.qml:6", "label": "Battery style", @@ -9085,6 +9695,22 @@ "runtimeType": "barWidgetOption", "optionFile": "ClockOptions.qml" }, + { + "section": "barWidgetOption:SystemTrayOptions.qml:7", + "label": "Tint saturation", + "tabIndex": 22, + "keywords": [], + "runtimeType": "barWidgetOption", + "optionFile": "SystemTrayOptions.qml" + }, + { + "section": "barWidgetOption:SystemTrayOptions.qml:8", + "label": "Tint strength", + "tabIndex": 22, + "keywords": [], + "runtimeType": "barWidgetOption", + "optionFile": "SystemTrayOptions.qml" + }, { "section": "barWidgetOption:AppsDockOptions.qml:17", "label": "Trash", @@ -9093,6 +9719,14 @@ "runtimeType": "barWidgetOption", "optionFile": "AppsDockOptions.qml" }, + { + "section": "barWidgetOption:SystemTrayOptions.qml:6", + "label": "Tray icon tint", + "tabIndex": 22, + "keywords": [], + "runtimeType": "barWidgetOption", + "optionFile": "SystemTrayOptions.qml" + }, { "section": "barWidgetOption:SystemTrayOptions.qml:1", "label": "Use inline expansion", @@ -10281,401 +10915,6 @@ "icon": "desktop_windows", "description": "The custom command used when attaching to sessions (receives the session name as the first argument)" }, - { - "section": "frameLauncherArcExtender", - "label": "Arc extender", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "arc", - "bar", - "border", - "center", - "connected", - "decoration", - "extender", - "frame", - "launcher", - "panel", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameBarInsetPadding", - "label": "Bar inset padding", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "corner", - "decoration", - "edge", - "end", - "frame", - "inset", - "padding", - "panel", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameBarSize", - "label": "Bar size", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "decoration", - "frame", - "height", - "panel", - "size", - "statusbar", - "taskbar", - "thickness", - "topbar", - "width", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameEnabled", - "label": "Behavior", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "behavior", - "border", - "decoration", - "frame", - "mode", - "overview", - "panel", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "icon": "tune", - "conditionKey": "frameEnabled" - }, - { - "section": "frameBlurEnabled", - "label": "Blur", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "background", - "bar", - "blur", - "border", - "decoration", - "frame", - "frosted", - "glass", - "panel", - "statusbar", - "taskbar", - "topbar", - "transparency", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameBorder", - "label": "Border", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "corner", - "decoration", - "frame", - "panel", - "radius", - "rounding", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "icon": "border_outer", - "conditionKey": "frameEnabled" - }, - { - "section": "frameConnectedOptions", - "label": "Connected", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "arcs", - "bar", - "border", - "connected", - "curves", - "decoration", - "edge", - "expose", - "frame", - "gap", - "notification", - "panel", - "popout", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "icon": "blur_linear", - "conditionKey": "frameEnabled" - }, - { - "section": "frameDisplays", - "label": "Displays", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "decoration", - "displays", - "frame", - "monitor", - "monitors", - "output", - "outputs", - "panel", - "screen", - "screens", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "icon": "monitor", - "conditionKey": "frameEnabled" - }, - { - "section": "frameLauncherEdgeHover", - "label": "Edge hover reveal", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "connected", - "decoration", - "edge", - "frame", - "hover", - "launcher", - "panel", - "reveal", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameCloseGaps", - "label": "Expose the arcs", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "arcs", - "bar", - "border", - "connected", - "curves", - "decoration", - "edge", - "expose", - "frame", - "gap", - "notification", - "panel", - "popout", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "_tab_33", - "label": "Frame", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "arcs", - "bar", - "border", - "connected", - "decoration", - "frame", - "mode", - "panel", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "icon": "frame_source", - "parentLabel": "Bar", - "description": "Border, connected mode, arcs", - "conditionKey": "frameEnabled" - }, - { - "section": "frameLauncherEmergeSide", - "label": "Launcher emerge side", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "app drawer", - "app menu", - "applications", - "bar", - "border", - "bottom", - "connected", - "decoration", - "direction", - "emerge", - "frame", - "launcher", - "modal", - "panel", - "side", - "start menu", - "statusbar", - "taskbar", - "top", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameRounding", - "label": "Radius", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "corner", - "decoration", - "frame", - "panel", - "radius", - "rounding", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameShowOnOverview", - "label": "Show on overview", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "decoration", - "frame", - "hide", - "niri", - "overview", - "panel", - "show", - "statusbar", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "nativeOverviewCapable" - }, - { - "section": "frameModeSelector", - "label": "Surfaces", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "connected", - "decoration", - "float", - "flush", - "frame", - "mode", - "panel", - "popout", - "separate", - "statusbar", - "surfaces", - "taskbar", - "topbar", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, - { - "section": "frameThickness", - "label": "Width", - "tabIndex": 33, - "category": "Frame", - "keywords": [ - "bar", - "border", - "decoration", - "frame", - "panel", - "size", - "statusbar", - "taskbar", - "thickness", - "topbar", - "width", - "window" - ], - "parentLabel": "Bar", - "conditionKey": "frameEnabled" - }, { "section": "_tab_34", "label": "Default apps", @@ -12991,481 +13230,6 @@ "parentLabel": "Input", "conditionKey": "isNiri" }, - { - "section": "islandSatelliteBackground", - "label": "Background", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "background", - "bar", - "chrome", - "island", - "panel", - "satellite", - "statusbar", - "taskbar", - "topbar", - "widgets" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandHomeBrightnessDisplay", - "label": "Brightness style", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "backlight", - "bar", - "bright", - "brightness", - "compact", - "dim", - "home", - "icon", - "island", - "panel", - "percentage", - "statusbar", - "style", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandNotificationBadgeClearOnOpen", - "label": "Clear badge on open", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "badge", - "bar", - "clear", - "dismiss", - "home", - "island", - "notifications", - "open", - "panel", - "statusbar", - "taskbar", - "topbar", - "unread" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandHomeClockDisplay", - "label": "Clock style", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "clock", - "compact", - "date", - "home", - "island", - "panel", - "statusbar", - "style", - "taskbar", - "time", - "topbar", - "watch" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandHomeCompactTight", - "label": "Compact pill", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "clock", - "compact", - "height", - "home", - "island", - "narrow", - "panel", - "pill", - "statusbar", - "taskbar", - "topbar", - "width" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandHomeStatusContent", - "label": "Control Center", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "battery", - "bluetooth", - "center", - "compact", - "connectivity", - "control", - "home", - "island", - "panel", - "status", - "statusbar", - "taskbar", - "topbar", - "wifi" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandNotificationExpand", - "label": "Expand by default", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "arrival", - "bar", - "default", - "expand", - "island", - "notifications", - "panel", - "size", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandSatelliteGap", - "label": "Gap", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "gap", - "island", - "panel", - "satellite", - "spacing", - "statusbar", - "taskbar", - "topbar", - "widgets" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandSatelliteSwoopRadius", - "label": "Goth corner radius", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "corner", - "corners", - "goth", - "island", - "panel", - "radius", - "round", - "rounded", - "satellite", - "size", - "statusbar", - "sweep", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandSatelliteGothCorners", - "label": "Goth corners", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "corners", - "goth", - "island", - "panel", - "radius", - "round", - "rounded", - "satellite", - "statusbar", - "sweep", - "taskbar", - "topbar", - "wing" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandHomeLayout", - "label": "Home Layout", - "tabIndex": 46, - "category": "Island", - "parentLabel": "Bar", - "keywords": [ - "around", - "badge", - "bar", - "battery", - "brightness", - "clock", - "groups", - "hidden", - "hide", - "home", - "island", - "launcher", - "layout", - "left", - "media", - "notifications", - "order", - "panel", - "reorder", - "right", - "statusbar", - "taskbar", - "time", - "topbar", - "volume", - "watch", - "weather" - ], - "icon": "home", - "description": "Order and hide the groups around the island clock", - "conditionKey": "islandEnabled" - }, - { - "section": "islandActivities", - "label": "Home compact", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "clock", - "compact", - "date", - "home", - "island", - "panel", - "statusbar", - "taskbar", - "time", - "topbar" - ], - "parentLabel": "Bar", - "icon": "home", - "conditionKey": "islandEnabled" - }, - { - "section": "_tab_46", - "label": "Island", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "alert", - "alerts", - "bar", - "home", - "island", - "layout", - "notif", - "notifications", - "notifs", - "panel", - "satellites", - "statusbar", - "taskbar", - "topbar" - ], - "icon": "view_in_ar", - "parentLabel": "Bar", - "description": "Home layout, notifications, satellites", - "conditionKey": "islandEnabled" - }, - { - "section": "islandNotifications", - "label": "Notifications", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "alert", - "alerts", - "arrival", - "bar", - "island", - "notif", - "notifications", - "notifs", - "panel", - "popup", - "stack", - "standard", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", - "icon": "notifications", - "conditionKey": "islandEnabled" - }, - { - "section": "islandSatelliteTransparency", - "label": "Opacity", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "background", - "bar", - "blur", - "island", - "opacity", - "panel", - "satellite", - "statusbar", - "taskbar", - "topbar", - "transparency" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandSatellitePosition", - "label": "Position", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "center", - "edges", - "island", - "panel", - "position", - "satellite", - "statusbar", - "taskbar", - "topbar", - "widgets" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandSatellites", - "label": "Satellites", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "island", - "left", - "panel", - "right", - "satellite", - "satellites", - "statusbar", - "taskbar", - "topbar", - "widgets" - ], - "parentLabel": "Bar", - "icon": "widgets", - "conditionKey": "islandEnabled" - }, - { - "section": "islandSatellitesEnabled", - "label": "Show", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "bar", - "island", - "left", - "panel", - "right", - "satellite", - "show", - "statusbar", - "taskbar", - "topbar", - "widgets" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandNotificationPopups", - "label": "Use standard popups", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "arrival", - "bar", - "island", - "notifications", - "panel", - "popup", - "popups", - "stack", - "standard", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandHomeVolumeDisplay", - "label": "Volume style", - "tabIndex": 46, - "category": "Island", - "keywords": [ - "audio", - "bar", - "compact", - "home", - "icon", - "island", - "loudness", - "panel", - "percentage", - "sound", - "speaker", - "statusbar", - "style", - "taskbar", - "topbar", - "volume" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, { "section": "_tab_47", "label": "Cellular", @@ -15487,26 +15251,6 @@ ], "parentLabel": "Dock" }, - { - "section": "_tab_59", - "label": "Advanced", - "tabIndex": 59, - "category": "Advanced", - "keywords": [ - "advanced", - "dock", - "exclusive", - "fullscreen", - "launcher bar", - "layers", - "panel", - "taskbar", - "zone" - ], - "icon": "settings", - "parentLabel": "Dock", - "description": "Layers, fullscreen, exclusive zone" - }, { "section": "dockAdvancedDisplays", "label": "Displays", @@ -15531,6 +15275,26 @@ "parentLabel": "Dock", "icon": "monitor" }, + { + "section": "_tab_59", + "label": "Dock: Advanced", + "tabIndex": 59, + "category": "Advanced", + "keywords": [ + "advanced", + "dock", + "exclusive", + "fullscreen", + "launcher bar", + "layers", + "panel", + "taskbar", + "zone" + ], + "icon": "settings", + "parentLabel": "Dock", + "description": "Layers, fullscreen, exclusive zone" + }, { "section": "dockExclusiveZone", "label": "Exclusive zone offset", @@ -15880,5 +15644,258 @@ "icon": "tune", "parentLabel": "Desktop widgets", "description": "Options of one widget instance" + }, + { + "section": "_tab_64", + "label": "Bar: Advanced", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "exclusive", + "fullscreen", + "layers", + "panel", + "statusbar", + "taskbar", + "topbar", + "zone" + ], + "icon": "settings", + "parentLabel": "Bar", + "description": "Layers, fullscreen, exclusive zone" + }, + { + "section": "barAdvanced", + "label": "Behavior", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "behavior", + "click", + "island", + "layer", + "maximize", + "motion", + "overlay", + "panel", + "spring", + "statusbar", + "taskbar", + "through", + "topbar" + ], + "parentLabel": "Bar", + "icon": "tune" + }, + { + "section": "barClickThrough", + "label": "Click through", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "click", + "clickthrough", + "input", + "mask", + "mouse", + "panel", + "passthrough", + "statusbar", + "taskbar", + "through", + "topbar" + ], + "parentLabel": "Bar" + }, + { + "section": "barExclusiveZone", + "label": "Exclusive zone offset", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "exclusive", + "offset", + "panel", + "reserved", + "statusbar", + "taskbar", + "topbar", + "zone" + ], + "parentLabel": "Bar" + }, + { + "section": "barAppearanceAdvanced", + "label": "Gaps", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "exclusive", + "gaps", + "panel", + "popup", + "statusbar", + "taskbar", + "topbar", + "zone" + ], + "parentLabel": "Bar", + "icon": "space_bar" + }, + { + "section": "barMaximizeDetection", + "label": "Maximize detection", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "border", + "detection", + "fullscreen", + "gaps", + "maximize", + "panel", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "windowRulesCapable" + }, + { + "section": "islandReducedMotion", + "label": "Reduce motion", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "accessibility", + "advanced", + "animation", + "bar", + "island", + "motion", + "panel", + "reduce", + "spring", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSpringDamping", + "label": "Spring damping", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "animation", + "bar", + "bounce", + "damping", + "island", + "motion", + "panel", + "spring", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSpringMass", + "label": "Spring mass", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "animation", + "bar", + "inertia", + "island", + "mass", + "motion", + "panel", + "spring", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSpringStiffness", + "label": "Spring stiffness", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "animation", + "bar", + "island", + "motion", + "panel", + "spring", + "statusbar", + "stiffness", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "barUseOverlayLayer", + "label": "Use overlay layer", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "fullscreen", + "layer", + "overlay", + "panel", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar" + }, + { + "section": "islandUseOverlayLayer", + "label": "Use overlay layer", + "tabIndex": 64, + "category": "Advanced", + "keywords": [ + "advanced", + "bar", + "fullscreen", + "island", + "layer", + "overlay", + "panel", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" } ]