From 4cb2be5fa4e011b9ff6f1a639e1370421322ecdf Mon Sep 17 00:00:00 2001 From: bbedward Date: Tue, 22 Sep 2026 22:12:15 -0400 Subject: [PATCH] bar: adjust settings UI --- quickshell/Common/SettingsTabs.qml | 18 +- quickshell/Common/SettingsUiState.qml | 12 +- .../Modals/Settings/SettingsContent.qml | 6 +- quickshell/Modules/Settings/BarHubHeader.qml | 129 +- .../Modules/Settings/DankBarAdvancedTab.qml | 192 --- .../Modules/Settings/DankBarAppearanceTab.qml | 291 ++-- quickshell/Modules/Settings/DankBarTab.qml | 605 +++---- quickshell/Modules/Settings/DankDotTab.qml | 329 ++++ .../Modules/Settings/SettingsHubPage.qml | 4 + .../Settings/Widgets/SettingsLayoutPicker.qml | 21 +- .../Settings/Widgets/SettingsToggleCard.qml | 23 +- quickshell/Modules/Settings/WidgetsTab.qml | 31 + quickshell/Services/SettingsSearchService.qml | 1 + .../translations/extract_settings_index.py | 6 +- .../translations/settings_search_index.json | 1454 ++++++++++------- 15 files changed, 1841 insertions(+), 1281 deletions(-) delete mode 100644 quickshell/Modules/Settings/DankBarAdvancedTab.qml create mode 100644 quickshell/Modules/Settings/DankDotTab.qml diff --git a/quickshell/Common/SettingsTabs.qml b/quickshell/Common/SettingsTabs.qml index 924d63fda..ccaff7587 100644 --- a/quickshell/Common/SettingsTabs.qml +++ b/quickshell/Common/SettingsTabs.qml @@ -86,12 +86,13 @@ Singleton { "id": "dankbar", "text": I18n.tr("Bar"), "icon": "toolbar", - "aliases": ["dot", "dankdot"], "hint": I18n.tr("Layout, position, appearance", "settings hub hint for the bar pages"), "hubHeader": "BarHubHeader", "children": [ { "id": "dankbar_settings", + "hidden": true, + "titleFrom": "selectedBarGeneralTitle", "aliases": ["dank_island", "island"], "text": I18n.tr("General", "adjective, settings page and section title for general options"), "icon": "tune", @@ -100,6 +101,8 @@ Singleton { }, { "id": "dankbar_appearance", + "hidden": true, + "titleFrom": "selectedBarAppearanceTitle", "aliases": ["frame"], "text": I18n.tr("Appearance", "settings page and section title for visual options"), "icon": "palette", @@ -107,12 +110,13 @@ Singleton { "hint": I18n.tr("Background, corners, spacing, widget style") }, { - "id": "dankbar_advanced", - "advanced": true, - "text": I18n.tr("Advanced"), - "icon": "settings", - "tabIndex": 64, - "hint": I18n.tr("Layers, fullscreen, exclusive zone") + "id": "dankbar_dot", + "hidden": true, + "aliases": ["dot", "dankdot"], + "text": I18n.tr("Dot", "bar layout: free-floating dot that opens island activities"), + "icon": "blur_on", + "tabIndex": 65, + "hint": I18n.tr("A floating companion that works alongside any bar layout", "bar settings: what the dot is") } ] }, diff --git a/quickshell/Common/SettingsUiState.qml b/quickshell/Common/SettingsUiState.qml index 907b8239a..8d328a00a 100644 --- a/quickshell/Common/SettingsUiState.qml +++ b/quickshell/Common/SettingsUiState.qml @@ -8,6 +8,12 @@ Singleton { id: root property string selectedBarId: "default" + readonly property string selectedBarTitle: { + SettingsData.barConfigs; + return SettingsData.getBarConfig(selectedBarId)?.name || I18n.tr("Bar", "fallback name for an unnamed bar"); + } + readonly property string selectedBarGeneralTitle: selectedBarTitle + " • " + I18n.tr("General", "adjective, settings page and section title for general options") + readonly property string selectedBarAppearanceTitle: selectedBarTitle + " • " + I18n.tr("Appearance", "settings page and section title for visual options") property string selectedWallpaperScreen: "" // Which dock the Dock hub pages are editing. property string dockHubSelection: "" @@ -21,10 +27,12 @@ Singleton { property string selectedWidgetDescription: "" property string selectedWidgetIcon: "" + // The dot has its own page, so bar selection never lands on it. function normalizeSelectedBar() { - if (SettingsData.getBarConfig(selectedBarId)) + const config = SettingsData.getBarConfig(selectedBarId); + if (config && !SettingsData.isDotBarConfig(config)) return; - selectedBarId = SettingsData.barConfigs[0]?.id ?? "default"; + selectedBarId = SettingsData.barConfigs.find(cfg => !SettingsData.isDotBarConfig(cfg))?.id ?? "default"; } Connections { diff --git a/quickshell/Modals/Settings/SettingsContent.qml b/quickshell/Modals/Settings/SettingsContent.qml index 2a2ce5ba1..cadb96734 100644 --- a/quickshell/Modals/Settings/SettingsContent.qml +++ b/quickshell/Modals/Settings/SettingsContent.qml @@ -155,6 +155,10 @@ FocusScope { running: loader.status === Loader.Ready && !host.presented onTriggered: { + if (loader.item?.settling) { + stableFrames = 0; + return; + } const h = loader.item?.contentHeight ?? loader.item?.height ?? 0; if (h === lastHeight) stableFrames++; @@ -186,7 +190,7 @@ FocusScope { "window_rules": "WindowRulesTab.qml", "dankbar_settings": "DankBarTab.qml", "dankbar_appearance": "DankBarAppearanceTab.qml", - "dankbar_advanced": "DankBarAdvancedTab.qml", + "dankbar_dot": "DankDotTab.qml", "bar_widget": "BarWidgetTab.qml", "compositor_layout": "CompositorLayoutTab.qml", "dock_general": "DockGeneralTab.qml", diff --git a/quickshell/Modules/Settings/BarHubHeader.qml b/quickshell/Modules/Settings/BarHubHeader.qml index 537014b63..b04b92588 100644 --- a/quickshell/Modules/Settings/BarHubHeader.qml +++ b/quickshell/Modules/Settings/BarHubHeader.qml @@ -11,23 +11,28 @@ Column { property var parentModal: null property string confirmingRemoveId: "" - property string editingBarId: "" + property bool renaming: false property string renameDraft: "" - readonly property bool dotSelected: SettingsData.isDotBarConfig(bar.selectedBarConfig) readonly property bool dotEnabled: SettingsData.dotBarConfig?.enabled ?? false + readonly property var barPages: ["dankbar_settings", "dankbar_appearance"].map(id => SettingsTabs.page(id)).filter(page => page) BarSelectionState { id: bar onSelectedBarIdChanged: { - root.editingBarId = ""; + root.renaming = false; root.confirmingRemoveId = ""; } } + function startRename() { + renameDraft = bar.selectedBarName; + renaming = true; + } + function finishRename(value) { - const id = editingBarId; - editingBarId = ""; + renaming = false; + const id = bar.selectedBarId; const name = value.trim(); if (!id || !name || SettingsData.barConfigs.some(config => config.id !== id && config.name === name)) return; @@ -83,18 +88,8 @@ 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); + return config.name || I18n.tr("Bar %1", "numbered name for an unnamed bar, %1 is its position").arg(SettingsData.barConfigs.findIndex(candidate => candidate.id === config.id) + 1); } function barSummary(config) { @@ -146,34 +141,40 @@ Column { onDeleteRequested: root.deleteBar(modelData.id) } } + } - SettingsRow { - title: I18n.tr("Name") - subtitle: root.editingBarId ? "" : bar.selectedBarName - visible: !!bar.selectedBarConfig && !root.dotSelected - + SettingsCard { + iconName: bar.selectedBarIsIsland ? "view_in_ar" : "toolbar" + title: bar.selectedBarName + settingKey: "barLayout" + tags: ["layout", "standard", "frame", "island", "mode", "bar", "name", "rename"] + visible: !!bar.selectedBarConfig + headerActions: [ DankActionButton { - iconName: root.editingBarId ? "check" : "edit" - Accessible.name: root.editingBarId ? I18n.tr("Save") : I18n.tr("Rename") + iconName: root.renaming ? "check" : "edit" + Accessible.name: root.renaming ? I18n.tr("Save") : I18n.tr("Rename") onClicked: { - if (root.editingBarId) { + if (root.renaming) { root.finishRename(root.renameDraft); return; } - root.renameDraft = bar.selectedBarName; - root.editingBarId = bar.selectedBarId; + root.startRename(); } - } + }, DankActionButton { - visible: root.editingBarId !== "" + visible: root.renaming iconName: "close" Accessible.name: I18n.tr("Cancel") - onClicked: root.editingBarId = "" + onClicked: root.renaming = false } + ] + + SettingsRow { + visible: root.renaming body: Loader { width: parent.width - active: root.editingBarId !== "" + active: root.renaming visible: active sourceComponent: DankTextField { id: renameField @@ -183,7 +184,7 @@ Column { text: root.renameDraft onTextEdited: root.renameDraft = renameField.text onAccepted: root.finishRename(renameField.text) - Keys.onEscapePressed: root.editingBarId = "" + Keys.onEscapePressed: root.renaming = false Component.onCompleted: { renameField.forceActiveFocus(); renameField.selectAll(); @@ -191,28 +192,62 @@ Column { } } } + + SettingsRow { + title: I18n.tr("Layout", "noun, settings section title for arrangement options") + + body: SettingsLayoutPicker {} + } + + Repeater { + model: root.barPages + + delegate: SettingsNavRow { + required property var modelData + + iconName: modelData.icon + title: modelData.text + hint: modelData.hint ?? "" + onClicked: root.parentModal?.navigateTo(modelData.id) + } + } } - 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") + SettingsRow { + id: dotRow + settingKey: "dotEnabled" tags: ["dot", "dankdot", "companion", "floating", "island", "enable"] + iconName: "blur_on" + iconColor: root.dotEnabled ? Theme.primary : Theme.onSurfaceVariant + title: I18n.tr("Dot", "bar layout: free-floating dot that opens island activities") + subtitle: I18n.tr("A floating companion that works alongside any bar layout", "bar settings: what the dot is") clickable: root.dotEnabled - selected: root.dotSelected - checked: root.dotEnabled - deletable: false - onClicked: bar.select(SettingsData.dotBarConfig.id) - onToggled: checked => root.setDotEnabled(checked) - } + onClicked: root.parentModal?.navigateTo("dankbar_dot") - SettingsCard { - iconName: "toolbar" - title: I18n.tr("Layout", "noun, settings section title for arrangement options") - settingKey: "barLayout" - visible: !root.dotSelected - tags: ["layout", "standard", "frame", "island", "mode", "bar"] + DankIcon { + name: "chevron_right" + size: Theme.iconSize + color: Theme.onSurfaceVariant + rotation: I18n.isRtl ? 180 : 0 + visible: root.dotEnabled + anchors.verticalCenter: parent.verticalCenter + } - SettingsLayoutPicker {} + Rectangle { + width: Theme.dividerWidth + height: SettingsMetrics.splitDividerHeight + color: Theme.outlineVariant + visible: root.dotEnabled + anchors.verticalCenter: parent.verticalCenter + } + + DankToggle { + hideText: true + text: dotRow.title + checked: root.dotEnabled + anchors.verticalCenter: parent.verticalCenter + onToggled: value => SettingsData.setDotEnabled(value, bar.selectedBarId) + } } } diff --git a/quickshell/Modules/Settings/DankBarAdvancedTab.qml b/quickshell/Modules/Settings/DankBarAdvancedTab.qml deleted file mode 100644 index 45463f928..000000000 --- a/quickshell/Modules/Settings/DankBarAdvancedTab.qml +++ /dev/null @@ -1,192 +0,0 @@ -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 fd4182215..7625193b9 100644 --- a/quickshell/Modules/Settings/DankBarAppearanceTab.qml +++ b/quickshell/Modules/Settings/DankBarAppearanceTab.qml @@ -7,8 +7,6 @@ import qs.Modules.Settings.Widgets Item { id: root - readonly property var barLengthModes: ["full", "percent", "fit"] - LayoutMirroring.enabled: I18n.isRtl LayoutMirroring.childrenInherit: true @@ -19,9 +17,12 @@ Item { 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 var clockDisplayValues: ["time", "date", "both"] + readonly property var systemLevelDisplayValues: ["icon", "percentage", "both"] + readonly property var statusContentValues: ["battery", "connectivity"] readonly property bool selectedIslandEnabled: bar.selectedBarIsIsland && (bar.selectedBarConfig?.enabled ?? false) readonly property bool selectedIslandFree: bar.selectedBarIsIsland && SettingsData.islandFreePlacement(bar.selectedBarConfig) + readonly property bool homeBatteryShown: root.selectedIslandEnabled && SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "status") && BatteryService.batteryAvailable && SettingsData.islandHomeStatusContent(bar.selectedBarConfig) === "battery" readonly property int frameInsetPaddingDisplay: Math.round(SettingsData.frameBarContentGap) function valueIndex(values, value, fallback) { @@ -41,7 +42,7 @@ Item { title: I18n.tr("Frame") settingKey: "frameBorder" collapsible: true - visible: !root.isDot && SettingsData.frameEnabled + visible: SettingsData.frameEnabled SettingsSliderRow { settingKey: "frameRounding" @@ -137,11 +138,10 @@ Item { SettingsCard { iconName: "rounded_corner" - title: !root.isDot ? I18n.tr("Bar") : I18n.tr("Dot", "bar layout: free-floating dot that opens island activities") + title: I18n.tr("Surface") settingKey: "barCorners" - tags: ["background", "opacity", "corners", "rounded", "goth", "shadow"] - // 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) + tags: ["background", "opacity", "corners", "rounded", "goth", "shadow", "palette", "contrast"] + visible: (bar.selectedBarConfig?.enabled ?? false) && !bar.selectedBarFrameStyled SettingsButtonGroupRow { settingKey: "islandPalette" @@ -169,40 +169,9 @@ Item { onToggled: checked => bar.apply("islandHighContrast", checked) } - SettingsButtonGroupRow { - settingKey: "islandBatteryStyle" - tags: ["island", "battery", "gauge", "solid", "outline", "ring", "circle", "appearance"] - resetStore: bar - resetKeys: ["islandBatteryStyle"] - text: I18n.tr("Battery style", "island settings: battery meter style row") - 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) => { - if (selected) - bar.apply("islandBatteryStyle", root.batteryStyleValues[index] ?? "solid"); - } - } - - 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: root.isDot || !bar.selectedBarFrameStyled resetStore: bar resetKeys: ["surfaceColor", "surfaceCustomColor"] text: I18n.tr("Background") @@ -215,46 +184,13 @@ Item { } SettingsControlledBy { - visible: !root.isDot && !bar.selectedBarFrameStyled && !bar.islandOwnsSelectedBarTop + visible: !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"] @@ -386,23 +322,7 @@ Item { title: I18n.tr("Size & spacing") settingKey: "barSpacing" tags: ["size", "scale", "font", "icon", "spacing", "padding", "inset", "length"] - 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) - } + visible: bar.selectedBarConfig?.enabled ?? false SettingsSliderRow { settingKey: "islandCompactThickness" @@ -419,36 +339,6 @@ Item { 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" tags: ["size", "thickness", "height", "inner"] @@ -508,21 +398,35 @@ Item { }) } - SettingsButtonGroupRow { + SettingsRow { settingKey: "barLengthMode" tags: ["bar", "width", "height", "length", "fit", "full", "custom", "percent", "compact", "widgets", "hug", "shrink"] - text: bar.selectedBarIsVertical ? I18n.tr("Height") : I18n.tr("Width") + title: bar.selectedBarIsVertical ? I18n.tr("Height") : I18n.tr("Width") visible: !bar.selectedBarFrameStyled && !bar.islandOwnsSelectedBarTop resetStore: bar resetKeys: ["barLengthMode", "barLengthPercent"] - model: [I18n.tr("Full", "bar length option, the bar spans the whole edge"), I18n.tr("Custom", "bar length option, the bar spans a percentage of the edge"), I18n.tr("Fit", "bar length option, the bar spans only its widgets")] - currentIndex: Math.max(0, root.barLengthModes.indexOf(bar.selectedBarConfig?.barLengthMode ?? "full")) - onSelectionChanged: (index, selected) => { - if (!selected) - return; - SettingsData.updateBarConfig(bar.selectedBarId, { - barLengthMode: root.barLengthModes[index] ?? "full" - }); + + body: SettingsLayoutPicker { + barLength: true + vertical: bar.selectedBarIsVertical + choices: [ + { + key: "full", + label: I18n.tr("Full", "bar length option, the bar spans the whole edge") + }, + { + key: "percent", + label: I18n.tr("Custom", "bar length option, the bar spans a percentage of the edge") + }, + { + key: "fit", + label: I18n.tr("Fit", "bar length option, the bar spans only its widgets") + } + ] + selectedKey: bar.selectedBarConfig?.barLengthMode ?? "full" + onSelected: key => SettingsData.updateBarConfig(bar.selectedBarId, { + barLengthMode: key + }) } } @@ -590,13 +494,133 @@ Item { } } + SettingsCard { + iconName: "home" + title: I18n.tr("Home compact", "island settings: home face card title") + settingKey: "islandActivities" + tags: ["island", "home", "compact", "clock", "volume", "brightness", "battery", "pill"] + visible: root.selectedIslandEnabled + + SettingsRow { + title: I18n.tr("Layout", "noun, settings section title for arrangement options") + + DankButton { + text: I18n.tr("Bar widgets") + iconName: "widgets" + onClicked: { + if (!root.parentModal) + return; + SettingsSearchService.navigateToSection("islandHomeLayout"); + root.parentModal.navigateTo("dankbar_widgets"); + } + } + } + + 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(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: 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(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: 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(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: root.valueIndex(root.statusContentValues, SettingsData.islandHomeStatusContent(bar.selectedBarConfig), "battery") + onSelectionChanged: (index, selected) => { + if (selected) + bar.apply("islandHomeStatusContent", root.statusContentValues[index] ?? "battery"); + } + } + + SettingsButtonGroupRow { + settingKey: "islandBatteryStyle" + tags: ["island", "battery", "gauge", "solid", "outline", "ring", "circle", "appearance"] + resetStore: bar + resetKeys: ["islandBatteryStyle"] + text: I18n.tr("Battery style", "island settings: battery meter style row") + visible: root.homeBatteryShown + 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) => { + if (selected) + bar.apply("islandBatteryStyle", root.batteryStyleValues[index] ?? "solid"); + } + } + + SettingsButtonGroupRow { + settingKey: "islandBatteryColorMode" + tags: ["island", "battery", "color", "level", "theme", "meter", "accent", "green", "red"] + resetStore: bar + resetKeys: ["batteryColorMode"] + text: I18n.tr("Battery") + visible: root.homeBatteryShown + 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"); + } + } + + 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) + } + } + SettingsCard { iconName: "widgets" title: I18n.tr("Satellites", "island settings: satellite widgets card title") settingKey: "islandSatellites" collapsible: true expanded: true - visible: root.selectedIslandEnabled && !root.isDot + visible: root.selectedIslandEnabled SettingsToggleRow { settingKey: "islandSatellitesEnabled" @@ -699,7 +723,7 @@ Item { title: I18n.tr("Widgets") settingKey: "barWidgets" tags: ["widget", "style", "pills", "segments", "opacity", "padding", "maximize"] - visible: (bar.selectedBarConfig?.enabled ?? false) && !root.isDot + visible: bar.selectedBarConfig?.enabled ?? false SettingsRow { settingKey: "barWidgetStyle" @@ -801,7 +825,7 @@ Item { settingKey: "barWidgetOutline" iconName: "highlight" title: I18n.tr("Widget outline") - visible: (bar.selectedBarConfig?.enabled ?? false) && !root.isDot + visible: bar.selectedBarConfig?.enabled ?? false enabled: root.widgetBackgroundEnabled resetStore: bar resetKeys: ["widgetOutlineEnabled"] @@ -859,7 +883,6 @@ Item { title: I18n.tr("Widget colors") settingKey: "widgetStyling" tags: ["widget", "background", "color", "colorful", "text", "all", "bars"] - visible: !root.isDot WidgetTextStyleRow {} diff --git a/quickshell/Modules/Settings/DankBarTab.qml b/quickshell/Modules/Settings/DankBarTab.qml index b6b426ef8..55c9b5d2e 100644 --- a/quickshell/Modules/Settings/DankBarTab.qml +++ b/quickshell/Modules/Settings/DankBarTab.qml @@ -18,13 +18,9 @@ Item { readonly property var interactionModeValues: ["click", "hybrid"] readonly property var routingValues: ["normal", "always", "last-used"] - 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 selectedIslandFloating: selectedIslandFree && !isDot + readonly property bool selectedIslandDocked: bar.selectedBarIsIsland && !selectedIslandFree readonly property int placementIndex: !bar.islandSetting("islandFloating") ? 0 : (bar.islandSetting("islandPlacement") === "free" ? 2 : 1) function valueIndex(values, value, fallback) { @@ -67,7 +63,7 @@ Item { SettingsButtonGroupRow { settingKey: "islandFreeOrientation" tags: ["island", "free", "orientation", "horizontal", "vertical"] - visible: dankBarTab.selectedIslandFloating + visible: dankBarTab.selectedIslandFree 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 @@ -100,7 +96,7 @@ Item { SettingsButtonGroupRow { settingKey: "islandPlacement" tags: ["island", "placement", "docked", "overlay", "floating", "float", "free", "anywhere", "edge", "drag", "exclusive", "reserve"] - visible: bar.selectedBarIsIsland && !dankBarTab.isDot + visible: bar.selectedBarIsIsland resetStore: bar resetKeys: ["islandFloating", "islandPlacement"] text: I18n.tr("Placement", "island settings: docked, overlay or floating placement row") @@ -120,7 +116,7 @@ Item { } SettingsRow { - visible: dankBarTab.selectedIslandFloating + visible: dankBarTab.selectedIslandFree body: StyledText { width: parent.width text: I18n.tr("Drag to move, click to open activities", "island settings: free placement hint") @@ -130,39 +126,9 @@ Item { } } - 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") - } - - SettingsSliderRow { - settingKey: "islandFreeSize" - tags: ["island", "free", "dot", "size", "diameter"] - visible: dankBarTab.isDot - resetStore: bar - resetKeys: ["islandFreeSize"] - text: I18n.tr("Dot size", "island settings: free dot diameter slider") - unit: "px" - minimum: 24 - maximum: 160 - step: 1 - value: bar.islandSetting("islandFreeSize") - onSliderValueChanged: value => bar.apply("islandFreeSize", value) - } - SettingsSliderRow { settingKey: "islandFreeEdgeMargin" - tags: ["island", "free", "dot", "edge", "margin", "gap"] + tags: ["island", "free", "edge", "margin", "gap"] visible: dankBarTab.selectedIslandFree resetStore: bar resetKeys: ["islandFreeEdgeMargin"] @@ -176,34 +142,49 @@ Item { } SettingsSliderRow { - settingKey: "islandFreeIdleDelay" - tags: ["island", "free", "dot", "idle", "delay", "fade", "timeout"] - visible: dankBarTab.isDot + settingKey: "islandOuterGap" + tags: ["island", "placement", "gap", "top", "margin"] + visible: dankBarTab.selectedIslandDocked resetStore: bar - resetKeys: ["islandFreeIdleDelay"] - text: I18n.tr("Idle delay", "island settings: time before the dot fades, 0 disables idling") - unit: "ms" + resetKeys: ["islandOuterGap"] + text: I18n.tr("Outer gap", "island settings: gap between screen edge and island") + unit: "px" minimum: 0 - maximum: 30000 - step: 500 - value: bar.islandSetting("islandFreeIdleDelay") - onSliderValueChanged: value => bar.apply("islandFreeIdleDelay", value) + maximum: 48 + step: 1 + value: bar.islandSetting("islandOuterGap") + onSliderValueChanged: value => bar.apply("islandOuterGap", value) } SettingsSliderRow { - settingKey: "islandFreeIdleScale" - tags: ["island", "free", "dot", "idle", "shrink", "scale"] - visible: dankBarTab.isDot + settingKey: "islandAlongOffset" + tags: ["island", "placement", "horizontal", "vertical", "offset", "center"] + visible: dankBarTab.selectedIslandDocked resetStore: bar - resetKeys: ["islandFreeIdleScale"] - text: I18n.tr("Idle size", "island settings: how far the dot shrinks while idle") - unit: "%" - minimum: 20 - maximum: 100 + 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: Math.round(bar.islandSetting("islandFreeIdleScale") * 100) - enabled: bar.islandSetting("islandFreeIdleDelay") > 0 - onSliderValueChanged: value => bar.apply("islandFreeIdleScale", value / 100) + value: bar.islandSetting("islandAlongOffset") + onSliderValueChanged: value => bar.apply("islandAlongOffset", value) + } + + SettingsSliderRow { + settingKey: "islandReserveThickness" + tags: ["island", "placement", "reservation", "exclusive", "height", "width", "thickness"] + visible: dankBarTab.selectedIslandDocked + 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) } } @@ -226,104 +207,6 @@ 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") @@ -402,21 +285,15 @@ Item { SettingsToggleRow { settingKey: "barOpenOnOverview" - tags: ["bar", "overview", "niri", "show", "frame"] - visible: CompositorService.supportsNativeOverview && !bar.islandOwnsSelectedBarTop + tags: ["bar", "overview", "niri", "show"] + visible: CompositorService.supportsNativeOverview && !bar.islandOwnsSelectedBarTop && !bar.selectedBarFrameStyled text: I18n.tr("Show on overview") - resetStore: bar.selectedBarFrameStyled ? SettingsData : bar - resetKeys: bar.selectedBarFrameStyled ? ["frameShowOnOverview"] : ["openOnOverview"] - checked: bar.selectedBarFrameStyled ? SettingsData.frameShowOnOverview : (bar.selectedBarConfig?.openOnOverview ?? false) - onToggled: toggled => { - if (bar.selectedBarFrameStyled) { - SettingsData.set("frameShowOnOverview", toggled); - return; - } - SettingsData.updateBarConfig(bar.selectedBarId, { + resetStore: bar + resetKeys: ["openOnOverview"] + checked: bar.selectedBarConfig?.openOnOverview ?? false + onToggled: toggled => SettingsData.updateBarConfig(bar.selectedBarId, { openOnOverview: toggled - }); - } + }) } SettingsToggleRow { @@ -440,12 +317,26 @@ Item { iconName: "touch_app" title: I18n.tr("Behavior", "island settings: behavior card title") settingKey: "islandInteraction" - tags: ["island", "interaction", "click", "hybrid", "expand", "hover", "delay"] - visible: (bar.selectedBarConfig?.enabled ?? false) && bar.selectedBarIsIsland && !dankBarTab.selectedIslandFree + tags: ["island", "interaction", "click", "hybrid", "expand", "hover", "delay", "routing", "shortcuts"] + visible: dankBarTab.selectedIslandEnabled + + SettingsDropdownRow { + settingKey: "islandSharedRouting" + tags: ["island", "routing", "launcher", "dash", "control center", "ipc", "last used"] + 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: "islandInteractionMode" tags: ["island", "interaction", "click", "hybrid", "expand"] + visible: dankBarTab.selectedIslandDocked resetStore: bar resetKeys: ["islandInteractionMode"] text: I18n.tr("Expansion mode", "island settings: click or hover expansion row") @@ -458,7 +349,7 @@ Item { } SettingsRow { - visible: bar.islandSetting("islandInteractionMode") !== "click" + visible: dankBarTab.selectedIslandDocked && bar.islandSetting("islandInteractionMode") !== "click" body: StyledText { width: parent.width text: I18n.tr("Hybrid peeks the current compact face on hover. Click pins a destination so it stays open", "island settings: hybrid mode hint") @@ -479,7 +370,7 @@ Item { maximum: 1000 step: 10 value: bar.islandSetting("islandHoverOpenDelay") - visible: bar.islandSetting("islandInteractionMode") !== "click" + visible: dankBarTab.selectedIslandDocked && bar.islandSetting("islandInteractionMode") !== "click" onSliderValueChanged: value => bar.apply("islandHoverOpenDelay", value) } @@ -494,7 +385,7 @@ Item { maximum: 1000 step: 10 value: bar.islandSetting("islandHoverCloseDelay") - visible: bar.islandSetting("islandInteractionMode") !== "click" + visible: dankBarTab.selectedIslandDocked && bar.islandSetting("islandInteractionMode") !== "click" onSliderValueChanged: value => bar.apply("islandHoverCloseDelay", value) } @@ -509,114 +400,6 @@ 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") @@ -650,7 +433,7 @@ Item { 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") + enabled: SettingsData.islandHomeGroupEnabled(bar.selectedBarConfig, "notifications") onToggled: checked => bar.apply("islandNotificationBadgeClearOnOpen", checked) } } @@ -662,7 +445,7 @@ Item { tags: ["bar", "hover", "popout", "reveal", "widget", "delay"] iconName: "touch_app" title: I18n.tr("Hover popouts") - visible: (bar.selectedBarConfig?.enabled ?? false) && !dankBarTab.isDot + visible: bar.selectedBarConfig?.enabled ?? false enabled: !(bar.selectedBarConfig?.clickThrough ?? false) opacity: (bar.selectedBarConfig?.clickThrough ?? false) ? 0.5 : 1.0 checked: bar.selectedBarConfig?.hoverPopouts ?? false @@ -783,5 +566,255 @@ Item { } } } + + SettingsCard { + iconName: "border_outer" + title: I18n.tr("Frame") + settingKey: "frameEnabled" + tags: ["frame", "mode", "bar", "overview", "connected", "separate", "displays"] + 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) + } + + SettingsToggleRow { + settingKey: "frameCloseGaps" + tags: ["frame", "connected", "gap", "edge", "curves", "arcs", "expose", "popout", "notification"] + visible: SettingsData.frameMode === "connected" + 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"] + visible: SettingsData.frameMode === "connected" + 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"] + visible: SettingsData.frameMode === "connected" + text: I18n.tr("Arc extender") + checked: SettingsData.frameLauncherArcExtender + onToggled: checked => SettingsData.set("frameLauncherArcExtender", checked) + } + + SettingsToggleRow { + settingKey: "frameLauncherEdgeHover" + tags: ["frame", "connected", "launcher", "hover", "edge", "reveal"] + visible: SettingsData.frameMode === "connected" + text: I18n.tr("Edge hover reveal") + checked: SettingsData.frameLauncherEdgeHover + onToggled: checked => SettingsData.set("frameLauncherEdgeHover", checked) + } + + SettingsDisplayPicker { + displayPreferences: SettingsData.frameScreenPreferences + onPreferencesChanged: prefs => SettingsData.set("frameScreenPreferences", prefs) + } + } + + SettingsCard { + iconName: "tune" + title: I18n.tr("Advanced") + settingKey: "barAdvanced" + tags: ["bar", "advanced", "overlay", "layer", "click", "through", "maximize", "island", "spring", "motion", "exclusive", "zone", "popup", "gaps"] + 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: "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 + }) + } + + SettingsSliderRow { + settingKey: "barExclusiveZone" + tags: ["exclusive", "zone", "reserved", "offset"] + visible: !bar.islandOwnsSelectedBarTop && !bar.selectedBarFrameStyled + 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"] + visible: !bar.selectedBarFrameStyled + resetStore: bar + resetKeys: ["popupGapsAuto"] + checked: bar.selectedBarConfig?.popupGapsAuto ?? true + onToggled: checked => SettingsData.updateBarConfig(bar.selectedBarId, { + popupGapsAuto: checked + }) + } + + SettingsSliderRow { + visible: !bar.selectedBarFrameStyled && !(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 + }) + } + + 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) + } + } } } diff --git a/quickshell/Modules/Settings/DankDotTab.qml b/quickshell/Modules/Settings/DankDotTab.qml new file mode 100644 index 000000000..070655574 --- /dev/null +++ b/quickshell/Modules/Settings/DankDotTab.qml @@ -0,0 +1,329 @@ +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 + + readonly property var routingValues: ["normal", "always", "last-used"] + readonly property var paletteValues: ["default", "bright", "dim"] + + function valueIndex(values, value, fallback) { + const index = values.indexOf(value); + return index >= 0 ? index : Math.max(0, values.indexOf(fallback)); + } + + QtObject { + id: dot + + readonly property var config: SettingsData.dotBarConfig + + function setting(key) { + return SettingsData.islandSetting(config, key); + } + + function apply(key, value) { + if (!config) + return; + SettingsData.updateBarConfig(config.id, { + [key]: value + }); + } + + function defaultFor(key) { + return key in SettingsData.islandDefaults ? SettingsData.islandDefaults[key] : SettingsData.barConfigDefault(key); + } + + function isDefault(keys) { + if (!config) + return true; + return keys.every(key => config[key] === undefined || JSON.stringify(config[key]) === JSON.stringify(defaultFor(key))); + } + + function resetToDefault(keys) { + if (!config) + return; + const patch = {}; + for (const key of keys) + patch[key] = defaultFor(key); + SettingsData.updateBarConfig(config.id, patch); + } + } + + SettingsPage { + SettingsCard { + settingKey: "dotSize" + tags: ["dot", "dankdot", "size", "diameter", "idle", "fade"] + iconName: "blur_on" + title: I18n.tr("Dot", "bar layout: free-floating dot that opens island activities") + + SettingsSliderRow { + settingKey: "islandFreeSize" + tags: ["dot", "size", "diameter"] + resetStore: dot + resetKeys: ["islandFreeSize"] + text: I18n.tr("Size") + unit: "px" + minimum: 24 + maximum: 160 + step: 1 + value: dot.setting("islandFreeSize") + onSliderValueChanged: value => dot.apply("islandFreeSize", value) + } + + SettingsSliderRow { + settingKey: "islandFreeEdgeMargin" + tags: ["dot", "edge", "margin", "gap"] + resetStore: dot + resetKeys: ["islandFreeEdgeMargin"] + text: I18n.tr("Edge margin", "island settings: gap kept from the display edge") + unit: "px" + minimum: 0 + maximum: 64 + step: 1 + value: dot.setting("islandFreeEdgeMargin") + onSliderValueChanged: value => dot.apply("islandFreeEdgeMargin", value) + } + + SettingsSliderRow { + settingKey: "islandFreeIdleDelay" + tags: ["dot", "idle", "delay", "fade", "timeout"] + resetStore: dot + resetKeys: ["islandFreeIdleDelay"] + text: I18n.tr("Idle delay", "island settings: time before the dot fades, 0 disables idling") + unit: "ms" + minimum: 0 + maximum: 30000 + step: 500 + value: dot.setting("islandFreeIdleDelay") + onSliderValueChanged: value => dot.apply("islandFreeIdleDelay", value) + } + + SettingsSliderRow { + settingKey: "islandFreeIdleScale" + tags: ["dot", "idle", "shrink", "scale"] + resetStore: dot + resetKeys: ["islandFreeIdleScale"] + text: I18n.tr("Idle size", "island settings: how far the dot shrinks while idle") + unit: "%" + minimum: 20 + maximum: 100 + step: 1 + value: Math.round(dot.setting("islandFreeIdleScale") * 100) + enabled: dot.setting("islandFreeIdleDelay") > 0 + onSliderValueChanged: value => dot.apply("islandFreeIdleScale", value / 100) + } + + SettingsSliderRow { + settingKey: "islandFreeIdleOpacity" + tags: ["dot", "idle", "opacity", "fade"] + resetStore: dot + resetKeys: ["islandFreeIdleOpacity"] + text: I18n.tr("Idle opacity", "island settings: dot opacity while idle") + unit: "%" + minimum: 5 + maximum: 100 + step: 1 + value: Math.round(dot.setting("islandFreeIdleOpacity") * 100) + enabled: dot.setting("islandFreeIdleDelay") > 0 + onSliderValueChanged: value => dot.apply("islandFreeIdleOpacity", value / 100) + } + } + + SettingsCard { + iconName: "palette" + title: I18n.tr("Surface") + settingKey: "dotSurface" + tags: ["dot", "background", "color", "opacity", "palette", "contrast"] + + SurfaceColorRow { + settingKey: "dotSurfaceColor" + tags: ["dot", "background", "color", "surface"] + resetStore: dot + resetKeys: ["surfaceColor", "surfaceCustomColor"] + text: I18n.tr("Background") + defaultColor: Theme.hostSurface + currentMode: dot.config?.surfaceColor ?? "default" + customColor: dot.config?.surfaceCustomColor ?? SettingsData.barConfigDefault("surfaceCustomColor") + pickerTitle: I18n.tr("Background") + onModeSelected: mode => dot.apply("surfaceColor", mode) + onCustomColorSelected: selectedColor => dot.apply("surfaceCustomColor", selectedColor.toString()) + } + + SettingsSliderRow { + settingKey: "dotOpacity" + tags: ["dot", "opacity", "transparency", "background"] + resetStore: dot + resetKeys: ["transparency"] + text: I18n.tr("Opacity") + minimum: 0 + maximum: 100 + step: 1 + value: Math.round(SettingsData.barTransparency(dot.config) * 100) + onSliderDragFinished: finalValue => SettingsData.updateBarConfig(dot.config.id, { + followInterfaceStyle: false, + transparency: finalValue / 100 + }) + } + + SettingsButtonGroupRow { + settingKey: "dotPalette" + tags: ["dot", "palette", "surface", "bright", "dim"] + resetStore: dot + resetKeys: ["islandPalette"] + text: I18n.tr("Palette", "island settings: surface tone choice") + model: [I18n.tr("Default", "island settings: default surface tone"), I18n.tr("Bright", "island settings: bright surface tone"), I18n.tr("Dim", "island settings: dim surface tone")] + currentIndex: root.valueIndex(root.paletteValues, dot.setting("islandPalette"), "default") + onSelectionChanged: (index, selected) => { + if (selected) + dot.apply("islandPalette", root.paletteValues[index] ?? "default"); + } + } + + SettingsToggleRow { + settingKey: "dotHighContrast" + tags: ["dot", "contrast", "accessibility", "outline"] + resetStore: dot + resetKeys: ["islandHighContrast"] + text: I18n.tr("High contrast", "island settings: high contrast toggle") + checked: dot.setting("islandHighContrast") + onToggled: checked => dot.apply("islandHighContrast", checked) + } + } + + SettingsCard { + iconName: "display_settings" + title: I18n.tr("Displays") + settingKey: "dotDisplays" + tags: ["dot", "display", "monitor", "screen"] + + SettingsDisplayPicker { + displayPreferences: dot.config?.screenPreferences || ["all"] + emptyMeansAll: false + allowEmpty: true + showLastDisplay: true + showOnLastDisplay: dot.config?.showOnLastDisplay ?? true + onPreferencesChanged: prefs => dot.apply("screenPreferences", prefs) + onLastDisplayToggled: checked => dot.apply("showOnLastDisplay", checked) + } + } + + SettingsCard { + iconName: "touch_app" + title: I18n.tr("Behavior", "island settings: behavior card title") + settingKey: "dotBehavior" + tags: ["dot", "routing", "shortcuts", "motion", "spring", "animation"] + + SettingsDropdownRow { + settingKey: "dotSharedRouting" + tags: ["dot", "routing", "launcher", "dash", "control center", "ipc", "last used"] + resetStore: dot + 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[root.valueIndex(root.routingValues, SettingsData.islandSharedRoutingMode(dot.config), "normal")] + onValueChanged: value => SettingsData.setIslandSharedRouting(dot.config.id, root.routingValues[options.indexOf(value)] ?? "normal") + } + + SettingsToggleRow { + settingKey: "dotReducedMotion" + tags: ["dot", "motion", "animation", "reduce", "accessibility", "spring"] + resetStore: dot + resetKeys: ["islandReducedMotion"] + text: I18n.tr("Reduce motion") + checked: dot.setting("islandReducedMotion") + onToggled: checked => dot.apply("islandReducedMotion", checked) + } + + SettingsSliderRow { + settingKey: "dotSpringStiffness" + tags: ["dot", "motion", "spring", "stiffness", "animation"] + resetStore: dot + resetKeys: ["islandSpringStiffness"] + text: I18n.tr("Spring stiffness", "island settings: spring stiffness slider") + unit: "" + minimum: 100 + maximum: 1200 + step: 10 + value: Math.round(dot.setting("islandSpringStiffness")) + enabled: !dot.setting("islandReducedMotion") + onSliderValueChanged: value => dot.apply("islandSpringStiffness", value) + } + + SettingsSliderRow { + settingKey: "dotSpringDamping" + tags: ["dot", "motion", "spring", "damping", "bounce", "animation"] + resetStore: dot + resetKeys: ["islandSpringDamping"] + text: I18n.tr("Spring damping", "island settings: spring damping slider") + unit: "" + minimum: 10 + maximum: 100 + step: 1 + value: Math.round(dot.setting("islandSpringDamping")) + enabled: !dot.setting("islandReducedMotion") + onSliderValueChanged: value => dot.apply("islandSpringDamping", value) + } + + SettingsSliderRow { + settingKey: "dotSpringMass" + tags: ["dot", "motion", "spring", "mass", "inertia", "animation"] + resetStore: dot + resetKeys: ["islandSpringMass"] + text: I18n.tr("Spring mass", "island settings: spring mass slider") + minimum: 25 + maximum: 300 + step: 5 + unit: "" + decimals: 2 + value: Math.round(dot.setting("islandSpringMass") * 100) + enabled: !dot.setting("islandReducedMotion") + onSliderValueChanged: value => dot.apply("islandSpringMass", value / 100) + } + } + + SettingsCard { + iconName: "notifications" + title: I18n.tr("Notifications", "island settings: notifications card title") + settingKey: "dotNotifications" + tags: ["dot", "notifications", "popup", "badge", "expand"] + + SettingsToggleRow { + settingKey: "dotNotificationPopups" + tags: ["dot", "notifications", "popup", "standard", "stack", "arrival"] + resetStore: dot + resetKeys: ["islandNotificationPopups"] + text: I18n.tr("Use standard popups", "island settings: show arriving notifications as stacked popups instead of in the island") + checked: dot.setting("islandNotificationPopups") + onToggled: checked => dot.apply("islandNotificationPopups", checked) + } + + SettingsToggleRow { + settingKey: "dotNotificationExpand" + tags: ["dot", "notifications", "expand", "arrival", "size"] + resetStore: dot + resetKeys: ["islandNotificationExpand"] + text: I18n.tr("Expand by default", "island settings: expanded notification toggle") + checked: dot.setting("islandNotificationExpand") + onToggled: checked => dot.apply("islandNotificationExpand", checked) + } + + SettingsToggleRow { + settingKey: "dotNotificationBadgeClearOnOpen" + tags: ["dot", "notifications", "badge", "unread", "clear", "dismiss", "open"] + resetStore: dot + resetKeys: ["islandNotificationBadgeClearOnOpen"] + text: I18n.tr("Clear badge on open", "island settings: clear the notification badge when the center opens") + checked: dot.setting("islandNotificationBadgeClearOnOpen") + onToggled: checked => dot.apply("islandNotificationBadgeClearOnOpen", checked) + } + } + } +} diff --git a/quickshell/Modules/Settings/SettingsHubPage.qml b/quickshell/Modules/Settings/SettingsHubPage.qml index 3f577e726..36f4a490e 100644 --- a/quickshell/Modules/Settings/SettingsHubPage.qml +++ b/quickshell/Modules/Settings/SettingsHubPage.qml @@ -15,6 +15,8 @@ FocusScope { readonly property var rows: SettingsTabs.hubMainRows(hubId) readonly property var moreRows: SettingsTabs.hubMoreRows(hubId) + readonly property real contentHeight: flickable.contentHeight + readonly property bool settling: headerLoader.status === Loader.Loading onHubIdChanged: flickable.contentY = 0 @@ -22,6 +24,8 @@ FocusScope { id: flickable Loader { + id: headerLoader + width: parent.width source: root.headerFile ? Qt.resolvedUrl(root.headerFile + ".qml") : "" onLoaded: item.parentModal = Qt.binding(() => root.parentModal) diff --git a/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml b/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml index a2c0a2c10..3e41dd2a2 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsLayoutPicker.qml @@ -11,11 +11,13 @@ GridLayout { property bool edgePlacement: false property bool widgetStyle: false + property bool barLength: false + property bool vertical: false property var choices: barModes property string selectedKey: activeBarMode signal selected(string key) onSelected: key => { - if (!edgePlacement && !widgetStyle) + if (!edgePlacement && !widgetStyle && !barLength) applyBarMode(key); } @@ -38,6 +40,11 @@ GridLayout { readonly property real previewAspect: 0.62 readonly property real previewStripRatio: 0.55 readonly property real previewIslandRatio: 0.42 + readonly property var lengthPreviewRatios: ({ + "full": 1, + "percent": 0.7, + "fit": 0.45 + }) readonly property real previewWidth: Math.round(Theme.iconSize * previewWidthRatio) readonly property real minimumCardWidth: previewWidth + Theme.spacingL * 2 readonly property var targetConfig: { @@ -173,6 +180,18 @@ GridLayout { color: Theme.primary } + Rectangle { + readonly property real span: root.lengthPreviewRatios[modeCard.modelData.key] ?? 1 + readonly property real extent: (root.vertical ? parent.height : parent.width) - screenPreview.edgePad * 2 + visible: root.barLength + x: root.vertical ? screenPreview.edgePad : Math.round((parent.width - width) / 2) + y: root.vertical ? Math.round((parent.height - height) / 2) : screenPreview.edgePad + width: root.vertical ? screenPreview.stripSize : Math.round(extent * span) + height: root.vertical ? Math.round(extent * span) : screenPreview.stripSize + radius: Theme.fullRadius(width, height) + color: Theme.primary + } + Rectangle { visible: !root.widgetStyle && !root.edgePlacement && modeCard.modelData.key === "standard" anchors.top: parent.top diff --git a/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml b/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml index 15a19e9fb..737c02fc7 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml @@ -19,6 +19,7 @@ Item { property string description: "" property string iconName: "" property bool checked: false + property bool userToggled: false property alias resetStore: header.resetStore property alias resetKeys: header.resetKeys @@ -60,12 +61,30 @@ Item { checked: root.checked enabled: root.enabled paintBackground: false - onToggled: value => root.toggled(value) + onToggled: value => { + root.userToggled = true; + root.toggled(value); + } } Item { width: parent.width - height: root.hasContent ? expandedContent.height : 0 + visible: root.checked || height > 0 + height: root.checked && root.hasContent ? expandedContent.height : 0 + clip: true + + Behavior on height { + enabled: root.userToggled && Theme.currentAnimationSpeed !== SettingsData.AnimationSpeed.None + NumberAnimation { + duration: SettingsMetrics.transitionDuration + easing.type: Easing.BezierSpline + easing.bezierCurve: Theme.expressiveCurves.expressiveDefaultSpatial + onRunningChanged: { + if (!running) + root.userToggled = false; + } + } + } Column { id: expandedContent diff --git a/quickshell/Modules/Settings/WidgetsTab.qml b/quickshell/Modules/Settings/WidgetsTab.qml index 4f9d2bf0e..09a1cc72b 100644 --- a/quickshell/Modules/Settings/WidgetsTab.qml +++ b/quickshell/Modules/Settings/WidgetsTab.qml @@ -715,6 +715,8 @@ Item { width: parent.width iconName: "view_in_ar" title: I18n.tr("Home compact", "island settings: home face card title") + settingKey: "islandHomeLayout" + tags: ["island", "home", "compact", "layout", "groups", "order"] visible: widgetsTab.dankIslandOwnsSelectedBarCenter Loader { @@ -728,6 +730,35 @@ Item { barId: widgetsTab.selectedBarId } } + + 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 (!widgetsTab.parentModal) + return; + SettingsSearchService.navigateToSection("launcherStyle"); + widgetsTab.parentModal.navigateTo("launcher"); + } + } + + DankButton { + text: I18n.tr("Time & weather", "island settings: button to weather tab") + iconName: "cloud" + onClicked: { + if (!widgetsTab.parentModal) + return; + SettingsSearchService.navigateToSection("weatherEnabled"); + widgetsTab.parentModal.navigateTo("time_weather"); + } + } + } + } } WidgetsTabSection { diff --git a/quickshell/Services/SettingsSearchService.qml b/quickshell/Services/SettingsSearchService.qml index 347541ca2..8932e2093 100644 --- a/quickshell/Services/SettingsSearchService.qml +++ b/quickshell/Services/SettingsSearchService.qml @@ -69,6 +69,7 @@ Singleton { "greeterAvailable": () => GreeterService.available, "frameEnabled": () => SettingsData.frameEnabled, "islandEnabled": () => SettingsData.islandBarConfigs.length > 0, + "dotEnabled": () => SettingsData.dotBarConfig?.enabled ?? false, "cellularAvailable": () => (NetworkService.cellularDevices?.length ?? 0) > 0 }) diff --git a/quickshell/translations/extract_settings_index.py b/quickshell/translations/extract_settings_index.py index 5fa25124c..fa92b8cfc 100644 --- a/quickshell/translations/extract_settings_index.py +++ b/quickshell/translations/extract_settings_index.py @@ -106,7 +106,7 @@ TAB_INDEX_MAP = { "DockAppearanceTab.qml": 58, "DockAdvancedTab.qml": 59, "DankBarAppearanceTab.qml": 6, - "DankBarAdvancedTab.qml": 64, + "DankDotTab.qml": 65, "NetworkStatusTab.qml": 7, "NetworkEthernetTab.qml": 39, "NetworkWifiTab.qml": 40, @@ -181,7 +181,7 @@ 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"} +BAR_TAB_FILES = {"DankBarTab.qml", "DankBarAppearanceTab.qml"} SEARCHABLE_COMPONENTS = [ "SettingsCard", @@ -440,6 +440,8 @@ def find_settings_components(content, filename, wrappers, tab_meta, hub_meta): condition_key = "frameEnabled" elif setting_key.startswith("island"): condition_key = "islandEnabled" + if filename == "DankDotTab.qml" and not condition_key and setting_key != "dotEnabled": + condition_key = "dotEnabled" 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) diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index d793fc9af..ffc399682 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -289,9 +289,9 @@ "page": "dankbar", "category": "Bar", "keywords": [ - "advanced", "appearance", "bar", + "dot", "general", "layout", "panel", @@ -960,7 +960,6 @@ "tabIndex": -1, "category": "Bar", "keywords": [ - "alongside", "bar", "companion", "dankdot", @@ -968,15 +967,13 @@ "enable", "floating", "island", - "layout", "panel", "statusbar", "taskbar", - "topbar", - "works" + "topbar" ], "page": "dankbar", - "description": "A floating companion that works alongside any bar layout" + "icon": "blur_on" }, { "section": "wallpaperFillMode", @@ -1260,6 +1257,30 @@ ], "page": "notifications" }, + { + "section": "islandHomeLayout", + "label": "Home compact", + "tabIndex": -1, + "category": "Bar widgets", + "keywords": [ + "bar", + "compact", + "components", + "groups", + "home", + "island", + "layout", + "modules", + "order", + "panel", + "statusbar", + "taskbar", + "topbar", + "widgets" + ], + "page": "dankbar_widgets", + "icon": "view_in_ar" + }, { "section": "controlCenterIconScale", "label": "Icon scale", @@ -1389,26 +1410,6 @@ ], "page": "theme_surfaces" }, - { - "section": "barLayout", - "label": "Layout", - "tabIndex": -1, - "category": "Bar", - "keywords": [ - "bar", - "frame", - "island", - "layout", - "mode", - "panel", - "standard", - "statusbar", - "taskbar", - "topbar" - ], - "page": "dankbar", - "icon": "toolbar" - }, { "section": "dockPlacement", "label": "Layout", @@ -2822,6 +2823,35 @@ "description": "Compositor and shell key bindings", "conditionKey": "keybindsAvailable" }, + { + "section": "barAdvanced", + "label": "Advanced", + "tabIndex": 3, + "category": "General", + "keywords": [ + "advanced", + "bar", + "click", + "exclusive", + "gaps", + "general", + "island", + "layer", + "maximize", + "motion", + "overlay", + "panel", + "popup", + "spring", + "statusbar", + "taskbar", + "through", + "topbar", + "zone" + ], + "parentLabel": "Bar", + "icon": "tune" + }, { "section": "frameLauncherArcExtender", "label": "Arc extender", @@ -2899,9 +2929,16 @@ "tabIndex": 3, "category": "General", "keywords": [ + "alert", + "app drawer", + "app menu", + "applications", "bar", "behavior", + "center", "click", + "control", + "dash", "delay", "expand", "general", @@ -2909,39 +2946,21 @@ "hybrid", "interaction", "island", + "launcher", + "notif", + "notification", "panel", + "routes", + "routing", + "shortcuts", + "start menu", "statusbar", "taskbar", "topbar" ], "parentLabel": "Bar", "icon": "touch_app", - "conditionKey": "islandEnabled" - }, - { - "section": "islandHomeBrightnessDisplay", - "label": "Brightness style", - "tabIndex": 3, - "category": "General", - "keywords": [ - "backlight", - "bar", - "bright", - "brightness", - "compact", - "dim", - "general", - "home", - "icon", - "island", - "panel", - "percentage", - "statusbar", - "style", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", + "description": "Routes launcher, dash, control center and notification shortcuts", "conditionKey": "islandEnabled" }, { @@ -2969,104 +2988,26 @@ "conditionKey": "islandEnabled" }, { - "section": "islandHomeClockDisplay", - "label": "Clock style", + "section": "barClickThrough", + "label": "Click through", "tabIndex": 3, "category": "General", "keywords": [ "bar", - "clock", - "compact", - "date", + "click", + "clickthrough", "general", - "home", - "island", + "input", + "mask", + "mouse", "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", - "pill", - "statusbar", - "taskbar", - "topbar", - "width" - ], - "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", + "passthrough", "statusbar", "taskbar", + "through", "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" + "parentLabel": "Bar" }, { "section": "barDisplay", @@ -3091,27 +3032,6 @@ "parentLabel": "Bar", "icon": "display_settings" }, - { - "section": "islandFreeSize", - "label": "Dot size", - "tabIndex": 3, - "category": "General", - "keywords": [ - "bar", - "diameter", - "dot", - "free", - "general", - "island", - "panel", - "size", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, { "section": "frameLauncherEdgeHover", "label": "Edge hover reveal", @@ -3141,7 +3061,6 @@ "category": "General", "keywords": [ "bar", - "dot", "edge", "free", "gap", @@ -3156,6 +3075,25 @@ "parentLabel": "Bar", "conditionKey": "islandEnabled" }, + { + "section": "barExclusiveZone", + "label": "Exclusive zone offset", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "exclusive", + "general", + "offset", + "panel", + "reserved", + "statusbar", + "taskbar", + "topbar", + "zone" + ], + "parentLabel": "Bar" + }, { "section": "islandNotificationExpand", "label": "Expand by default", @@ -3233,42 +3171,20 @@ "category": "General", "keywords": [ "bar", + "connected", + "displays", "frame", "general", "mode", "overview", "panel", + "separate", "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", + "icon": "border_outer", "conditionKey": "frameEnabled" }, { @@ -3314,69 +3230,6 @@ "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", @@ -3399,59 +3252,6 @@ "parentLabel": "Bar", "icon": "touch_app" }, - { - "section": "islandFreeIdleDelay", - "label": "Idle delay", - "tabIndex": 3, - "category": "General", - "keywords": [ - "afk", - "bar", - "delay", - "dot", - "fade", - "free", - "general", - "idle", - "inactive", - "island", - "panel", - "screensaver", - "statusbar", - "taskbar", - "timeout", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, - { - "section": "islandFreeIdleScale", - "label": "Idle size", - "tabIndex": 3, - "category": "General", - "keywords": [ - "afk", - "bar", - "dot", - "free", - "general", - "idle", - "inactive", - "island", - "panel", - "scale", - "screensaver", - "shrink", - "size", - "statusbar", - "taskbar", - "timeout", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, { "section": "islandMediaClockVisible", "label": "Keep clock with media", @@ -3524,6 +3324,27 @@ ], "parentLabel": "Bar" }, + { + "section": "barMaximizeDetection", + "label": "Maximize detection", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "border", + "detection", + "fullscreen", + "gaps", + "general", + "maximize", + "panel", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "windowRulesCapable" + }, { "section": "islandNotifications", "label": "Notifications", @@ -3593,6 +3414,28 @@ "parentLabel": "Bar", "conditionKey": "islandEnabled" }, + { + "section": "islandOuterGap", + "label": "Outer gap", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "gap", + "general", + "island", + "margin", + "outer", + "panel", + "placement", + "statusbar", + "taskbar", + "top", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "islandPlacement", "label": "Placement", @@ -3627,35 +3470,67 @@ "tabIndex": 3, "category": "General", "keywords": [ - "alert", - "app drawer", - "app menu", - "applications", "bar", - "center", - "control", - "dash", "free", "general", "horizontal", "island", - "launcher", - "notif", - "notification", "orientation", "panel", "position", - "routes", - "shortcuts", - "start menu", "statusbar", "taskbar", "topbar", "vertical" ], "parentLabel": "Bar", - "icon": "vertical_align_center", - "description": "Routes launcher, dash, control center and notification shortcuts" + "icon": "vertical_align_center" + }, + { + "section": "islandReducedMotion", + "label": "Reduce motion", + "tabIndex": 3, + "category": "General", + "keywords": [ + "accessibility", + "animation", + "bar", + "general", + "island", + "motion", + "panel", + "reduce", + "spring", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "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", + "conditionKey": "islandEnabled" }, { "section": "barScrollWheel", @@ -3693,7 +3568,6 @@ "control", "control center", "dash", - "dot", "general", "ipc", "island", @@ -3722,7 +3596,6 @@ "category": "General", "keywords": [ "bar", - "frame", "general", "niri", "overview", @@ -3756,6 +3629,71 @@ "parentLabel": "Bar", "conditionKey": "nativeOverviewCapable" }, + { + "section": "islandSpringDamping", + "label": "Spring damping", + "tabIndex": 3, + "category": "General", + "keywords": [ + "animation", + "bar", + "bounce", + "damping", + "general", + "island", + "motion", + "panel", + "spring", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSpringMass", + "label": "Spring mass", + "tabIndex": 3, + "category": "General", + "keywords": [ + "animation", + "bar", + "general", + "inertia", + "island", + "mass", + "motion", + "panel", + "spring", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandSpringStiffness", + "label": "Spring stiffness", + "tabIndex": 3, + "category": "General", + "keywords": [ + "animation", + "bar", + "general", + "island", + "motion", + "panel", + "spring", + "statusbar", + "stiffness", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "barAutoHideStrict", "label": "Strict auto-hide", @@ -3800,6 +3738,44 @@ "parentLabel": "Bar", "conditionKey": "frameEnabled" }, + { + "section": "barUseOverlayLayer", + "label": "Use overlay layer", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "fullscreen", + "general", + "layer", + "overlay", + "panel", + "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", + "conditionKey": "islandEnabled" + }, { "section": "islandNotificationPopups", "label": "Use standard popups", @@ -3823,6 +3799,28 @@ "parentLabel": "Bar", "conditionKey": "islandEnabled" }, + { + "section": "islandAlongOffset", + "label": "Vertical offset", + "tabIndex": 3, + "category": "General", + "keywords": [ + "bar", + "center", + "general", + "horizontal", + "island", + "offset", + "panel", + "placement", + "statusbar", + "taskbar", + "topbar", + "vertical" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "barVisibility", "label": "Visibility", @@ -3848,33 +3846,6 @@ "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", @@ -4125,28 +4096,6 @@ ], "parentLabel": "Bar" }, - { - "section": "barCorners", - "label": "Bar", - "tabIndex": 6, - "category": "Appearance", - "keywords": [ - "appearance", - "background", - "bar", - "corners", - "goth", - "opacity", - "panel", - "rounded", - "shadow", - "statusbar", - "taskbar", - "topbar" - ], - "parentLabel": "Bar", - "icon": "rounded_corner" - }, { "section": "frameBarInsetPadding", "label": "Bar inset padding", @@ -4314,6 +4263,80 @@ "parentLabel": "Bar", "icon": "border_style" }, + { + "section": "islandHomeBrightnessDisplay", + "label": "Brightness style", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "backlight", + "bar", + "bright", + "brightness", + "compact", + "dim", + "home", + "icon", + "island", + "panel", + "percentage", + "statusbar", + "style", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandHomeClockDisplay", + "label": "Clock style", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "clock", + "compact", + "date", + "home", + "island", + "panel", + "statusbar", + "style", + "taskbar", + "time", + "topbar", + "watch" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, + { + "section": "islandHomeCompactTight", + "label": "Compact pill", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "clock", + "compact", + "height", + "home", + "island", + "narrow", + "panel", + "pill", + "statusbar", + "taskbar", + "topbar", + "width" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "islandCompactThickness", "label": "Compact width", @@ -4338,6 +4361,32 @@ "parentLabel": "Bar", "conditionKey": "islandEnabled" }, + { + "section": "islandHomeStatusContent", + "label": "Control Center", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "battery", + "bluetooth", + "center", + "compact", + "connectivity", + "control", + "home", + "island", + "panel", + "status", + "statusbar", + "taskbar", + "topbar", + "wifi" + ], + "parentLabel": "Bar", + "conditionKey": "islandEnabled" + }, { "section": "barCornerStyle", "label": "Corner style", @@ -4566,6 +4615,31 @@ "parentLabel": "Bar", "conditionKey": "islandEnabled" }, + { + "section": "islandActivities", + "label": "Home compact", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "bar", + "battery", + "brightness", + "clock", + "compact", + "home", + "island", + "panel", + "pill", + "statusbar", + "taskbar", + "topbar", + "volume" + ], + "parentLabel": "Bar", + "icon": "home", + "conditionKey": "islandEnabled" + }, { "section": "barIconScale", "label": "Icon scale", @@ -4584,32 +4658,6 @@ ], "parentLabel": "Bar" }, - { - "section": "islandFreeIdleOpacity", - "label": "Idle opacity", - "tabIndex": 6, - "category": "Appearance", - "keywords": [ - "afk", - "appearance", - "bar", - "dot", - "fade", - "free", - "idle", - "inactive", - "island", - "opacity", - "panel", - "screensaver", - "statusbar", - "taskbar", - "timeout", - "topbar" - ], - "parentLabel": "Bar", - "conditionKey": "islandEnabled" - }, { "section": "barLengthPadding", "label": "Length padding", @@ -4668,25 +4716,6 @@ ], "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", @@ -4709,28 +4738,6 @@ "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", @@ -4816,30 +4823,6 @@ "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", @@ -4932,6 +4915,31 @@ "parentLabel": "Bar", "icon": "space_bar" }, + { + "section": "barCorners", + "label": "Surface", + "tabIndex": 6, + "category": "Appearance", + "keywords": [ + "appearance", + "background", + "bar", + "contrast", + "corners", + "goth", + "opacity", + "palette", + "panel", + "rounded", + "shadow", + "statusbar", + "surface", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "icon": "rounded_corner" + }, { "section": "widgetColorMode", "label": "Text style", @@ -4955,23 +4963,28 @@ "parentLabel": "Bar" }, { - "section": "islandAlongOffset", - "label": "Vertical offset", + "section": "islandHomeVolumeDisplay", + "label": "Volume style", "tabIndex": 6, "category": "Appearance", "keywords": [ "appearance", + "audio", "bar", - "center", - "horizontal", + "compact", + "home", + "icon", "island", - "offset", + "loudness", "panel", - "placement", + "percentage", + "sound", + "speaker", "statusbar", + "style", "taskbar", "topbar", - "vertical" + "volume" ], "parentLabel": "Bar", "conditionKey": "islandEnabled" @@ -15251,6 +15264,26 @@ ], "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", @@ -15275,26 +15308,6 @@ "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", @@ -15646,144 +15659,314 @@ "description": "Options of one widget instance" }, { - "section": "_tab_64", - "label": "Bar: Advanced", - "tabIndex": 64, - "category": "Advanced", + "section": "dotSurfaceColor", + "label": "Background", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", + "background", "bar", - "exclusive", - "fullscreen", - "layers", + "color", + "dot", "panel", "statusbar", + "surface", "taskbar", - "topbar", - "zone" + "topbar" ], - "icon": "settings", "parentLabel": "Bar", - "description": "Layers, fullscreen, exclusive zone" + "conditionKey": "dotEnabled" }, { - "section": "barAdvanced", + "section": "dotBehavior", "label": "Behavior", - "tabIndex": 64, - "category": "Advanced", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", + "alert", + "animation", + "app drawer", + "app menu", + "applications", "bar", "behavior", - "click", - "island", - "layer", - "maximize", + "center", + "control", + "dash", + "dot", + "launcher", "motion", - "overlay", + "notif", + "notification", "panel", + "routes", + "routing", + "shortcuts", "spring", + "start menu", "statusbar", "taskbar", - "through", "topbar" ], "parentLabel": "Bar", - "icon": "tune" + "icon": "touch_app", + "description": "Routes launcher, dash, control center and notification shortcuts", + "conditionKey": "dotEnabled" }, { - "section": "barClickThrough", - "label": "Click through", - "tabIndex": 64, - "category": "Advanced", + "section": "dotNotificationBadgeClearOnOpen", + "label": "Clear badge on open", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", + "badge", "bar", - "click", - "clickthrough", - "input", - "mask", - "mouse", + "clear", + "dismiss", + "dot", + "notifications", + "open", "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" + "unread" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "conditionKey": "dotEnabled" }, { - "section": "barAppearanceAdvanced", - "label": "Gaps", - "tabIndex": 64, - "category": "Advanced", + "section": "dotDisplays", + "label": "Displays", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", "bar", - "exclusive", - "gaps", + "display", + "displays", + "dot", + "monitor", + "monitors", + "output", + "outputs", + "panel", + "screen", + "screens", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "icon": "display_settings", + "conditionKey": "dotEnabled" + }, + { + "section": "dotSize", + "label": "Dot", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "bar", + "dankdot", + "diameter", + "dot", + "fade", + "idle", + "panel", + "size", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "icon": "blur_on", + "conditionKey": "dotEnabled" + }, + { + "section": "dotNotificationExpand", + "label": "Expand by default", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "arrival", + "bar", + "default", + "dot", + "expand", + "notifications", + "panel", + "size", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "dotEnabled" + }, + { + "section": "dotHighContrast", + "label": "High contrast", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "accessibility", + "bar", + "contrast", + "dot", + "high", + "outline", + "panel", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "dotEnabled" + }, + { + "section": "islandFreeIdleDelay", + "label": "Idle delay", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "afk", + "bar", + "delay", + "dot", + "fade", + "idle", + "inactive", + "panel", + "screensaver", + "statusbar", + "taskbar", + "timeout", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "dotEnabled" + }, + { + "section": "islandFreeIdleOpacity", + "label": "Idle opacity", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "afk", + "bar", + "dot", + "fade", + "idle", + "inactive", + "opacity", + "panel", + "screensaver", + "statusbar", + "taskbar", + "timeout", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "dotEnabled" + }, + { + "section": "islandFreeIdleScale", + "label": "Idle size", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "afk", + "bar", + "dot", + "idle", + "inactive", + "panel", + "scale", + "screensaver", + "shrink", + "size", + "statusbar", + "taskbar", + "timeout", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "dotEnabled" + }, + { + "section": "dotNotifications", + "label": "Notifications", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "alert", + "alerts", + "badge", + "bar", + "dot", + "expand", + "notif", + "notifications", + "notifs", "panel", "popup", "statusbar", "taskbar", - "topbar", - "zone" + "topbar" ], "parentLabel": "Bar", - "icon": "space_bar" + "icon": "notifications", + "conditionKey": "dotEnabled" }, { - "section": "barMaximizeDetection", - "label": "Maximize detection", - "tabIndex": 64, - "category": "Advanced", + "section": "dotOpacity", + "label": "Opacity", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", + "background", "bar", - "border", - "detection", - "fullscreen", - "gaps", - "maximize", + "dot", + "opacity", "panel", "statusbar", "taskbar", + "topbar", + "transparency" + ], + "parentLabel": "Bar", + "conditionKey": "dotEnabled" + }, + { + "section": "dotPalette", + "label": "Palette", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "bar", + "bright", + "dim", + "dot", + "palette", + "panel", + "statusbar", + "surface", + "taskbar", "topbar" ], "parentLabel": "Bar", - "conditionKey": "windowRulesCapable" + "conditionKey": "dotEnabled" }, { - "section": "islandReducedMotion", + "section": "dotReducedMotion", "label": "Reduce motion", - "tabIndex": 64, - "category": "Advanced", + "tabIndex": 65, + "category": "Dot", "keywords": [ "accessibility", - "advanced", "animation", "bar", - "island", + "dot", "motion", "panel", "reduce", @@ -15793,20 +15976,72 @@ "topbar" ], "parentLabel": "Bar", - "conditionKey": "islandEnabled" + "conditionKey": "dotEnabled" }, { - "section": "islandSpringDamping", + "section": "dotSharedRouting", + "label": "Shared shortcuts", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "alert", + "app drawer", + "app menu", + "applications", + "bar", + "center", + "control", + "control center", + "dash", + "dot", + "ipc", + "last used", + "launcher", + "notif", + "notification", + "panel", + "routes", + "routing", + "shared", + "shortcuts", + "start menu", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "description": "Routes launcher, dash, control center and notification shortcuts", + "conditionKey": "dotEnabled" + }, + { + "section": "islandFreeSize", + "label": "Size", + "tabIndex": 65, + "category": "Dot", + "keywords": [ + "bar", + "diameter", + "dot", + "panel", + "size", + "statusbar", + "taskbar", + "topbar" + ], + "parentLabel": "Bar", + "conditionKey": "dotEnabled" + }, + { + "section": "dotSpringDamping", "label": "Spring damping", - "tabIndex": 64, - "category": "Advanced", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", "animation", "bar", "bounce", "damping", - "island", + "dot", "motion", "panel", "spring", @@ -15815,19 +16050,18 @@ "topbar" ], "parentLabel": "Bar", - "conditionKey": "islandEnabled" + "conditionKey": "dotEnabled" }, { - "section": "islandSpringMass", + "section": "dotSpringMass", "label": "Spring mass", - "tabIndex": 64, - "category": "Advanced", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", "animation", "bar", + "dot", "inertia", - "island", "mass", "motion", "panel", @@ -15837,18 +16071,17 @@ "topbar" ], "parentLabel": "Bar", - "conditionKey": "islandEnabled" + "conditionKey": "dotEnabled" }, { - "section": "islandSpringStiffness", + "section": "dotSpringStiffness", "label": "Spring stiffness", - "tabIndex": 64, - "category": "Advanced", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", "animation", "bar", - "island", + "dot", "motion", "panel", "spring", @@ -15858,44 +16091,51 @@ "topbar" ], "parentLabel": "Bar", - "conditionKey": "islandEnabled" + "conditionKey": "dotEnabled" }, { - "section": "barUseOverlayLayer", - "label": "Use overlay layer", - "tabIndex": 64, - "category": "Advanced", + "section": "dotSurface", + "label": "Surface", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", + "background", "bar", - "fullscreen", - "layer", - "overlay", + "color", + "contrast", + "dot", + "opacity", + "palette", "panel", "statusbar", + "surface", "taskbar", "topbar" ], - "parentLabel": "Bar" + "parentLabel": "Bar", + "icon": "palette", + "conditionKey": "dotEnabled" }, { - "section": "islandUseOverlayLayer", - "label": "Use overlay layer", - "tabIndex": 64, - "category": "Advanced", + "section": "dotNotificationPopups", + "label": "Use standard popups", + "tabIndex": 65, + "category": "Dot", "keywords": [ - "advanced", + "arrival", "bar", - "fullscreen", - "island", - "layer", - "overlay", + "dot", + "notifications", "panel", + "popup", + "popups", + "stack", + "standard", "statusbar", "taskbar", "topbar" ], "parentLabel": "Bar", - "conditionKey": "islandEnabled" + "conditionKey": "dotEnabled" } ]