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