From ee1a2bc7dec320f72af42e6c04b7e68b66cc551d Mon Sep 17 00:00:00 2001 From: Jonas Bloch <128738169+Silzinc@users.noreply.github.com> Date: Sun, 1 Mar 2026 02:37:16 +0100 Subject: [PATCH] feat: add setting for first day of the week (#1854) * feat: add setting for first day of the week * fix: extract settings indices * fix: formatting mistake * fix(ui): add outline rectangle between settings and reorder settings * fix: don't set firstDayOfWeek automatically to system's locale --- quickshell/Common/SettingsData.qml | 1 + quickshell/Common/settings/SettingsSpec.js | 1 + .../Overview/CalendarOverviewCard.qml | 11 +- .../Modules/Settings/TimeWeatherTab.qml | 39 ++++ .../translations/settings_search_index.json | 173 +++++++++++++----- 5 files changed, 179 insertions(+), 46 deletions(-) diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 7b585ff9..9a901ef6 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -149,6 +149,7 @@ Singleton { property int mangoLayoutRadiusOverride: -1 property int mangoLayoutBorderSize: -1 + property int firstDayOfWeek: -1 property bool use24HourClock: true property bool showSeconds: false property bool padHours12Hour: false diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index 9a94d6e2..3abf845d 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -32,6 +32,7 @@ var SPEC = { mangoLayoutRadiusOverride: { def: -1, onChange: "updateCompositorLayout" }, mangoLayoutBorderSize: { def: -1, onChange: "updateCompositorLayout" }, + firstDayOfWeek: { def: -1 }, use24HourClock: { def: true }, showSeconds: { def: false }, padHours12Hour: { def: false }, diff --git a/quickshell/Modules/DankDash/Overview/CalendarOverviewCard.qml b/quickshell/Modules/DankDash/Overview/CalendarOverviewCard.qml index 1ee5b613..a401422f 100644 --- a/quickshell/Modules/DankDash/Overview/CalendarOverviewCard.qml +++ b/quickshell/Modules/DankDash/Overview/CalendarOverviewCard.qml @@ -14,8 +14,15 @@ Rectangle { signal closeDash + function weekStartQt() { + if (SettingsData.firstDayOfWeek >= 7 || SettingsData.firstDayOfWeek < 0) { + return Qt.locale().firstDayOfWeek; + } + return SettingsData.firstDayOfWeek; + } + function weekStartJs() { - return Qt.locale().firstDayOfWeek % 7; + return weekStartQt() % 7; } function startOfWeek(dateObj) { @@ -223,7 +230,7 @@ Rectangle { Repeater { model: { const days = []; - const qtFirst = Qt.locale().firstDayOfWeek; + const qtFirst = weekStartQt(); for (let i = 0; i < 7; ++i) { const qtDay = ((qtFirst - 1 + i) % 7) + 1; days.push(I18n.locale().dayName(qtDay, Locale.ShortFormat)); diff --git a/quickshell/Modules/Settings/TimeWeatherTab.qml b/quickshell/Modules/Settings/TimeWeatherTab.qml index e533004c..6cbcf108 100644 --- a/quickshell/Modules/Settings/TimeWeatherTab.qml +++ b/quickshell/Modules/Settings/TimeWeatherTab.qml @@ -9,6 +9,16 @@ import qs.Modules.Settings.Widgets Item { id: root + function weekStartQt() { + if (SettingsData.firstDayOfWeek >= 7 || SettingsData.firstDayOfWeek < 0) { + return Qt.locale().firstDayOfWeek; + } + return SettingsData.firstDayOfWeek; + } + function weekStartJs() { + return weekStartQt() % 7; + } + DankFlickable { anchors.fill: parent clip: true @@ -69,6 +79,35 @@ Item { settingKey: "dateFormat" iconName: "calendar_today" + SettingsDropdownRow { + tab: "time" + tags: ["first", "day", "week"] + settingKey: "firstDayOfWeek" + text: I18n.tr("First Day of Week") + // Days from Sunday to Saturday in the selected language + // 1st of February 2026 is a Sunday, any Sunday works + options: { + return Array(7).fill(0).map( + (_, i) => new Date(Date.UTC(2026, 2, 1 + i, 0, 0, 0)).toLocaleDateString( + I18n.locale(), "dddd" + ) + ).map( + d => d[0].toUpperCase() + d.slice(1) + ); + } + currentValue: options[root.weekStartJs()] + onValueChanged: value => { + SettingsData.set("firstDayOfWeek", options.indexOf(value)); + } + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + } + SettingsDropdownRow { tab: "time" tags: ["date", "format", "topbar"] diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index acb27f17..7874d363 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -468,6 +468,22 @@ ], "description": "Show weather information in top bar and control center" }, + { + "section": "firstDayOfWeek", + "label": "First Day of Week", + "tabIndex": 1, + "category": "Time & Weather", + "keywords": [ + "clock", + "date", + "day", + "first", + "forecast", + "time", + "weather", + "week" + ] + }, { "section": "lockDateFormat", "label": "Lock Screen Format", @@ -2187,7 +2203,7 @@ "theme", "wide" ], - "icon": "terminal", + "icon": "apps", "description": "Sync dark mode with settings portals for system-wide theme hints" }, { @@ -2648,6 +2664,7 @@ "system", "theme" ], + "icon": "interests", "description": "DankShell & System Icons (requires restart)" }, { @@ -2810,6 +2827,7 @@ "style", "theme" ], + "icon": "layers", "description": "Show darkened overlay behind modal dialogs" }, { @@ -3181,7 +3199,7 @@ "theme", "theming" ], - "icon": "extension", + "icon": "brush", "conditionKey": "matugenAvailable" }, { @@ -3749,6 +3767,52 @@ "security" ] }, + { + "section": "lockScreenVideoCycling", + "label": "Automatic Cycling", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "automatic", + "cycling", + "different", + "folder", + "lock", + "login", + "password", + "pick", + "random", + "same", + "screen", + "screensaver", + "security", + "shuffle", + "time", + "video" + ], + "description": "Pick a different random video each time from the same folder" + }, + { + "section": "lockScreenVideoEnabled", + "label": "Enable Video Screensaver", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "animation", + "enable", + "lock", + "locks", + "login", + "movie", + "password", + "play", + "screen", + "screensaver", + "security", + "video" + ], + "description": "Play a video when the screen locks." + }, { "section": "enableFprint", "label": "Enable fingerprint authentication", @@ -3771,48 +3835,6 @@ ], "description": "Use fingerprint reader for lock screen authentication (requires enrolled fingerprints)" }, - { - "section": "enableU2f", - "label": "Enable security key authentication", - "tabIndex": 11, - "category": "Lock Screen", - "keywords": [ - "authentication", - "enable", - "fido", - "hardware", - "key", - "lock", - "lockscreen", - "login", - "password", - "screen", - "security", - "u2f", - "yubikey" - ], - "description": "Use a FIDO2/U2F security key (e.g. YubiKey) for lock screen authentication (requires enrolled keys)" - }, - { - "section": "u2fMode", - "label": "Security key mode", - "tabIndex": 11, - "category": "Lock Screen", - "keywords": [ - "alternative", - "authentication", - "factor", - "key", - "lock", - "lockscreen", - "mode", - "second", - "security", - "u2f", - "yubikey" - ], - "description": "Alternative lets the key unlock on its own. Second factor requires password or fingerprint first, then the key." - }, { "section": "loginctlLockIntegration", "label": "Enable loginctl lock integration", @@ -3836,6 +3858,29 @@ ], "description": "Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen" }, + { + "section": "enableU2f", + "label": "Enable security key authentication", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "authentication", + "enable", + "enrolled", + "fido", + "hardware", + "key", + "lock", + "lockscreen", + "login", + "password", + "screen", + "security", + "u2f", + "yubikey" + ], + "description": "Use a FIDO2/U2F security key (e.g. YubiKey) for lock screen authentication (requires enrolled keys)" + }, { "section": "lockDisplay", "label": "Lock Screen Display", @@ -4028,6 +4073,25 @@ ], "description": "Turn off all displays immediately when the lock screen activates" }, + { + "section": "u2fMode", + "label": "Security key mode", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "factor", + "key", + "lock", + "login", + "mode", + "password", + "screen", + "second", + "security", + "u2f", + "yubikey" + ] + }, { "section": "lockScreenShowMediaPlayer", "label": "Show Media Player", @@ -4163,6 +4227,27 @@ "time" ] }, + { + "section": "videoScreensaver", + "label": "Video Screensaver", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "animation", + "lock", + "locks", + "login", + "movie", + "password", + "play", + "screen", + "screensaver", + "security", + "video" + ], + "icon": "movie", + "description": "Play a video when the screen locks." + }, { "section": "_tab_12", "label": "Plugins",