bar: adjust settings UI

This commit is contained in:
bbedward committed 2026-09-22 22:12:34 -04:00
1 parent edf936973f
commit 4cb2be5fa4
15 files changed
+1841 -1281

No files matched your search

+11 -7
View File
@@ -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")
}
]
},
+10 -2
View File
@@ -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 {
@@ -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",
+82 -47
View File
@@ -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)
}
}
}
@@ -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
})
}
}
}
}
@@ -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 {}
+319 -286
View File
@@ -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)
}
}
}
}
+329
View File
@@ -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)
}
}
}
}
@@ -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)
@@ -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
@@ -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
@@ -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 {
@@ -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
})
@@ -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)
File diff suppressed because it is too large. Load diff