1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -05:00

Compare commits

...

64 Commits

Author SHA1 Message Date
bbedward
cd488a8623 Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-10 15:01:10 -04:00
bbedward
080b7a28b1 Fix force focus 2025-10-10 15:00:57 -04:00
purian23
6949ed0ebd No inline package comments 2025-10-10 14:57:32 -04:00
purian23
8465fa45bb Adjust inline spec comments 2025-10-10 14:49:34 -04:00
purian23
40835ffc89 Update copr dms spec 2025-10-10 14:20:47 -04:00
bbedward
01a42ff330 Fix key forward targets 2025-10-10 13:51:17 -04:00
bbedward
ba49654a64 Fix launcher context menu sizing 2025-10-10 13:42:55 -04:00
bbedward
bc6577fe18 Fix icon theme overflow 2025-10-10 12:47:22 -04:00
bbedward
4ca3f0da67 Fix tab/backtab in launchers 2025-10-10 12:40:02 -04:00
bbedward
7f2086488b Fix power menu focus activation 2025-10-10 12:29:14 -04:00
bbedward
3014fd8095 Fractional scaling fixes + bar border settings 2025-10-10 12:25:00 -04:00
bbedward
27885c8ac3 Update readme and about page 2025-10-10 00:05:49 -04:00
bbedward
d6be0509ac Put release bin in bin/ folder 2025-10-09 23:32:20 -04:00
bbedward
1c85f5e857 Make release assets more sane and understandable 2025-10-09 23:28:10 -04:00
bbedward
abe5515aca Expose ensureVisible to PluginSettings 2025-10-09 23:07:42 -04:00
bbedward
6fba975490 Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-09 20:38:26 -04:00
bbedward
2de6798f45 Clean up variants from bar whhen removed from plugin data 2025-10-09 20:37:14 -04:00
purian23
04fdfa2a35 simplify Fedora Spec 2025-10-09 18:52:27 -04:00
bbedward
8f3085290d Update wrapper for consistency 2025-10-09 17:59:16 -04:00
bbedward
0839fe45f5 Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-09 17:54:07 -04:00
bbedward
18f4795fda add dms-greeter wrapper 2025-10-09 17:53:56 -04:00
Parthiv Seetharaman
55d9fa622a Re-introduce default settings option and fix dms-cli build (#366)
* Reapply "Add default configuration option to home-manager (#356)"

This reverts commit bc23109f99.

* fix multiple xdg.configFile definitions error

* update dms-cli flake to fix build
2025-10-09 16:11:35 -04:00
bbedward
7dc723c764 Middle clock to close window on dock 2025-10-09 15:16:22 -04:00
bbedward
5a63205972 Fix light mode binding 2025-10-09 15:08:21 -04:00
bbedward
a4ceeafb1e Add ability to disable loginctl lock integration 2025-10-09 14:58:16 -04:00
bbedward
242e05cc0e Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-09 14:47:18 -04:00
bbedward
065dddbe6e Fix lock before suspend 2025-10-09 14:44:55 -04:00
purian23
fa6825252b prep Fedora Copr support 2025-10-09 14:42:09 -04:00
bbedward
b06e48a444 FolderListModel filters 2025-10-09 14:30:43 -04:00
bbedward
97dbd40f07 remove unused fileURL property 2025-10-09 14:17:29 -04:00
bbedward
bc23109f99 Revert "Add default configuration option to home-manager (#356)"
This reverts commit 67a4e3074e.
2025-10-09 13:53:27 -04:00
bbedward
ecb9675e9c Try more plugin loading things 2025-10-09 13:51:43 -04:00
bbedward
e1f9b9e7a4 Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-09 13:37:46 -04:00
bbedward
067b485bb3 Bind perms directly to availablePlugins map 2025-10-09 13:37:34 -04:00
bokicoder
67a4e3074e Add default configuration option to home-manager (#356) 2025-10-09 13:23:44 -04:00
bokicoder
010bc4e8c3 fix systemd startup (#364) 2025-10-09 13:23:33 -04:00
bbedward
9de5e3253e Re-do plugin scanning 2025-10-09 13:22:33 -04:00
bbedward
e32622ac48 Some lockscreen restructure 2025-10-09 11:30:02 -04:00
bbedward
5e2371c2cb Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-09 09:01:39 -04:00
bbedward
a6ce26ee87 i18n: update loading + add zh_CN 2025-10-09 09:01:20 -04:00
Parthiv Seetharaman
2a72c126f1 Add nix home-manager option for adding plugins (#354)
* add plugins nix hm option

* add nix hm plugins option usage to readme
2025-10-09 08:34:05 -04:00
bbedward
36e1a5d379 Update greeter docs 2025-10-08 23:37:45 -04:00
bbedward
c12eafa1db Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-08 23:18:07 -04:00
bbedward
9e26d8755c Add os keyboard to greeter 2025-10-08 23:17:52 -04:00
Lukas Krejci
90bd30e351 add support for system updates on fedora (#353) 2025-10-08 22:19:40 -04:00
bbedward
3fb5d5c4f3 i18n: don't load en json - move animated terms to properties 2025-10-08 20:31:41 -04:00
bbedward
9f3685e4d5 clip spotlight result listview 2025-10-08 18:58:14 -04:00
bbedward
6565988952 Cleanup some of the backwards compat crap 2025-10-08 18:28:46 -04:00
bbedward
10b7a0875b Crop CircularImages not fit 2025-10-08 18:16:16 -04:00
bbedward
bb4b9f1a58 Only ignore left/right keys in grid launcher mode 2025-10-08 17:55:24 -04:00
bbedward
981e527560 Remove artifacts of search fields overriding key inputs 2025-10-08 17:36:12 -04:00
bbedward
80b2ee719c Restore ipc target 2025-10-08 17:31:26 -04:00
bbedward
6103d6196f override cachyos logo 2025-10-08 16:35:49 -04:00
bbedward
ed1a5bfded i18n: Add japanese + i18n service 2025-10-08 16:25:06 -04:00
bbedward
3909ce3350 Remove minimum menu size constraint 2025-10-08 15:23:09 -04:00
bbedward
d64cd0b8a4 Fix launcher button mask 2025-10-08 15:12:47 -04:00
bbedward
676aa9f93f Merge branch 'master' of github.com:bbedward/DankMaterialShell 2025-10-08 14:51:59 -04:00
bbedward
ebd48e2556 Many more logo customization options 2025-10-08 14:51:38 -04:00
bokicoder
ad5871aae4 Update flake.lock (#347) 2025-10-08 14:15:38 -04:00
bbedward
e327b1ca5b Add proxy service for legacy nmcli version 2025-10-08 14:00:51 -04:00
bbedward
ad43ca11eb Insta fallback 2025-10-08 13:41:37 -04:00
omar
41ba76e2e2 Change lock activation to use lockLoader (#346)
Fixes broken lock button
2025-10-08 13:40:27 -04:00
bbedward
15e773434e Portal/Loginctl fallbacks for DMS_SOCKET unavail 2025-10-08 13:37:03 -04:00
bbedward
ed118f4e7a Dropbox icon workaround 2025-10-08 12:54:06 -04:00
128 changed files with 8799 additions and 1876 deletions

View File

@@ -57,7 +57,28 @@ jobs:
CHANGELOG=$(git log --oneline --pretty=format:"- %s (%h)" "${PREVIOUS_TAG}..${TAG}")
fi
cat > CHANGELOG.md << EOF
cat > RELEASE_BODY.md << 'EOF'
## Assets
### Complete Packages
- **`dms-full-amd64.tar.gz`** - Complete package for x86_64 systems (CLI binary + QML source + installation guide)
- **`dms-full-arm64.tar.gz`** - Complete package for ARM64 systems (CLI binary + QML source + installation guide)
### Individual Components
- **`dms-cli-amd64.gz`** - DMS CLI binary for x86_64 systems
- **`dms-cli-arm64.gz`** - DMS CLI binary for ARM64 systems
- **`dms-qml.tar.gz`** - QML source code only
### Checksums
- **`*.sha256`** - SHA256 checksums for verifying download integrity
**Installation:** Extract the `dms-full-*.tar.gz` package for your architecture and follow the `INSTALL.md` instructions inside.
---
EOF
cat >> RELEASE_BODY.md << EOF
## What's Changed
$CHANGELOG
@@ -66,7 +87,7 @@ jobs:
EOF
echo "changelog<<EOF" >> $GITHUB_OUTPUT
cat CHANGELOG.md >> $GITHUB_OUTPUT
cat RELEASE_BODY.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create/Update DankMaterialShell Release
@@ -80,18 +101,113 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download DMS release assets
- name: Download and prepare release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euxo pipefail
# gh is preinstalled on ubuntu-24.04; auth via GH_TOKEN env
mkdir -p _release_assets
# Download DMS CLI binaries from the danklinux repo
gh release download "${TAG}" -R "${DMS_REPO}" --dir ./_dms_assets
- name: Attach DMS assets to DankMaterialShell release
# Rename CLI binaries to dms-cli-* format
for file in _dms_assets/dms-*.gz*; do
if [ -f "$file" ]; then
basename=$(basename "$file")
# dms-amd64.gz -> dms-cli-amd64.gz
# dms-amd64.gz.sha256 -> dms-cli-amd64.gz.sha256
newname=$(echo "$basename" | sed 's/^dms-/dms-cli-/')
cp "$file" "_release_assets/$newname"
fi
done
# Create QML source package (exclude .git, .github, build artifacts)
tar --exclude='.git' \
--exclude='.github' \
--exclude='_dms_assets' \
--exclude='_release_assets' \
--exclude='*.tar.gz' \
-czf _release_assets/dms-qml.tar.gz .
# Generate checksum for QML package
(cd _release_assets && sha256sum dms-qml.tar.gz > dms-qml.tar.gz.sha256)
# Create full packages for each architecture
for arch in amd64 arm64; do
mkdir -p _temp_full/dms
mkdir -p _temp_full/bin
# Extract QML source to temp directory
tar -xzf _release_assets/dms-qml.tar.gz -C _temp_full/dms
# Copy CLI binary if it exists
if [ -f "_dms_assets/dms-${arch}.gz" ]; then
gunzip -c "_dms_assets/dms-${arch}.gz" > _temp_full/bin/dms
chmod +x _temp_full/bin/dms
fi
# Create INSTALL.md
cat > _temp_full/INSTALL.md << 'EOF'
# DankMaterialShell Installation
## Requirements
- Wayland compositor (niri or Hyprland recommended)
- Quickshell framework
- Qt6
## Installation Steps
1. **Install quickshell assets:**
```bash
mkdir -p ~/.config/quickshell
cp -r dms ~/.config/quickshell/
```
2. **Install the DMS CLI binary:**
```bash
sudo install -m 755 bin/dms /usr/local/bin/dms
# or install to a local directory:
mkdir -p ~/.local/bin
install -m 755 bin/dms ~/.local/bin/dms
```
3. **Start the shell:**
```bash
dms run
# or directly with quickshell (will lack some dbus integrations & plugin management):
quickshell -p ~/.config/quickshell/dms
```
## Configuration
- Settings are stored in `~/.config/DankMaterialShell/settings.json`
- Plugins go in `~/.config/DankMaterialShell/plugins/`
- See the documentation in the `dms/` directory for more details
## Troubleshooting
- Run with verbose output: `quickshell -v -p ~/.config/quickshell/dms`
- Check logs in `~/.local/state/DankMaterialShell/`
- Ensure all dependencies are installed
EOF
# Create the full package
(cd _temp_full && tar -czf "../_release_assets/dms-full-${arch}.tar.gz" .)
# Generate checksum
(cd _release_assets && sha256sum "dms-full-${arch}.tar.gz" > "dms-full-${arch}.tar.gz.sha256")
# Cleanup
rm -rf _temp_full
done
- name: Attach all assets to release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ env.TAG }}
files: _dms_assets/**
files: _release_assets/**
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

113
Common/I18n.qml Normal file
View File

@@ -0,0 +1,113 @@
import QtQuick
import Qt.labs.folderlistmodel
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
readonly property string _rawLocale: Qt.locale().name
readonly property string _lang: _rawLocale.split(/[_-]/)[0]
readonly property var _candidates: {
const fullUnderscore = _rawLocale;
const fullHyphen = _rawLocale.replace("_", "-");
return [fullUnderscore, fullHyphen, _lang].filter(c => c && c !== "en");
}
readonly property url translationsFolder: Qt.resolvedUrl("../translations/poexports")
property string currentLocale: "en"
property var translations: ({})
property bool translationsLoaded: false
property url _selectedPath: ""
FolderListModel {
id: dir
folder: root.translationsFolder
nameFilters: ["*.json"]
showDirs: false
showDotAndDotDot: false
onStatusChanged: if (status === FolderListModel.Ready) root._pickTranslation()
}
FileView {
id: translationLoader
path: root._selectedPath
onLoaded: {
try {
root.translations = JSON.parse(text())
root.translationsLoaded = true
console.log(`I18n: Loaded translations for '${root.currentLocale}' ` +
`(${Object.keys(root.translations).length} contexts)`)
} catch (e) {
console.warn(`I18n: Error parsing '${root.currentLocale}':`, e,
"- falling back to English")
root._fallbackToEnglish()
}
}
onLoadFailed: (error) => {
console.warn(`I18n: Failed to load '${root.currentLocale}' (${error}), ` +
"falling back to English")
root._fallbackToEnglish()
}
}
function _pickTranslation() {
const present = new Set()
for (let i = 0; i < dir.count; i++) {
const name = dir.get(i, "fileName") // e.g. "zh_CN.json"
if (name && name.endsWith(".json")) {
present.add(name.slice(0, -5))
}
}
for (let i = 0; i < _candidates.length; i++) {
const cand = _candidates[i]
if (present.has(cand)) {
_useLocale(cand, dir.folder + "/" + cand + ".json")
return
}
}
_fallbackToEnglish()
}
function _useLocale(localeTag, fileUrl) {
currentLocale = localeTag
_selectedPath = fileUrl
translationsLoaded = false
translations = ({})
console.log(`I18n: Using locale '${localeTag}' from ${fileUrl}`)
}
function _fallbackToEnglish() {
currentLocale = "en"
_selectedPath = ""
translationsLoaded = false
translations = ({})
console.warn("I18n: Falling back to built-in English strings")
}
function tr(term, context) {
if (!translationsLoaded || !translations) return term
const ctx = context || term
if (translations[ctx] && translations[ctx][term]) return translations[ctx][term]
for (const c in translations) {
if (translations[c] && translations[c][term]) return translations[c][term]
}
return term
}
function trContext(context, term) {
if (!translationsLoaded || !translations) return term
if (translations[context] && translations[context][term]) return translations[context][term]
return term
}
}

View File

@@ -38,6 +38,10 @@ Singleton {
return stringify(path).replace("file://", "")
}
function toFileUrl(path: string): string {
return path.startsWith("file://") ? path : "file://" + path
}
function mkdir(path: url): void {
Quickshell.execDetached(["mkdir", "-p", strip(path)])
}

View File

@@ -70,6 +70,7 @@ Singleton {
property int batteryHibernateTimeout: 0 // Never
property bool lockBeforeSuspend: false
property bool loginctlLockIntegration: true
property var recentColors: []
property bool showThirdPartyPlugins: false
@@ -152,6 +153,7 @@ Singleton {
batterySuspendTimeout = settings.batterySuspendTimeout !== undefined ? settings.batterySuspendTimeout : 0
batteryHibernateTimeout = settings.batteryHibernateTimeout !== undefined ? settings.batteryHibernateTimeout : 0
lockBeforeSuspend = settings.lockBeforeSuspend !== undefined ? settings.lockBeforeSuspend : false
loginctlLockIntegration = settings.loginctlLockIntegration !== undefined ? settings.loginctlLockIntegration : true
recentColors = settings.recentColors !== undefined ? settings.recentColors : []
showThirdPartyPlugins = settings.showThirdPartyPlugins !== undefined ? settings.showThirdPartyPlugins : false
@@ -215,6 +217,7 @@ Singleton {
"batterySuspendTimeout": batterySuspendTimeout,
"batteryHibernateTimeout": batteryHibernateTimeout,
"lockBeforeSuspend": lockBeforeSuspend,
"loginctlLockIntegration": loginctlLockIntegration,
"recentColors": recentColors,
"showThirdPartyPlugins": showThirdPartyPlugins
}, null, 2))
@@ -643,6 +646,11 @@ Singleton {
saveSettings()
}
function setLoginctlLockIntegration(enabled) {
loginctlLockIntegration = enabled
saveSettings()
}
function setShowThirdPartyPlugins(enabled) {
showThirdPartyPlugins = enabled
saveSettings()

View File

@@ -155,6 +155,14 @@ Singleton {
property bool dankBarNoBackground: false
property bool dankBarGothCornersEnabled: false
property bool dankBarBorderEnabled: false
property string dankBarBorderColor: "surfaceText"
property real dankBarBorderOpacity: 1.0
property real dankBarBorderThickness: 1
onDankBarBorderColorChanged: saveSettings()
onDankBarBorderOpacityChanged: saveSettings()
onDankBarBorderThicknessChanged: saveSettings()
property int dankBarPosition: SettingsData.Position.Top
property bool dankBarIsVertical: dankBarPosition === SettingsData.Position.Left || dankBarPosition === SettingsData.Position.Right
property bool lockScreenShowPowerActions: true
@@ -407,6 +415,9 @@ Singleton {
dankBarNoBackground = settings.dankBarNoBackground !== undefined ? settings.dankBarNoBackground : (settings.topBarNoBackground !== undefined ? settings.topBarNoBackground : false)
dankBarGothCornersEnabled = settings.dankBarGothCornersEnabled !== undefined ? settings.dankBarGothCornersEnabled : (settings.topBarGothCornersEnabled !== undefined ? settings.topBarGothCornersEnabled : false)
dankBarBorderEnabled = settings.dankBarBorderEnabled !== undefined ? settings.dankBarBorderEnabled : false
dankBarBorderColor = settings.dankBarBorderColor !== undefined ? settings.dankBarBorderColor : "surfaceText"
dankBarBorderOpacity = settings.dankBarBorderOpacity !== undefined ? settings.dankBarBorderOpacity : 1.0
dankBarBorderThickness = settings.dankBarBorderThickness !== undefined ? settings.dankBarBorderThickness : 1
dankBarPosition = settings.dankBarPosition !== undefined ? settings.dankBarPosition : (settings.dankBarAtBottom !== undefined ? (settings.dankBarAtBottom ? SettingsData.Position.Bottom : SettingsData.Position.Top) : (settings.topBarAtBottom !== undefined ? (settings.topBarAtBottom ? SettingsData.Position.Bottom : SettingsData.Position.Top) : SettingsData.Position.Top))
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true
hideBrightnessSlider = settings.hideBrightnessSlider !== undefined ? settings.hideBrightnessSlider : false
@@ -533,6 +544,9 @@ Singleton {
"dankBarNoBackground": dankBarNoBackground,
"dankBarGothCornersEnabled": dankBarGothCornersEnabled,
"dankBarBorderEnabled": dankBarBorderEnabled,
"dankBarBorderColor": dankBarBorderColor,
"dankBarBorderOpacity": dankBarBorderOpacity,
"dankBarBorderThickness": dankBarBorderThickness,
"dankBarPosition": dankBarPosition,
"lockScreenShowPowerActions": lockScreenShowPowerActions,
"hideBrightnessSlider": hideBrightnessSlider,
@@ -969,7 +983,7 @@ Singleton {
updateQtIconTheme(themeName)
saveSettings()
if (typeof Theme !== "undefined" && Theme.currentTheme === Theme.dynamic)
Theme.generateSystemThemes()
Theme.generateSystemThemesFromCurrentTheme()
}
function updateGtkIconTheme(themeName) {

View File

@@ -74,7 +74,6 @@ Singleton {
property bool qtThemingEnabled: typeof SettingsData !== "undefined" ? (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable) : false
property var workerRunning: false
property var matugenColors: ({})
property int colorUpdateTrigger: 0
property var customThemeData: null
readonly property string stateDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.CacheLocation).toString()) + "/dankshell"
@@ -84,7 +83,6 @@ Singleton {
matugenCheck.running = true
if (typeof SessionData !== "undefined") {
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
isLightMode = SessionData.isLightMode
}
if (typeof SettingsData !== "undefined" && SettingsData.currentThemeName) {
@@ -100,7 +98,6 @@ Singleton {
}
function getMatugenColor(path, fallback) {
colorUpdateTrigger
const colorMode = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "light" : "dark"
let cur = matugenColors && matugenColors.colors && matugenColors.colors[colorMode]
for (const part of path.split(".")) {
@@ -578,10 +575,6 @@ Singleton {
function onLightModeChanged() {
if (matugenColors && Object.keys(matugenColors).length > 0) {
colorUpdateTrigger++
}
if (currentTheme === "custom" && customThemeFileView.path) {
customThemeFileView.reload()
}
@@ -692,7 +685,17 @@ Singleton {
function withAlpha(c, a) { return Qt.rgba(c.r, c.g, c.b, a); }
function snap(value, dpr) {
return Math.round(value * dpr) / dpr
const s = dpr || 1
return Math.round(value * s) / s
}
function px(value, dpr) {
const s = dpr || 1
return Math.round(value * s) / s
}
function hairline(dpr) {
return 1 / (dpr || 1)
}
function invertHex(hex) {
@@ -717,6 +720,8 @@ Singleton {
if (typeof SettingsData === "undefined") return ""
const colorOverride = SettingsData.launcherLogoColorOverride
if (!colorOverride || colorOverride === "") return ""
if (colorOverride === "primary") return primary
if (colorOverride === "surface") return surfaceText
return colorOverride
}
@@ -726,15 +731,18 @@ Singleton {
const colorOverride = SettingsData.launcherLogoColorOverride
if (!colorOverride || colorOverride === "") return ""
if (colorOverride === "primary") return primary
if (colorOverride === "surface") return surfaceText
if (!SettingsData.launcherLogoColorInvertOnMode) {
return colorOverride
}
if (typeof SessionData !== "undefined" && SessionData.isLightMode) {
return invertHex(baseLogoColor)
if (isLightMode) {
return invertHex(colorOverride)
}
return baseLogoColor
return colorOverride
}
@@ -900,7 +908,6 @@ Singleton {
const colorsText = dynamicColorsFileView.text()
if (colorsText) {
root.matugenColors = JSON.parse(colorsText)
root.colorUpdateTrigger++
if (typeof ToastService !== "undefined") {
ToastService.clearWallpaperError()
}

View File

@@ -195,7 +195,7 @@ Item {
powerMenuModalLoader: controlCenterLoader.powerModalLoaderRef
onLockRequested: {
lock.activate()
lockLoader.item.activate()
}
Component.onCompleted: {
@@ -409,7 +409,7 @@ Item {
delegate: DankSlideout {
id: notepadSlideout
modelData: item
title: qsTr("Notepad")
title: I18n.tr("Notepad")
slideoutWidth: 480
expandable: true
expandedWidthValue: 960

View File

@@ -30,7 +30,7 @@ Item {
showKeyboardHints: modal.showKeyboardHints
onKeyboardHintsToggled: modal.showKeyboardHints = !modal.showKeyboardHints
onClearAllClicked: {
clearConfirmDialog.show("Clear All History?", "This will permanently delete all clipboard history.", function () {
clearConfirmDialog.show(I18n.tr("Clear All History?"), I18n.tr("This will permanently delete all clipboard history."), function () {
modal.clearAll()
modal.hide()
}, function () {})
@@ -46,7 +46,7 @@ Item {
leftIconName: "search"
showClearButton: true
focus: true
ignoreLeftRightKeys: true
ignoreTabKeys: true
keyForwardTargets: [modal.modalFocusScope]
onTextChanged: {
modal.searchText = text
@@ -116,7 +116,7 @@ Item {
}
StyledText {
text: qsTr("No clipboard entries found")
text: I18n.tr("No clipboard entries found")
anchors.centerIn: parent
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText

View File

@@ -80,11 +80,11 @@ Rectangle {
text: {
switch (entryType) {
case "image":
return "Image • " + entryPreview
return I18n.tr("Image") + " • " + entryPreview
case "long_text":
return "Long Text"
return I18n.tr("Long Text")
default:
return "Text"
return I18n.tr("Text")
}
}
font.pixelSize: Theme.fontSizeSmall

View File

@@ -28,7 +28,7 @@ Item {
}
StyledText {
text: `Clipboard History (${totalCount})`
text: I18n.tr("Clipboard History") + ` (${totalCount})`
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium

View File

@@ -91,7 +91,7 @@ DankModal {
function copyEntry(entry) {
const entryId = entry.split('\t')[0]
Quickshell.execDetached(["sh", "-c", `cliphist decode ${entryId} | wl-copy`])
ToastService.showInfo("Copied to clipboard")
ToastService.showInfo(I18n.tr("Copied to clipboard"))
hide()
}
@@ -153,7 +153,7 @@ DankModal {
ConfirmModal {
id: clearConfirmDialog
confirmButtonText: "Clear All"
confirmButtonText: I18n.tr("Clear All")
confirmButtonColor: Theme.primary
onVisibleChanged: {
if (visible) {

View File

@@ -6,6 +6,8 @@ import qs.Modals.Clipboard
Rectangle {
id: keyboardHints
readonly property string hintsText: I18n.tr("Shift+Del: Clear All • Esc: Close")
height: ClipboardConstants.keyboardHintsHeight
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95)
@@ -26,7 +28,7 @@ Rectangle {
}
StyledText {
text: qsTr("Shift+Del: Clear All • Esc: Close")
text: keyboardHints.hintsText
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -68,9 +68,11 @@ DankModal {
}
}
onOpened: {
modalFocusScope.forceActiveFocus()
modalFocusScope.focus = true
shouldHaveFocus = true
Qt.callLater(function () {
modalFocusScope.forceActiveFocus()
modalFocusScope.focus = true
shouldHaveFocus = true
})
}
modalFocusScope.Keys.onPressed: function (event) {
switch (event.key) {

View File

@@ -1,7 +1,9 @@
import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Wayland
import qs.Common
import qs.Services
PanelWindow {
id: root
@@ -14,14 +16,16 @@ PanelWindow {
property real height: 300
readonly property real screenWidth: screen ? screen.width : 1920
readonly property real screenHeight: screen ? screen.height : 1080
readonly property real dpr: (screen && screen.devicePixelRatio) || 1
function snap(v) {
return Math.round(v * dpr) / dpr
}
function px(v) {
return Math.round(v)
readonly property real dpr: {
if (CompositorService.isNiri && screen) {
const niriScale = NiriService.displayScales[screen.name]
if (niriScale !== undefined) return niriScale
}
if (CompositorService.isHyprland && screen) {
const hyprlandMonitor = Hyprland.monitors.values.find(m => m.name === screen.name)
if (hyprlandMonitor?.scale !== undefined) return hyprlandMonitor.scale
}
return (screen?.devicePixelRatio) || 1
}
property bool showBackground: true
property real backgroundOpacity: 0.5
@@ -142,26 +146,26 @@ PanelWindow {
Rectangle {
id: contentContainer
width: px(root.width)
height: px(root.height)
width: Theme.px(root.width, dpr)
height: Theme.px(root.height, dpr)
anchors.centerIn: undefined
x: {
if (positioning === "center") {
return snap((root.screenWidth - width) / 2)
return Theme.snap((root.screenWidth - width) / 2, dpr)
} else if (positioning === "top-right") {
return px(Math.max(Theme.spacingL, root.screenWidth - width - Theme.spacingL))
return Theme.px(Math.max(Theme.spacingL, root.screenWidth - width - Theme.spacingL), dpr)
} else if (positioning === "custom") {
return snap(root.customPosition.x)
return Theme.snap(root.customPosition.x, dpr)
}
return 0
}
y: {
if (positioning === "center") {
return snap((root.screenHeight - height) / 2)
return Theme.snap((root.screenHeight - height) / 2, dpr)
} else if (positioning === "top-right") {
return px(Theme.barHeight + Theme.spacingXS)
return Theme.px(Theme.barHeight + Theme.spacingXS, dpr)
} else if (positioning === "custom") {
return snap(root.customPosition.y)
return Theme.snap(root.customPosition.y, dpr)
}
return 0
}
@@ -170,6 +174,7 @@ PanelWindow {
border.color: root.borderColor
border.width: root.borderWidth
clip: false
layer.enabled: true
opacity: root.shouldBeVisible ? 1 : 0
transform: root.animationType === "slide" ? slideTransform : null
@@ -179,8 +184,8 @@ PanelWindow {
readonly property real rawX: root.shouldBeVisible ? 0 : 15
readonly property real rawY: root.shouldBeVisible ? 0 : -30
x: snap(rawX)
y: snap(rawY)
x: Theme.snap(rawX, root.dpr)
y: Theme.snap(rawY, root.dpr)
}
Behavior on opacity {

View File

@@ -188,7 +188,7 @@ PanelWindow {
}
StyledText {
text: qsTr("Select a color from the palette or use custom sliders")
text: I18n.tr("Select a color from the palette or use custom sliders")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
}
@@ -346,7 +346,7 @@ PanelWindow {
spacing: Theme.spacingS
StyledText {
text: qsTr("Material Colors")
text: I18n.tr("Material Colors")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -394,7 +394,7 @@ PanelWindow {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Recent Colors")
text: I18n.tr("Recent Colors")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -444,7 +444,7 @@ PanelWindow {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Opacity")
text: I18n.tr("Opacity")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -480,7 +480,7 @@ PanelWindow {
spacing: Theme.spacingS
StyledText {
text: qsTr("Hex:")
text: I18n.tr("Hex:")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
anchors.verticalCenter: parent.verticalCenter
@@ -518,7 +518,7 @@ PanelWindow {
DankButton {
width: 80
buttonHeight: 36
text: qsTr("Apply")
text: I18n.tr("Apply")
backgroundColor: Theme.primary
textColor: Theme.background
anchors.verticalCenter: parent.verticalCenter
@@ -545,7 +545,7 @@ PanelWindow {
DankButton {
width: 70
buttonHeight: 36
text: qsTr("Cancel")
text: I18n.tr("Cancel")
backgroundColor: "transparent"
textColor: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -564,7 +564,7 @@ PanelWindow {
DankButton {
width: 70
buttonHeight: 36
text: qsTr("Copy")
text: I18n.tr("Copy")
backgroundColor: Theme.primary
textColor: Theme.background
anchors.verticalCenter: parent.verticalCenter

View File

@@ -621,7 +621,6 @@ DankModal {
required property bool fileIsDir
required property string filePath
required property string fileName
required property url fileURL
required property int index
width: weMode ? 245 : 140
@@ -781,7 +780,7 @@ DankModal {
width: parent.width - saveButton.width - Theme.spacingM
height: 40
text: defaultFileName
placeholderText: qsTr("Enter filename...")
placeholderText: I18n.tr("Enter filename...")
ignoreLeftRightKeys: false
focus: saveMode
topPadding: Theme.spacingS
@@ -814,7 +813,7 @@ DankModal {
StyledText {
anchors.centerIn: parent
text: qsTr("Save")
text: I18n.tr("Save")
color: fileNameInput.text.trim() !== "" ? Theme.primaryText : Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeMedium
}
@@ -918,7 +917,7 @@ DankModal {
spacing: Theme.spacingM
StyledText {
text: qsTr("File Already Exists")
text: I18n.tr("File Already Exists")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -926,7 +925,7 @@ DankModal {
}
StyledText {
text: qsTr("A file with this name already exists. Do you want to overwrite it?")
text: I18n.tr("A file with this name already exists. Do you want to overwrite it?")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
width: parent.width
@@ -948,7 +947,7 @@ DankModal {
StyledText {
anchors.centerIn: parent
text: qsTr("Cancel")
text: I18n.tr("Cancel")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -974,7 +973,7 @@ DankModal {
StyledText {
anchors.centerIn: parent
text: qsTr("Overwrite")
text: I18n.tr("Overwrite")
font.pixelSize: Theme.fontSizeMedium
color: Theme.background
font.weight: Font.Medium

View File

@@ -134,7 +134,7 @@ Rectangle {
}
StyledText {
text: qsTr("File Information")
text: I18n.tr("File Information")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -197,7 +197,7 @@ Rectangle {
}
StyledText {
text: "F1/I: Toggle • F10: Help"
text: I18n.tr("F1/I: Toggle • F10: Help")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
anchors.bottom: parent.bottom

View File

@@ -23,7 +23,7 @@ Rectangle {
spacing: 2
StyledText {
text: "Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select"
text: I18n.tr("Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
@@ -32,7 +32,7 @@ Rectangle {
}
StyledText {
text: "Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close"
text: I18n.tr("Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width

View File

@@ -17,7 +17,7 @@ DankModal {
networkData = data
networkInfoModalVisible = true
open()
NetworkManagerService.fetchNetworkInfo(ssid)
NetworkService.fetchNetworkInfo(ssid)
}
function hideDialog() {
@@ -56,7 +56,7 @@ DankModal {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Network Information")
text: I18n.tr("Network Information")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -101,7 +101,7 @@ DankModal {
id: detailsText
width: parent.width
text: NetworkManagerService.networkInfoDetails && NetworkManagerService.networkInfoDetails.replace(/\\n/g, '\n') || "No information available"
text: NetworkService.networkInfoDetails && NetworkService.networkInfoDetails.replace(/\\n/g, '\n') || "No information available"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
wrapMode: Text.WordWrap
@@ -126,7 +126,7 @@ DankModal {
id: closeText
anchors.centerIn: parent
text: qsTr("Close")
text: I18n.tr("Close")
font.pixelSize: Theme.fontSizeMedium
color: Theme.background
font.weight: Font.Medium

View File

@@ -54,6 +54,9 @@ DankModal {
height: 700
visible: false
onBackgroundClicked: hide()
onOpened: () => {
Qt.callLater(() => modalFocusScope.forceActiveFocus());
}
onShouldBeVisibleChanged: (shouldBeVisible) => {
if (!shouldBeVisible) {
notificationModalOpen = false

View File

@@ -32,24 +32,24 @@ DankModal {
close();
const actions = {
"logout": {
"title": qsTr("Log Out"),
"message": qsTr("Are you sure you want to log out?")
"title": I18n.tr("Log Out"),
"message": I18n.tr("Are you sure you want to log out?")
},
"suspend": {
"title": qsTr("Suspend"),
"message": qsTr("Are you sure you want to suspend the system?")
"title": I18n.tr("Suspend"),
"message": I18n.tr("Are you sure you want to suspend the system?")
},
"hibernate": {
"title": qsTr("Hibernate"),
"message": qsTr("Are you sure you want to hibernate the system?")
"title": I18n.tr("Hibernate"),
"message": I18n.tr("Are you sure you want to hibernate the system?")
},
"reboot": {
"title": qsTr("Reboot"),
"message": qsTr("Are you sure you want to reboot the system?")
"title": I18n.tr("Reboot"),
"message": I18n.tr("Are you sure you want to reboot the system?")
},
"poweroff": {
"title": qsTr("Power Off"),
"message": qsTr("Are you sure you want to power off the system?")
"title": I18n.tr("Power Off"),
"message": I18n.tr("Are you sure you want to power off the system?")
}
}
const selected = actions[action]
@@ -78,7 +78,7 @@ DankModal {
}
onOpened: () => {
selectedIndex = 0;
modalFocusScope.forceActiveFocus();
Qt.callLater(() => modalFocusScope.forceActiveFocus());
}
modalFocusScope.Keys.onPressed: (event) => {
switch (event.key) {
@@ -144,7 +144,7 @@ DankModal {
width: parent.width
StyledText {
text: qsTr("Power Options")
text: I18n.tr("Power Options")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -201,7 +201,7 @@ DankModal {
}
StyledText {
text: qsTr("Log Out")
text: I18n.tr("Log Out")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -254,7 +254,7 @@ DankModal {
}
StyledText {
text: qsTr("Suspend")
text: I18n.tr("Suspend")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -308,7 +308,7 @@ DankModal {
}
StyledText {
text: qsTr("Hibernate")
text: I18n.tr("Hibernate")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -362,7 +362,7 @@ DankModal {
}
StyledText {
text: qsTr("Reboot")
text: I18n.tr("Reboot")
font.pixelSize: Theme.fontSizeMedium
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
font.weight: Font.Medium
@@ -416,7 +416,7 @@ DankModal {
}
StyledText {
text: qsTr("Power Off")
text: I18n.tr("Power Off")
font.pixelSize: Theme.fontSizeMedium
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
font.weight: Font.Medium

View File

@@ -123,7 +123,7 @@ DankModal {
}
StyledText {
text: qsTr("System Monitor Unavailable")
text: I18n.tr("System Monitor Unavailable")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.error
@@ -131,7 +131,7 @@ DankModal {
}
StyledText {
text: "The 'dgop' tool is required for system monitoring.\nPlease install dgop to use this feature."
text: I18n.tr("The 'dgop' tool is required for system monitoring.\nPlease install dgop to use this feature.")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
@@ -154,7 +154,7 @@ DankModal {
height: 40
StyledText {
text: qsTr("System Monitor")
text: I18n.tr("System Monitor")
font.pixelSize: Theme.fontSizeLarge + 4
font.weight: Font.Bold
color: Theme.surfaceText

View File

@@ -19,7 +19,7 @@ Item {
spacing: Theme.spacingXL
StyledText {
text: qsTr("Battery not detected - only AC power settings available")
text: I18n.tr("Battery not detected - only AC power settings available")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
visible: !BatteryService.batteryAvailable
@@ -51,7 +51,7 @@ Item {
}
StyledText {
text: qsTr("Idle Settings")
text: I18n.tr("Idle Settings")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -79,7 +79,7 @@ Item {
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
text: qsTr("Automatically lock after")
text: I18n.tr("Automatically lock after")
options: timeoutOptions
Connections {
@@ -115,7 +115,7 @@ Item {
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
text: qsTr("Turn off monitors after")
text: I18n.tr("Turn off monitors after")
options: timeoutOptions
Connections {
@@ -151,7 +151,7 @@ Item {
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
text: qsTr("Suspend system after")
text: I18n.tr("Suspend system after")
options: timeoutOptions
Connections {
@@ -187,7 +187,7 @@ Item {
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
text: qsTr("Hibernate system after")
text: I18n.tr("Hibernate system after")
options: timeoutOptions
visible: SessionService.hibernateSupported
@@ -221,14 +221,23 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Lock before suspend")
text: I18n.tr("Enable loginctl lock integration")
description: "Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen."
checked: SessionData.loginctlLockIntegration
onToggled: checked => SessionData.setLoginctlLockIntegration(checked)
}
DankToggle {
width: parent.width
text: I18n.tr("Lock before suspend")
description: "Automatically lock the screen when the system prepares to suspend"
checked: SessionData.lockBeforeSuspend
visible: SessionData.loginctlLockIntegration
onToggled: checked => SessionData.setLockBeforeSuspend(checked)
}
StyledText {
text: qsTr("Idle monitoring not supported - requires newer Quickshell version")
text: I18n.tr("Idle monitoring not supported - requires newer Quickshell version")
font.pixelSize: Theme.fontSizeSmall
color: Theme.error
anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -140,7 +140,7 @@ DankModal {
}
StyledText {
text: qsTr("Settings")
text: I18n.tr("Settings")
font.pixelSize: Theme.fontSizeXLarge
color: Theme.surfaceText
font.weight: Font.Medium

View File

@@ -9,40 +9,40 @@ Rectangle {
property int currentIndex: 0
property var parentModal: null
readonly property var sidebarItems: [{
"text": "Personalization",
"text": I18n.tr("Personalization"),
"icon": "person"
}, {
"text": "Time & Date",
"text": I18n.tr("Time & Date"),
"icon": "schedule"
}, {
"text": "Weather",
"text": I18n.tr("Weather"),
"icon": "cloud"
}, {
"text": "Dank Bar",
"text": I18n.tr("Dank Bar"),
"icon": "toolbar"
}, {
"text": "Widgets",
"text": I18n.tr("Widgets"),
"icon": "widgets"
}, {
"text": "Dock",
"text": I18n.tr("Dock"),
"icon": "dock_to_bottom"
}, {
"text": "Displays",
"text": I18n.tr("Displays"),
"icon": "monitor"
}, {
"text": "Launcher",
"text": I18n.tr("Launcher"),
"icon": "apps"
}, {
"text": "Theme & Colors",
"text": I18n.tr("Theme & Colors"),
"icon": "palette"
}, {
"text": "Power",
"text": I18n.tr("Power"),
"icon": "power_settings_new"
}, {
"text": "Plugins",
"text": I18n.tr("Plugins"),
"icon": "extension"
}, {
"text": "About",
"text": I18n.tr("About"),
"icon": "info"
}]

View File

@@ -81,10 +81,6 @@ Item {
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
appLauncher.launchSelected()
event.accepted = true
} else if (!searchField.activeFocus && event.text && event.text.length > 0 && event.text.match(/[a-zA-Z0-9\\s]/)) {
searchField.forceActiveFocus()
searchField.insertText(event.text)
event.accepted = true
}
}
@@ -131,7 +127,8 @@ Item {
font.pixelSize: Theme.fontSizeLarge
enabled: parentModal ? parentModal.spotlightOpen : true
placeholderText: ""
ignoreLeftRightKeys: true
ignoreLeftRightKeys: appLauncher.viewMode !== "list"
ignoreTabKeys: true
keyForwardTargets: [spotlightKeyHandler]
text: appLauncher.searchQuery
onTextEdited: () => {

View File

@@ -24,7 +24,7 @@ Popup {
contextMenu.close()
}
width: Math.max(180, Math.min(300, menuColumn.implicitWidth + Theme.spacingS * 2))
width: Math.max(180, menuColumn.implicitWidth + Theme.spacingS * 2)
height: menuColumn.implicitHeight + Theme.spacingS * 2
padding: 0
closePolicy: Popup.CloseOnPressOutside
@@ -77,12 +77,14 @@ Popup {
spacing: 1
Rectangle {
width: parent.width
implicitWidth: pinRow.implicitWidth + Theme.spacingS * 2
width: implicitWidth
height: 32
radius: Theme.cornerRadius
color: pinMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
id: pinRow
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
@@ -105,10 +107,10 @@ Popup {
StyledText {
text: {
if (!contextMenu.currentApp || !contextMenu.currentApp.desktopEntry)
return "Pin to Dock"
return I18n.tr("Pin to Dock")
const appId = contextMenu.currentApp.desktopEntry.id || contextMenu.currentApp.desktopEntry.execString || ""
return SessionData.isPinnedApp(appId) ? "Unpin from Dock" : "Pin to Dock"
return SessionData.isPinnedApp(appId) ? I18n.tr("Unpin from Dock") : I18n.tr("Pin to Dock")
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
@@ -155,16 +157,16 @@ Popup {
model: contextMenu.currentApp && contextMenu.currentApp.desktopEntry && contextMenu.currentApp.desktopEntry.actions ? contextMenu.currentApp.desktopEntry.actions : []
Rectangle {
width: parent.width
implicitWidth: actionRow.implicitWidth + Theme.spacingS * 2
width: implicitWidth
height: 32
radius: Theme.cornerRadius
color: actionMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
id: actionRow
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
@@ -189,8 +191,6 @@ Popup {
color: Theme.surfaceText
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
width: parent.width - (modelData.icon && modelData.icon !== "" ? (Theme.iconSize - 2 + Theme.spacingS) : 0)
}
}
@@ -228,12 +228,14 @@ Popup {
}
Rectangle {
width: parent.width
implicitWidth: launchRow.implicitWidth + Theme.spacingS * 2
width: implicitWidth
height: 32
radius: Theme.cornerRadius
color: launchMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
id: launchRow
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
@@ -248,7 +250,7 @@ Popup {
}
StyledText {
text: qsTr("Launch")
text: I18n.tr("Launch")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -288,12 +290,14 @@ Popup {
Rectangle {
visible: SessionService.hasPrimeRun
width: parent.width
implicitWidth: primeRunRow.implicitWidth + Theme.spacingS * 2
width: implicitWidth
height: 32
radius: Theme.cornerRadius
color: primeRunMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
id: primeRunRow
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
@@ -308,7 +312,7 @@ Popup {
}
StyledText {
text: qsTr("Launch on dGPU")
text: I18n.tr("Launch on dGPU")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal

View File

@@ -36,7 +36,7 @@ DankModal {
if (contentLoader.item.appLauncher) {
contentLoader.item.appLauncher.searchQuery = ""
contentLoader.item.appLauncher.selectedIndex = 0
contentLoader.item.appLauncher.setCategory("All")
contentLoader.item.appLauncher.setCategory(I18n.tr("All"))
}
if (contentLoader.item.resetScroll) {
contentLoader.item.resetScroll()

View File

@@ -19,7 +19,7 @@ Rectangle {
height: parent.height - y
radius: Theme.cornerRadius
color: "transparent"
clip: false
clip: true
DankListView {
id: resultsList

View File

@@ -17,7 +17,7 @@ DankModal {
wifiPasswordInput = ""
wifiUsernameInput = ""
const network = NetworkManagerService.wifiNetworks.find(n => n.ssid === ssid)
const network = NetworkService.wifiNetworks.find(n => n.ssid === ssid)
requiresEnterprise = network?.enterprise || false
open()
@@ -59,14 +59,14 @@ DankModal {
}
Connections {
target: NetworkManagerService
target: NetworkService
function onPasswordDialogShouldReopenChanged() {
if (NetworkManagerService.passwordDialogShouldReopen && NetworkManagerService.connectingSSID !== "") {
wifiPasswordSSID = NetworkManagerService.connectingSSID
if (NetworkService.passwordDialogShouldReopen && NetworkService.connectingSSID !== "") {
wifiPasswordSSID = NetworkService.connectingSSID
wifiPasswordInput = ""
open()
NetworkManagerService.passwordDialogShouldReopen = false
NetworkService.passwordDialogShouldReopen = false
}
}
}
@@ -100,7 +100,7 @@ DankModal {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Connect to Wi-Fi")
text: I18n.tr("Connect to Wi-Fi")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -196,7 +196,7 @@ DankModal {
}
onAccepted: () => {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkManagerService.connectToWifi(wifiPasswordSSID, passwordInput.text, username)
NetworkService.connectToWifi(wifiPasswordSSID, passwordInput.text, username)
close()
wifiPasswordInput = ""
wifiUsernameInput = ""
@@ -269,7 +269,7 @@ DankModal {
}
StyledText {
text: qsTr("Show password")
text: I18n.tr("Show password")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -297,7 +297,7 @@ DankModal {
id: cancelText
anchors.centerIn: parent
text: qsTr("Cancel")
text: I18n.tr("Cancel")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -329,7 +329,7 @@ DankModal {
id: connectText
anchors.centerIn: parent
text: qsTr("Connect")
text: I18n.tr("Connect")
font.pixelSize: Theme.fontSizeMedium
color: Theme.background
font.weight: Font.Medium
@@ -344,7 +344,7 @@ DankModal {
enabled: parent.enabled
onClicked: () => {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkManagerService.connectToWifi(wifiPasswordSSID, passwordInput.text, username)
NetworkService.connectToWifi(wifiPasswordSSID, passwordInput.text, username)
close()
wifiPasswordInput = ""
wifiUsernameInput = ""

View File

@@ -42,7 +42,7 @@ DankPopout {
if (shouldBeVisible) {
appLauncher.searchQuery = ""
appLauncher.selectedIndex = 0
appLauncher.setCategory("All")
appLauncher.setCategory(I18n.tr("All"))
Qt.callLater(() => {
if (contentLoader.item && contentLoader.item.searchField) {
contentLoader.item.searchField.text = ""
@@ -112,6 +112,8 @@ DankPopout {
mappings[Qt.Key_Up] = () => appLauncher.selectPrevious()
mappings[Qt.Key_Return] = () => appLauncher.launchSelected()
mappings[Qt.Key_Enter] = () => appLauncher.launchSelected()
mappings[Qt.Key_Tab] = () => appLauncher.viewMode === "grid" ? appLauncher.selectNextInRow() : appLauncher.selectNext()
mappings[Qt.Key_Backtab] = () => appLauncher.viewMode === "grid" ? appLauncher.selectPreviousInRow() : appLauncher.selectPrevious()
if (appLauncher.viewMode === "grid") {
mappings[Qt.Key_Right] = () => appLauncher.selectNextInRow()
@@ -166,11 +168,6 @@ DankPopout {
}
}
if (!searchField.activeFocus && event.text && /[a-zA-Z0-9\s]/.test(event.text)) {
searchField.forceActiveFocus()
searchField.insertText(event.text)
event.accepted = true
}
}
Column {
@@ -180,25 +177,23 @@ DankPopout {
y: Theme.spacingS
spacing: Theme.spacingS
Row {
Item {
width: parent.width
height: 40
leftPadding: Theme.spacingS
StyledText {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Applications")
text: I18n.tr("Applications")
font.pixelSize: Theme.fontSizeLarge + 4
font.weight: Font.Bold
color: Theme.surfaceText
}
Item {
width: parent.width - 200
height: 1
}
StyledText {
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: appLauncher.model.count + " apps"
font.pixelSize: Theme.fontSizeMedium
@@ -223,7 +218,8 @@ DankPopout {
showClearButton: true
font.pixelSize: Theme.fontSizeLarge
enabled: appDrawerPopout.shouldBeVisible
ignoreLeftRightKeys: true
ignoreLeftRightKeys: appLauncher.viewMode !== "list"
ignoreTabKeys: true
keyForwardTargets: [keyHandler]
onTextEdited: {
appLauncher.searchQuery = text
@@ -248,7 +244,7 @@ DankPopout {
return
}
const navigationKeys = [Qt.Key_Down, Qt.Key_Up, Qt.Key_Left, Qt.Key_Right]
const navigationKeys = [Qt.Key_Down, Qt.Key_Up, Qt.Key_Left, Qt.Key_Right, Qt.Key_Tab, Qt.Key_Backtab]
const isNavigationKey = navigationKeys.includes(event.key)
const isEmptyEnter = isEnterKey && !hasText
@@ -684,7 +680,7 @@ DankPopout {
contextMenu.close()
}
width: 180
width: Math.max(180, menuColumn.implicitWidth + Theme.spacingS * 2)
height: menuColumn.implicitHeight + Theme.spacingS * 2
padding: 0
closePolicy: Popup.CloseOnPressOutside
@@ -757,7 +753,7 @@ DankPopout {
}
StyledText {
text: contextMenu.isPinned ? "Unpin from Dock" : "Pin to Dock"
text: contextMenu.isPinned ? I18n.tr("Unpin from Dock") : I18n.tr("Pin to Dock")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -804,12 +800,13 @@ DankPopout {
model: contextMenu.currentApp && contextMenu.currentApp.desktopEntry && contextMenu.currentApp.desktopEntry.actions ? contextMenu.currentApp.desktopEntry.actions : []
Rectangle {
width: parent.width
width: Math.max(parent.width, actionRow.implicitWidth + Theme.spacingS * 2)
height: 32
radius: Theme.cornerRadius
color: actionMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
id: actionRow
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
@@ -891,7 +888,7 @@ DankPopout {
}
StyledText {
text: qsTr("Launch")
text: I18n.tr("Launch")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -951,7 +948,7 @@ DankPopout {
}
StyledText {
text: qsTr("Launch on dGPU")
text: I18n.tr("Launch on dGPU")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal

View File

@@ -9,7 +9,7 @@ Item {
id: root
property string searchQuery: ""
property string selectedCategory: "All"
property string selectedCategory: I18n.tr("All")
property string viewMode: "list" // "list" or "grid"
property int selectedIndex: 0
property int maxResults: 50
@@ -20,8 +20,8 @@ Item {
property bool suppressUpdatesWhileLaunching: false
readonly property var categories: {
const allCategories = AppSearchService.getAllCategories().filter(cat => cat !== "Education" && cat !== "Science")
const result = ["All"]
return result.concat(allCategories.filter(cat => cat !== "All"))
const result = [I18n.tr("All")]
return result.concat(allCategories.filter(cat => cat !== I18n.tr("All")))
}
readonly property var categoryIcons: categories.map(category => AppSearchService.getCategoryIcon(category))
property var appUsageRanking: AppUsageHistoryData.appUsageRanking || {}
@@ -42,10 +42,11 @@ Item {
keyboardNavigationActive = false
let apps = []
const allCategory = I18n.tr("All")
if (searchQuery.length === 0) {
apps = selectedCategory === "All" ? AppSearchService.getAppsInCategory("All") : AppSearchService.getAppsInCategory(selectedCategory).slice(0, maxResults)
apps = selectedCategory === allCategory ? AppSearchService.getAppsInCategory(allCategory) : AppSearchService.getAppsInCategory(selectedCategory).slice(0, maxResults)
} else {
if (selectedCategory === "All") {
if (selectedCategory === allCategory) {
apps = AppSearchService.searchApplications(searchQuery)
} else {
const categoryApps = AppSearchService.getAppsInCategory(selectedCategory)

View File

@@ -1,13 +1,14 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Services
import qs.Widgets
Item {
id: root
property var categories: []
property string selectedCategory: "All"
property string selectedCategory: I18n.tr("All")
property bool compact: false
signal categorySelected(string category)

View File

@@ -87,7 +87,7 @@ PluginComponent {
}
StyledText {
text: qsTr("Disconnect")
text: I18n.tr("Disconnect")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -138,14 +138,14 @@ PluginComponent {
}
StyledText {
text: qsTr("No VPN profiles found")
text: I18n.tr("No VPN profiles found")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: qsTr("Add a VPN in NetworkManager")
text: I18n.tr("Add a VPN in NetworkManager")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -126,15 +126,7 @@ Column {
return builtinPluginWidgetComponent
} else if (id.startsWith("plugin_")) {
return pluginWidgetComponent
} else if (id === "wifi") {
if (!DMSService.dmsAvailable) {
return errorPillComponent
}
if (DMSService.dmsAvailable && !DMSService.capabilities.includes("network")) {
return errorPillComponent
}
return compoundPillComponent
} else if (id === "bluetooth" || id === "audioOutput" || id === "audioInput") {
} else if (id === "wifi" || id === "bluetooth" || id === "audioOutput" || id === "audioInput") {
return compoundPillComponent
} else if (id === "volumeSlider") {
return audioSliderComponent
@@ -191,11 +183,11 @@ Column {
height: 60
primaryMessage: {
if (!DMSService.dmsAvailable) {
return qsTr("DMS_SOCKET not available")
return I18n.tr("DMS_SOCKET not available")
}
return qsTr("NM not supported")
return I18n.tr("NM not supported")
}
secondaryMessage: qsTr("update dms for NM integration.")
secondaryMessage: I18n.tr("update dms for NM integration.")
}
}
@@ -211,13 +203,13 @@ Column {
switch (widgetData.id || "") {
case "wifi":
{
if (NetworkManagerService.wifiToggling)
if (NetworkService.wifiToggling)
return "sync"
if (NetworkManagerService.networkStatus === "ethernet")
if (NetworkService.networkStatus === "ethernet")
return "settings_ethernet"
if (NetworkManagerService.networkStatus === "wifi")
return NetworkManagerService.wifiSignalIcon
if (NetworkManagerService.wifiEnabled)
if (NetworkService.networkStatus === "wifi")
return NetworkService.wifiSignalIcon
if (NetworkService.wifiEnabled)
return "wifi_off"
return "wifi_off"
}
@@ -270,13 +262,13 @@ Column {
switch (widgetData.id || "") {
case "wifi":
{
if (NetworkManagerService.wifiToggling)
return NetworkManagerService.wifiEnabled ? "Disabling WiFi..." : "Enabling WiFi..."
if (NetworkManagerService.networkStatus === "ethernet")
if (NetworkService.wifiToggling)
return NetworkService.wifiEnabled ? "Disabling WiFi..." : "Enabling WiFi..."
if (NetworkService.networkStatus === "ethernet")
return "Ethernet"
if (NetworkManagerService.networkStatus === "wifi" && NetworkManagerService.currentWifiSSID)
return NetworkManagerService.currentWifiSSID
if (NetworkManagerService.wifiEnabled)
if (NetworkService.networkStatus === "wifi" && NetworkService.currentWifiSSID)
return NetworkService.currentWifiSSID
if (NetworkService.wifiEnabled)
return "Not connected"
return "WiFi off"
}
@@ -302,13 +294,13 @@ Column {
switch (widgetData.id || "") {
case "wifi":
{
if (NetworkManagerService.wifiToggling)
if (NetworkService.wifiToggling)
return "Please wait..."
if (NetworkManagerService.networkStatus === "ethernet")
if (NetworkService.networkStatus === "ethernet")
return "Connected"
if (NetworkManagerService.networkStatus === "wifi")
return NetworkManagerService.wifiSignalStrength > 0 ? NetworkManagerService.wifiSignalStrength + "%" : "Connected"
if (NetworkManagerService.wifiEnabled)
if (NetworkService.networkStatus === "wifi")
return NetworkService.wifiSignalStrength > 0 ? NetworkService.wifiSignalStrength + "%" : "Connected"
if (NetworkService.wifiEnabled)
return "Select network"
return ""
}
@@ -356,13 +348,13 @@ Column {
switch (widgetData.id || "") {
case "wifi":
{
if (NetworkManagerService.wifiToggling)
if (NetworkService.wifiToggling)
return false
if (NetworkManagerService.networkStatus === "ethernet")
if (NetworkService.networkStatus === "ethernet")
return true
if (NetworkManagerService.networkStatus === "wifi")
if (NetworkService.networkStatus === "wifi")
return true
return NetworkManagerService.wifiEnabled
return NetworkService.wifiEnabled
}
case "bluetooth":
return !!(BluetoothService.available && BluetoothService.adapter && BluetoothService.adapter.enabled)

View File

@@ -55,7 +55,7 @@ Row {
}
Typography {
text: qsTr("Add Widget")
text: I18n.tr("Add Widget")
style: Typography.Style.Subtitle
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -155,7 +155,7 @@ Row {
}
Typography {
text: qsTr("Add Widget")
text: I18n.tr("Add Widget")
style: Typography.Style.Button
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
@@ -189,7 +189,7 @@ Row {
}
Typography {
text: qsTr("Defaults")
text: I18n.tr("Defaults")
style: Typography.Style.Button
color: Theme.warning
anchors.verticalCenter: parent.verticalCenter
@@ -223,7 +223,7 @@ Row {
}
Typography {
text: qsTr("Reset")
text: I18n.tr("Reset")
style: Typography.Style.Button
color: Theme.error
anchors.verticalCenter: parent.verticalCenter

View File

@@ -73,13 +73,17 @@ DankPopout {
onShouldBeVisibleChanged: {
if (shouldBeVisible) {
Qt.callLater(() => {
NetworkManagerService.autoRefreshEnabled = NetworkManagerService.wifiEnabled
if (NetworkService.activeService) {
NetworkService.activeService.autoRefreshEnabled = NetworkService.wifiEnabled
}
if (UserInfoService)
UserInfoService.getUptime()
})
} else {
Qt.callLater(() => {
NetworkManagerService.autoRefreshEnabled = false
if (NetworkService.activeService) {
NetworkService.activeService.autoRefreshEnabled = false
}
if (BluetoothService.adapter && BluetoothService.adapter.discovering)
BluetoothService.adapter.discovering = false
editMode = false

View File

@@ -30,7 +30,7 @@ Rectangle {
StyledText {
id: headerText
text: qsTr("Input Devices")
text: I18n.tr("Input Devices")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium

View File

@@ -30,7 +30,7 @@ Rectangle {
StyledText {
id: headerText
text: qsTr("Audio Devices")
text: I18n.tr("Audio Devices")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium

View File

@@ -133,7 +133,7 @@ Rectangle {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Health")
text: I18n.tr("Health")
font.pixelSize: Theme.fontSizeSmall
color: Theme.primary
font.weight: Font.Medium
@@ -168,7 +168,7 @@ Rectangle {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Capacity")
text: I18n.tr("Capacity")
font.pixelSize: Theme.fontSizeSmall
color: Theme.primary
font.weight: Font.Medium
@@ -237,7 +237,7 @@ Rectangle {
width: parent.width - Theme.iconSize - Theme.spacingM
StyledText {
text: qsTr("Power Profile Degradation")
text: I18n.tr("Power Profile Degradation")
font.pixelSize: Theme.fontSizeLarge
color: Theme.error
font.weight: Font.Medium

View File

@@ -170,7 +170,7 @@ Item {
}
StyledText {
text: qsTr("Audio Codec Selection")
text: I18n.tr("Audio Codec Selection")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
}

View File

@@ -39,7 +39,7 @@ Rectangle {
StyledText {
id: headerText
text: qsTr("Bluetooth Settings")
text: I18n.tr("Bluetooth Settings")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -422,7 +422,7 @@ Rectangle {
StyledText {
anchors.centerIn: parent
text: qsTr("No Bluetooth adapter found")
text: I18n.tr("No Bluetooth adapter found")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
}
@@ -473,7 +473,7 @@ Rectangle {
}
MenuItem {
text: qsTr("Audio Codec")
text: I18n.tr("Audio Codec")
height: bluetoothContextMenu.currentDevice && BluetoothService.isAudioDevice(bluetoothContextMenu.currentDevice) && bluetoothContextMenu.currentDevice.connected ? 32 : 0
visible: bluetoothContextMenu.currentDevice && BluetoothService.isAudioDevice(bluetoothContextMenu.currentDevice) && bluetoothContextMenu.currentDevice.connected
@@ -498,7 +498,7 @@ Rectangle {
}
MenuItem {
text: qsTr("Forget Device")
text: I18n.tr("Forget Device")
height: 32
contentItem: StyledText {

View File

@@ -8,10 +8,10 @@ import qs.Modals
Rectangle {
implicitHeight: {
if (NetworkManagerService.wifiToggling) {
if (NetworkService.wifiToggling) {
return headerRow.height + wifiToggleContent.height + Theme.spacingM
}
if (NetworkManagerService.wifiEnabled) {
if (NetworkService.wifiEnabled) {
return headerRow.height + wifiContent.height + Theme.spacingM
}
return headerRow.height + wifiOffContent.height + Theme.spacingM
@@ -22,11 +22,11 @@ Rectangle {
border.width: 0
Component.onCompleted: {
NetworkManagerService.addRef()
NetworkService.addRef()
}
Component.onDestruction: {
NetworkManagerService.removeRef()
NetworkService.removeRef()
}
Row {
@@ -41,7 +41,7 @@ Rectangle {
StyledText {
id: headerText
text: qsTr("Network Settings")
text: I18n.tr("Network Settings")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -56,11 +56,11 @@ Rectangle {
DankButtonGroup {
id: preferenceControls
anchors.verticalCenter: parent.verticalCenter
visible: NetworkManagerService.ethernetConnected
visible: NetworkService.ethernetConnected
property int currentPreferenceIndex: {
const pref = NetworkManagerService.userPreference
const status = NetworkManagerService.networkStatus
const pref = NetworkService.userPreference
const status = NetworkService.networkStatus
let index = 1
if (pref === "ethernet") {
@@ -80,7 +80,7 @@ Rectangle {
onSelectionChanged: (index, selected) => {
if (!selected) return
console.log("NetworkDetail: Setting preference to", index === 0 ? "ethernet" : "wifi")
NetworkManagerService.setNetworkPreference(index === 0 ? "ethernet" : "wifi")
NetworkService.setNetworkPreference(index === 0 ? "ethernet" : "wifi")
}
}
}
@@ -92,7 +92,7 @@ Rectangle {
anchors.right: parent.right
anchors.margins: Theme.spacingM
anchors.topMargin: Theme.spacingM
visible: NetworkManagerService.wifiToggling
visible: NetworkService.wifiToggling
height: visible ? 80 : 0
Column {
@@ -106,7 +106,7 @@ Rectangle {
color: Theme.primary
RotationAnimation on rotation {
running: NetworkManagerService.wifiToggling
running: NetworkService.wifiToggling
loops: Animation.Infinite
from: 0
to: 360
@@ -116,7 +116,7 @@ Rectangle {
StyledText {
anchors.horizontalCenter: parent.horizontalCenter
text: NetworkManagerService.wifiEnabled ? "Disabling WiFi..." : "Enabling WiFi..."
text: NetworkService.wifiEnabled ? "Disabling WiFi..." : "Enabling WiFi..."
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
horizontalAlignment: Text.AlignHCenter
@@ -131,7 +131,7 @@ Rectangle {
anchors.right: parent.right
anchors.margins: Theme.spacingM
anchors.topMargin: Theme.spacingM
visible: !NetworkManagerService.wifiEnabled && !NetworkManagerService.wifiToggling
visible: !NetworkService.wifiEnabled && !NetworkService.wifiToggling
height: visible ? 120 : 0
Column {
@@ -148,7 +148,7 @@ Rectangle {
StyledText {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("WiFi is off")
text: I18n.tr("WiFi is off")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -166,7 +166,7 @@ Rectangle {
StyledText {
anchors.centerIn: parent
text: qsTr("Enable WiFi")
text: I18n.tr("Enable WiFi")
color: Theme.primary
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
@@ -177,7 +177,7 @@ Rectangle {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: NetworkManagerService.toggleWifiRadio()
onClicked: NetworkService.toggleWifiRadio()
}
}
@@ -192,7 +192,7 @@ Rectangle {
anchors.bottom: parent.bottom
anchors.margins: Theme.spacingM
anchors.topMargin: Theme.spacingM
visible: NetworkManagerService.wifiInterface && NetworkManagerService.wifiEnabled && !NetworkManagerService.wifiToggling
visible: NetworkService.wifiInterface && NetworkService.wifiEnabled && !NetworkService.wifiToggling
contentHeight: wifiColumn.height
clip: true
@@ -204,7 +204,7 @@ Rectangle {
Item {
width: parent.width
height: 200
visible: NetworkManagerService.wifiInterface && NetworkManagerService.wifiNetworks?.length < 1 && !NetworkManagerService.wifiToggling && NetworkManagerService.isScanning
visible: NetworkService.wifiInterface && NetworkService.wifiNetworks?.length < 1 && !NetworkService.wifiToggling && NetworkService.isScanning
DankIcon {
anchors.centerIn: parent
@@ -213,7 +213,7 @@ Rectangle {
color: Qt.rgba(Theme.surfaceText.r || 0.8, Theme.surfaceText.g || 0.8, Theme.surfaceText.b || 0.8, 0.3)
RotationAnimation on rotation {
running: NetworkManagerService.isScanning
running: NetworkService.isScanning
loops: Animation.Infinite
from: 0
to: 360
@@ -226,8 +226,8 @@ Rectangle {
model: sortedNetworks
property var sortedNetworks: {
const ssid = NetworkManagerService.currentWifiSSID
const networks = NetworkManagerService.wifiNetworks
const ssid = NetworkService.currentWifiSSID
const networks = NetworkService.wifiNetworks
let sorted = [...networks]
sorted.sort((a, b) => {
if (a.ssid === ssid) return -1
@@ -244,7 +244,7 @@ Rectangle {
height: 50
radius: Theme.cornerRadius
color: networkMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
border.color: modelData.ssid === NetworkManagerService.currentWifiSSID ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 0
Row {
@@ -261,7 +261,7 @@ Rectangle {
return "wifi_1_bar"
}
size: Theme.iconSize - 4
color: modelData.ssid === NetworkManagerService.currentWifiSSID ? Theme.primary : Theme.surfaceText
color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
@@ -273,7 +273,7 @@ Rectangle {
text: modelData.ssid || "Unknown Network"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: modelData.ssid === NetworkManagerService.currentWifiSSID ? Font.Medium : Font.Normal
font.weight: modelData.ssid === NetworkService.currentWifiSSID ? Font.Medium : Font.Normal
elide: Text.ElideRight
width: parent.width
}
@@ -282,7 +282,7 @@ Rectangle {
spacing: Theme.spacingXS
StyledText {
text: modelData.ssid === NetworkManagerService.currentWifiSSID ? "Connected" : (modelData.secured ? "Secured" : "Open")
text: modelData.ssid === NetworkService.currentWifiSSID ? "Connected" : (modelData.secured ? "Secured" : "Open")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -316,7 +316,7 @@ Rectangle {
} else {
networkContextMenu.currentSSID = modelData.ssid
networkContextMenu.currentSecured = modelData.secured
networkContextMenu.currentConnected = modelData.ssid === NetworkManagerService.currentWifiSSID
networkContextMenu.currentConnected = modelData.ssid === NetworkService.currentWifiSSID
networkContextMenu.currentSaved = modelData.saved
networkContextMenu.currentSignal = modelData.signal
networkContextMenu.popup(optionsButton, -networkContextMenu.width + optionsButton.width, optionsButton.height + Theme.spacingXS)
@@ -331,11 +331,11 @@ Rectangle {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: function(event) {
if (modelData.ssid !== NetworkManagerService.currentWifiSSID) {
if (modelData.ssid !== NetworkService.currentWifiSSID) {
if (modelData.secured && !modelData.saved) {
wifiPasswordModal.show(modelData.ssid)
} else {
NetworkManagerService.connectToWifi(modelData.ssid)
NetworkService.connectToWifi(modelData.ssid)
}
}
event.accepted = true
@@ -384,19 +384,19 @@ Rectangle {
onTriggered: {
if (networkContextMenu.currentConnected) {
NetworkManagerService.disconnectWifi()
NetworkService.disconnectWifi()
} else {
if (networkContextMenu.currentSecured && !networkContextMenu.currentSaved) {
wifiPasswordModal.show(networkContextMenu.currentSSID)
} else {
NetworkManagerService.connectToWifi(networkContextMenu.currentSSID)
NetworkService.connectToWifi(networkContextMenu.currentSSID)
}
}
}
}
MenuItem {
text: qsTr("Network Info")
text: I18n.tr("Network Info")
height: 32
contentItem: StyledText {
@@ -413,13 +413,13 @@ Rectangle {
}
onTriggered: {
let networkData = NetworkManagerService.getNetworkInfo(networkContextMenu.currentSSID)
let networkData = NetworkService.getNetworkInfo(networkContextMenu.currentSSID)
networkInfoModal.showNetworkInfo(networkContextMenu.currentSSID, networkData)
}
}
MenuItem {
text: qsTr("Forget Network")
text: I18n.tr("Forget Network")
height: networkContextMenu.currentSaved || networkContextMenu.currentConnected ? 32 : 0
visible: networkContextMenu.currentSaved || networkContextMenu.currentConnected
@@ -437,7 +437,7 @@ Rectangle {
}
onTriggered: {
NetworkManagerService.forgetWifiNetwork(networkContextMenu.currentSSID)
NetworkService.forgetWifiNetwork(networkContextMenu.currentSSID)
}
}
}

View File

@@ -67,8 +67,8 @@ QtObject {
"description": "Wi-Fi and Ethernet connection",
"icon": "wifi",
"type": "connection",
"enabled": NetworkManagerService.wifiAvailable,
"warning": !NetworkManagerService.wifiAvailable ? "Wi-Fi not available" : undefined
"enabled": NetworkService.wifiAvailable,
"warning": !NetworkService.wifiAvailable ? "Wi-Fi not available" : undefined
}, {
"id": "bluetooth",
"text": "Bluetooth",

View File

@@ -10,6 +10,12 @@ import qs.Widgets
PanelWindow {
id: root
readonly property string powerOptionsText: I18n.tr("Power Options")
readonly property string logOutText: I18n.tr("Log Out")
readonly property string suspendText: I18n.tr("Suspend")
readonly property string rebootText: I18n.tr("Reboot")
readonly property string powerOffText: I18n.tr("Power Off")
property bool powerMenuVisible: false
signal powerActionRequested(string action, string title, string message)
@@ -65,7 +71,7 @@ PanelWindow {
width: parent.width
StyledText {
text: qsTr("Power Options")
text: root.powerOptionsText
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -118,7 +124,7 @@ PanelWindow {
}
StyledText {
text: qsTr("Log Out")
text: root.logOutText
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -168,7 +174,7 @@ PanelWindow {
}
StyledText {
text: qsTr("Suspend")
text: root.suspendText
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -218,7 +224,7 @@ PanelWindow {
}
StyledText {
text: qsTr("Reboot")
text: root.rebootText
font.pixelSize: Theme.fontSizeMedium
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
font.weight: Font.Medium
@@ -268,7 +274,7 @@ PanelWindow {
}
StyledText {
text: qsTr("Power Off")
text: root.powerOffText
font.pixelSize: Theme.fontSizeMedium
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
font.weight: Font.Medium

View File

@@ -25,7 +25,7 @@ Item {
readonly property real correctWidth: root.width
readonly property real correctHeight: root.height
canvasSize: Qt.size(barWindow.px(correctWidth), barWindow.px(correctHeight))
canvasSize: Qt.size(Math.ceil(correctWidth), Math.ceil(correctHeight))
property real wing: SettingsData.dankBarGothCornersEnabled ? barWindow._wingR : 0
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.cornerRadius
@@ -40,7 +40,6 @@ Item {
Connections {
target: barWindow
function on_BgColorChanged() { barShape.requestPaint() }
function on_DprChanged() { barShape.requestPaint() }
}
Connections {
@@ -50,19 +49,16 @@ Item {
onPaint: {
const ctx = getContext("2d")
const scale = barWindow._dpr
const W = barWindow.px(barWindow.isVertical ? correctHeight : correctWidth)
const H_raw = barWindow.px(barWindow.isVertical ? correctWidth : correctHeight)
const R = barWindow.px(wing)
const RT = barWindow.px(rt)
const W = barWindow.isVertical ? correctHeight : correctWidth
const H_raw = barWindow.isVertical ? correctWidth : correctHeight
const R = wing
const RT = rt
const H = H_raw - (R > 0 ? R : 0)
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
const isLeft = SettingsData.dankBarPosition === SettingsData.Position.Left
const isRight = SettingsData.dankBarPosition === SettingsData.Position.Right
ctx.scale(scale, scale)
function drawTopPath() {
ctx.beginPath()
ctx.moveTo(RT, 0)
@@ -89,7 +85,7 @@ Item {
}
ctx.reset()
ctx.clearRect(0, 0, W, H_raw)
ctx.clearRect(0, 0, Math.ceil(W), Math.ceil(H_raw))
ctx.save()
if (isBottom) {
@@ -120,7 +116,7 @@ Item {
readonly property real correctWidth: root.width
readonly property real correctHeight: root.height
canvasSize: Qt.size(barWindow.px(correctWidth), barWindow.px(correctHeight))
canvasSize: Qt.size(Math.ceil(correctWidth), Math.ceil(correctHeight))
property real wing: SettingsData.dankBarGothCornersEnabled ? barWindow._wingR : 0
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.cornerRadius
@@ -137,7 +133,6 @@ Item {
Connections {
target: barWindow
function on_BgColorChanged() { barTint.requestPaint() }
function on_DprChanged() { barTint.requestPaint() }
}
Connections {
@@ -147,19 +142,16 @@ Item {
onPaint: {
const ctx = getContext("2d")
const scale = barWindow._dpr
const W = barWindow.px(barWindow.isVertical ? correctHeight : correctWidth)
const H_raw = barWindow.px(barWindow.isVertical ? correctWidth : correctHeight)
const R = barWindow.px(wing)
const RT = barWindow.px(rt)
const W = barWindow.isVertical ? correctHeight : correctWidth
const H_raw = barWindow.isVertical ? correctWidth : correctHeight
const R = wing
const RT = rt
const H = H_raw - (R > 0 ? R : 0)
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
const isLeft = SettingsData.dankBarPosition === SettingsData.Position.Left
const isRight = SettingsData.dankBarPosition === SettingsData.Position.Right
ctx.scale(scale, scale)
function drawTopPath() {
ctx.beginPath()
ctx.moveTo(RT, 0)
@@ -186,7 +178,7 @@ Item {
}
ctx.reset()
ctx.clearRect(0, 0, W, H_raw)
ctx.clearRect(0, 0, Math.ceil(W), Math.ceil(H_raw))
ctx.save()
if (isBottom) {
@@ -211,14 +203,14 @@ Item {
Canvas {
id: barBorder
anchors.fill: parent
antialiasing: true
antialiasing: false
visible: SettingsData.dankBarBorderEnabled
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
readonly property real correctWidth: root.width
readonly property real correctHeight: root.height
canvasSize: Qt.size(barWindow.px(correctWidth), barWindow.px(correctHeight))
canvasSize: Qt.size(Math.ceil(correctWidth), Math.ceil(correctHeight))
property real wing: SettingsData.dankBarGothCornersEnabled ? barWindow._wingR : 0
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.cornerRadius
@@ -232,32 +224,28 @@ Item {
onVisibleChanged: if (visible) requestPaint()
Component.onCompleted: requestPaint()
Connections {
target: barWindow
function on_DprChanged() { barBorder.requestPaint() }
}
Connections {
target: Theme
function onSecondaryChanged() { barBorder.requestPaint() }
function onIsLightModeChanged() { barBorder.requestPaint() }
}
Connections {
target: SettingsData
function onDankBarBorderColorChanged() { barBorder.requestPaint() }
function onDankBarBorderOpacityChanged() { barBorder.requestPaint() }
function onDankBarBorderThicknessChanged() { barBorder.requestPaint() }
function onDankBarSpacingChanged() { barBorder.requestPaint() }
function onDankBarSquareCornersChanged() { barBorder.requestPaint() }
function onCornerRadiusChanged() { barBorder.requestPaint() }
}
onPaint: {
if (!borderEnabled) return
const ctx = getContext("2d")
const scale = barWindow._dpr
const W = barWindow.px(barWindow.isVertical ? correctHeight : correctWidth)
const H_raw = barWindow.px(barWindow.isVertical ? correctWidth : correctHeight)
const R = barWindow.px(wing)
const RT = barWindow.px(rt)
const W = barWindow.isVertical ? correctHeight : correctWidth
const H_raw = barWindow.isVertical ? correctWidth : correctHeight
const R = wing
const RT = rt
const H = H_raw - (R > 0 ? R : 0)
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
@@ -267,8 +255,6 @@ Item {
const spacing = SettingsData.dankBarSpacing
const hasEdgeGap = spacing > 0 || RT > 0
ctx.scale(scale, scale)
function drawTopBorder() {
ctx.beginPath()
@@ -302,7 +288,7 @@ Item {
}
ctx.reset()
ctx.clearRect(0, 0, W, H_raw)
ctx.clearRect(0, 0, Math.ceil(W), Math.ceil(H_raw))
ctx.save()
if (isBottom) {
@@ -319,9 +305,17 @@ Item {
drawTopBorder()
ctx.restore()
ctx.lineWidth = 1
ctx.strokeStyle = Theme.secondary
const key = SettingsData.dankBarBorderColor || "surfaceText"
const base = (key === "surfaceText") ? Theme.surfaceText
: (key === "primary") ? Theme.primary
: Theme.secondary
const color = Theme.withAlpha(base, SettingsData.dankBarBorderOpacity ?? 1.0)
const thickness = Math.max(1, SettingsData.dankBarBorderThickness ?? 1)
ctx.globalCompositeOperation = "source-over"
ctx.lineWidth = thickness
ctx.strokeStyle = color
ctx.stroke()
}
}
}
}

View File

@@ -3,6 +3,7 @@ import QtQuick.Controls
import QtQuick.Effects
import QtQuick.Shapes
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import Quickshell.Services.Mpris
import Quickshell.Services.Notifications
@@ -61,8 +62,17 @@ Item {
property real wingtipsRadius: Theme.cornerRadius
readonly property real _wingR: Math.max(0, wingtipsRadius)
readonly property color _bgColor: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, topBarCore?.backgroundTransparency ?? SettingsData.dankBarTransparency)
readonly property real _dpr: (barWindow.screen && barWindow.screen.devicePixelRatio) ? barWindow.screen.devicePixelRatio : 1
function px(v) { return Math.round(v * _dpr) / _dpr }
readonly property real _dpr: {
if (CompositorService.isNiri && barWindow.screen) {
const niriScale = NiriService.displayScales[barWindow.screen.name]
if (niriScale !== undefined) return niriScale
}
if (CompositorService.isHyprland && barWindow.screen) {
const hyprlandMonitor = Hyprland.monitors.values.find(m => m.name === barWindow.screen.name)
if (hyprlandMonitor?.scale !== undefined) return hyprlandMonitor.scale
}
return (barWindow.screen?.devicePixelRatio) || 1
}
property string screenName: modelData.name
readonly property int notificationCount: NotificationService.notifications.length
@@ -70,8 +80,8 @@ Item {
readonly property real widgetThickness: Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
screen: modelData
implicitHeight: !isVertical ? px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0)) : 0
implicitWidth: isVertical ? px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0)) : 0
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0), _dpr) : 0
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0), _dpr) : 0
color: "transparent"
property var nativeInhibitor: null
@@ -234,7 +244,7 @@ Item {
Item {
id: inputMask
readonly property int barThickness: px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing)
readonly property int barThickness: Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr)
readonly property bool inOverviewWithShow: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview
readonly property bool effectiveVisible: SettingsData.dankBarVisible || inOverviewWithShow
@@ -367,8 +377,8 @@ Item {
id: topBarMouseArea
y: !barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? parent.height - height : 0) : 0
x: barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.width - width : 0) : 0
height: !barWindow.isVertical ? px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing) : undefined
width: barWindow.isVertical ? px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing) : undefined
height: !barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined
width: barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined
anchors {
left: !barWindow.isVertical ? parent.left : (SettingsData.dankBarPosition === SettingsData.Position.Left ? parent.left : undefined)
right: !barWindow.isVertical ? parent.right : (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.right : undefined)
@@ -387,8 +397,8 @@ Item {
transform: Translate {
id: topBarSlide
x: barWindow.isVertical ? px(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth)) : 0
y: !barWindow.isVertical ? px(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight)) : 0
x: barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth), barWindow._dpr) : 0
y: !barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight), barWindow._dpr) : 0
Behavior on x {
NumberAnimation {
@@ -408,10 +418,10 @@ Item {
Item {
id: barUnitInset
anchors.fill: parent
anchors.leftMargin: !barWindow.isVertical ? px(SettingsData.dankBarSpacing) : (axis.edge === "left" ? px(SettingsData.dankBarSpacing) : 0)
anchors.rightMargin: !barWindow.isVertical ? px(SettingsData.dankBarSpacing) : (axis.edge === "right" ? px(SettingsData.dankBarSpacing) : 0)
anchors.topMargin: barWindow.isVertical ? px(SettingsData.dankBarSpacing) : (axis.outerVisualEdge() === "bottom" ? 0 : px(SettingsData.dankBarSpacing))
anchors.bottomMargin: barWindow.isVertical ? px(SettingsData.dankBarSpacing) : (axis.outerVisualEdge() === "bottom" ? px(SettingsData.dankBarSpacing) : 0)
anchors.leftMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "left" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.rightMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "right" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.topMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? 0 : Theme.px(SettingsData.dankBarSpacing, barWindow._dpr))
anchors.bottomMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
BarCanvas {
id: barBackground
@@ -1003,8 +1013,8 @@ Item {
}
controlCenterLoader.item.triggerScreen = barWindow.screen
controlCenterLoader.item.toggle()
if (controlCenterLoader.item.shouldBeVisible && NetworkManagerService.wifiEnabled) {
NetworkManagerService.scanWifi()
if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) {
NetworkService.scanWifi()
}
}
}

View File

@@ -311,7 +311,7 @@ DankPopout {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Health")
text: I18n.tr("Health")
font.pixelSize: Theme.fontSizeSmall
color: Theme.primary
font.weight: Font.Medium
@@ -346,7 +346,7 @@ DankPopout {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Capacity")
text: I18n.tr("Capacity")
font.pixelSize: Theme.fontSizeSmall
color: Theme.primary
font.weight: Font.Medium
@@ -415,7 +415,7 @@ DankPopout {
width: parent.width - Theme.iconSize - Theme.spacingM
StyledText {
text: qsTr("Power Profile Degradation")
text: I18n.tr("Power Profile Degradation")
font.pixelSize: Theme.fontSizeLarge
color: Theme.error
font.weight: Font.Medium

View File

@@ -100,7 +100,7 @@ DankPopout {
height: 32
StyledText {
text: qsTr("VPN Connections")
text: I18n.tr("VPN Connections")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -210,7 +210,7 @@ DankPopout {
}
StyledText {
text: qsTr("Disconnect")
text: I18n.tr("Disconnect")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -266,14 +266,14 @@ DankPopout {
}
StyledText {
text: qsTr("No VPN profiles found")
text: I18n.tr("No VPN profiles found")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: qsTr("Add a VPN in NetworkManager")
text: I18n.tr("Add a VPN in NetworkManager")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -42,26 +42,26 @@ Rectangle {
DankIcon {
name: {
if (NetworkManagerService.wifiToggling) {
if (NetworkService.wifiToggling) {
return "sync"
}
if (NetworkManagerService.networkStatus === "ethernet") {
if (NetworkService.networkStatus === "ethernet") {
return "lan"
}
return NetworkManagerService.wifiSignalIcon
return NetworkService.wifiSignalIcon
}
size: Theme.barIconSize(barThickness)
color: {
if (NetworkManagerService.wifiToggling) {
if (NetworkService.wifiToggling) {
return Theme.primary
}
return NetworkManagerService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton
return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton
}
anchors.horizontalCenter: parent.horizontalCenter
visible: root.showNetworkIcon && NetworkManagerService.networkAvailable
visible: root.showNetworkIcon && NetworkService.networkAvailable
}
DankIcon {
@@ -141,26 +141,26 @@ Rectangle {
id: networkIcon
name: {
if (NetworkManagerService.wifiToggling) {
if (NetworkService.wifiToggling) {
return "sync";
}
if (NetworkManagerService.networkStatus === "ethernet") {
if (NetworkService.networkStatus === "ethernet") {
return "lan";
}
return NetworkManagerService.wifiSignalIcon;
return NetworkService.wifiSignalIcon;
}
size: Theme.barIconSize(barThickness)
color: {
if (NetworkManagerService.wifiToggling) {
if (NetworkService.wifiToggling) {
return Theme.primary;
}
return NetworkManagerService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton;
return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton;
}
anchors.verticalCenter: parent.verticalCenter
visible: root.showNetworkIcon && NetworkManagerService.networkAvailable
visible: root.showNetworkIcon && NetworkService.networkAvailable
}

View File

@@ -91,6 +91,7 @@ Item {
}
layer.enabled: Theme.effectiveLogoColor !== ""
layer.effect: MultiEffect {
saturation: 0
colorization: 1
colorizationColor: Theme.effectiveLogoColor
brightness: SettingsData.launcherLogoBrightness
@@ -108,6 +109,7 @@ Item {
source: SettingsData.launcherLogoCustomPath ? "file://" + SettingsData.launcherLogoCustomPath.replace("file://", "") : ""
layer.enabled: Theme.effectiveLogoColor !== ""
layer.effect: MultiEffect {
saturation: 0
colorization: 1
colorizationColor: Theme.effectiveLogoColor
brightness: SettingsData.launcherLogoBrightness

View File

@@ -611,7 +611,7 @@ Rectangle {
StyledText {
anchors.centerIn: parent
text: qsTr("Close")
text: I18n.tr("Close")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal

View File

@@ -66,7 +66,10 @@ Rectangle {
const name = split[0];
const path = split[1];
const fileName = name.substring(name.lastIndexOf("/") + 1);
let fileName = name.substring(name.lastIndexOf("/") + 1);
if (fileName.startsWith("dropboxstatus")) {
fileName = `hicolor/16x16/status/${fileName}`;
}
return `file://${path}/${fileName}`;
}
if (icon.startsWith("/") && !icon.startsWith("file://")) {
@@ -445,7 +448,7 @@ Rectangle {
}
StyledText {
text: qsTr("Back")
text: I18n.tr("Back")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter

View File

@@ -131,15 +131,15 @@ DankPopout {
model: {
let tabs = [
{ icon: "dashboard", text: qsTr("Overview") },
{ icon: "music_note", text: qsTr("Media") }
{ icon: "dashboard", text: I18n.tr("Overview") },
{ icon: "music_note", text: I18n.tr("Media") }
]
if (SettingsData.weatherEnabled) {
tabs.push({ icon: "wb_sunny", text: qsTr("Weather") })
tabs.push({ icon: "wb_sunny", text: I18n.tr("Weather") })
}
tabs.push({ icon: "settings", text: qsTr("Settings"), isAction: true })
tabs.push({ icon: "settings", text: I18n.tr("Settings"), isAction: true })
return tabs
}

View File

@@ -305,7 +305,7 @@ Item {
}
StyledText {
text: qsTr("No Active Players")
text: I18n.tr("No Active Players")
font.pixelSize: Theme.fontSizeLarge
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
@@ -406,7 +406,7 @@ Item {
anchors.margins: Theme.spacingM
StyledText {
text: qsTr("Audio Output Devices (") + audioDevicesDropdown.availableDevices.length + ")"
text: I18n.tr("Audio Output Devices (") + audioDevicesDropdown.availableDevices.length + ")"
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -491,7 +491,6 @@ Item {
}
}
Behavior on color { ColorAnimation { duration: Anims.durShort } }
Behavior on border.color { ColorAnimation { duration: Anims.durShort } }
}
}
@@ -564,7 +563,7 @@ Item {
anchors.margins: Theme.spacingM
StyledText {
text: qsTr("Media Players (") + (allPlayers?.length || 0) + ")"
text: I18n.tr("Media Players (") + (allPlayers?.length || 0) + ")"
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -675,14 +674,6 @@ Item {
}
}
Behavior on color {
ColorAnimation {
duration: Anims.durShort
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
}
Behavior on border.color {
ColorAnimation {
duration: Anims.durShort
@@ -858,14 +849,6 @@ Item {
}
}
}
Behavior on color {
ColorAnimation {
duration: Anims.durShort
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
}
}
}
@@ -1024,14 +1007,6 @@ Item {
}
}
}
Behavior on color {
ColorAnimation {
duration: Anims.durShort
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
}
}
}
}

View File

@@ -53,7 +53,7 @@ Card {
}
StyledText {
text: qsTr("No Media")
text: I18n.tr("No Media")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -33,7 +33,7 @@ Card {
}
Button {
text: qsTr("Refresh")
text: I18n.tr("Refresh")
flat: true
visible: !WeatherService.weather.loading
anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -24,7 +24,7 @@ Item {
}
StyledText {
text: qsTr("No Weather Data Available")
text: I18n.tr("No Weather Data Available")
font.pixelSize: Theme.fontSizeLarge
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
@@ -257,7 +257,7 @@ Item {
spacing: 2
StyledText {
text: qsTr("Feels Like")
text: I18n.tr("Feels Like")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
@@ -304,7 +304,7 @@ Item {
spacing: 2
StyledText {
text: qsTr("Humidity")
text: I18n.tr("Humidity")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
@@ -351,7 +351,7 @@ Item {
spacing: 2
StyledText {
text: qsTr("Wind")
text: I18n.tr("Wind")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
@@ -398,7 +398,7 @@ Item {
spacing: 2
StyledText {
text: qsTr("Pressure")
text: I18n.tr("Pressure")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
@@ -445,7 +445,7 @@ Item {
spacing: 2
StyledText {
text: qsTr("Rain Chance")
text: I18n.tr("Rain Chance")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
@@ -492,14 +492,14 @@ Item {
spacing: 2
StyledText {
text: qsTr("Visibility")
text: I18n.tr("Visibility")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: qsTr("Good")
text: I18n.tr("Good")
font.pixelSize: Theme.fontSizeSmall + 1
color: Theme.surfaceText
font.weight: Font.Medium
@@ -522,7 +522,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("7-Day Forecast")
text: I18n.tr("7-Day Forecast")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium

View File

@@ -322,7 +322,21 @@ Item {
}
}
} else if (mouse.button === Qt.MiddleButton) {
if (appData && appData.appId) {
if (appData && appData.type === "window") {
const sortedToplevels = CompositorService.sortedToplevels
for (var i = 0; i < sortedToplevels.length; i++) {
const toplevel = sortedToplevels[i]
const checkId = toplevel.title + "|" + (toplevel.appId || "") + "|" + i
if (checkId === appData.uniqueId) {
toplevel.close()
break
}
}
} else if (appData && appData.type === "grouped") {
if (contextMenu) {
contextMenu.showForButton(root, appData, 40, false, cachedDesktopEntry)
}
} else if (appData && appData.appId) {
const desktopEntry = cachedDesktopEntry
if (desktopEntry) {
AppUsageHistoryData.addAppUsage({
@@ -333,7 +347,7 @@ Item {
"comment": desktopEntry.comment || ""
})
}
SessionService.launchDesktopEntry(desktopEntry)
SessionService.launchDesktopEntry(desktopEntry)
}
} else if (mouse.button === Qt.RightButton) {
if (contextMenu && appData) {

View File

@@ -232,7 +232,7 @@ PanelWindow {
anchors.right: closeButton.left
anchors.rightMargin: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
text: (modelData && modelData.title) ? modelData.title: qsTr("(Unnamed)")
text: (modelData && modelData.title) ? modelData.title: I18n.tr("(Unnamed)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -376,7 +376,7 @@ PanelWindow {
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: root.appData && root.appData.isPinned ? "Unpin from Dock" : "Pin to Dock"
text: root.appData && root.appData.isPinned ? I18n.tr("Unpin from Dock") : I18n.tr("Pin to Dock")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -423,7 +423,7 @@ PanelWindow {
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Launch on dGPU")
text: I18n.tr("Launch on dGPU")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal

View File

@@ -11,6 +11,7 @@ import Quickshell.Services.Mpris
import qs.Common
import qs.Services
import qs.Widgets
import qs.Modules.Lock
Item {
id: root
@@ -322,6 +323,8 @@ Item {
TextInput {
id: inputField
property bool syncingFromState: false
anchors.fill: parent
anchors.leftMargin: lockIcon.width + Theme.spacingM * 2
anchors.rightMargin: {
@@ -329,6 +332,9 @@ Item {
if (GreeterState.showPasswordInput && revealButton.visible) {
margin += revealButton.width
}
if (virtualKeyboardButton.visible) {
margin += virtualKeyboardButton.width
}
if (enterButton.visible) {
margin += enterButton.width + 2
}
@@ -338,6 +344,7 @@ Item {
focus: true
echoMode: GreeterState.showPasswordInput ? (parent.showPassword ? TextInput.Normal : TextInput.Password) : TextInput.Normal
onTextChanged: {
if (syncingFromState) return
if (GreeterState.showPasswordInput) {
GreeterState.passwordBuffer = text
} else {
@@ -355,13 +362,17 @@ Item {
GreeterState.showPasswordInput = true
PortalService.getGreeterUserProfileImage(GreeterState.username)
GreeterState.passwordBuffer = ""
inputField.text = ""
syncingFromState = true
text = ""
syncingFromState = false
}
}
}
Component.onCompleted: {
syncingFromState = true
text = GreeterState.showPasswordInput ? GreeterState.passwordBuffer : GreeterState.usernameInput
syncingFromState = false
if (isPrimaryScreen)
forceActiveFocus()
}
@@ -371,12 +382,18 @@ Item {
}
}
KeyboardController {
id: keyboard_controller
target: inputField
rootObject: root
}
StyledText {
id: placeholder
anchors.left: lockIcon.right
anchors.leftMargin: Theme.spacingM
anchors.right: (GreeterState.showPasswordInput && revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : parent.right))
anchors.right: (GreeterState.showPasswordInput && revealButton.visible ? revealButton.left : (virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : parent.right)))
anchors.rightMargin: 2
anchors.verticalCenter: parent.verticalCenter
text: {
@@ -413,7 +430,7 @@ Item {
StyledText {
anchors.left: lockIcon.right
anchors.leftMargin: Theme.spacingM
anchors.right: (GreeterState.showPasswordInput && revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : parent.right))
anchors.right: (GreeterState.showPasswordInput && revealButton.visible ? revealButton.left : (virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : parent.right)))
anchors.rightMargin: 2
anchors.verticalCenter: parent.verticalCenter
text: {
@@ -441,8 +458,8 @@ Item {
DankActionButton {
id: revealButton
anchors.right: enterButton.visible ? enterButton.left : parent.right
anchors.rightMargin: enterButton.visible ? 0 : Theme.spacingS
anchors.right: virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : parent.right)
anchors.rightMargin: 0
anchors.verticalCenter: parent.verticalCenter
iconName: parent.showPassword ? "visibility_off" : "visibility"
buttonSize: 32
@@ -450,6 +467,24 @@ Item {
enabled: visible
onClicked: parent.showPassword = !parent.showPassword
}
DankActionButton {
id: virtualKeyboardButton
anchors.right: enterButton.visible ? enterButton.left : parent.right
anchors.rightMargin: enterButton.visible ? 0 : Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
iconName: "keyboard"
buttonSize: 32
visible: Greetd.state === GreetdState.Inactive && !GreeterState.unlocking
enabled: visible
onClicked: {
if (keyboard_controller.isKeyboardActive) {
keyboard_controller.hide()
} else {
keyboard_controller.show()
}
}
}
DankActionButton {
id: enterButton
@@ -549,7 +584,7 @@ Item {
}
StyledText {
text: qsTr("Switch User")
text: I18n.tr("Switch User")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -1256,7 +1291,7 @@ Item {
if (sessionCmd) {
GreetdMemory.setLastSessionId(GreeterState.sessionPaths[GreeterState.currentSessionIndex])
GreetdMemory.setLastSuccessfulUser(GreeterState.username)
Greetd.launch(sessionCmd.split(" "), ["XDG_SESSION_TYPE=wayland"], true)
Greetd.launch(sessionCmd.split(" "), ["XDG_SESSION_TYPE=wayland"])
}
}
@@ -1325,7 +1360,7 @@ Item {
StyledText {
anchors.centerIn: parent
text: qsTr("Cancel")
text: I18n.tr("Cancel")
color: Theme.surfaceText
font.pixelSize: Theme.fontSizeMedium
}

View File

@@ -18,34 +18,43 @@ The easiest thing is to run `dms greeter install` or `dms` for interactive insta
### Manual
1. Install `greetd` (in most distro's standard repositories)
2. Copy `assets/dms-niri.kdl` or `assets/dms-hypr.conf` to `/etc/greetd`
- niri if you want to run the greeter under niri, hypr if you want to run the greeter under Hyprland
3. Copy `assets/greet-niri.sh` or `assets/greet-hyprland.sh` to `/usr/local/bin/start-dms-greetd.sh`
4. Edit `/etc/greetd/dms-niri.kdl` or `/etc/greetd/dms-hypr.conf` and replace `_DMS_PATH_` with the absolute path to dms, e.g. `/home/joecool/.config/quickshell/dms`
5. Edit or create `/etc/greetd/config.toml`
1. Install `greetd` (in most distro's standard repositories) and `quickshell`
2. Clone the dms project to `/etc/xdg/quickshell/dms-greeter`
```bash
sudo git clone https://github.com/AvengeMedia/DankMaterialShell.git /etc/xdg/quickshell/dms-greeter
```
3. Copy `assets/dms-greeter` to `/usr/local/bin/dms-greeter`:
```bash
sudo cp assets/dms-greeter /usr/local/bin/dms-greeter
sudo chmod +x /usr/local/bin/dms-greeter
```
4. Create greeter cache directory with proper permissions:
```bash
sudo mkdir -p /var/cache/dms-greeter
sudo chown greeter:greeter /var/cache/dms-greeter
sudo chmod 770 /var/cache/dms-greeter
```
6. Edit or create `/etc/greetd/config.toml`:
```toml
[terminal]
# The VT to run the greeter on. Can be "next", "current" or a number
# designating the VT.
vt = 1
# The default session, also known as the greeter.
[default_session]
# `agreety` is the bundled agetty/login-lookalike. You can replace `/bin/sh`
# with whatever you want started, such as `sway`.
# The user to run the command as. The privileges this user must have depends
# on the greeter. A graphical greeter may for example require the user to be
# in the `video` group.
user = "greeter"
command = "/usr/local/bin/start-dms-greetd.sh"
# Change compositor to sway or hyprland if preferred
command = "/usr/local/bin/dms-greeter --command niri"
```
Enable the greeter with `sudo systemctl enable greetd`
#### Legacy installation (deprecated)
If you prefer the old method with separate shell scripts and config files:
1. Copy `assets/dms-niri.kdl` or `assets/dms-hypr.conf` to `/etc/greetd`
2. Copy `assets/greet-niri.sh` or `assets/greet-hyprland.sh` to `/usr/local/bin/start-dms-greetd.sh`
3. Edit the config file and replace `_DMS_PATH_` with your DMS installation path
4. Configure greetd to use `/usr/local/bin/start-dms-greetd.sh`
### NixOS
To install the greeter on NixOS add the repo to your flake inputs as described in the readme. Then somewhere in your NixOS config add this to imports:
@@ -66,7 +75,30 @@ programs.dankMaterialShell.greeter = {
## Usage
To run dms in greeter mode you just need to set `DMS_RUN_GREETER=1` in the environment.
### Using dms-greeter wrapper (recommended)
The `dms-greeter` wrapper simplifies running the greeter with any compositor:
```bash
dms-greeter --command niri
dms-greeter --command hyprland
dms-greeter --command sway
dms-greeter --command niri -C /path/to/custom-niri.kdl
```
Configure greetd to use it in `/etc/greetd/config.toml`:
```toml
[terminal]
vt = 1
[default_session]
user = "greeter"
command = "/usr/local/bin/dms-greeter --command niri"
```
### Manual usage
To run dms in greeter mode you can also manually set environment variables:
```bash
DMS_RUN_GREETER=1 qs -p /path/to/dms
@@ -86,15 +118,17 @@ Wallpapers and themes and weather and clock formats and things are a TODO on the
You can synchronize those configurations with a specific user if you want greeter settings to always mirror the shell.
The greeter uses the `dms-greeter` group for file access permissions, so ensure your user and the greeter user are both members of this group.
```bash
# For core settings (theme, clock formats, etc)
sudo ln -sf ~/.config/DankMaterialShell/settings.json /etc/greetd/.dms/settings.json
sudo ln -sf ~/.config/DankMaterialShell/settings.json /var/cache/dms-greeter/settings.json
# For state (mainly you would configure wallpaper in this file)
sudo ln -sf ~/.local/state/DankMaterialShell/session.json /etc/greetd/.dms/session.json
sudo ln -sf ~/.local/state/DankMaterialShell/session.json /var/cache/dms-greeter/session.json
# For wallpaper based theming
sudo ln -sf ~/.cache/quickshell/dankshell/dms-colors.json /etc/greetd/.dms/dms-colors.json
sudo ln -sf ~/.cache/quickshell/dankshell/dms-colors.json /var/cache/dms-greeter/dms-colors.json
```
You can override the configuration path with the `DMS_GREET_CFG_DIR` environment variable, the default is `/etc/greetd/.dms`
You can override the configuration path with the `DMS_GREET_CFG_DIR` environment variable or the `--cache-dir` flag when using `dms-greeter`. The default is `/var/cache/dms-greeter`.
It should be writable by the greeter user.
The cache directory should be owned by `greeter:greeter` with `770` permissions.

174
Modules/Greetd/assets/dms-greeter Executable file
View File

@@ -0,0 +1,174 @@
#!/bin/bash
set -e
COMPOSITOR=""
COMPOSITOR_CONFIG=""
DMS_PATH="dms-greeter"
CACHE_DIR="/var/cache/dms-greeter"
show_help() {
cat << EOF
dms-greeter - DankMaterialShell greeter launcher
Usage: dms-greeter --command COMPOSITOR [OPTIONS]
Required:
--command COMPOSITOR Compositor to use (niri, hyprland, or sway)
Options:
-C, --config PATH Custom compositor config file
-p, --path PATH DMS path (config name or absolute path)
(default: dms-greeter)
--cache-dir PATH Cache directory for greeter data
(default: /var/cache/dms-greeter)
-h, --help Show this help message
Examples:
dms-greeter --command niri
dms-greeter --command hyprland -C /etc/greetd/custom-hypr.conf
dms-greeter --command sway -p /home/user/.config/quickshell/custom-dms
dms-greeter --command niri --cache-dir /tmp/dmsgreeter
EOF
}
while [[ $# -gt 0 ]]; do
case $1 in
--command)
COMPOSITOR="$2"
shift 2
;;
-C|--config)
COMPOSITOR_CONFIG="$2"
shift 2
;;
-p|--path)
DMS_PATH="$2"
shift 2
;;
--cache-dir)
CACHE_DIR="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1" >&2
show_help
exit 1
;;
esac
done
if [[ -z "$COMPOSITOR" ]]; then
echo "Error: --command COMPOSITOR is required" >&2
show_help
exit 1
fi
export XDG_SESSION_TYPE=wayland
export QT_QPA_PLATFORM=wayland
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
export EGL_PLATFORM=gbm
export DMS_RUN_GREETER=1
export DMS_GREET_CFG_DIR="$CACHE_DIR"
mkdir -p "$CACHE_DIR"
QS_CMD="qs"
if [[ "$DMS_PATH" == /* ]]; then
QS_CMD="qs -p $DMS_PATH"
else
QS_CMD="qs -c $DMS_PATH"
fi
case "$COMPOSITOR" in
niri)
if [[ -z "$COMPOSITOR_CONFIG" ]]; then
TEMP_CONFIG=$(mktemp)
cat > "$TEMP_CONFIG" << NIRI_EOF
hotkey-overlay {
skip-at-startup
}
environment {
DMS_RUN_GREETER "1"
}
spawn-at-startup "sh" "-c" "$QS_CMD; niri msg action quit --skip-confirmation"
debug {
keep-max-bpc-unchanged
}
gestures {
hot-corners {
off
}
}
layout {
background-color "#000000"
}
NIRI_EOF
COMPOSITOR_CONFIG="$TEMP_CONFIG"
else
TEMP_CONFIG=$(mktemp)
cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG"
cat >> "$TEMP_CONFIG" << NIRI_EOF
spawn-at-startup "sh" "-c" "$QS_CMD; niri msg action quit --skip-confirmation"
NIRI_EOF
COMPOSITOR_CONFIG="$TEMP_CONFIG"
fi
exec niri -c "$COMPOSITOR_CONFIG"
;;
hyprland)
if [[ -z "$COMPOSITOR_CONFIG" ]]; then
TEMP_CONFIG=$(mktemp)
cat > "$TEMP_CONFIG" << HYPRLAND_EOF
env = DMS_RUN_GREETER,1
exec = sh -c "$QS_CMD; hyprctl dispatch exit"
HYPRLAND_EOF
COMPOSITOR_CONFIG="$TEMP_CONFIG"
else
TEMP_CONFIG=$(mktemp)
cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG"
cat >> "$TEMP_CONFIG" << HYPRLAND_EOF
exec = sh -c "$QS_CMD; hyprctl dispatch exit"
HYPRLAND_EOF
COMPOSITOR_CONFIG="$TEMP_CONFIG"
fi
exec Hyprland -c "$COMPOSITOR_CONFIG"
;;
sway)
if [[ -z "$COMPOSITOR_CONFIG" ]]; then
TEMP_CONFIG=$(mktemp)
cat > "$TEMP_CONFIG" << SWAY_EOF
exec "$QS_CMD; swaymsg exit"
SWAY_EOF
COMPOSITOR_CONFIG="$TEMP_CONFIG"
else
TEMP_CONFIG=$(mktemp)
cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG"
cat >> "$TEMP_CONFIG" << SWAY_EOF
exec "$QS_CMD; swaymsg exit"
SWAY_EOF
COMPOSITOR_CONFIG="$TEMP_CONFIG"
fi
exec sway -c "$COMPOSITOR_CONFIG"
;;
*)
echo "Error: Unsupported compositor: $COMPOSITOR" >&2
echo "Supported compositors: niri, hyprland, sway" >&2
exit 1
;;
esac

View File

@@ -8,81 +8,54 @@ import qs.Services
Item {
id: root
function activate() {
loader.activeAsync = true
}
property string sharedPasswordBuffer: ""
property bool shouldLock: false
Component.onCompleted: {
if (SessionService.loginctlAvailable) {
if (SessionService.locked || SessionService.lockedHint) {
console.log("Lock: Session locked on startup")
loader.activeAsync = true
}
}
IdleService.lockComponent = root
}
Connections {
target: IdleService
function onLockRequested() {
console.log("Lock: Received lock request from IdleService")
SessionService.lockSession()
}
function activate() {
shouldLock = true
}
Connections {
target: SessionService
function onSessionLocked() {
console.log("Lock: Lock signal received -> show lock")
loader.activeAsync = true
shouldLock = true
}
function onSessionUnlocked() {
console.log("Lock: Unlock signal received -> hide lock")
loader.active = false
}
function onLoginctlStateChanged() {
if (SessionService.lockedHint && !loader.active) {
console.log("Lock: LockedHint=true -> show lock")
loader.activeAsync = true
} else if (!SessionService.locked && !SessionService.lockedHint && loader.active) {
console.log("Lock: LockedHint=false -> hide lock")
loader.active = false
}
}
function onPrepareForSleep() {
if (SessionService.preparingForSleep && SessionData.lockBeforeSuspend) {
console.log("Lock: PrepareForSleep -> lock before suspend")
loader.activeAsync = true
}
shouldLock = false
}
}
LazyLoader {
id: loader
Connections {
target: IdleService
WlSessionLock {
id: sessionLock
function onLockRequested() {
shouldLock = true
}
}
property bool unlocked: false
property string sharedPasswordBuffer: ""
WlSessionLock {
id: sessionLock
locked: true
locked: root.shouldLock
onLockedChanged: {
if (!locked) {
loader.active = false
}
}
WlSessionLockSurface {
color: "transparent"
LockSurface {
id: lockSurface
anchors.fill: parent
lock: sessionLock
sharedPasswordBuffer: sessionLock.sharedPasswordBuffer
sharedPasswordBuffer: root.sharedPasswordBuffer
onUnlockRequested: {
root.shouldLock = false
}
onPasswordChanged: newPassword => {
sessionLock.sharedPasswordBuffer = newPassword
root.sharedPasswordBuffer = newPassword
}
}
}
@@ -96,17 +69,15 @@ Item {
target: "lock"
function lock() {
console.log("Lock screen requested via IPC")
SessionService.lockSession()
shouldLock = true
}
function demo() {
console.log("Lock screen DEMO mode requested via IPC")
demoWindow.showDemo()
}
function isLocked(): bool {
return SessionService.locked || loader.active
return sessionLock.locked
}
}
}

View File

@@ -609,7 +609,7 @@ Item {
anchors.top: parent.top
anchors.left: parent.left
anchors.margins: Theme.spacingXL
text: qsTr("DEMO MODE - Click anywhere to exit")
text: I18n.tr("DEMO MODE - Click anywhere to exit")
font.pixelSize: Theme.fontSizeSmall
color: "white"
opacity: 0.7
@@ -906,20 +906,20 @@ Item {
height: 24
color: Qt.rgba(255, 255, 255, 0.2)
anchors.verticalCenter: parent.verticalCenter
visible: WeatherService.weather.available && (NetworkManagerService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio) || BatteryService.batteryAvailable)
visible: WeatherService.weather.available && (NetworkService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio) || BatteryService.batteryAvailable)
}
Row {
spacing: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
visible: NetworkManagerService.networkStatus !== "disconnected" || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio)
visible: NetworkService.networkStatus !== "disconnected" || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio)
DankIcon {
name: NetworkManagerService.networkStatus === "ethernet" ? "lan" : NetworkManagerService.wifiSignalIcon
name: NetworkService.networkStatus === "ethernet" ? "lan" : NetworkService.wifiSignalIcon
size: Theme.iconSize - 2
color: NetworkManagerService.networkStatus !== "disconnected" ? "white" : Qt.rgba(255, 255, 255, 0.5)
color: NetworkService.networkStatus !== "disconnected" ? "white" : Qt.rgba(255, 255, 255, 0.5)
anchors.verticalCenter: parent.verticalCenter
visible: NetworkManagerService.networkStatus !== "disconnected"
visible: NetworkService.networkStatus !== "disconnected"
}
DankIcon {
@@ -955,7 +955,7 @@ Item {
height: 24
color: Qt.rgba(255, 255, 255, 0.2)
anchors.verticalCenter: parent.verticalCenter
visible: BatteryService.batteryAvailable && (NetworkManagerService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio))
visible: BatteryService.batteryAvailable && (NetworkService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio))
}
Row {
@@ -1244,7 +1244,7 @@ Item {
StyledText {
anchors.centerIn: parent
text: qsTr("Cancel")
text: I18n.tr("Cancel")
color: Theme.surfaceText
font.pixelSize: Theme.fontSizeMedium
}

View File

@@ -4,33 +4,26 @@ import Quickshell
import Quickshell.Wayland
import qs.Common
WlSessionLockSurface {
Rectangle {
id: root
required property WlSessionLock lock
required property string sharedPasswordBuffer
signal passwordChanged(string newPassword)
readonly property bool locked: lock && !lock.locked
function unlock(): void {
lock.locked = false
}
signal unlockRequested()
color: "transparent"
Loader {
LockScreenContent {
anchors.fill: parent
sourceComponent: LockScreenContent {
demoMode: false
passwordBuffer: root.sharedPasswordBuffer
screenName: root.screen?.name ?? ""
onUnlockRequested: root.unlock()
onPasswordBufferChanged: {
if (root.sharedPasswordBuffer !== passwordBuffer) {
root.passwordChanged(passwordBuffer)
}
demoMode: false
passwordBuffer: root.sharedPasswordBuffer
screenName: ""
onUnlockRequested: root.unlockRequested()
onPasswordBufferChanged: {
if (root.sharedPasswordBuffer !== passwordBuffer) {
root.passwordChanged(passwordBuffer)
}
}
}

View File

@@ -254,7 +254,7 @@ Item {
FileBrowserModal {
id: saveBrowser
browserTitle: qsTr("Save Notepad File")
browserTitle: I18n.tr("Save Notepad File")
browserIcon: "save"
browserType: "notepad_save"
fileExtensions: ["*.txt", "*.md", "*.*"]
@@ -318,7 +318,7 @@ Item {
FileBrowserModal {
id: loadBrowser
browserTitle: qsTr("Open Notepad File")
browserTitle: I18n.tr("Open Notepad File")
browserIcon: "folder_open"
browserType: "notepad_load"
fileExtensions: ["*.txt", "*.md", "*.*"]
@@ -381,7 +381,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Unsaved Changes")
text: I18n.tr("Unsaved Changes")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -389,12 +389,12 @@ Item {
StyledText {
text: root.pendingAction === "new" ?
qsTr("You have unsaved changes. Save before creating a new file?") :
I18n.tr("You have unsaved changes. Save before creating a new file?") :
root.pendingAction.startsWith("close_tab_") ?
qsTr("You have unsaved changes. Save before closing this tab?") :
I18n.tr("You have unsaved changes. Save before closing this tab?") :
root.pendingAction === "load_file" || root.pendingAction === "open" ?
qsTr("You have unsaved changes. Save before opening a file?") :
qsTr("You have unsaved changes. Save before continuing?")
I18n.tr("You have unsaved changes. Save before opening a file?") :
I18n.tr("You have unsaved changes. Save before continuing?")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
width: parent.width
@@ -433,7 +433,7 @@ Item {
StyledText {
id: discardText
anchors.centerIn: parent
text: qsTr("Don't Save")
text: I18n.tr("Don't Save")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -473,7 +473,7 @@ Item {
StyledText {
id: saveAsText
anchors.centerIn: parent
text: qsTr("Save")
text: I18n.tr("Save")
font.pixelSize: Theme.fontSizeMedium
color: Theme.background
font.weight: Font.Medium

View File

@@ -119,7 +119,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: -Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Notepad Font Settings")
text: I18n.tr("Notepad Font Settings")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -136,7 +136,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: -Theme.spacingM
width: parent.width + Theme.spacingM
text: qsTr("Use Monospace Font")
text: I18n.tr("Use Monospace Font")
description: "Toggle fonts"
checked: SettingsData.notepadUseMonospace
onToggled: checked => {
@@ -148,7 +148,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: -Theme.spacingM
width: parent.width + Theme.spacingM
text: qsTr("Show Line Numbers")
text: I18n.tr("Show Line Numbers")
description: "Display line numbers in editor"
checked: SettingsData.notepadShowLineNumbers
onToggled: checked => {
@@ -191,14 +191,14 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Find in Text")
text: I18n.tr("Find in Text")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Open search bar to find text")
text: I18n.tr("Open search bar to find text")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -217,7 +217,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: -Theme.spacingM
width: parent.width + Theme.spacingM
text: qsTr("Font Family")
text: I18n.tr("Font Family")
options: cachedFontFamilies
currentValue: {
if (!SettingsData.notepadFontFamily || SettingsData.notepadFontFamily === "")
@@ -251,7 +251,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Font Size")
text: I18n.tr("Font Size")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
@@ -330,7 +330,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: -Theme.spacingM
width: parent.width + Theme.spacingM
text: qsTr("Custom Transparency")
text: I18n.tr("Custom Transparency")
description: "Override global transparency for Notepad"
checked: SettingsData.notepadTransparencyOverride >= 0
onToggled: checked => {

View File

@@ -265,7 +265,7 @@ Column {
StyledText {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
text: qsTr("Find in note...")
text: I18n.tr("Find in note...")
font: searchField.font
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
visible: searchField.text.length === 0 && !searchField.activeFocus
@@ -275,7 +275,7 @@ Column {
// Match count display
StyledText {
Layout.alignment: Qt.AlignVCenter
text: matchCount > 0 ? qsTr("%1/%2").arg(currentMatchIndex + 1).arg(matchCount) : searchQuery.length > 0 ? qsTr("No matches") : ""
text: matchCount > 0 ? I18n.tr("%1/%2").arg(currentMatchIndex + 1).arg(matchCount) : searchQuery.length > 0 ? I18n.tr("No matches") : ""
font.pixelSize: Theme.fontSizeSmall
color: matchCount > 0 ? Theme.primary : Theme.surfaceTextMedium
visible: searchQuery.length > 0
@@ -383,7 +383,7 @@ Column {
TextArea.flickable: TextArea {
id: textArea
placeholderText: qsTr("Start typing your notes here...")
placeholderText: I18n.tr("Start typing your notes here...")
placeholderTextColor: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
font.family: SettingsData.notepadUseMonospace ? SettingsData.monoFontFamily : (SettingsData.notepadFontFamily || SettingsData.fontFamily)
font.pixelSize: SettingsData.notepadFontSize * SettingsData.fontScale
@@ -508,7 +508,7 @@ Column {
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Save")
text: I18n.tr("Save")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
}
@@ -524,7 +524,7 @@ Column {
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Open")
text: I18n.tr("Open")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
}
@@ -540,7 +540,7 @@ Column {
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("New")
text: I18n.tr("New")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
}
@@ -562,13 +562,13 @@ Column {
spacing: Theme.spacingL
StyledText {
text: textArea.text.length > 0 ? qsTr("%1 characters").arg(textArea.text.length) : qsTr("Empty")
text: textArea.text.length > 0 ? I18n.tr("%1 characters").arg(textArea.text.length) : I18n.tr("Empty")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
}
StyledText {
text: qsTr("Lines: %1").arg(textArea.lineCount)
text: I18n.tr("Lines: %1").arg(textArea.lineCount)
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
visible: textArea.text.length > 0
@@ -578,17 +578,17 @@ Column {
StyledText {
text: {
if (autoSaveTimer.running) {
return qsTr("Auto-saving...")
return I18n.tr("Auto-saving...")
}
if (hasUnsavedChanges()) {
if (currentTab && currentTab.isTemporary) {
return qsTr("Unsaved note...")
return I18n.tr("Unsaved note...")
} else {
return qsTr("Unsaved changes")
return I18n.tr("Unsaved changes")
}
} else {
return qsTr("Saved")
return I18n.tr("Saved")
}
}
font.pixelSize: Theme.fontSizeSmall

View File

@@ -537,7 +537,7 @@ Rectangle {
StyledText {
id: clearText
text: qsTr("Clear")
text: I18n.tr("Clear")
color: parent.isHovered ? Theme.primary : Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
@@ -630,7 +630,7 @@ Rectangle {
StyledText {
id: clearText
text: qsTr("Clear")
text: I18n.tr("Clear")
color: clearButton.isHovered ? Theme.primary : Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium

View File

@@ -24,7 +24,7 @@ Item {
StyledText {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Nothing to see here")
text: I18n.tr("Nothing to see here")
font.pixelSize: Theme.fontSizeLarge
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3)
font.weight: Font.Medium

View File

@@ -19,7 +19,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Notifications")
text: I18n.tr("Notifications")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -53,7 +53,7 @@ Item {
StyledText {
id: tooltipText
text: qsTr("Do Not Disturb")
text: I18n.tr("Do Not Disturb")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -120,7 +120,7 @@ Item {
}
StyledText {
text: qsTr("Clear All")
text: I18n.tr("Clear All")
font.pixelSize: Theme.fontSizeSmall
color: clearArea.containsMouse ? Theme.primary : Theme.surfaceText
font.weight: Font.Medium

View File

@@ -32,7 +32,7 @@ Rectangle {
}
StyledText {
text: qsTr("Del: Clear • Shift+Del: Clear All • 1-9: Actions • F10: Help • Esc: Close")
text: I18n.tr("Del: Clear • Shift+Del: Clear All • 1-9: Actions • F10: Help • Esc: Close")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width

View File

@@ -105,7 +105,7 @@ Rectangle {
spacing: Theme.spacingM
StyledText {
text: qsTr("Notification Settings")
text: I18n.tr("Notification Settings")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Bold
color: Theme.surfaceText
@@ -128,7 +128,7 @@ Rectangle {
}
StyledText {
text: qsTr("Do Not Disturb")
text: I18n.tr("Do Not Disturb")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -150,14 +150,14 @@ Rectangle {
}
StyledText {
text: qsTr("Notification Timeouts")
text: I18n.tr("Notification Timeouts")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceVariantText
}
DankDropdown {
text: qsTr("Low Priority")
text: I18n.tr("Low Priority")
description: "Timeout for low priority notifications"
currentValue: getTimeoutText(SettingsData.notificationTimeoutLow)
options: timeoutOptions.map(opt => opt.text)
@@ -172,7 +172,7 @@ Rectangle {
}
DankDropdown {
text: qsTr("Normal Priority")
text: I18n.tr("Normal Priority")
description: "Timeout for normal priority notifications"
currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal)
options: timeoutOptions.map(opt => opt.text)
@@ -187,7 +187,7 @@ Rectangle {
}
DankDropdown {
text: qsTr("Critical Priority")
text: I18n.tr("Critical Priority")
description: "Timeout for critical priority notifications"
currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical)
options: timeoutOptions.map(opt => opt.text)
@@ -228,13 +228,13 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Notification Overlay")
text: I18n.tr("Notification Overlay")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
}
StyledText {
text: qsTr("Display all priorities over fullscreen apps")
text: I18n.tr("Display all priorities over fullscreen apps")
font.pixelSize: Theme.fontSizeSmall - 1
color: Theme.surfaceVariantText
}

View File

@@ -21,6 +21,7 @@ PanelWindow {
property bool exiting: false
property bool _isDestroying: false
property bool _finalized: false
readonly property string clearText: I18n.tr("Clear")
signal entered
signal exitFinished
@@ -476,16 +477,16 @@ PanelWindow {
anchors.rightMargin: 16
anchors.bottom: parent.bottom
anchors.bottomMargin: 8
width: Math.max(clearText.implicitWidth + 12, 50)
width: Math.max(clearTextLabel.implicitWidth + 12, 50)
height: 24
radius: 4
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
z: 20
StyledText {
id: clearText
id: clearTextLabel
text: qsTr("Clear")
text: win.clearText
color: clearButton.isHovered ? Theme.primary : Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium

View File

@@ -76,7 +76,7 @@ Column {
}
StyledText {
text: qsTr("No items added yet")
text: I18n.tr("No items added yet")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
visible: root.items.length === 0
@@ -111,7 +111,7 @@ Column {
StyledText {
anchors.centerIn: parent
text: qsTr("Remove")
text: I18n.tr("Remove")
color: Theme.errorText
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium

View File

@@ -123,7 +123,7 @@ Column {
id: addButton
width: 50
height: 36
text: qsTr("Add")
text: I18n.tr("Add")
onClicked: {
let newItem = {}
@@ -159,7 +159,7 @@ Column {
}
StyledText {
text: qsTr("Current Items")
text: I18n.tr("Current Items")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -227,7 +227,7 @@ Column {
StyledText {
anchors.centerIn: parent
text: qsTr("Remove")
text: I18n.tr("Remove")
color: Theme.onError
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
@@ -247,7 +247,7 @@ Column {
}
StyledText {
text: qsTr("No items added yet")
text: I18n.tr("No items added yet")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
visible: root.items.length === 0

View File

@@ -17,7 +17,14 @@ Item {
implicitHeight: hasPermission ? settingsColumn.implicitHeight : errorText.implicitHeight
height: implicitHeight
readonly property bool hasPermission: pluginService && pluginService.hasPermission ? pluginService.hasPermission(pluginId, "settings_write") : true
readonly property bool hasPermission: {
if (!pluginService || !pluginId) return true
const allPlugins = pluginService.availablePlugins
const plugin = allPlugins[pluginId]
if (!plugin) return true
const permissions = Array.isArray(plugin.permissions) ? plugin.permissions : []
return permissions.indexOf("settings_write") !== -1
}
Component.onCompleted: {
loadVariants()
@@ -94,11 +101,47 @@ Item {
return defaultValue
}
function findFlickable(item) {
var current = item?.parent
while (current) {
if (current.contentY !== undefined && current.contentHeight !== undefined) {
return current
}
current = current.parent
}
return null
}
function ensureItemVisible(item) {
if (!item) return
var flickable = findFlickable(root)
if (!flickable) return
var itemGlobalY = item.mapToItem(null, 0, 0).y
var itemHeight = item.height
var flickableGlobalY = flickable.mapToItem(null, 0, 0).y
var viewportHeight = flickable.height
var itemRelativeY = itemGlobalY - flickableGlobalY
var viewportTop = 0
var viewportBottom = viewportHeight
if (itemRelativeY < viewportTop) {
flickable.contentY = Math.max(0, flickable.contentY - (viewportTop - itemRelativeY) - Theme.spacingL)
} else if (itemRelativeY + itemHeight > viewportBottom) {
flickable.contentY = Math.min(
flickable.contentHeight - viewportHeight,
flickable.contentY + (itemRelativeY + itemHeight - viewportBottom) + Theme.spacingL
)
}
}
StyledText {
id: errorText
visible: pluginService && !root.hasPermission
anchors.fill: parent
text: "This plugin does not have 'settings_write' permission.\n\nAdd \"permissions\": [\"settings_read\", \"settings_write\"] to plugin.json"
text: qsTr("This plugin does not have 'settings_write' permission.\n\nAdd \"permissions\": [\"settings_read\", \"settings_write\"] to plugin.json")
color: Theme.error
font.pixelSize: Theme.fontSizeMedium
wrapMode: Text.WordWrap

View File

@@ -194,7 +194,7 @@ Column {
spacing: 4
StyledText {
text: qsTr("Memory")
text: I18n.tr("Memory")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
@@ -269,7 +269,7 @@ Column {
spacing: 4
StyledText {
text: qsTr("Swap")
text: I18n.tr("Swap")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
@@ -359,7 +359,7 @@ Column {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Network")
text: I18n.tr("Network")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Bold
color: Theme.surfaceText
@@ -425,7 +425,7 @@ Column {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Disk")
text: I18n.tr("Disk")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Bold
color: Theme.surfaceText

View File

@@ -85,7 +85,7 @@ Popup {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Copy PID")
text: I18n.tr("Copy PID")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -118,7 +118,7 @@ Popup {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Copy Process Name")
text: I18n.tr("Copy Process Name")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -168,7 +168,7 @@ Popup {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Kill Process")
text: I18n.tr("Kill Process")
font.pixelSize: Theme.fontSizeSmall
color: parent.enabled ? (killArea.containsMouse ? Theme.error : Theme.surfaceText) : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
font.weight: Font.Normal
@@ -204,7 +204,7 @@ Popup {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Force Kill Process")
text: I18n.tr("Force Kill Process")
font.pixelSize: Theme.fontSizeSmall
color: parent.enabled ? (forceKillArea.containsMouse ? Theme.error : Theme.surfaceText) : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
font.weight: Font.Normal

View File

@@ -38,7 +38,7 @@ Column {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Process")
text: I18n.tr("Process")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: DgopService.currentSort === "name" ? Font.Bold : Font.Medium

View File

@@ -48,7 +48,7 @@ Row {
spacing: 2
StyledText {
text: qsTr("CPU")
text: I18n.tr("CPU")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: DgopService.sortBy === "cpu" ? Theme.primary : Theme.secondary
@@ -163,7 +163,7 @@ Row {
spacing: 2
StyledText {
text: qsTr("Memory")
text: I18n.tr("Memory")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: DgopService.sortBy === "memory" ? Theme.primary : Theme.secondary
@@ -315,7 +315,7 @@ Row {
spacing: 2
StyledText {
text: qsTr("GPU")
text: I18n.tr("GPU")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.secondary
@@ -388,7 +388,7 @@ Row {
id: gpuContextMenu
MenuItem {
text: qsTr("Enable GPU Temperature")
text: I18n.tr("Enable GPU Temperature")
checkable: true
checked: {
if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) {

View File

@@ -127,7 +127,7 @@ DankFlickable {
}
StyledText {
text: qsTr("System")
text: I18n.tr("System")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
@@ -411,7 +411,7 @@ DankFlickable {
}
StyledText {
text: qsTr("Storage & Disks")
text: I18n.tr("Storage & Disks")
font.pixelSize: Theme.fontSizeLarge
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
@@ -431,7 +431,7 @@ DankFlickable {
spacing: Theme.spacingS
StyledText {
text: qsTr("Device")
text: I18n.tr("Device")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
@@ -442,7 +442,7 @@ DankFlickable {
}
StyledText {
text: qsTr("Mount")
text: I18n.tr("Mount")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
@@ -453,7 +453,7 @@ DankFlickable {
}
StyledText {
text: qsTr("Size")
text: I18n.tr("Size")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
@@ -464,7 +464,7 @@ DankFlickable {
}
StyledText {
text: qsTr("Used")
text: I18n.tr("Used")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
@@ -475,7 +475,7 @@ DankFlickable {
}
StyledText {
text: qsTr("Available")
text: I18n.tr("Available")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
@@ -486,7 +486,7 @@ DankFlickable {
}
StyledText {
text: qsTr("Use%")
text: I18n.tr("Use%")
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold

View File

@@ -248,7 +248,7 @@ Item {
}
StyledText {
text: qsTr("About")
text: I18n.tr("About")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -258,7 +258,7 @@ Item {
StyledText {
text: `dms is a highly customizable, modern desktop shell with a <a href="https://m3.material.io/" style="text-decoration:none; color:${Theme.primary};">material 3 inspired</a> design.
<br /><br/>It is built on top of <a href="https://quickshell.org" style="text-decoration:none; color:${Theme.primary};">Quickshell</a>, a QT6 framework for building desktop shells.
<br /><br/>It is built with <a href="https://quickshell.org" style="text-decoration:none; color:${Theme.primary};">Quickshell</a>, a QT6 framework for building desktop shells, and <a href="https://go.dev" style="text-decoration:none; color:${Theme.primary};">Go</a>, a statically typed, compiled programming language.
`
textFormat: Text.RichText
font.pixelSize: Theme.fontSizeMedium
@@ -307,7 +307,7 @@ Item {
}
StyledText {
text: qsTr("Technical Details")
text: I18n.tr("Technical Details")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -322,7 +322,7 @@ Item {
rowSpacing: Theme.spacingS
StyledText {
text: qsTr("Framework:")
text: I18n.tr("Framework:")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -345,20 +345,20 @@ Item {
}
StyledText {
text: qsTr("Language:")
text: I18n.tr("Language:")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("QML (Qt Modeling Language)")
text: I18n.tr("QML, JavaScript, Go")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("Compositor:")
text: I18n.tr("Compositor:")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -410,7 +410,7 @@ Item {
}
StyledText {
text: qsTr("Github:")
text: I18n.tr("Github:")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -437,7 +437,7 @@ Item {
}
StyledText {
text: qsTr("- Support Us With a Star ⭐")
text: I18n.tr("- Support Us With a Star ⭐")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
@@ -445,7 +445,7 @@ Item {
}
StyledText {
text: qsTr("System Monitoring:")
text: I18n.tr("System Monitoring:")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -472,7 +472,7 @@ Item {
}
StyledText {
text: qsTr("- Stateless System Monitoring")
text: I18n.tr("- Stateless System Monitoring")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
@@ -480,7 +480,7 @@ Item {
}
StyledText {
text: qsTr("Dank Suite:")
text: I18n.tr("Dank Suite:")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText

View File

@@ -22,170 +22,170 @@ Item {
property var baseWidgetDefinitions: {
var coreWidgets = [{
"id": "launcherButton",
"text": "App Launcher",
"description": "Quick access to application launcher",
"text": I18n.tr("App Launcher"),
"description": I18n.tr("Quick access to application launcher"),
"icon": "apps",
"enabled": true
}, {
"id": "workspaceSwitcher",
"text": "Workspace Switcher",
"description": "Shows current workspace and allows switching",
"text": I18n.tr("Workspace Switcher"),
"description": I18n.tr("Shows current workspace and allows switching"),
"icon": "view_module",
"enabled": true
}, {
"id": "focusedWindow",
"text": "Focused Window",
"description": "Display currently focused application title",
"text": I18n.tr("Focused Window"),
"description": I18n.tr("Display currently focused application title"),
"icon": "window",
"enabled": true
}, {
"id": "runningApps",
"text": "Running Apps",
"description": "Shows all running applications with focus indication",
"text": I18n.tr("Running Apps"),
"description": I18n.tr("Shows all running applications with focus indication"),
"icon": "apps",
"enabled": true
}, {
"id": "clock",
"text": "Clock",
"description": "Current time and date display",
"text": I18n.tr("Clock"),
"description": I18n.tr("Current time and date display"),
"icon": "schedule",
"enabled": true
}, {
"id": "weather",
"text": "Weather Widget",
"description": "Current weather conditions and temperature",
"text": I18n.tr("Weather Widget"),
"description": I18n.tr("Current weather conditions and temperature"),
"icon": "wb_sunny",
"enabled": true
}, {
"id": "music",
"text": "Media Controls",
"description": "Control currently playing media",
"text": I18n.tr("Media Controls"),
"description": I18n.tr("Control currently playing media"),
"icon": "music_note",
"enabled": true
}, {
"id": "clipboard",
"text": "Clipboard Manager",
"description": "Access clipboard history",
"text": I18n.tr("Clipboard Manager"),
"description": I18n.tr("Access clipboard history"),
"icon": "content_paste",
"enabled": true
}, {
"id": "cpuUsage",
"text": "CPU Usage",
"description": "CPU usage indicator",
"text": I18n.tr("CPU Usage"),
"description": I18n.tr("CPU usage indicator"),
"icon": "memory",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
}, {
"id": "memUsage",
"text": "Memory Usage",
"description": "Memory usage indicator",
"text": I18n.tr("Memory Usage"),
"description": I18n.tr("Memory usage indicator"),
"icon": "developer_board",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
}, {
"id": "diskUsage",
"text": "Disk Usage",
"description": "Percentage",
"text": I18n.tr("Disk Usage"),
"description": I18n.tr("Percentage"),
"icon": "storage",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
}, {
"id": "cpuTemp",
"text": "CPU Temperature",
"description": "CPU temperature display",
"text": I18n.tr("CPU Temperature"),
"description": I18n.tr("CPU temperature display"),
"icon": "device_thermostat",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
}, {
"id": "gpuTemp",
"text": "GPU Temperature",
"description": "GPU temperature display",
"text": I18n.tr("GPU Temperature"),
"description": I18n.tr("GPU temperature display"),
"icon": "auto_awesome_mosaic",
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : "This widget prevents GPU power off states, which can significantly impact battery life on laptops. It is not recommended to use this on laptops with hybrid graphics.",
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : I18n.tr("This widget prevents GPU power off states, which can significantly impact battery life on laptops. It is not recommended to use this on laptops with hybrid graphics."),
"enabled": DgopService.dgopAvailable
}, {
"id": "systemTray",
"text": "System Tray",
"description": "System notification area icons",
"text": I18n.tr("System Tray"),
"description": I18n.tr("System notification area icons"),
"icon": "notifications",
"enabled": true
}, {
"id": "privacyIndicator",
"text": "Privacy Indicator",
"description": "Shows when microphone, camera, or screen sharing is active",
"text": I18n.tr("Privacy Indicator"),
"description": I18n.tr("Shows when microphone, camera, or screen sharing is active"),
"icon": "privacy_tip",
"enabled": true
}, {
"id": "controlCenterButton",
"text": "Control Center",
"description": "Access to system controls and settings",
"text": I18n.tr("Control Center"),
"description": I18n.tr("Access to system controls and settings"),
"icon": "settings",
"enabled": true
}, {
"id": "notificationButton",
"text": "Notification Center",
"description": "Access to notifications and do not disturb",
"text": I18n.tr("Notification Center"),
"description": I18n.tr("Access to notifications and do not disturb"),
"icon": "notifications",
"enabled": true
}, {
"id": "battery",
"text": "Battery",
"description": "Battery level and power management",
"text": I18n.tr("Battery"),
"description": I18n.tr("Battery level and power management"),
"icon": "battery_std",
"enabled": true
}, {
"id": "vpn",
"text": "VPN",
"description": "VPN status and quick connect",
"text": I18n.tr("VPN"),
"description": I18n.tr("VPN status and quick connect"),
"icon": "vpn_lock",
"enabled": true
}, {
"id": "idleInhibitor",
"text": "Idle Inhibitor",
"description": "Prevent screen timeout",
"text": I18n.tr("Idle Inhibitor"),
"description": I18n.tr("Prevent screen timeout"),
"icon": "motion_sensor_active",
"enabled": true
}, {
"id": "spacer",
"text": "Spacer",
"description": "Customizable empty space",
"text": I18n.tr("Spacer"),
"description": I18n.tr("Customizable empty space"),
"icon": "more_horiz",
"enabled": true
}, {
"id": "separator",
"text": "Separator",
"description": "Visual divider between widgets",
"text": I18n.tr("Separator"),
"description": I18n.tr("Visual divider between widgets"),
"icon": "remove",
"enabled": true
},
{
"id": "network_speed_monitor",
"text": "Network Speed Monitor",
"description": "Network download and upload speed display",
"text": I18n.tr("Network Speed Monitor"),
"description": I18n.tr("Network download and upload speed display"),
"icon": "network_check",
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined,
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined,
"enabled": DgopService.dgopAvailable
}, {
"id": "keyboard_layout_name",
"text": "Keyboard Layout Name",
"description": "Displays the active keyboard layout and allows switching",
"text": I18n.tr("Keyboard Layout Name"),
"description": I18n.tr("Displays the active keyboard layout and allows switching"),
"icon": "keyboard",
}, {
"id": "notepadButton",
"text": "Notepad",
"description": "Quick access to notepad",
"text": I18n.tr("Notepad"),
"description": I18n.tr("Quick access to notepad"),
"icon": "assignment",
"enabled": true
}, {
"id": "colorPicker",
"text": "Color Picker",
"description": "Quick access to color picker",
"text": I18n.tr("Color Picker"),
"description": I18n.tr("Quick access to color picker"),
"icon": "palette",
"enabled": true
}, {
"id": "systemUpdate",
"text": "System Update",
"description": "Check for system updates",
"text": I18n.tr("System Update"),
"description": I18n.tr("Check for system updates"),
"icon": "update",
"enabled": SystemUpdateService.distributionSupported
}]
@@ -199,7 +199,7 @@ Item {
"description": variant.description,
"icon": variant.icon,
"enabled": variant.loaded,
"warning": !variant.loaded ? "Plugin is disabled - enable in Plugins settings to use" : undefined
"warning": !variant.loaded ? I18n.tr("Plugin is disabled - enable in Plugins settings to use") : undefined
})
}
@@ -695,7 +695,7 @@ Item {
}
StyledText {
text: qsTr("Position")
text: I18n.tr("Position")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -765,14 +765,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Auto-hide")
text: I18n.tr("Auto-hide")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Automatically hide the top bar to expand screen real estate")
text: I18n.tr("Automatically hide the top bar to expand screen real estate")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -817,14 +817,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: "Manual Show/Hide"
text: I18n.tr("Manual Show/Hide")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Toggle top bar visibility manually (can be controlled via IPC)")
text: I18n.tr("Toggle top bar visibility manually (can be controlled via IPC)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -871,14 +871,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Show on Overview")
text: I18n.tr("Show on Overview")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: "Always show the top bar when niri's overview is open"
text: I18n.tr("Always show the top bar when niri's overview is open")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -930,7 +930,7 @@ Item {
}
StyledText {
text: qsTr("Spacing")
text: I18n.tr("Spacing")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -942,14 +942,51 @@ Item {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: "Edge Spacing (0 = edge-to-edge)"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
Row {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Edge Spacing (0 = edge-to-edge)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - edgeSpacingText.implicitWidth - resetEdgeSpacingBtn.width - Theme.spacingS - Theme.spacingM
height: 1
StyledText {
id: edgeSpacingText
visible: false
text: I18n.tr("Edge Spacing (0 = edge-to-edge)")
font.pixelSize: Theme.fontSizeSmall
}
}
DankActionButton {
id: resetEdgeSpacingBtn
buttonSize: 20
iconName: "refresh"
iconSize: 12
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
onClicked: {
SettingsData.setDankBarSpacing(4)
}
}
Item {
width: Theme.spacingS
height: 1
}
}
DankSlider {
id: edgeSpacingSlider
width: parent.width
height: 24
value: SettingsData.dankBarSpacing
@@ -963,6 +1000,13 @@ Item {
SettingsData.setDankBarSpacing(
newValue)
}
Binding {
target: edgeSpacingSlider
property: "value"
value: SettingsData.dankBarSpacing
restoreMode: Binding.RestoreBinding
}
}
}
@@ -970,19 +1014,56 @@ Item {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: qsTr("Exclusive Zone Offset")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
Row {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Exclusive Zone Offset")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - exclusiveZoneText.implicitWidth - resetExclusiveZoneBtn.width - Theme.spacingS - Theme.spacingM
height: 1
StyledText {
id: exclusiveZoneText
visible: false
text: I18n.tr("Exclusive Zone Offset")
font.pixelSize: Theme.fontSizeSmall
}
}
DankActionButton {
id: resetExclusiveZoneBtn
buttonSize: 20
iconName: "refresh"
iconSize: 12
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
onClicked: {
SettingsData.setDankBarBottomGap(0)
}
}
Item {
width: Theme.spacingS
height: 1
}
}
DankSlider {
id: exclusiveZoneSlider
width: parent.width
height: 24
value: SettingsData.dankBarBottomGap
minimum: -100
maximum: 100
minimum: -50
maximum: 50
unit: ""
showValue: true
wheelEnabled: false
@@ -991,6 +1072,13 @@ Item {
SettingsData.setDankBarBottomGap(
newValue)
}
Binding {
target: exclusiveZoneSlider
property: "value"
value: SettingsData.dankBarBottomGap
restoreMode: Binding.RestoreBinding
}
}
}
@@ -998,14 +1086,51 @@ Item {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: qsTr("Size")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
Row {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Size")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - sizeText.implicitWidth - resetSizeBtn.width - Theme.spacingS - Theme.spacingM
height: 1
StyledText {
id: sizeText
visible: false
text: I18n.tr("Size")
font.pixelSize: Theme.fontSizeSmall
}
}
DankActionButton {
id: resetSizeBtn
buttonSize: 20
iconName: "refresh"
iconSize: 12
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
onClicked: {
SettingsData.setDankBarInnerPadding(4)
}
}
Item {
width: Theme.spacingS
height: 1
}
}
DankSlider {
id: sizeSlider
width: parent.width
height: 24
value: SettingsData.dankBarInnerPadding
@@ -1019,13 +1144,20 @@ Item {
SettingsData.setDankBarInnerPadding(
newValue)
}
Binding {
target: sizeSlider
property: "value"
value: SettingsData.dankBarInnerPadding
restoreMode: Binding.RestoreBinding
}
}
}
DankToggle {
width: parent.width
text: qsTr("Square Corners")
text: I18n.tr("Square Corners")
description: "Removes rounded corners from bar container."
checked: SettingsData.dankBarSquareCorners
onToggled: checked => {
@@ -1036,7 +1168,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("No Background")
text: I18n.tr("No Background")
description: "Remove widget backgrounds for a minimal look with tighter spacing."
checked: SettingsData.dankBarNoBackground
onToggled: checked => {
@@ -1047,7 +1179,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Goth Corners")
text: I18n.tr("Goth Corners")
description: "Add curved swooping tips at the bottom of the bar."
checked: SettingsData.dankBarGothCornersEnabled
onToggled: checked => {
@@ -1056,14 +1188,227 @@ Item {
}
}
DankToggle {
Column {
width: parent.width
text: qsTr("Border")
description: "Add a 1px border to the bar. Smart edge detection only shows border on exposed sides."
checked: SettingsData.dankBarBorderEnabled
onToggled: checked => {
SettingsData.setDankBarBorderEnabled(checked)
}
spacing: Theme.spacingM
DankToggle {
width: parent.width
text: I18n.tr("Border")
description: "Add a 1px border to the bar. Smart edge detection only shows border on exposed sides."
checked: SettingsData.dankBarBorderEnabled
onToggled: checked => {
SettingsData.setDankBarBorderEnabled(checked)
}
}
Column {
width: parent.width
leftPadding: Theme.spacingM
spacing: Theme.spacingM
visible: SettingsData.dankBarBorderEnabled
Rectangle {
width: parent.width - parent.leftPadding
height: 1
color: Theme.outline
opacity: 0.2
}
Row {
width: parent.width - parent.leftPadding
spacing: Theme.spacingM
Column {
width: parent.width - borderColorGroup.width - Theme.spacingM
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Border Color")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
}
StyledText {
text: I18n.tr("Choose the border accent color")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
}
}
DankButtonGroup {
id: borderColorGroup
anchors.verticalCenter: parent.verticalCenter
model: ["Surface", "Secondary", "Primary"]
currentIndex: {
const colorOption = SettingsData.dankBarBorderColor || "surfaceText"
switch (colorOption) {
case "surfaceText": return 0
case "secondary": return 1
case "primary": return 2
default: return 0
}
}
onSelectionChanged: (index, selected) => {
if (selected) {
let newColor = "surfaceText"
switch (index) {
case 0: newColor = "surfaceText"; break
case 1: newColor = "secondary"; break
case 2: newColor = "primary"; break
}
if (SettingsData.dankBarBorderColor !== newColor) {
SettingsData.dankBarBorderColor = newColor
}
}
}
}
}
Column {
width: parent.width - parent.leftPadding
spacing: Theme.spacingS
Row {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Border Opacity")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - borderOpacityText.implicitWidth - resetBorderOpacityBtn.width - Theme.spacingS - Theme.spacingM
height: 1
StyledText {
id: borderOpacityText
visible: false
text: I18n.tr("Border Opacity")
font.pixelSize: Theme.fontSizeSmall
}
}
DankActionButton {
id: resetBorderOpacityBtn
buttonSize: 20
iconName: "refresh"
iconSize: 12
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
onClicked: {
SettingsData.dankBarBorderOpacity = 1.0
}
}
Item {
width: Theme.spacingS
height: 1
}
}
DankSlider {
id: borderOpacitySlider
width: parent.width
height: 24
value: (SettingsData.dankBarBorderOpacity ?? 1.0) * 100
minimum: 0
maximum: 100
unit: "%"
showValue: true
wheelEnabled: false
thumbOutlineColor: Theme.surfaceContainerHigh
onSliderValueChanged: newValue => {
SettingsData.dankBarBorderOpacity = newValue / 100
}
Binding {
target: borderOpacitySlider
property: "value"
value: (SettingsData.dankBarBorderOpacity ?? 1.0) * 100
restoreMode: Binding.RestoreBinding
}
}
}
Column {
width: parent.width - parent.leftPadding
spacing: Theme.spacingS
Row {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Border Thickness")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - borderThicknessText.implicitWidth - resetBorderThicknessBtn.width - Theme.spacingS - Theme.spacingM
height: 1
StyledText {
id: borderThicknessText
visible: false
text: I18n.tr("Border Thickness")
font.pixelSize: Theme.fontSizeSmall
}
}
DankActionButton {
id: resetBorderThicknessBtn
buttonSize: 20
iconName: "refresh"
iconSize: 12
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
onClicked: {
SettingsData.dankBarBorderThickness = 1
}
}
Item {
width: Theme.spacingS
height: 1
}
}
DankSlider {
id: borderThicknessSlider
width: parent.width
height: 24
value: SettingsData.dankBarBorderThickness ?? 1
minimum: 1
maximum: 10
unit: "px"
showValue: true
wheelEnabled: false
thumbOutlineColor: Theme.surfaceContainerHigh
onSliderValueChanged: newValue => {
SettingsData.dankBarBorderThickness = newValue
}
Binding {
target: borderThicknessSlider
property: "value"
value: SettingsData.dankBarBorderThickness ?? 1
restoreMode: Binding.RestoreBinding
}
}
}
}
}
Rectangle {
@@ -1088,14 +1433,14 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("DankBar Font Scale")
text: I18n.tr("DankBar Font Scale")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Scale DankBar font sizes independently")
text: I18n.tr("Scale DankBar font sizes independently")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
@@ -1190,7 +1535,7 @@ Item {
StyledText {
id: widgetTitle
text: qsTr("Widget Management")
text: I18n.tr("Widget Management")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1228,7 +1573,7 @@ Item {
}
StyledText {
text: qsTr("Reset")
text: I18n.tr("Reset")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1270,7 +1615,7 @@ Item {
StyledText {
width: parent.width
text: "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely."
text: I18n.tr("Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -1372,7 +1717,7 @@ Item {
id: centerSection
anchors.fill: parent
anchors.margins: Theme.spacingL
title: qsTr("Center Section")
title: I18n.tr("Center Section")
titleIcon: "format_align_center"
sectionId: "center"
allWidgets: dankBarTab.baseWidgetDefinitions

View File

@@ -108,14 +108,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Connected Displays")
text: I18n.tr("Connected Displays")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Configure which displays show shell components")
text: I18n.tr("Configure which displays show shell components")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -131,7 +131,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Available Screens (") + Quickshell.screens.length + ")"
text: I18n.tr("Available Screens (") + Quickshell.screens.length + ")"
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
@@ -273,7 +273,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Show on screens:")
text: I18n.tr("Show on screens:")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -288,8 +288,8 @@ Item {
DankToggle {
width: parent.width
text: qsTr("All displays")
description: "Show on all connected displays"
text: I18n.tr("All displays")
description: I18n.tr("Show on all connected displays")
checked: parent.selectedScreens.includes("all")
onToggled: (checked) => {
if (checked)

View File

@@ -50,7 +50,7 @@ Item {
StyledText {
id: positionText
text: qsTr("Dock Position")
text: I18n.tr("Dock Position")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -125,14 +125,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Auto-hide Dock")
text: I18n.tr("Auto-hide Dock")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Hide the dock when not in use and reveal it when hovering near the dock area")
text: I18n.tr("Hide the dock when not in use and reveal it when hovering near the dock area")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -176,14 +176,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Show Dock")
text: I18n.tr("Show Dock")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen")
text: I18n.tr("Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -229,14 +229,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Show on Overview")
text: I18n.tr("Show on Overview")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: "Always show the dock when niri's overview is open"
text: I18n.tr("Always show the dock when niri's overview is open")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -294,14 +294,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Group by App")
text: I18n.tr("Group by App")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Group multiple windows of the same app together with a window count indicator")
text: I18n.tr("Group multiple windows of the same app together with a window count indicator")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -360,7 +360,7 @@ Item {
}
StyledText {
text: qsTr("Spacing")
text: I18n.tr("Spacing")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -373,7 +373,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Padding")
text: I18n.tr("Padding")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -401,7 +401,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Height to Edge Gap (Exclusive Zone)")
text: I18n.tr("Height to Edge Gap (Exclusive Zone)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -464,7 +464,7 @@ Item {
}
StyledText {
text: qsTr("Dock Transparency")
text: I18n.tr("Dock Transparency")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText

View File

@@ -13,7 +13,7 @@ Item {
FileBrowserModal {
id: logoFileBrowser
browserTitle: qsTr("Select Launcher Logo")
browserTitle: I18n.tr("Select Launcher Logo")
browserIcon: "image"
browserType: "generic"
filterExtensions: ["*.svg", "*.png", "*.jpg", "*.jpeg", "*.webp"]
@@ -62,7 +62,7 @@ Item {
}
StyledText {
text: qsTr("Launcher Button Logo")
text: I18n.tr("Launcher Button Logo")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -72,7 +72,7 @@ Item {
StyledText {
width: parent.width
text: qsTr("Choose the logo displayed on the launcher button in DankBar")
text: I18n.tr("Choose the logo displayed on the launcher button in DankBar")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -86,12 +86,12 @@ Item {
id: logoModeGroup
anchors.horizontalCenter: parent.horizontalCenter
model: {
const modes = [qsTr("Apps Icon"), qsTr("OS Logo")]
const modes = [I18n.tr("Apps Icon"), I18n.tr("OS Logo")]
if (CompositorService.isNiri || CompositorService.isHyprland) {
const compositorName = CompositorService.isNiri ? "niri" : "Hyprland"
modes.push(compositorName)
}
modes.push(qsTr("Custom"))
modes.push(I18n.tr("Custom"))
return modes
}
currentIndex: {
@@ -149,7 +149,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
text: SettingsData.launcherLogoCustomPath || qsTr("Select an image file...")
text: SettingsData.launcherLogoCustomPath || I18n.tr("Select an image file...")
font.pixelSize: Theme.fontSizeMedium
color: SettingsData.launcherLogoCustomPath ? Theme.surfaceText : Theme.outlineButton
width: parent.width - Theme.spacingM * 2
@@ -166,7 +166,7 @@ Item {
}
}
Row {
Column {
width: parent.width
spacing: Theme.spacingL
visible: SettingsData.launcherLogoMode !== "apps"
@@ -180,61 +180,97 @@ Item {
}
Column {
width: 120
spacing: Theme.spacingS
width: parent.width
spacing: Theme.spacingM
StyledText {
text: qsTr("Color Override")
text: I18n.tr("Color Override")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
width: 32
height: 32
radius: 16
color: SettingsData.launcherLogoColorOverride !== "" ? SettingsData.launcherLogoColorOverride : Qt.rgba(255, 255, 255, 0.9)
border.color: Theme.outline
border.width: 1
Row {
anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.spacingM
DankIcon {
visible: SettingsData.launcherLogoColorOverride === ""
anchors.centerIn: parent
name: "palette"
size: 18
color: "black"
DankButtonGroup {
id: colorModeGroup
model: [I18n.tr("Default"), I18n.tr("Primary"), I18n.tr("Surface"), I18n.tr("Custom")]
currentIndex: {
const override = SettingsData.launcherLogoColorOverride
if (override === "") return 0
if (override === "primary") return 1
if (override === "surface") return 2
return 3
}
onSelectionChanged: (index, selected) => {
if (!selected) return
if (index === 0) {
SettingsData.setLauncherLogoColorOverride("")
} else if (index === 1) {
SettingsData.setLauncherLogoColorOverride("primary")
} else if (index === 2) {
SettingsData.setLauncherLogoColorOverride("surface")
} else if (index === 3) {
const currentOverride = SettingsData.launcherLogoColorOverride
const isPreset = currentOverride === "" || currentOverride === "primary" || currentOverride === "surface"
if (isPreset) {
SettingsData.setLauncherLogoColorOverride("#ffffff")
}
}
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (PopoutService.colorPickerModal) {
PopoutService.colorPickerModal.selectedColor = SettingsData.launcherLogoColorOverride !== "" ? SettingsData.launcherLogoColorOverride : Qt.rgba(0, 0, 0, 0)
PopoutService.colorPickerModal.pickerTitle = qsTr("Choose Launcher Logo Color")
PopoutService.colorPickerModal.onColorSelectedCallback = function(selectedColor) {
SettingsData.setLauncherLogoColorOverride(selectedColor)
Rectangle {
visible: {
const override = SettingsData.launcherLogoColorOverride
return override !== "" && override !== "primary" && override !== "surface"
}
width: 36
height: 36
radius: 18
color: {
const override = SettingsData.launcherLogoColorOverride
if (override !== "" && override !== "primary" && override !== "surface") {
return override
}
return "#ffffff"
}
border.color: Theme.outline
border.width: 1
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (PopoutService.colorPickerModal) {
PopoutService.colorPickerModal.selectedColor = SettingsData.launcherLogoColorOverride
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Choose Launcher Logo Color")
PopoutService.colorPickerModal.onColorSelectedCallback = function(selectedColor) {
SettingsData.setLauncherLogoColorOverride(selectedColor)
}
PopoutService.colorPickerModal.show()
}
PopoutService.colorPickerModal.show()
}
}
}
}
}
Flow {
width: parent.width - 120 - Theme.spacingL
Column {
width: parent.width
spacing: Theme.spacingS
Column {
width: 120
spacing: Theme.spacingS
anchors.horizontalCenter: parent.horizontalCenter
StyledText {
text: qsTr("Size Offset")
text: I18n.tr("Size Offset")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -257,85 +293,107 @@ Item {
}
}
}
}
Column {
width: 120
spacing: Theme.spacingS
Item {
width: parent.width
height: customControlsFlow.height
visible: {
const override = SettingsData.launcherLogoColorOverride
return override !== "" && override !== "primary" && override !== "surface"
}
opacity: visible ? 1 : 0
StyledText {
text: qsTr("Brightness")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
DankSlider {
width: 100
height: 20
minimum: 0
maximum: 100
value: Math.round(SettingsData.launcherLogoBrightness * 100)
unit: "%"
showValue: true
wheelEnabled: false
thumbOutlineColor: Theme.surfaceContainerHigh
anchors.horizontalCenter: parent.horizontalCenter
onSliderValueChanged: newValue => {
SettingsData.setLauncherLogoBrightness(newValue / 100)
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Column {
width: 120
Flow {
id: customControlsFlow
anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.spacingS
StyledText {
text: qsTr("Contrast")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
Column {
width: 120
spacing: Theme.spacingS
DankSlider {
width: 100
height: 20
minimum: 0
maximum: 200
value: Math.round(SettingsData.launcherLogoContrast * 100)
unit: "%"
showValue: true
wheelEnabled: false
thumbOutlineColor: Theme.surfaceContainerHigh
anchors.horizontalCenter: parent.horizontalCenter
onSliderValueChanged: newValue => {
SettingsData.setLauncherLogoContrast(newValue / 100)
StyledText {
text: I18n.tr("Brightness")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
DankSlider {
width: 100
height: 20
minimum: 0
maximum: 100
value: Math.round(SettingsData.launcherLogoBrightness * 100)
unit: "%"
showValue: true
wheelEnabled: false
thumbOutlineColor: Theme.surfaceContainerHigh
anchors.horizontalCenter: parent.horizontalCenter
onSliderValueChanged: newValue => {
SettingsData.setLauncherLogoBrightness(newValue / 100)
}
}
}
}
Column {
width: 120
spacing: Theme.spacingS
visible: SettingsData.launcherLogoColorOverride !== ""
Column {
width: 120
spacing: Theme.spacingS
StyledText {
text: qsTr("Invert on mode change")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
StyledText {
text: I18n.tr("Contrast")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
DankSlider {
width: 100
height: 20
minimum: 0
maximum: 200
value: Math.round(SettingsData.launcherLogoContrast * 100)
unit: "%"
showValue: true
wheelEnabled: false
thumbOutlineColor: Theme.surfaceContainerHigh
anchors.horizontalCenter: parent.horizontalCenter
onSliderValueChanged: newValue => {
SettingsData.setLauncherLogoContrast(newValue / 100)
}
}
}
DankToggle {
width: 32
height: 18
checked: SettingsData.launcherLogoColorInvertOnMode
anchors.horizontalCenter: parent.horizontalCenter
onToggled: checked => {
SettingsData.setLauncherLogoColorInvertOnMode(checked)
Column {
width: 120
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Invert on mode change")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
DankToggle {
width: 32
height: 18
checked: SettingsData.launcherLogoColorInvertOnMode
anchors.horizontalCenter: parent.horizontalCenter
onToggled: checked => {
SettingsData.setLauncherLogoColorInvertOnMode(checked)
}
}
}
}
@@ -372,7 +430,7 @@ Item {
}
StyledText {
text: qsTr("Launch Prefix")
text: I18n.tr("Launch Prefix")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -382,7 +440,7 @@ Item {
StyledText {
width: parent.width
text: "Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers."
text: I18n.tr("Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -452,7 +510,7 @@ Item {
}
StyledText {
text: qsTr("Recently Used Apps")
text: I18n.tr("Recently Used Apps")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -482,7 +540,7 @@ Item {
StyledText {
width: parent.width
text: qsTr("Apps are ordered by usage frequency, then last used, then alphabetically.")
text: I18n.tr("Apps are ordered by usage frequency, then last used, then alphabetically.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap

View File

@@ -104,7 +104,7 @@ Item {
}
StyledText {
text: qsTr("Wallpaper")
text: I18n.tr("Wallpaper")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -438,14 +438,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Per-Mode Wallpapers")
text: I18n.tr("Per-Mode Wallpapers")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Set different wallpapers for light and dark mode")
text: I18n.tr("Set different wallpapers for light and dark mode")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
@@ -495,14 +495,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Per-Monitor Wallpapers")
text: I18n.tr("Per-Monitor Wallpapers")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Set different wallpapers for each connected monitor")
text: I18n.tr("Set different wallpapers for each connected monitor")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
@@ -527,7 +527,7 @@ Item {
leftPadding: Theme.iconSize + Theme.spacingM
StyledText {
text: qsTr("Monitor Selection:")
text: I18n.tr("Monitor Selection:")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -536,8 +536,8 @@ Item {
DankDropdown {
id: monitorDropdown
text: qsTr("Monitor")
description: "Select monitor to configure wallpaper"
text: I18n.tr("Monitor")
description: I18n.tr("Select monitor to configure wallpaper")
currentValue: selectedMonitorName || "No monitors"
options: {
var screenNames = []
@@ -584,14 +584,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Automatic Cycling")
text: I18n.tr("Automatic Cycling")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Automatically cycle through wallpapers in the same folder")
text: I18n.tr("Automatically cycle through wallpapers in the same folder")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
@@ -633,7 +633,7 @@ Item {
width: parent.width - parent.leftPadding
StyledText {
text: qsTr("Mode:")
text: I18n.tr("Mode:")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -700,8 +700,8 @@ Item {
return SessionData.wallpaperCyclingMode === "interval"
}
}
text: qsTr("Interval")
description: "How often to change wallpaper"
text: I18n.tr("Interval")
description: I18n.tr("How often to change wallpaper")
options: intervalOptions
currentValue: {
var currentSeconds
@@ -755,7 +755,7 @@ Item {
width: parent.width - parent.leftPadding
StyledText {
text: qsTr("Daily at:")
text: I18n.tr("Daily at:")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -830,7 +830,7 @@ Item {
}
StyledText {
text: qsTr("24-hour format")
text: I18n.tr("24-hour format")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
@@ -847,8 +847,8 @@ Item {
}
DankDropdown {
text: qsTr("Transition Effect")
description: "Visual effect used when wallpaper changes"
text: I18n.tr("Transition Effect")
description: I18n.tr("Visual effect used when wallpaper changes")
currentValue: {
if (SessionData.wallpaperTransition === "random") return "Random"
return SessionData.wallpaperTransition.charAt(0).toUpperCase() + SessionData.wallpaperTransition.slice(1)
@@ -866,14 +866,14 @@ Item {
visible: SessionData.wallpaperTransition === "random"
StyledText {
text: qsTr("Include Transitions")
text: I18n.tr("Include Transitions")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
}
StyledText {
text: qsTr("Select which transitions to include in randomization")
text: I18n.tr("Select which transitions to include in randomization")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -938,14 +938,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Dynamic Theming")
text: I18n.tr("Dynamic Theming")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Automatically extract colors from wallpaper")
text: I18n.tr("Automatically extract colors from wallpaper")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -970,7 +970,7 @@ Item {
DankDropdown {
id: personalizationMatugenPaletteDropdown
text: qsTr("Matugen Palette")
text: I18n.tr("Matugen Palette")
description: "Select the palette algorithm used for wallpaper-based colors"
options: Theme.availableMatugenSchemes.map(function (option) { return option.label })
currentValue: Theme.getMatugenScheme(SettingsData.matugenScheme).label
@@ -999,7 +999,7 @@ Item {
}
StyledText {
text: qsTr("matugen not detected - dynamic theming unavailable")
text: I18n.tr("matugen not detected - dynamic theming unavailable")
font.pixelSize: Theme.fontSizeSmall
color: Theme.error
visible: ToastService.wallpaperErrorStatus === "matugen_missing"
@@ -1037,7 +1037,7 @@ Item {
}
StyledText {
text: qsTr("Display Settings")
text: I18n.tr("Display Settings")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1047,8 +1047,8 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Light Mode")
description: "Use light theme instead of dark theme"
text: I18n.tr("Light Mode")
description: I18n.tr("Use light theme instead of dark theme")
checked: SessionData.isLightMode
onToggleCompleted: checked => {
Theme.screenTransition()
@@ -1068,7 +1068,7 @@ Item {
id: nightModeToggle
width: parent.width
text: qsTr("Night Mode")
text: I18n.tr("Night Mode")
description: "Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates."
checked: DisplayService.nightModeEnabled
onToggled: checked => {
@@ -1085,8 +1085,8 @@ Item {
}
DankDropdown {
text: qsTr("Temperature")
description: "Color temperature for night mode"
text: I18n.tr("Temperature")
description: I18n.tr("Color temperature for night mode")
currentValue: SessionData.nightModeTemperature + "K"
options: {
var temps = []
@@ -1104,7 +1104,7 @@ Item {
DankToggle {
id: automaticToggle
width: parent.width
text: qsTr("Automatic Control")
text: I18n.tr("Automatic Control")
description: "Only adjust gamma based on time or location rules."
checked: SessionData.nightModeAutoEnabled
onToggled: checked => {
@@ -1187,7 +1187,7 @@ Item {
leftPadding: 45
StyledText {
text: qsTr("Hour")
text: I18n.tr("Hour")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: 50
@@ -1196,7 +1196,7 @@ Item {
}
StyledText {
text: qsTr("Minute")
text: I18n.tr("Minute")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: 50
@@ -1212,7 +1212,7 @@ Item {
StyledText {
id: startLabel
text: qsTr("Start")
text: I18n.tr("Start")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
width: 50
@@ -1260,7 +1260,7 @@ Item {
height: 32
StyledText {
text: qsTr("End")
text: I18n.tr("End")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
width: startLabel.width
@@ -1311,7 +1311,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Auto-location")
text: I18n.tr("Auto-location")
description: DisplayService.geoclueAvailable ? "Use automatic location detection (geoclue2)" : "Geoclue service not running - cannot auto-detect location"
checked: SessionData.nightModeLocationProvider === "geoclue2"
enabled: DisplayService.geoclueAvailable
@@ -1327,7 +1327,7 @@ Item {
}
StyledText {
text: qsTr("Manual Coordinates")
text: I18n.tr("Manual Coordinates")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
visible: SessionData.nightModeLocationProvider !== "geoclue2"
@@ -1341,7 +1341,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Latitude")
text: I18n.tr("Latitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -1364,7 +1364,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Longitude")
text: I18n.tr("Longitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -1385,7 +1385,7 @@ Item {
}
StyledText {
text: "Uses sunrise/sunset times to automatically adjust night mode based on your location."
text: I18n.tr("Uses sunrise/sunset times to automatically adjust night mode based on your location.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
@@ -1424,7 +1424,7 @@ Item {
}
StyledText {
text: qsTr("Notification Popups")
text: I18n.tr("Notification Popups")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1433,8 +1433,8 @@ Item {
}
DankDropdown {
text: qsTr("Popup Position")
description: "Choose where notification popups appear on screen"
text: I18n.tr("Popup Position")
description: I18n.tr("Choose where notification popups appear on screen")
currentValue: {
if (SettingsData.notificationPopupPosition === -1) {
return "Top Center"
@@ -1484,8 +1484,8 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Always Show OSD Percentage")
description: "Display volume and brightness percentage values by default in OSD popups"
text: I18n.tr("Always Show OSD Percentage")
description: I18n.tr("Display volume and brightness percentage values by default in OSD popups")
checked: SettingsData.osdAlwaysShowValue
onToggled: checked => {
SettingsData.setOsdAlwaysShowValue(checked)
@@ -1522,7 +1522,7 @@ Item {
}
StyledText {
text: qsTr("Font Settings")
text: I18n.tr("Font Settings")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1531,8 +1531,8 @@ Item {
}
DankDropdown {
text: qsTr("Font Family")
description: "Select system font family"
text: I18n.tr("Font Family")
description: I18n.tr("Select system font family")
currentValue: {
if (SettingsData.fontFamily === SettingsData.defaultFontFamily)
return "Default"
@@ -1552,8 +1552,8 @@ Item {
}
DankDropdown {
text: qsTr("Font Weight")
description: "Select font weight"
text: I18n.tr("Font Weight")
description: I18n.tr("Select font weight")
currentValue: {
switch (SettingsData.fontWeight) {
case Font.Thin:
@@ -1618,8 +1618,8 @@ Item {
}
DankDropdown {
text: qsTr("Monospace Font")
description: "Select monospace font for process list and technical displays"
text: I18n.tr("Monospace Font")
description: I18n.tr("Select monospace font for process list and technical displays")
currentValue: {
if (SettingsData.monoFontFamily === SettingsData.defaultMonoFontFamily)
return "Default"
@@ -1653,14 +1653,14 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Font Scale")
text: I18n.tr("Font Scale")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Scale all font sizes")
text: I18n.tr("Scale all font sizes")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
@@ -1752,7 +1752,7 @@ Item {
}
StyledText {
text: qsTr("Animations")
text: I18n.tr("Animations")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1765,14 +1765,14 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Animation Speed")
text: I18n.tr("Animation Speed")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
}
StyledText {
text: qsTr("Control the speed of animations throughout the interface")
text: I18n.tr("Control the speed of animations throughout the interface")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -1823,7 +1823,7 @@ Item {
}
StyledText {
text: qsTr("Lock Screen")
text: I18n.tr("Lock Screen")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1833,7 +1833,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Show Power Actions")
text: I18n.tr("Show Power Actions")
description: "Show power, restart, and logout buttons on the lock screen"
checked: SettingsData.lockScreenShowPowerActions
onToggled: checked => {

View File

@@ -58,14 +58,14 @@ FocusScope {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Plugin Management")
text: I18n.tr("Plugin Management")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
}
StyledText {
text: qsTr("Manage and configure plugins for extending DMS functionality")
text: I18n.tr("Manage and configure plugins for extending DMS functionality")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -98,7 +98,7 @@ FocusScope {
}
StyledText {
text: qsTr("DMS Plugin Manager Unavailable")
text: I18n.tr("DMS Plugin Manager Unavailable")
font.pixelSize: Theme.fontSizeSmall
color: Theme.warning
font.weight: Font.Medium
@@ -107,7 +107,7 @@ FocusScope {
}
StyledText {
text: qsTr("The DMS_SOCKET environment variable is not set or the socket is unavailable. Automated plugin management requires the DMS_SOCKET.")
text: I18n.tr("The DMS_SOCKET environment variable is not set or the socket is unavailable. Automated plugin management requires the DMS_SOCKET.")
font.pixelSize: Theme.fontSizeSmall - 1
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -121,7 +121,7 @@ FocusScope {
spacing: Theme.spacingM
DankButton {
text: qsTr("Browse")
text: I18n.tr("Browse")
iconName: "store"
enabled: DMSService.dmsAvailable
onClicked: {
@@ -130,7 +130,7 @@ FocusScope {
}
DankButton {
text: qsTr("Scan")
text: I18n.tr("Scan")
iconName: "refresh"
onClicked: {
pluginsTab.isRefreshingPlugins = true
@@ -143,7 +143,7 @@ FocusScope {
}
DankButton {
text: qsTr("Create Dir")
text: I18n.tr("Create Dir")
iconName: "create_new_folder"
onClicked: {
PluginService.createPluginDirectory()
@@ -169,7 +169,7 @@ FocusScope {
spacing: Theme.spacingM
StyledText {
text: qsTr("Plugin Directory")
text: I18n.tr("Plugin Directory")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -183,7 +183,7 @@ FocusScope {
}
StyledText {
text: qsTr("Place plugin directories here. Each plugin should have a plugin.json manifest file.")
text: I18n.tr("Place plugin directories here. Each plugin should have a plugin.json manifest file.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -207,7 +207,7 @@ FocusScope {
spacing: Theme.spacingM
StyledText {
text: qsTr("Available Plugins")
text: I18n.tr("Available Plugins")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -256,6 +256,7 @@ FocusScope {
anchors.bottomMargin: pluginDelegate.isExpanded ? settingsContainer.height : 0
hoverEnabled: true
cursorShape: pluginDelegate.hasSettings ? Qt.PointingHandCursor : Qt.ArrowCursor
enabled: !pluginDelegate.isExpanded || !pluginDelegate.hasSettings
onClicked: {
if (pluginDelegate.hasSettings) {
pluginsTab.expandedPluginId = pluginsTab.expandedPluginId === pluginDelegate.pluginId ? "" : pluginDelegate.pluginId
@@ -504,6 +505,10 @@ FocusScope {
clip: true
focus: pluginDelegate.isExpanded && pluginDelegate.hasSettings
Keys.onPressed: event => {
event.accepted = true
}
Rectangle {
anchors.fill: parent
color: Theme.surfaceContainerHighest
@@ -563,7 +568,7 @@ FocusScope {
StyledText {
width: parent.width
text: "No plugins found.\nPlace plugins in " + PluginService.pluginDirectory
text: I18n.tr("No plugins found.") + "\n" + I18n.tr("Place plugins in") + " " + PluginService.pluginDirectory
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
horizontalAlignment: Text.AlignHCenter
@@ -600,6 +605,9 @@ FocusScope {
pluginsTab.expandedPluginId = ""
}
}
function onPluginListUpdated() {
refreshPluginList()
}
}
Connections {
@@ -782,7 +790,7 @@ FocusScope {
StyledText {
id: headerText
text: qsTr("Browse Plugins")
text: I18n.tr("Browse Plugins")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -831,7 +839,7 @@ FocusScope {
}
StyledText {
text: qsTr("Install plugins from the DMS plugin registry")
text: I18n.tr("Install plugins from the DMS plugin registry")
font.pixelSize: Theme.fontSizeSmall
color: Theme.outline
width: parent.width
@@ -853,7 +861,7 @@ FocusScope {
showClearButton: true
textColor: Theme.surfaceText
font.pixelSize: Theme.fontSizeMedium
placeholderText: qsTr("Search plugins...")
placeholderText: I18n.tr("Search plugins...")
text: pluginBrowserModal.searchQuery
focus: true
ignoreLeftRightKeys: true
@@ -889,7 +897,7 @@ FocusScope {
}
StyledText {
text: qsTr("Loading plugins...")
text: I18n.tr("Loading plugins...")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
@@ -969,7 +977,7 @@ FocusScope {
StyledText {
id: firstPartyText
anchors.centerIn: parent
text: qsTr("official")
text: I18n.tr("official")
font.pixelSize: Theme.fontSizeSmall - 2
color: Theme.primary
font.weight: Font.Medium
@@ -989,7 +997,7 @@ FocusScope {
StyledText {
id: thirdPartyText
anchors.centerIn: parent
text: qsTr("3rd party")
text: I18n.tr("3rd party")
font.pixelSize: Theme.fontSizeSmall - 2
color: Theme.warning
font.weight: Font.Medium
@@ -1113,7 +1121,7 @@ FocusScope {
}
StyledText {
text: qsTr("No plugins found")
text: I18n.tr("No plugins found")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
@@ -1162,7 +1170,7 @@ FocusScope {
}
StyledText {
text: qsTr("Third-Party Plugin Warning")
text: I18n.tr("Third-Party Plugin Warning")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1172,7 +1180,7 @@ FocusScope {
StyledText {
width: parent.width
text: "Third-party plugins are created by the community and are not officially supported by DankMaterialShell.\n\nThese plugins may pose security and privacy risks - install at your own risk."
text: I18n.tr("Third-party plugins are created by the community and are not officially supported by DankMaterialShell.\n\nThese plugins may pose security and privacy risks - install at your own risk.")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
wrapMode: Text.WordWrap
@@ -1183,19 +1191,19 @@ FocusScope {
spacing: Theme.spacingS
StyledText {
text: qsTr("• Plugins may contain bugs or security issues")
text: I18n.tr("• Plugins may contain bugs or security issues")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• Review code before installation when possible")
text: I18n.tr("• Review code before installation when possible")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• Install only from trusted sources")
text: I18n.tr("• Install only from trusted sources")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -1211,13 +1219,13 @@ FocusScope {
spacing: Theme.spacingM
DankButton {
text: qsTr("Cancel")
text: I18n.tr("Cancel")
iconName: "close"
onClicked: thirdPartyConfirmModal.close()
}
DankButton {
text: qsTr("I Understand")
text: I18n.tr("I Understand")
iconName: "check"
onClicked: {
SessionData.setShowThirdPartyPlugins(true)

View File

@@ -130,7 +130,7 @@ Item {
}
StyledText {
text: qsTr("Theme Color")
text: I18n.tr("Theme Color")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -651,7 +651,7 @@ Item {
DankDropdown {
id: matugenPaletteDropdown
text: qsTr("Matugen Palette")
text: I18n.tr("Matugen Palette")
description: "Select the palette algorithm used for wallpaper-based colors"
options: Theme.availableMatugenSchemes.map(function (option) { return option.label })
currentValue: Theme.getMatugenScheme(SettingsData.matugenScheme).label
@@ -756,7 +756,7 @@ Item {
}
StyledText {
text: qsTr("Widget Styling")
text: I18n.tr("Widget Styling")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -769,7 +769,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Dank Bar Transparency")
text: I18n.tr("Dank Bar Transparency")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -803,7 +803,7 @@ Item {
StyledText {
id: transparencyLabel
text: qsTr("Dank Bar Widget Transparency")
text: I18n.tr("Dank Bar Widget Transparency")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -867,7 +867,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Popup Transparency")
text: I18n.tr("Popup Transparency")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -904,7 +904,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: "Corner Radius (0 = square corners)"
text: I18n.tr("Corner Radius (0 = square corners)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -955,7 +955,7 @@ Item {
StyledText {
id: warningText
font.pixelSize: Theme.fontSizeSmall
text: "The below settings will modify your GTK and Qt settings. If you wish to preserve your current configurations, please back them up (qt5ct.conf|qt6ct.conf and ~/.config/gtk-3.0|gtk-4.0)."
text: I18n.tr("The below settings will modify your GTK and Qt settings. If you wish to preserve your current configurations, please back them up (qt5ct.conf|qt6ct.conf and ~/.config/gtk-3.0|gtk-4.0).")
wrapMode: Text.WordWrap
width: parent.width - Theme.iconSizeSmall - Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
@@ -992,8 +992,9 @@ Item {
}
DankDropdown {
width: parent.width - Theme.iconSize - Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Icon Theme")
text: I18n.tr("Icon Theme")
description: "DankShell & System Icons\n(requires restart)"
currentValue: SettingsData.iconTheme
enableFuzzySearch: true
@@ -1046,7 +1047,7 @@ Item {
}
StyledText {
text: qsTr("System App Theming")
text: I18n.tr("System App Theming")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -1078,7 +1079,7 @@ Item {
}
StyledText {
text: qsTr("Apply GTK Colors")
text: I18n.tr("Apply GTK Colors")
font.pixelSize: Theme.fontSizeMedium
color: Theme.primary
font.weight: Font.Medium
@@ -1114,7 +1115,7 @@ Item {
}
StyledText {
text: qsTr("Apply Qt Colors")
text: I18n.tr("Apply Qt Colors")
font.pixelSize: Theme.fontSizeMedium
color: Theme.primary
font.weight: Font.Medium

View File

@@ -54,14 +54,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("24-Hour Format")
text: I18n.tr("24-Hour Format")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: "Use 24-hour time format instead of 12-hour AM/PM"
text: I18n.tr("Use 24-hour time format instead of 12-hour AM/PM")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -112,7 +112,7 @@ Item {
}
StyledText {
text: qsTr("Date Format")
text: I18n.tr("Date Format")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -122,7 +122,7 @@ Item {
DankDropdown {
height: 50
text: qsTr("Top Bar Format")
text: I18n.tr("Top Bar Format")
description: "Preview: " + (SettingsData.clockDateFormat ? new Date().toLocaleDateString(Qt.locale(), SettingsData.clockDateFormat) : new Date().toLocaleDateString(Qt.locale(), "ddd d"))
currentValue: {
if (!SettingsData.clockDateFormat || SettingsData.clockDateFormat.length === 0) {
@@ -158,7 +158,7 @@ Item {
return p.format
=== SettingsData.clockDateFormat
})
return match ? match.label: qsTr("Custom: ") + SettingsData.clockDateFormat
return match ? match.label: I18n.tr("Custom: ") + SettingsData.clockDateFormat
}
options: ["System Default", "Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
onValueChanged: value => {
@@ -185,7 +185,7 @@ Item {
DankDropdown {
height: 50
text: qsTr("Lock Screen Format")
text: I18n.tr("Lock Screen Format")
description: "Preview: " + (SettingsData.lockDateFormat ? new Date().toLocaleDateString(Qt.locale(), SettingsData.lockDateFormat) : new Date().toLocaleDateString(Qt.locale(), Locale.LongFormat))
currentValue: {
if (!SettingsData.lockDateFormat || SettingsData.lockDateFormat.length === 0) {
@@ -221,7 +221,7 @@ Item {
return p.format
=== SettingsData.lockDateFormat
})
return match ? match.label: qsTr("Custom: ") + SettingsData.lockDateFormat
return match ? match.label: I18n.tr("Custom: ") + SettingsData.lockDateFormat
}
options: ["System Default", "Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
onValueChanged: value => {
@@ -251,7 +251,7 @@ Item {
width: parent.width
visible: false
placeholderText: qsTr("Enter custom top bar format (e.g., ddd MMM d)")
placeholderText: I18n.tr("Enter custom top bar format (e.g., ddd MMM d)")
text: SettingsData.clockDateFormat
onTextChanged: {
if (visible && text)
@@ -264,7 +264,7 @@ Item {
width: parent.width
visible: false
placeholderText: qsTr("Enter custom lock screen format (e.g., dddd, MMMM d)")
placeholderText: I18n.tr("Enter custom lock screen format (e.g., dddd, MMMM d)")
text: SettingsData.lockDateFormat
onTextChanged: {
if (visible && text)
@@ -289,7 +289,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Format Legend")
text: I18n.tr("Format Legend")
font.pixelSize: Theme.fontSizeSmall
color: Theme.primary
font.weight: Font.Medium
@@ -304,31 +304,31 @@ Item {
spacing: 2
StyledText {
text: qsTr("• d - Day (1-31)")
text: I18n.tr("• d - Day (1-31)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• dd - Day (01-31)")
text: I18n.tr("• dd - Day (01-31)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• ddd - Day name (Mon)")
text: I18n.tr("• ddd - Day name (Mon)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• dddd - Day name (Monday)")
text: I18n.tr("• dddd - Day name (Monday)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• M - Month (1-12)")
text: I18n.tr("• M - Month (1-12)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -339,31 +339,31 @@ Item {
spacing: 2
StyledText {
text: qsTr("• MM - Month (01-12)")
text: I18n.tr("• MM - Month (01-12)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• MMM - Month (Jan)")
text: I18n.tr("• MMM - Month (Jan)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• MMMM - Month (January)")
text: I18n.tr("• MMMM - Month (January)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• yy - Year (24)")
text: I18n.tr("• yy - Year (24)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: qsTr("• yyyy - Year (2024)")
text: I18n.tr("• yyyy - Year (2024)")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}

View File

@@ -54,14 +54,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Enable Weather")
text: I18n.tr("Enable Weather")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Show weather information in top bar and control center")
text: I18n.tr("Show weather information in top bar and control center")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -120,14 +120,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Use Fahrenheit")
text: I18n.tr("Use Fahrenheit")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Use Fahrenheit instead of Celsius for temperature")
text: I18n.tr("Use Fahrenheit instead of Celsius for temperature")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -193,14 +193,14 @@ Item {
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: qsTr("Auto Location")
text: I18n.tr("Auto Location")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: qsTr("Automatically determine your location using your IP address")
text: I18n.tr("Automatically determine your location using your IP address")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
@@ -233,7 +233,7 @@ Item {
}
StyledText {
text: qsTr("Custom Location")
text: I18n.tr("Custom Location")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -248,7 +248,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Latitude")
text: I18n.tr("Latitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -299,7 +299,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Longitude")
text: I18n.tr("Longitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
@@ -352,7 +352,7 @@ Item {
spacing: Theme.spacingXS
StyledText {
text: qsTr("Location Search")
text: I18n.tr("Location Search")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
font.weight: Font.Medium
@@ -362,7 +362,7 @@ Item {
id: locationSearchInput
width: parent.width
currentLocation: ""
placeholderText: qsTr("New York, NY")
placeholderText: I18n.tr("New York, NY")
keyNavigationBacktab: longitudeInput
onLocationSelected: (displayName, coordinates) => {
SettingsData.setWeatherLocation(displayName, coordinates)

View File

@@ -165,10 +165,6 @@ DankModal {
root.close()
}
event.accepted = true
} else if (!searchField.activeFocus && event.text && event.text.length > 0 && event.text.match(/[a-zA-Z0-9\s]/)) {
searchField.forceActiveFocus()
searchField.insertText(event.text)
event.accepted = true
}
}
@@ -203,7 +199,7 @@ DankModal {
}
StyledText {
text: qsTr("Add Widget to ") + root.targetSection + " Section"
text: I18n.tr("Add Widget to ") + root.targetSection + " Section"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -212,7 +208,7 @@ DankModal {
}
StyledText {
text: qsTr("Select a widget to add to the ") + root.targetSection.toLowerCase(
text: I18n.tr("Select a widget to add to the ") + root.targetSection.toLowerCase(
) + " section of the top bar. You can add multiple instances of the same widget if needed."
font.pixelSize: Theme.fontSizeSmall
color: Theme.outline

View File

@@ -47,7 +47,7 @@ Item {
}
StyledText {
text: qsTr("Workspace Settings")
text: I18n.tr("Workspace Settings")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -57,7 +57,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Workspace Index Numbers")
text: I18n.tr("Workspace Index Numbers")
description: "Show workspace index numbers in the top bar workspace switcher"
checked: SettingsData.showWorkspaceIndex
onToggled: checked => {
@@ -68,7 +68,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Workspace Padding")
text: I18n.tr("Workspace Padding")
description: "Always show a minimum of 3 workspaces, even if fewer are available"
checked: SettingsData.showWorkspacePadding
onToggled: checked => {
@@ -79,7 +79,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Show Workspace Apps")
text: I18n.tr("Show Workspace Apps")
description: "Display application icons in workspace indicators"
checked: SettingsData.showWorkspaceApps
onToggled: checked => {
@@ -101,7 +101,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: qsTr("Max apps to show")
text: I18n.tr("Max apps to show")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
@@ -132,7 +132,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Per-Monitor Workspaces")
text: I18n.tr("Per-Monitor Workspaces")
description: "Show only workspaces belonging to each specific monitor."
checked: SettingsData.workspacesPerMonitor
onToggled: checked => {
@@ -170,7 +170,7 @@ Item {
}
StyledText {
text: qsTr("Media Player Settings")
text: I18n.tr("Media Player Settings")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -180,7 +180,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Wave Progress Bars")
text: I18n.tr("Wave Progress Bars")
description: "Use animated wave progress bars for media playback"
checked: SettingsData.waveProgressEnabled
onToggled: checked => {
@@ -218,7 +218,7 @@ Item {
}
StyledText {
text: qsTr("Running Apps Settings")
text: I18n.tr("Running Apps Settings")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -228,7 +228,7 @@ Item {
DankToggle {
width: parent.width
text: qsTr("Running Apps Only In Current Workspace")
text: I18n.tr("Running Apps Only In Current Workspace")
description: "Show only apps running in current workspace"
checked: SettingsData.runningAppsCurrentWorkspace
onToggled: checked => {
@@ -268,7 +268,7 @@ Item {
}
StyledText {
text: qsTr("Named Workspace Icons")
text: I18n.tr("Named Workspace Icons")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
@@ -278,7 +278,7 @@ Item {
StyledText {
width: parent.width
text: qsTr("Configure icons for named workspaces. Icons take priority over numbers when both are enabled.")
text: I18n.tr("Configure icons for named workspaces. Icons take priority over numbers when both are enabled.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.outline
wrapMode: Text.WordWrap

View File

@@ -480,7 +480,7 @@ Column {
StyledText {
id: tooltipText
anchors.centerIn: parent
text: qsTr("Compact Mode")
text: I18n.tr("Compact Mode")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
}
@@ -667,7 +667,7 @@ Column {
anchors.horizontalCenter: parent.horizontalCenter
StyledText {
text: qsTr("Add Widget")
text: I18n.tr("Add Widget")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.primary
@@ -752,7 +752,7 @@ Column {
}
StyledText {
text: qsTr("Network Icon")
text: I18n.tr("Network Icon")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -805,7 +805,7 @@ Column {
}
StyledText {
text: qsTr("Bluetooth Icon")
text: I18n.tr("Bluetooth Icon")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
@@ -858,7 +858,7 @@ Column {
}
StyledText {
text: qsTr("Audio Icon")
text: I18n.tr("Audio Icon")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal

View File

@@ -86,7 +86,7 @@ DankPopout {
height: 40
StyledText {
text: qsTr("System Updates")
text: I18n.tr("System Updates")
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
@@ -171,7 +171,7 @@ DankPopout {
return "Failed to check for updates:\n" + SystemUpdateService.errorMessage;
}
if (!SystemUpdateService.helperAvailable) {
return "No package manager found. Please install 'paru' or 'yay' to check for updates.";
return "No package manager found. Please install 'paru' or 'yay' on Arch-based systems to check for updates.";
}
if (SystemUpdateService.isChecking) {
return "Checking for updates...";
@@ -282,7 +282,7 @@ DankPopout {
}
StyledText {
text: qsTr("Update All")
text: I18n.tr("Update All")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.primary
@@ -326,7 +326,7 @@ DankPopout {
}
StyledText {
text: qsTr("Close")
text: I18n.tr("Close")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText

View File

@@ -14,6 +14,7 @@ PanelWindow {
property var modelData
property bool shouldBeVisible: false
property real frozenWidth: 0
readonly property string copiedText: I18n.tr("Copied!")
Connections {
target: ToastService
@@ -280,7 +281,7 @@ PanelWindow {
StyledText {
id: tooltipLabel
anchors.centerIn: parent
text: qsTr("Copied!")
text: root.copiedText
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
}

View File

@@ -12,7 +12,7 @@
</div>
A modern Wayland desktop shell built with [Quickshell](https://quickshell.org/) and optimized for the [niri](https://github.com/YaLTeR/niri) and [Hyprland](https://hyprland.org/) compositors.
A modern Wayland desktop shell built with [Quickshell](https://quickshell.org/) and [Go](https://go.dev/). Optimized for the [niri](https://github.com/YaLTeR/niri) and [Hyprland](https://hyprland.org/) compositors.
Features notifications, app launcher, wallpaper customization, and fully customizable with [plugins](https://github.com/AvengeMedia/dms-plugin-registry).
@@ -134,7 +134,7 @@ curl -fsSL https://install.danklinux.com | sh
### Compositor Setup
DankMaterialShell supports both **niri** and **Hyprland** compositors:
DankMaterialShell particularly aims at supporting the **niri** and **Hyprland** compositors, but it does support more wayland compositors with a diminished feature set (no monitor off, workspace switcher, overview integration, etc.):
**Niri**:
```bash
@@ -661,6 +661,16 @@ cp -R ./PLUGINS/ExampleEmojiPlugin ~/.config/DankMaterialShell/plugins
**Only install plugins from TRUSTED sources.** Plugins execute QML and javascript at runtime, plugins from third parties should be reviewed before enabling them in dms.
### nixOS - via home-manager
Add the following to your home-manager config to install a plugin:
```nix
programs.dankMaterialShell.plugins = {
ExampleEmojiPlugin.src = "${inputs.dankMaterialShell}/PLUGINS/ExampleEmojiPlugin";
};
```
### Calendar Setup
Sync your caldev compatible calendar (Google, Office365, etc.) for dashboard integration:

View File

@@ -152,30 +152,30 @@ Singleton {
return []
const categoryMap = {
"AudioVideo": qsTr("Media"),
"Audio": qsTr("Media"),
"Video": qsTr("Media"),
"Development": qsTr("Development"),
"TextEditor": qsTr("Development"),
"IDE": qsTr("Development"),
"Education": qsTr("Education"),
"Game": qsTr("Games"),
"Graphics": qsTr("Graphics"),
"Photography": qsTr("Graphics"),
"Network": qsTr("Internet"),
"WebBrowser": qsTr("Internet"),
"Email": qsTr("Internet"),
"Office": qsTr("Office"),
"WordProcessor": qsTr("Office"),
"Spreadsheet": qsTr("Office"),
"Presentation": qsTr("Office"),
"Science": qsTr("Science"),
"Settings": qsTr("Settings"),
"System": qsTr("System"),
"Utility": qsTr("Utilities"),
"Accessories": qsTr("Utilities"),
"FileManager": qsTr("Utilities"),
"TerminalEmulator": qsTr("Utilities")
"AudioVideo": I18n.tr("Media"),
"Audio": I18n.tr("Media"),
"Video": I18n.tr("Media"),
"Development": I18n.tr("Development"),
"TextEditor": I18n.tr("Development"),
"IDE": I18n.tr("Development"),
"Education": I18n.tr("Education"),
"Game": I18n.tr("Games"),
"Graphics": I18n.tr("Graphics"),
"Photography": I18n.tr("Graphics"),
"Network": I18n.tr("Internet"),
"WebBrowser": I18n.tr("Internet"),
"Email": I18n.tr("Internet"),
"Office": I18n.tr("Office"),
"WordProcessor": I18n.tr("Office"),
"Spreadsheet": I18n.tr("Office"),
"Presentation": I18n.tr("Office"),
"Science": I18n.tr("Science"),
"Settings": I18n.tr("Settings"),
"System": I18n.tr("System"),
"Utility": I18n.tr("Utilities"),
"Accessories": I18n.tr("Utilities"),
"FileManager": I18n.tr("Utilities"),
"TerminalEmulator": I18n.tr("Utilities")
}
const mappedCategories = new Set()
@@ -206,7 +206,7 @@ Singleton {
}
function getAllCategories() {
const categories = new Set([qsTr("All")])
const categories = new Set([I18n.tr("All")])
for (const app of applications) {
const appCategories = getCategoriesForApp(app)
@@ -217,7 +217,7 @@ Singleton {
}
function getAppsInCategory(category) {
if (category === qsTr("All")) {
if (category === I18n.tr("All")) {
return applications
}

Some files were not shown because too many files have changed in this diff Show More