diff --git a/quickshell/Common/I18n.qml b/quickshell/Common/I18n.qml index 1b770f16..aae0009b 100644 --- a/quickshell/Common/I18n.qml +++ b/quickshell/Common/I18n.qml @@ -1,5 +1,6 @@ pragma Singleton pragma ComponentBehavior: Bound + import QtQuick import Qt.labs.folderlistmodel import Quickshell @@ -24,7 +25,9 @@ Singleton { readonly property url translationsFolder: Qt.resolvedUrl("../translations/poexports") readonly property alias folder: dir.folder - property var presentLocales: ({ "en": Qt.locale("en") }) + property var presentLocales: ({ + "en": Qt.locale("en") + }) property var translations: ({}) property bool translationsLoaded: false @@ -65,7 +68,9 @@ Singleton { } function locale() { - return presentLocales[_resolvedLocale] ?? presentLocales["en"]; + if (SessionData.timeLocale) + return Qt.locale(SessionData.timeLocale); + return Qt.locale(); } function _loadPresentLocales() { @@ -84,7 +89,8 @@ Singleton { function _pickTranslation() { for (let i = 0; i < _candidates.length; i++) { const cand = _candidates[i]; - if (presentLocales[cand] === undefined) continue; + if (presentLocales[cand] === undefined) + continue; _resolvedLocale = cand; useLocale(cand, cand.startsWith("en") ? "" : translationsFolder + "/" + cand + ".json"); return; diff --git a/quickshell/Common/SessionData.qml b/quickshell/Common/SessionData.qml index 4ca0fa8a..82a39c2f 100644 --- a/quickshell/Common/SessionData.qml +++ b/quickshell/Common/SessionData.qml @@ -129,6 +129,7 @@ Singleton { property var hiddenInputDeviceNames: [] property string locale: "" + property string timeLocale: "" property string launcherLastMode: "all" property string appDrawerLastMode: "apps" diff --git a/quickshell/Common/settings/SessionSpec.js b/quickshell/Common/settings/SessionSpec.js index b9805ede..69af83d5 100644 --- a/quickshell/Common/settings/SessionSpec.js +++ b/quickshell/Common/settings/SessionSpec.js @@ -80,6 +80,7 @@ var SPEC = { hiddenInputDeviceNames: { def: [] }, locale: { def: "", onChange: "updateLocale" }, + timeLocale: { def: "" }, launcherLastMode: { def: "all" }, appDrawerLastMode: { def: "apps" }, diff --git a/quickshell/Modules/Settings/LocaleTab.qml b/quickshell/Modules/Settings/LocaleTab.qml index f0b23d4b..d4f7f5ef 100644 --- a/quickshell/Modules/Settings/LocaleTab.qml +++ b/quickshell/Modules/Settings/LocaleTab.qml @@ -1,6 +1,5 @@ import QtQuick import qs.Common -import qs.Services import qs.Widgets import qs.Modules.Settings.Widgets @@ -9,17 +8,25 @@ Item { readonly property string _systemDefaultLabel: I18n.tr("System Default") - function capitalizeNativeLanguageName(localeCode) { - if (I18n.presentLocales[localeCode] == undefined) { + function _localeDisplayName(localeCode) { + if (!I18n.presentLocales[localeCode]) return; - } const nativeName = I18n.presentLocales[localeCode].nativeLanguageName; return nativeName[0].toUpperCase() + nativeName.slice(1); } - function _displayValue() { - if (!SessionData.locale) return _systemDefaultLabel; - return capitalizeNativeLanguageName(SessionData.locale); + function _allLocaleOptions() { + return [_systemDefaultLabel].concat(Object.keys(I18n.presentLocales).map(_localeDisplayName)); + } + + function _codeForDisplayName(displayName) { + if (displayName === _systemDefaultLabel) + return ""; + for (const code of Object.keys(I18n.presentLocales)) { + if (_localeDisplayName(code) === displayName) + return code; + } + return ""; } DankFlickable { @@ -48,24 +55,34 @@ Item { settingKey: "locale" text: I18n.tr("Current Locale") description: I18n.tr("Change the locale used by the DMS interface.") - options: [localeTab._systemDefaultLabel].concat(Object.keys(I18n.presentLocales).map(localeTab.capitalizeNativeLanguageName)) + options: localeTab._allLocaleOptions() enableFuzzySearch: true Component.onCompleted: { - currentValue = localeTab._displayValue(); + currentValue = SessionData.locale ? localeTab._localeDisplayName(SessionData.locale) : localeTab._systemDefaultLabel; } onValueChanged: value => { - if (value === localeTab._systemDefaultLabel) { - SessionData.set("locale", ""); - return; - } - for (let code of Object.keys(I18n.presentLocales)) { - if (localeTab.capitalizeNativeLanguageName(code) === value) { - SessionData.set("locale", code); - return; - } - } + SessionData.set("locale", localeTab._codeForDisplayName(value)); + } + } + + SettingsDropdownRow { + id: timeLocaleDropdown + tab: "locale" + tags: ["locale", "time", "date", "format", "region"] + settingKey: "timeLocale" + text: I18n.tr("Time & Date Locale") + description: I18n.tr("Change the locale used for date and time formatting, independent of the interface language.") + options: localeTab._allLocaleOptions() + enableFuzzySearch: true + + Component.onCompleted: { + currentValue = SessionData.timeLocale ? localeTab._localeDisplayName(SessionData.timeLocale) : localeTab._systemDefaultLabel; + } + + onValueChanged: value => { + SessionData.set("timeLocale", localeTab._codeForDisplayName(value)); } } } diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index 7416566c..45e9a3f6 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -733,6 +733,26 @@ ], "icon": "toolbar" }, + { + "section": "barShadowDirectionSource", + "label": "Direction Source", + "tabIndex": 3, + "category": "Dank Bar", + "keywords": [ + "bar", + "choose", + "dank", + "direction", + "panel", + "resolves", + "shadow", + "source", + "statusbar", + "taskbar", + "topbar" + ], + "description": "Choose how this bar resolves shadow direction" + }, { "section": "barDisplay", "label": "Display Assignment", @@ -752,6 +772,25 @@ ], "icon": "display_settings" }, + { + "section": "barShadowDirectionManual", + "label": "Manual Direction", + "tabIndex": 3, + "category": "Dank Bar", + "keywords": [ + "bar", + "dank", + "direction", + "fixed", + "manual", + "panel", + "shadow", + "statusbar", + "taskbar", + "topbar" + ], + "description": "Use a fixed shadow direction for this bar" + }, { "section": "barPosition", "label": "Position", @@ -769,18 +808,23 @@ }, { "section": "barShadow", - "label": "Shadow", + "label": "Shadow Override", "tabIndex": 3, "category": "Dank Bar", "keywords": [ "bar", "dank", + "global", + "override", "panel", + "settings", "shadow", "statusbar", + "taskbar", "topbar" ], - "icon": "layers" + "icon": "layers", + "description": "Override the global shadow with per-bar settings" }, { "section": "barSpacing", @@ -2252,6 +2296,33 @@ ], "icon": "schedule" }, + { + "section": "barElevationEnabled", + "label": "Bar Shadows", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "bar", + "bars", + "colors", + "elevation", + "look", + "m3", + "navigation", + "panel", + "panels", + "scheme", + "shadow", + "shadows", + "statusbar", + "style", + "taskbar", + "theme", + "topbar" + ], + "description": "Shadow elevation on bars and panels" + }, { "section": "niriLayoutBorderSize", "label": "Border Size", @@ -2416,74 +2487,6 @@ ], "description": "0 = square corners" }, - { - "section": "m3ElevationEnabled", - "label": "M3 Elevation & Shadows", - "tabIndex": 10, - "category": "Theme & Colors", - "keywords": [ - "appearance", - "elevation", - "lift", - "material", - "m3", - "shadow", - "shadows", - "theme" - ], - "description": "Material Design 3 shadows and elevation on modals, popouts, and dialogs" - }, - { - "section": "modalElevationEnabled", - "label": "Modal Shadows", - "tabIndex": 10, - "category": "Theme & Colors", - "keywords": [ - "dialog", - "elevation", - "m3", - "material", - "modal", - "shadow", - "shadows" - ], - "description": "Shadow elevation on modals and dialogs" - }, - { - "section": "popoutElevationEnabled", - "label": "Popout Shadows", - "tabIndex": 10, - "category": "Theme & Colors", - "keywords": [ - "dropdown", - "elevation", - "m3", - "material", - "osd", - "popout", - "popup", - "shadow", - "shadows" - ], - "description": "Shadow elevation on popouts, OSDs, and dropdowns" - }, - { - "section": "barElevationEnabled", - "label": "Bar Shadows", - "tabIndex": 10, - "category": "Theme & Colors", - "keywords": [ - "bar", - "elevation", - "m3", - "material", - "navigation", - "panel", - "shadow", - "shadows" - ], - "description": "Shadow elevation on bars and panels" - }, { "section": "cursorSize", "label": "Cursor Size", @@ -2758,6 +2761,32 @@ "tint" ] }, + { + "section": "m3ElevationLightDirection", + "label": "Light Direction", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "advanced", + "appearance", + "cast", + "colors", + "controls", + "day", + "direction", + "elevation", + "layers", + "light", + "light mode", + "look", + "m3", + "scheme", + "shadow", + "style", + "theme" + ], + "description": "Controls shadow cast direction for elevation layers" + }, { "section": "isLightMode", "label": "Light Mode", @@ -2898,6 +2927,29 @@ "icon": "layers", "description": "Show darkened overlay behind modal dialogs" }, + { + "section": "modalElevationEnabled", + "label": "Modal Shadows", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "colors", + "dialog", + "dialogs", + "elevation", + "look", + "m3", + "modal", + "modals", + "scheme", + "shadow", + "shadows", + "style", + "theme" + ], + "description": "Shadow elevation on modals and dialogs" + }, { "section": "niriLayout", "label": "Niri Layout Overrides", @@ -3158,6 +3210,32 @@ ], "description": "Use custom gaps instead of bar spacing" }, + { + "section": "popoutElevationEnabled", + "label": "Popout Shadows", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "colors", + "dropdown", + "dropdowns", + "elevation", + "look", + "m3", + "osd", + "osds", + "popout", + "popouts", + "popup", + "scheme", + "shadow", + "shadows", + "style", + "theme" + ], + "description": "Shadow elevation on popouts, OSDs, and dropdowns" + }, { "section": "popupTransparency", "label": "Popup Transparency", @@ -3222,6 +3300,105 @@ "user" ] }, + { + "section": "m3ElevationColorMode", + "label": "Shadow Color", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "applied", + "base", + "color", + "colors", + "colour", + "elevation", + "hue", + "look", + "m3", + "scheme", + "shadow", + "shadows", + "style", + "theme", + "tint" + ], + "description": "Base color for shadows (opacity is applied automatically)" + }, + { + "section": "m3ElevationIntensity", + "label": "Shadow Intensity", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "base", + "blur", + "colors", + "controls", + "elevation", + "intensity", + "look", + "m3", + "offset", + "radius", + "scheme", + "shadow", + "shadows", + "style", + "theme" + ], + "description": "Controls the base blur radius and offset of shadows" + }, + { + "section": "m3ElevationOpacity", + "label": "Shadow Opacity", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "alpha", + "appearance", + "colors", + "controls", + "elevation", + "look", + "m3", + "opacity", + "scheme", + "shadow", + "style", + "theme", + "translucent", + "transparency", + "transparent" + ], + "description": "Controls the transparency of the shadow" + }, + { + "section": "m3ElevationEnabled", + "label": "Shadows", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "colors", + "dialogs", + "elevation", + "inspired", + "lift", + "look", + "m3", + "material", + "modals", + "popouts", + "scheme", + "shadow", + "shadows", + "style", + "theme" + ], + "description": "Material inspired shadows and elevation on modals, popouts, and dialogs" + }, { "section": "syncModeWithPortal", "label": "Sync Mode with Portal", @@ -4038,27 +4215,6 @@ ], "description": "Automatically lock the screen when DMS starts" }, - { - "section": "lockBeforeSuspend", - "label": "Lock before suspend", - "tabIndex": 11, - "category": "Lock Screen", - "keywords": [ - "automatic", - "automatically", - "before", - "lock", - "login", - "password", - "prepares", - "screen", - "security", - "sleep", - "suspend", - "system" - ], - "description": "Automatically lock the screen when the system prepares to suspend" - }, { "section": "lockScreenNotificationMode", "label": "Notification Display", @@ -5358,20 +5514,33 @@ "keywords": [ "alert", "alerts", + "appearance", + "colors", + "colour", + "colours", "drop", + "elevation", + "enabled", + "hue", + "look", "messages", "notif", "notification", "notifications", + "palette", "popup", "popups", "radius", + "requires", "rounded", "shadow", "show", + "style", + "theme", + "tint", "toast" ], - "description": "Show drop shadow on notification popups" + "description": "Show drop shadow on notification popups. Requires M3 Elevation to be enabled in Theme & Colors." }, { "section": "notificationPopupPrivacyMode", @@ -6023,6 +6192,27 @@ "icon": "schedule", "description": "Gradually fade the screen before locking with a configurable grace period" }, + { + "section": "lockBeforeSuspend", + "label": "Lock before suspend", + "tabIndex": 21, + "category": "Power & Sleep", + "keywords": [ + "automatically", + "before", + "energy", + "lock", + "power", + "prepares", + "screen", + "security", + "shutdown", + "sleep", + "suspend", + "system" + ], + "description": "Automatically lock the screen when the system prepares to suspend" + }, { "section": "fadeToLockGracePeriod", "label": "Lock fade grace period", @@ -6618,5 +6808,25 @@ ], "icon": "language", "description": "Change the locale used by the DMS interface." + }, + { + "section": "timeLocale", + "label": "Time & Date Locale", + "tabIndex": 30, + "category": "Locale", + "keywords": [ + "change", + "country", + "date", + "format", + "formatting", + "independent", + "interface", + "language", + "locale", + "region", + "time" + ], + "description": "Change the locale used for date and time formatting, independent of the interface language." } ]