diff --git a/quickshell/Modules/Settings/AutoStartTab.qml b/quickshell/Modules/Settings/AutoStartTab.qml index fd489588a..8a0eeebe8 100644 --- a/quickshell/Modules/Settings/AutoStartTab.qml +++ b/quickshell/Modules/Settings/AutoStartTab.qml @@ -11,8 +11,6 @@ import qs.Modules.Settings.Widgets Item { id: root - readonly property int contentMaxWidth: 550 - readonly property var log: Log.scoped("AutoStartTab") property var parentModal: null property var entries: [] @@ -371,7 +369,7 @@ Item { Column { id: mainColumn topPadding: Theme.spacingXS - width: Math.min(root.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) anchors.horizontalCenter: parent.horizontalCenter spacing: Theme.spacingXL visible: DesktopService.autostartAvailable diff --git a/quickshell/Modules/Settings/BatteryTab.qml b/quickshell/Modules/Settings/BatteryTab.qml index 36caca4bb..90a025ed7 100644 --- a/quickshell/Modules/Settings/BatteryTab.qml +++ b/quickshell/Modules/Settings/BatteryTab.qml @@ -79,8 +79,7 @@ done SettingsRow { body: Column { - width: parent.width - Theme.spacingM * 2 - x: Theme.spacingM + width: parent.width spacing: Theme.spacingM Row { diff --git a/quickshell/Modules/Settings/DankBarTab.qml b/quickshell/Modules/Settings/DankBarTab.qml index 82d9d274c..a6d5dd2f0 100644 --- a/quickshell/Modules/Settings/DankBarTab.qml +++ b/quickshell/Modules/Settings/DankBarTab.qml @@ -364,26 +364,19 @@ Item { hoverPopouts: checked }) - Column { - width: parent.width - spacing: Theme.spacingS + SettingsSliderRow { visible: bar.selectedBarConfig?.hoverPopouts ?? false - leftPadding: Theme.spacingM - - SettingsSliderRow { - width: parent.width - parent.leftPadding - text: I18n.tr("Open delay") - resetStore: bar - resetKeys: ["hoverPopoutDelay"] - value: bar.selectedBarConfig?.hoverPopoutDelay ?? 150 - minimum: 0 - maximum: 1000 - unit: "ms" - onSliderValueChanged: newValue => { - SettingsData.updateBarConfig(bar.selectedBarId, { - hoverPopoutDelay: newValue - }); - } + text: I18n.tr("Open delay") + resetStore: bar + resetKeys: ["hoverPopoutDelay"] + value: bar.selectedBarConfig?.hoverPopoutDelay ?? 150 + minimum: 0 + maximum: 1000 + unit: "ms" + onSliderValueChanged: newValue => { + SettingsData.updateBarConfig(bar.selectedBarId, { + hoverPopoutDelay: newValue + }); } } } diff --git a/quickshell/Modules/Settings/DesktopWidgetsTab.qml b/quickshell/Modules/Settings/DesktopWidgetsTab.qml index 09751981f..898c2263f 100644 --- a/quickshell/Modules/Settings/DesktopWidgetsTab.qml +++ b/quickshell/Modules/Settings/DesktopWidgetsTab.qml @@ -95,8 +95,7 @@ Item { SettingsRow { body: Column { - width: parent.width - Theme.spacingM * 2 - x: Theme.spacingM + width: parent.width spacing: Theme.spacingM Row { @@ -129,8 +128,7 @@ Item { SettingsRow { body: Column { - width: parent.width - Theme.spacingM * 2 - x: Theme.spacingM + width: parent.width spacing: Theme.spacingM Row { @@ -344,8 +342,7 @@ Item { SettingsRow { body: Column { - width: parent.width - Theme.spacingM * 2 - x: Theme.spacingM + width: parent.width spacing: Theme.spacingM Row { diff --git a/quickshell/Modules/Settings/DisplayWidgetsTab.qml b/quickshell/Modules/Settings/DisplayWidgetsTab.qml index b4aaff216..a08276cee 100644 --- a/quickshell/Modules/Settings/DisplayWidgetsTab.qml +++ b/quickshell/Modules/Settings/DisplayWidgetsTab.qml @@ -1,5 +1,4 @@ import QtQuick -import QtQuick.Layouts import Quickshell import qs.Common import qs.Modules.Settings.Widgets @@ -15,12 +14,9 @@ Item { function getBarComponentsFromSettings() { const bars = SettingsData.barConfigs || []; return bars.map(bar => { - const isIsland = SettingsData.isIslandBarConfig(bar); return { "id": "bar:" + bar.id, "name": bar.name || "Bar", - "description": isIsland ? I18n.tr("Dank Island instance") : I18n.tr("Individual bar configuration"), - "icon": isIsland ? "view_in_ar" : "toolbar", "barId": bar.id }; }); @@ -32,28 +28,23 @@ Item { return [...getBarComponentsFromSettings(), { "id": "notifications", - "name": I18n.tr("Notification popups"), - "icon": "notifications" + "name": I18n.tr("Notification popups") }, { "id": "wallpaper", - "name": I18n.tr("Wallpaper"), - "icon": "wallpaper" + "name": I18n.tr("Wallpaper") }, { "id": "osd", - "name": I18n.tr("OSD", "on-screen display, shell component name in per-display settings"), - "icon": "picture_in_picture" + "name": I18n.tr("OSD", "on-screen display, shell component name in per-display settings") }, { "id": "toast", - "name": I18n.tr("Toasts", "noun plural, toast popups, shell component name in per-display settings"), - "icon": "campaign" + "name": I18n.tr("Toasts", "noun plural, toast popups, shell component name in per-display settings") }, { "id": "notepad", - "name": I18n.tr("Notepad"), - "icon": "sticky_note_2" + "name": I18n.tr("Notepad") } ]; } @@ -114,398 +105,66 @@ Item { SettingsPage { id: mainColumn - StyledRect { - width: parent.width - height: screensInfoSection.implicitHeight + Theme.spacingL * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth + SettingsCard { + title: I18n.tr("Available displays (%1)", "display widgets settings heading, %1 is the monitor count").arg(Quickshell.screens.length) - Column { - id: screensInfoSection - - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingM - - Row { - width: parent.width - spacing: Theme.spacingM - - DankIcon { - name: "monitor" - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - width: parent.width - Theme.iconSize - Theme.spacingM - spacing: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - - StyledText { - text: I18n.tr("Connected displays") - font.pixelSize: Theme.fontSizeLarge - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } + SettingsButtonGroupRow { + id: displayModeGroup + readonly property bool modelMode: SettingsData.displayNameMode === "model" + text: I18n.tr("Name format") + model: [I18n.tr("Name"), I18n.tr("Model")] + currentIndex: modelMode ? 1 : 0 + onModelModeChanged: currentIndex = modelMode ? 1 : 0 + onSelectionChanged: (index, selected) => { + if (!selected) + return; + SettingsData.displayNameMode = index === 1 ? "model" : "system"; + SettingsData.saveSettings(); } + } - Column { - width: parent.width - spacing: Theme.spacingS + Repeater { + model: Quickshell.screens - Column { - width: parent.width - spacing: Theme.spacingXS + SettingsRow { + required property var modelData + readonly property var currentMode: WlrOutputService.wlrOutputAvailable ? WlrOutputService.getOutput(modelData.name)?.currentMode : null - Row { - width: parent.width - spacing: Theme.spacingM - - StyledText { - text: I18n.tr("Available displays (%1)", "display widgets settings heading, %1 is the monitor count").arg(Quickshell.screens.length) - font.pixelSize: Theme.fontSizeMedium - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - horizontalAlignment: Text.AlignLeft - } - - Item { - width: 1 - height: 1 - Layout.fillWidth: true - } - - Column { - spacing: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - - StyledText { - text: I18n.tr("Name format") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - - DankButtonGroup { - id: displayModeGroup - model: [I18n.tr("Name"), I18n.tr("Model")] - currentIndex: SettingsData.displayNameMode === "model" ? 1 : 0 - onSelectionChanged: (index, selected) => { - if (!selected) - return; - SettingsData.displayNameMode = index === 1 ? "model" : "system"; - SettingsData.saveSettings(); - } - - Connections { - target: SettingsData - function onDisplayNameModeChanged() { - displayModeGroup.currentIndex = SettingsData.displayNameMode === "model" ? 1 : 0; - } - } - } - } - } - } - - Repeater { - model: Quickshell.screens - - delegate: Rectangle { - width: parent.width - height: screenRow.implicitHeight + Theme.spacingS * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth - - Row { - id: screenRow - - anchors.fill: parent - anchors.margins: Theme.spacingS - spacing: Theme.spacingM - - DankIcon { - name: "desktop_windows" - size: Theme.iconSizeMedium - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - width: parent.width - Theme.iconSize - Theme.spacingM * 2 - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS / 2 - - StyledText { - text: SettingsData.getScreenDisplayName(modelData) - font.pixelSize: Theme.fontSizeMedium - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - Row { - width: parent.width - spacing: Theme.spacingS - - property var wlrOutput: WlrOutputService.wlrOutputAvailable ? WlrOutputService.getOutput(modelData.name) : null - property var currentMode: wlrOutput?.currentMode - - StyledText { - text: { - if (parent.currentMode) { - return parent.currentMode.width + "×" + parent.currentMode.height + "@" + Math.round(parent.currentMode.refresh / 1000) + "Hz"; - } - return modelData.width + "×" + modelData.height; - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: "•" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: SettingsData.displayNameMode === "system" ? (modelData.model || "Unknown Model") : modelData.name - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - } - } - } - } + iconName: "desktop_windows" + title: SettingsData.getScreenDisplayName(modelData) + subtitle: { + const size = currentMode ? currentMode.width + "×" + currentMode.height + "@" + Math.round(currentMode.refresh / 1000) + "Hz" : modelData.width + "×" + modelData.height; + return size + " · " + (SettingsData.displayNameMode === "system" ? (modelData.model || I18n.tr("Unknown Model")) : modelData.name); } } } } - Column { - width: parent.width - spacing: Theme.spacingL + Repeater { + model: root.variantComponents - Repeater { - model: root.variantComponents + SettingsCard { + id: componentCard + required property var modelData - delegate: StyledRect { - width: parent.width - height: componentSection.implicitHeight + Theme.spacingL * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth + title: modelData.name - Column { - id: componentSection + SettingsDisplayPicker { + displayPreferences: root.getScreenPreferences(componentCard.modelData.id) + emptyMeansAll: false + allowEmpty: true + showLastDisplay: ["notifications", "osd", "toast", "notepad"].includes(componentCard.modelData.id) || componentCard.modelData.id.startsWith("bar:") + showOnLastDisplay: root.getShowOnLastDisplay(componentCard.modelData.id) + onPreferencesChanged: prefs => root.setScreenPreferences(componentCard.modelData.id, prefs) + onLastDisplayToggled: checked => root.setShowOnLastDisplay(componentCard.modelData.id, checked) + } - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingM - - Row { - width: parent.width - spacing: Theme.spacingM - - DankIcon { - name: modelData.icon - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - width: parent.width - Theme.iconSize - Theme.spacingM - spacing: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - - StyledText { - text: modelData.name - font.pixelSize: Theme.fontSizeLarge - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - StyledText { - visible: text !== "" - text: modelData.description ?? "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - wrapMode: Text.WordWrap - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - } - - SettingsDisplayPicker { - readonly property string componentId: modelData.id - visible: componentId !== "dock" - displayPreferences: root.getScreenPreferences(componentId) - emptyMeansAll: false - allowEmpty: true - showLastDisplay: ["dankBar", "notifications", "osd", "toast", "notepad"].includes(componentId) || componentId.startsWith("bar:") - showOnLastDisplay: root.getShowOnLastDisplay(componentId) - onPreferencesChanged: prefs => root.setScreenPreferences(componentId, prefs) - onLastDisplayToggled: checked => root.setShowOnLastDisplay(componentId, checked) - } - - SettingsToggleRow { - resetKeys: ["notificationFocusedMonitor"] - visible: modelData.id === "notifications" - text: I18n.tr("Focused display only") - checked: SettingsData.notificationFocusedMonitor - onToggled: checked => SettingsData.set("notificationFocusedMonitor", checked) - } - - Column { - visible: modelData.id === "dock" - width: parent.width - spacing: Theme.spacingS - - StyledText { - text: I18n.tr("Show on displays") + ":" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Theme.fontWeightMedium - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - Column { - property string componentId: modelData.id - - width: parent.width - spacing: Theme.spacingXS - - DankToggle { - width: parent.width - text: I18n.tr("All displays") - checked: { - var prefs = root.getScreenPreferences(parent.componentId); - return prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all"); - } - onToggled: checked => { - if (checked) { - root.setScreenPreferences(parent.componentId, ["all"]); - } else { - root.setScreenPreferences(parent.componentId, []); - const cid = parent.componentId; - if (["dankBar", "notifications", "osd", "toast"].includes(cid) || cid.startsWith("bar:")) { - root.setShowOnLastDisplay(cid, true); - } - } - } - } - - DankToggle { - width: parent.width - text: I18n.tr("Focused display only") - visible: parent.componentId === "notifications" - checked: SettingsData.notificationFocusedMonitor - onToggled: checked => SettingsData.set("notificationFocusedMonitor", checked) - } - - DankToggle { - width: parent.width - text: I18n.tr("Show on last display") - checked: root.getShowOnLastDisplay(parent.componentId) - visible: { - const prefs = root.getScreenPreferences(parent.componentId); - const isAll = prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all"); - const cid = parent.componentId; - const isRelevantComponent = ["dankBar", "notifications", "osd", "toast", "notepad"].includes(cid) || cid.startsWith("bar:"); - return !isAll && isRelevantComponent; - } - onToggled: checked => { - root.setShowOnLastDisplay(parent.componentId, checked); - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outline - opacity: 0.2 - visible: { - var prefs = root.getScreenPreferences(parent.componentId); - return !prefs.includes("all") && !(typeof prefs[0] === "string" && prefs[0] === "all"); - } - } - - Column { - width: parent.width - spacing: Theme.spacingXS - visible: { - var prefs = root.getScreenPreferences(parent.componentId); - return !prefs.includes("all") && !(typeof prefs[0] === "string" && prefs[0] === "all"); - } - - Repeater { - model: Quickshell.screens - - delegate: DankToggle { - property var screenData: modelData - property string componentId: parent.parent.componentId - - width: parent.width - text: SettingsData.getScreenDisplayName(screenData) - description: screenData.width + "×" + screenData.height + " • " + (SettingsData.displayNameMode === "system" ? (screenData.model || "Unknown Model") : screenData.name) - checked: { - var prefs = root.getScreenPreferences(componentId); - if (typeof prefs[0] === "string" && prefs[0] === "all") - return false; - return SettingsData.isScreenInPreferences(screenData, prefs); - } - onToggled: checked => { - var currentPrefs = root.getScreenPreferences(componentId); - if (typeof currentPrefs[0] === "string" && currentPrefs[0] === "all") { - currentPrefs = []; - } - - const screenModelIndex = SettingsData.getScreenModelIndex(screenData); - - var newPrefs = currentPrefs.filter(pref => { - if (typeof pref === "string") - return false; - if (pref.modelIndex !== undefined && screenModelIndex >= 0) { - return !(pref.model === screenData.model && pref.modelIndex === screenModelIndex); - } - return pref.name !== screenData.name || pref.model !== screenData.model; - }); - - if (checked) { - const prefObj = { - "name": screenData.name, - "model": screenData.model || "" - }; - if (screenModelIndex >= 0) { - prefObj.modelIndex = screenModelIndex; - } - newPrefs.push(prefObj); - } - - root.setScreenPreferences(componentId, newPrefs); - } - } - } - } - } - } - } + SettingsToggleRow { + resetKeys: ["notificationFocusedMonitor"] + visible: componentCard.modelData.id === "notifications" + text: I18n.tr("Focused display only") + checked: SettingsData.notificationFocusedMonitor + onToggled: checked => SettingsData.set("notificationFocusedMonitor", checked) } } } diff --git a/quickshell/Modules/Settings/GammaControlTab.qml b/quickshell/Modules/Settings/GammaControlTab.qml index 94922b1ce..af43230ce 100644 --- a/quickshell/Modules/Settings/GammaControlTab.qml +++ b/quickshell/Modules/Settings/GammaControlTab.qml @@ -8,482 +8,250 @@ import "../../Common/Format.js" as Format Item { id: root + component StatusTile: Rectangle { + id: tile + + property string iconName: "" + property color iconColor: Theme.primary + property string value: "" + property string label: "" + + width: (parent.width - Theme.spacingM) / 2 + height: tileColumn.implicitHeight + Theme.spacingM * 2 + radius: Theme.cornerRadius + color: Theme.floatingWindowNestedSurface + border.color: Theme.outlineMedium + border.width: Theme.layerOutlineWidth + + Column { + id: tileColumn + anchors.centerIn: parent + spacing: Theme.spacingXS + + DankIcon { + name: tile.iconName + size: Theme.iconSize + color: tile.iconColor + anchors.horizontalCenter: parent.horizontalCenter + } + + StyledText { + text: tile.value + font.pixelSize: Theme.fontSizeLarge + font.weight: Theme.fontWeightMedium + color: Theme.surfaceText + anchors.horizontalCenter: parent.horizontalCenter + } + + StyledText { + text: tile.label + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + SettingsPage { id: mainColumn - StyledRect { - width: parent.width - height: gammaSection.implicitHeight + Theme.spacingL * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth + SettingsCard { + visible: NightModeService.gammaAdjustAvailable + + SettingsSliderRow { + settingKey: "displayGamma" + resetStore: SessionData + resetKeys: ["displayGamma"] + tags: ["gamma", "display", "panel", "washed out", "brightness"] + text: I18n.tr("Gamma") + minimum: 50 + maximum: 200 + step: 5 + unit: "" + decimals: 2 + value: Math.round(SessionData.displayGamma * 100) + onSliderValueChanged: newValue => NightModeService.setDisplayGamma(newValue / 100) + } + + SettingsSliderRow { + settingKey: "displayContrast" + resetStore: SessionData + resetKeys: ["displayContrast"] + tags: ["contrast", "display", "panel", "washed out"] + text: I18n.tr("Contrast") + minimum: 50 + maximum: 200 + step: 5 + value: Math.round(SessionData.displayContrast * 100) + onSliderValueChanged: newValue => NightModeService.setDisplayContrast(newValue / 100) + } + } + + SettingsCard { + SettingsToggleRow { + text: I18n.tr("Night mode") + description: NightModeService.gammaControlAvailable ? "" : I18n.tr("Gamma control not available. Requires DMS API v6+.") + checked: NightModeService.nightModeEnabled + enabled: NightModeService.gammaControlAvailable + onToggled: NightModeService.toggleNightMode() + } + + SettingsSliderRow { + settingKey: "nightModeTemperature" + resetStore: SessionData + resetKeys: ["nightModeTemperature"] + tags: ["gamma", "night", "temperature", "kelvin", "warm", "color", "blue light"] + visible: NightModeService.gammaControlAvailable + text: SessionData.nightModeAutoEnabled ? I18n.tr("Night temperature") : I18n.tr("Color Temperature", "Color Temperature") + minimum: 1000 + maximum: 6000 + step: 100 + unit: "K" + value: SessionData.nightModeTemperature + onSliderValueChanged: newValue => { + SessionData.setNightModeTemperature(newValue); + if (SessionData.nightModeHighTemperature < newValue) + SessionData.setNightModeHighTemperature(newValue); + } + } + + SettingsSliderRow { + settingKey: "nightModeHighTemperature" + resetStore: SessionData + resetKeys: ["nightModeHighTemperature"] + tags: ["gamma", "day", "temperature", "kelvin", "color"] + visible: NightModeService.gammaControlAvailable && SessionData.nightModeAutoEnabled + text: I18n.tr("Day temperature") + minimum: SessionData.nightModeTemperature + maximum: 10000 + step: 100 + unit: "K" + value: Math.max(SessionData.nightModeHighTemperature, SessionData.nightModeTemperature) + onSliderValueChanged: newValue => SessionData.setNightModeHighTemperature(newValue) + } + + SettingsToggleRow { + text: I18n.tr("Automatic control") + checked: SessionData.nightModeAutoEnabled + visible: NightModeService.gammaControlAvailable + onToggled: checked => { + if (checked !== NightModeService.nightModeEnabled) + NightModeService.toggleNightMode(); + SessionData.setNightModeAutoEnabled(checked); + } + } + } + + SettingsCard { + visible: SessionData.nightModeAutoEnabled && NightModeService.gammaControlAvailable + + SettingsButtonGroupRow { + id: autoModeGroup + readonly property bool locationMode: SessionData.nightModeAutoMode === "location" + text: I18n.tr("Mode", "noun, setting label, e.g. wallpaper cycling mode, wifi mode, display mode") + model: [I18n.tr("Time"), I18n.tr("Location")] + currentIndex: locationMode ? 1 : 0 + onLocationModeChanged: currentIndex = locationMode ? 1 : 0 + onSelectionChanged: (index, selected) => { + if (!selected) + return; + SessionData.setNightModeAutoMode(index === 1 ? "location" : "time"); + } + } + + SettingsTimeRow { + visible: !autoModeGroup.locationMode + is24Hour: SettingsData.use24HourClock + startTitle: I18n.tr("Start") + startHour: SessionData.nightModeStartHour + startMinute: SessionData.nightModeStartMinute + endTitle: I18n.tr("End", "noun, end time label for night mode schedule or calendar event") + endHour: SessionData.nightModeEndHour + endMinute: SessionData.nightModeEndMinute + onStartChanged: (hour, minute) => { + SessionData.setNightModeStartHour(hour); + SessionData.setNightModeStartMinute(minute); + } + onEndChanged: (hour, minute) => { + SessionData.setNightModeEndHour(hour); + SessionData.setNightModeEndMinute(minute); + } + } + + SettingsSliderRow { + settingKey: "nightModeTransitionMinutes" + resetStore: SessionData + resetKeys: ["nightModeTransitionMinutes"] + tags: ["gamma", "night", "transition", "duration", "fade"] + text: I18n.tr("Transition duration") + minimum: 0 + maximum: 180 + step: 5 + unit: "min" + value: SessionData.nightModeTransitionMinutes + visible: !autoModeGroup.locationMode && DMSService.apiVersion >= 32 + onSliderValueChanged: newValue => SessionData.setNightModeTransitionMinutes(newValue) + } + + SettingsLocationSection { + visible: autoModeGroup.locationMode + description: "" + } + } + + SettingsCard { + title: I18n.tr("Current status") + visible: SessionData.nightModeAutoEnabled && NightModeService.gammaControlAvailable && NightModeService.nightModeEnabled && NightModeService.gammaCurrentTemp > 0 Column { - id: gammaSection - - anchors.fill: parent - anchors.margins: Theme.spacingL spacing: Theme.spacingM - Column { + Row { width: parent.width - spacing: Theme.spacingS - leftPadding: Theme.spacingM - rightPadding: Theme.spacingM - visible: NightModeService.gammaAdjustAvailable + spacing: Theme.spacingM - SettingsSliderRow { - settingKey: "displayGamma" - resetStore: SessionData - resetKeys: ["displayGamma"] - tags: ["gamma", "display", "panel", "washed out", "brightness"] - width: parent.width - parent.leftPadding - parent.rightPadding - text: I18n.tr("Gamma") - minimum: 50 - maximum: 200 - step: 5 - unit: "" - decimals: 2 - value: Math.round(SessionData.displayGamma * 100) - onSliderValueChanged: newValue => NightModeService.setDisplayGamma(newValue / 100) + StatusTile { + iconName: "device_thermostat" + value: NightModeService.gammaCurrentTemp + "K" + label: I18n.tr("Current temperature") } - SettingsSliderRow { - settingKey: "displayContrast" - resetStore: SessionData - resetKeys: ["displayContrast"] - tags: ["contrast", "display", "panel", "washed out"] - width: parent.width - parent.leftPadding - parent.rightPadding - text: I18n.tr("Contrast") - minimum: 50 - maximum: 200 - step: 5 - value: Math.round(SessionData.displayContrast * 100) - onSliderValueChanged: newValue => NightModeService.setDisplayContrast(newValue / 100) + StatusTile { + iconName: NightModeService.gammaIsDay ? "wb_sunny" : "nightlight" + iconColor: NightModeService.gammaIsDay ? Theme.warning : Theme.secondary + value: NightModeService.gammaIsDay ? I18n.tr("Daytime", "night mode status label, current period is day") : I18n.tr("Night") + label: I18n.tr("Current period") } } - DankToggle { - id: nightModeToggle - + Row { width: parent.width - text: I18n.tr("Night mode") - description: NightModeService.gammaControlAvailable ? "" : I18n.tr("Gamma control not available. Requires DMS API v6+.") - checked: NightModeService.nightModeEnabled - enabled: NightModeService.gammaControlAvailable - onToggled: checked => { - NightModeService.toggleNightMode(); + spacing: Theme.spacingM + visible: autoModeGroup.locationMode && (NightModeService.gammaSunriseTime || NightModeService.gammaSunsetTime) + + StatusTile { + visible: NightModeService.gammaSunriseTime + iconName: "wb_twilight" + iconColor: Theme.warning + value: Format.formatIsoTime(NightModeService.gammaSunriseTime) + label: I18n.tr("Sunrise") } - Connections { - function onNightModeEnabledChanged() { - nightModeToggle.checked = NightModeService.nightModeEnabled; - } - - target: NightModeService + StatusTile { + visible: NightModeService.gammaSunsetTime + iconName: "wb_twilight" + iconColor: Theme.secondary + value: Format.formatIsoTime(NightModeService.gammaSunsetTime) + label: I18n.tr("Sunset") } } + } - Column { - width: parent.width - spacing: Theme.spacingS - leftPadding: Theme.spacingM - rightPadding: Theme.spacingM - visible: NightModeService.gammaControlAvailable - - SettingsSliderRow { - id: nightTempSlider - settingKey: "nightModeTemperature" - resetStore: SessionData - resetKeys: ["nightModeTemperature"] - tags: ["gamma", "night", "temperature", "kelvin", "warm", "color", "blue light"] - width: parent.width - parent.leftPadding - parent.rightPadding - text: SessionData.nightModeAutoEnabled ? I18n.tr("Night temperature") : I18n.tr("Color Temperature", "Color Temperature") - minimum: 1000 - maximum: 6000 - step: 100 - unit: "K" - value: SessionData.nightModeTemperature - onSliderValueChanged: newValue => { - SessionData.setNightModeTemperature(newValue); - if (SessionData.nightModeHighTemperature < newValue) - SessionData.setNightModeHighTemperature(newValue); - } - } - - SettingsSliderRow { - id: dayTempSlider - settingKey: "nightModeHighTemperature" - resetStore: SessionData - resetKeys: ["nightModeHighTemperature"] - tags: ["gamma", "day", "temperature", "kelvin", "color"] - width: parent.width - parent.leftPadding - parent.rightPadding - text: I18n.tr("Day temperature") - minimum: SessionData.nightModeTemperature - maximum: 10000 - step: 100 - unit: "K" - value: Math.max(SessionData.nightModeHighTemperature, SessionData.nightModeTemperature) - visible: SessionData.nightModeAutoEnabled - onSliderValueChanged: newValue => SessionData.setNightModeHighTemperature(newValue) - } - } - - DankToggle { - id: automaticToggle - width: parent.width - text: I18n.tr("Automatic control") - checked: SessionData.nightModeAutoEnabled - visible: NightModeService.gammaControlAvailable - onToggled: checked => { - if (checked && !NightModeService.nightModeEnabled) { - NightModeService.toggleNightMode(); - } else if (!checked && NightModeService.nightModeEnabled) { - NightModeService.toggleNightMode(); - } - SessionData.setNightModeAutoEnabled(checked); - } - - Connections { - target: SessionData - function onNightModeAutoEnabledChanged() { - automaticToggle.checked = SessionData.nightModeAutoEnabled; - } - } - } - - Column { - id: automaticSettings - width: parent.width - spacing: Theme.spacingS - visible: SessionData.nightModeAutoEnabled && NightModeService.gammaControlAvailable - - Connections { - target: SessionData - function onNightModeAutoEnabledChanged() { - automaticSettings.visible = SessionData.nightModeAutoEnabled; - } - } - - Item { - width: parent.width - height: modeTabBarNight.height + Theme.spacingM - - DankTabBar { - id: modeTabBarNight - width: 200 - tabHeight: 45 - anchors.horizontalCenter: parent.horizontalCenter - model: [ - { - "text": I18n.tr("Time"), - "icon": "access_time" - }, - { - "text": I18n.tr("Location"), - "icon": "place" - } - ] - - Component.onCompleted: { - currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0; - Qt.callLater(updateIndicator); - } - - onTabClicked: index => { - SessionData.setNightModeAutoMode(index === 1 ? "location" : "time"); - currentIndex = index; - } - - Connections { - target: SessionData - function onNightModeAutoModeChanged() { - modeTabBarNight.currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0; - Qt.callLater(modeTabBarNight.updateIndicator); - } - } - } - } - - SettingsTimeRow { - visible: SessionData.nightModeAutoMode === "time" - is24Hour: SettingsData.use24HourClock - startTitle: I18n.tr("Start") - startHour: SessionData.nightModeStartHour - startMinute: SessionData.nightModeStartMinute - endTitle: I18n.tr("End", "noun, end time label for night mode schedule or calendar event") - endHour: SessionData.nightModeEndHour - endMinute: SessionData.nightModeEndMinute - onStartChanged: (hour, minute) => { - SessionData.setNightModeStartHour(hour); - SessionData.setNightModeStartMinute(minute); - } - onEndChanged: (hour, minute) => { - SessionData.setNightModeEndHour(hour); - SessionData.setNightModeEndMinute(minute); - } - } - - SettingsSliderRow { - settingKey: "nightModeTransitionMinutes" - resetStore: SessionData - resetKeys: ["nightModeTransitionMinutes"] - tags: ["gamma", "night", "transition", "duration", "fade"] - width: parent.width - text: I18n.tr("Transition duration") - minimum: 0 - maximum: 180 - step: 5 - unit: "min" - value: SessionData.nightModeTransitionMinutes - visible: (SessionData.nightModeAutoMode === "time") && (DMSService.apiVersion >= 32) - onSliderValueChanged: newValue => SessionData.setNightModeTransitionMinutes(newValue) - } - - SettingsLocationSection { - width: parent.width - visible: SessionData.nightModeAutoMode === "location" - description: "" - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outline - opacity: 0.2 - visible: gammaStatusSection.visible - } - - Column { - id: gammaStatusSection - width: parent.width - spacing: Theme.spacingM - visible: NightModeService.nightModeEnabled && NightModeService.gammaCurrentTemp > 0 - - Row { - width: parent.width - spacing: Theme.spacingS - - DankIcon { - name: NightModeService.gammaIsDay ? "light_mode" : "dark_mode" - size: Theme.iconSizeSmall - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Current status") - font.pixelSize: Theme.fontSizeMedium - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - - Rectangle { - width: (parent.width - Theme.spacingM) / 2 - height: tempColumn.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth - - Column { - id: tempColumn - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: "device_thermostat" - size: Theme.iconSize - color: Theme.primary - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: NightModeService.gammaCurrentTemp + "K" - font.pixelSize: Theme.fontSizeLarge - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("Current temperature") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - Rectangle { - width: (parent.width - Theme.spacingM) / 2 - height: periodColumn.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth - - Column { - id: periodColumn - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: NightModeService.gammaIsDay ? "wb_sunny" : "nightlight" - size: Theme.iconSize - color: NightModeService.gammaIsDay ? "#FFA726" : "#7E57C2" - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: NightModeService.gammaIsDay ? I18n.tr("Daytime", "night mode status label, current period is day") : I18n.tr("Night") - font.pixelSize: Theme.fontSizeLarge - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("Current period") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: SessionData.nightModeAutoMode === "location" && (NightModeService.gammaSunriseTime || NightModeService.gammaSunsetTime) - - Rectangle { - width: (parent.width - Theme.spacingM) / 2 - height: sunriseColumn.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth - visible: NightModeService.gammaSunriseTime - - Column { - id: sunriseColumn - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: "wb_twilight" - size: Theme.iconSize - color: "#FF7043" - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: Format.formatIsoTime(NightModeService.gammaSunriseTime) - font.pixelSize: Theme.fontSizeLarge - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("Sunrise") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - Rectangle { - width: (parent.width - Theme.spacingM) / 2 - height: sunsetColumn.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth - visible: NightModeService.gammaSunsetTime - - Column { - id: sunsetColumn - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: "wb_twilight" - size: Theme.iconSize - color: "#5C6BC0" - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: Format.formatIsoTime(NightModeService.gammaSunsetTime) - font.pixelSize: Theme.fontSizeLarge - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("Sunset") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - } - - Rectangle { - width: parent.width - height: nextChangeRow.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.floatingWindowNestedSurface - border.color: Theme.outlineMedium - border.width: Theme.layerOutlineWidth - visible: NightModeService.gammaNextTransition - - Row { - id: nextChangeRow - anchors.centerIn: parent - spacing: Theme.spacingM - - DankIcon { - name: "schedule" - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - spacing: Theme.spacingXXS - anchors.verticalCenter: parent.verticalCenter - - StyledText { - text: I18n.tr("Next Transition") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: Format.formatIsoTime(NightModeService.gammaNextTransition) - font.pixelSize: Theme.fontSizeMedium - font.weight: Theme.fontWeightMedium - color: Theme.surfaceText - } - } - } - } - } - } + SettingsRow { + visible: NightModeService.gammaNextTransition + iconName: "schedule" + title: I18n.tr("Next Transition") + subtitle: Format.formatIsoTime(NightModeService.gammaNextTransition) } } } diff --git a/quickshell/Modules/Settings/KeybindsTab.qml b/quickshell/Modules/Settings/KeybindsTab.qml index 2e13529f7..26bdc1807 100644 --- a/quickshell/Modules/Settings/KeybindsTab.qml +++ b/quickshell/Modules/Settings/KeybindsTab.qml @@ -11,8 +11,6 @@ import qs.Widgets Item { id: keybindsTab - readonly property int contentMaxWidth: 650 - LayoutMirroring.enabled: I18n.isRtl LayoutMirroring.childrenInherit: true @@ -472,7 +470,7 @@ Item { bottomPadding: Theme.spacingXL StyledRect { - width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) height: headerSection.implicitHeight + Theme.spacingL * 2 anchors.horizontalCenter: parent.horizontalCenter radius: Theme.cornerRadius @@ -557,7 +555,7 @@ Item { StyledRect { id: warningBox - width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) height: warningSection.implicitHeight + Theme.spacingL * 2 anchors.horizontalCenter: parent.horizontalCenter radius: Theme.cornerRadius @@ -646,7 +644,7 @@ Item { } StyledRect { - width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) height: categorySection.implicitHeight + Theme.spacingL * 2 anchors.horizontalCenter: parent.horizontalCenter radius: Theme.cornerRadius @@ -727,7 +725,7 @@ Item { } SettingsGroup { - width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) anchors.horizontalCenter: parent.horizontalCenter visible: keybindsTab.hasEditDraft && (keybindsTab.reviewingEdit || keybindsTab.editError !== "" || keybindsTab.editDraft.operation !== "set") @@ -788,7 +786,7 @@ Item { } StyledRect { - width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) height: newBindSection.implicitHeight + Theme.spacingL * 2 anchors.horizontalCenter: parent.horizontalCenter radius: Theme.cornerRadius @@ -859,7 +857,7 @@ Item { } StyledRect { - width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) height: bindsListHeader.implicitHeight + Theme.spacingL * 2 anchors.horizontalCenter: parent.horizontalCenter radius: Theme.cornerRadius @@ -957,7 +955,7 @@ Item { KeybindItem { id: bindItem - width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2) + width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2) anchors.horizontalCenter: parent.horizontalCenter bindData: modelData isExpanded: keybindsTab.expandedKey === modelData.action diff --git a/quickshell/Modules/Settings/LockScreenTab.qml b/quickshell/Modules/Settings/LockScreenTab.qml index eb82cfa88..d9d194dc5 100644 --- a/quickshell/Modules/Settings/LockScreenTab.qml +++ b/quickshell/Modules/Settings/LockScreenTab.qml @@ -578,8 +578,7 @@ Item { SettingsRow { visible: SettingsData.lockScreenSecurityKeyShortcutEnabled && SettingsData.enableU2f && SettingsData.u2fMode === "or" && !root.lockU2fControlledByPrimary body: Row { - width: parent.width - Theme.spacingM * 2 - x: Theme.spacingM + width: parent.width spacing: Theme.spacingM Column { diff --git a/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml b/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml index 222597a93..15a19e9fb 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsToggleCard.qml @@ -65,16 +65,15 @@ Item { Item { width: parent.width - height: root.hasContent ? expandedContent.height + Theme.spacingM : 0 + height: root.hasContent ? expandedContent.height : 0 Column { id: expandedContent enabled: root.checked anchors.left: parent.left anchors.right: parent.right - anchors.leftMargin: SettingsMetrics.rowPaddingH - anchors.rightMargin: SettingsMetrics.rowPaddingH - spacing: Theme.spacingM + anchors.leftMargin: root.iconName !== "" ? Theme.iconSize + Theme.spacingL : 0 + spacing: 0 } } } diff --git a/quickshell/Modules/Settings/WindowRulesTab.qml b/quickshell/Modules/Settings/WindowRulesTab.qml index 11a982261..45c8599be 100644 --- a/quickshell/Modules/Settings/WindowRulesTab.qml +++ b/quickshell/Modules/Settings/WindowRulesTab.qml @@ -12,8 +12,6 @@ import qs.Modules.Settings.Widgets Item { id: root - readonly property int contentMaxWidth: 650 - LayoutMirroring.enabled: I18n.isRtl LayoutMirroring.childrenInherit: true @@ -301,7 +299,6 @@ Item { SettingsPage { id: flickable - contentMaxWidth: root.contentMaxWidth SettingsCard { id: headerSection diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index 50c9e50d9..9a0a9068b 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -9379,40 +9379,9 @@ "parentLabel": "Displays", "description": "Night mode, gamma, contrast" }, - { - "section": "nightModeTemperature", - "label": "Night temperature", - "tabIndex": 25, - "category": "Gamma control", - "keywords": [ - "blue light", - "celsius", - "color", - "color temperature", - "control", - "displays", - "fahrenheit", - "gamma", - "kelvin", - "monitor", - "monitors", - "night", - "night light", - "output", - "outputs", - "redshift", - "resolution", - "screen", - "screens", - "temp", - "temperature", - "warm" - ], - "parentLabel": "Displays" - }, { "section": "nightModeTransitionMinutes", - "label": "Transition duration", + "label": "Mode", "tabIndex": 25, "category": "Gamma control", "keywords": [ @@ -9423,6 +9392,7 @@ "duration", "fade", "gamma", + "mode", "monitor", "monitors", "night", @@ -9437,6 +9407,38 @@ ], "parentLabel": "Displays" }, + { + "section": "nightModeTemperature", + "label": "Night mode", + "tabIndex": 25, + "category": "Gamma control", + "keywords": [ + "available", + "blue light", + "color", + "color temperature", + "control", + "displays", + "gamma", + "kelvin", + "mode", + "monitor", + "monitors", + "night", + "night light", + "output", + "outputs", + "redshift", + "requires", + "resolution", + "screen", + "screens", + "temperature", + "warm" + ], + "parentLabel": "Displays", + "description": "Gamma control not available. Requires DMS API v6+." + }, { "section": "_tab_26", "label": "Display assignment",