mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
Compare commits
16 Commits
v1.2.1
...
doctor-dbu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17ec547737 | ||
|
|
f9a2ed025f | ||
|
|
f8cfbdcd90 | ||
|
|
623eec3689 | ||
|
|
53a033fe35 | ||
|
|
c490ee24f4 | ||
|
|
cc1e49294e | ||
|
|
e6fa46ae26 | ||
|
|
35fe774a1b | ||
|
|
1e6a0f9423 | ||
|
|
cc1877aadb | ||
|
|
f1eb1fa9ba | ||
|
|
bdd01e335d | ||
|
|
4b7baf82cd | ||
|
|
15c88ce1d2 | ||
|
|
8891c388d0 |
78
.github/workflows/run-obs.yml
vendored
78
.github/workflows/run-obs.yml
vendored
@@ -4,13 +4,14 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
package:
|
package:
|
||||||
description: "Package to update (dms, dms-git, or all)"
|
description: "Package to update"
|
||||||
required: false
|
required: true
|
||||||
default: "all"
|
type: choice
|
||||||
tag_version:
|
options:
|
||||||
description: "Specific tag version for dms stable (e.g., v1.0.2). Leave empty to auto-detect latest release."
|
- dms
|
||||||
required: false
|
- dms-git
|
||||||
default: ""
|
- all
|
||||||
|
default: "dms"
|
||||||
rebuild_release:
|
rebuild_release:
|
||||||
description: "Release number for rebuilds (e.g., 2, 3, 4 to increment spec Release)"
|
description: "Release number for rebuilds (e.g., 2, 3, 4 to increment spec Release)"
|
||||||
required: false
|
required: false
|
||||||
@@ -56,8 +57,9 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Helper function to check dms stable tag
|
# Helper function to check dms stable tag
|
||||||
|
# Sets LATEST_TAG variable in parent scope if update needed
|
||||||
check_dms_stable() {
|
check_dms_stable() {
|
||||||
local LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "v\?\([^"]*\)".*/\1/' || echo "")
|
LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "")
|
||||||
local OBS_SPEC=$(curl -s -u "$OBS_USERNAME:$OBS_PASSWORD" "https://api.opensuse.org/source/home:AvengeMedia:dms/dms/dms.spec" 2>/dev/null || echo "")
|
local OBS_SPEC=$(curl -s -u "$OBS_USERNAME:$OBS_PASSWORD" "https://api.opensuse.org/source/home:AvengeMedia:dms/dms/dms.spec" 2>/dev/null || echo "")
|
||||||
local OBS_VERSION=$(echo "$OBS_SPEC" | grep "^Version:" | awk '{print $2}' | xargs || echo "")
|
local OBS_VERSION=$(echo "$OBS_SPEC" | grep "^Version:" | awk '{print $2}' | xargs || echo "")
|
||||||
|
|
||||||
@@ -73,8 +75,8 @@ jobs:
|
|||||||
# Main logic
|
# Main logic
|
||||||
REBUILD="${{ github.event.inputs.rebuild_release }}"
|
REBUILD="${{ github.event.inputs.rebuild_release }}"
|
||||||
|
|
||||||
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" =~ ^refs/tags/ ]]; then
|
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then
|
||||||
# Tag push - always update stable package
|
# Tag selected or pushed - always update stable package
|
||||||
echo "packages=dms" >> $GITHUB_OUTPUT
|
echo "packages=dms" >> $GITHUB_OUTPUT
|
||||||
VERSION="${GITHUB_REF#refs/tags/}"
|
VERSION="${GITHUB_REF#refs/tags/}"
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
@@ -104,7 +106,12 @@ jobs:
|
|||||||
# Check each package and build list of those needing updates
|
# Check each package and build list of those needing updates
|
||||||
PACKAGES_TO_UPDATE=()
|
PACKAGES_TO_UPDATE=()
|
||||||
check_dms_git && PACKAGES_TO_UPDATE+=("dms-git")
|
check_dms_git && PACKAGES_TO_UPDATE+=("dms-git")
|
||||||
check_dms_stable && PACKAGES_TO_UPDATE+=("dms")
|
if check_dms_stable; then
|
||||||
|
PACKAGES_TO_UPDATE+=("dms")
|
||||||
|
if [[ -n "$LATEST_TAG" ]]; then
|
||||||
|
echo "version=$LATEST_TAG" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ${#PACKAGES_TO_UPDATE[@]} -gt 0 ]]; then
|
if [[ ${#PACKAGES_TO_UPDATE[@]} -gt 0 ]]; then
|
||||||
echo "packages=${PACKAGES_TO_UPDATE[*]}" >> $GITHUB_OUTPUT
|
echo "packages=${PACKAGES_TO_UPDATE[*]}" >> $GITHUB_OUTPUT
|
||||||
@@ -129,6 +136,9 @@ jobs:
|
|||||||
if check_dms_stable; then
|
if check_dms_stable; then
|
||||||
echo "packages=$PKG" >> $GITHUB_OUTPUT
|
echo "packages=$PKG" >> $GITHUB_OUTPUT
|
||||||
echo "has_updates=true" >> $GITHUB_OUTPUT
|
echo "has_updates=true" >> $GITHUB_OUTPUT
|
||||||
|
if [[ -n "$LATEST_TAG" ]]; then
|
||||||
|
echo "version=$LATEST_TAG" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "packages=" >> $GITHUB_OUTPUT
|
echo "packages=" >> $GITHUB_OUTPUT
|
||||||
echo "has_updates=false" >> $GITHUB_OUTPUT
|
echo "has_updates=false" >> $GITHUB_OUTPUT
|
||||||
@@ -161,12 +171,19 @@ jobs:
|
|||||||
- name: Determine packages to update
|
- name: Determine packages to update
|
||||||
id: packages
|
id: packages
|
||||||
run: |
|
run: |
|
||||||
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" =~ ^refs/tags/ ]]; then
|
# Check if GITHUB_REF points to a tag (works for both push events and workflow_dispatch with tag selected)
|
||||||
# Tag push event - use the pushed tag
|
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then
|
||||||
|
# Tag selected or pushed - use the tag from GITHUB_REF
|
||||||
echo "packages=dms" >> $GITHUB_OUTPUT
|
echo "packages=dms" >> $GITHUB_OUTPUT
|
||||||
VERSION="${GITHUB_REF#refs/tags/}"
|
VERSION="${GITHUB_REF#refs/tags/}"
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
echo "Triggered by tag: $VERSION"
|
echo "Using tag from GITHUB_REF: $VERSION"
|
||||||
|
# Check if check-updates already determined a version (from auto-detection)
|
||||||
|
elif [[ -n "${{ needs.check-updates.outputs.version }}" ]]; then
|
||||||
|
# Use version from check-updates job
|
||||||
|
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version=${{ needs.check-updates.outputs.version }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "Using version from check-updates: ${{ needs.check-updates.outputs.version }}"
|
||||||
elif [[ "${{ github.event_name }}" == "schedule" ]]; then
|
elif [[ "${{ github.event_name }}" == "schedule" ]]; then
|
||||||
# Scheduled run - dms-git only
|
# Scheduled run - dms-git only
|
||||||
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
|
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
|
||||||
@@ -176,22 +193,28 @@ jobs:
|
|||||||
|
|
||||||
# Determine version for dms stable
|
# Determine version for dms stable
|
||||||
if [[ "${{ github.event.inputs.package }}" == "dms" ]]; then
|
if [[ "${{ github.event.inputs.package }}" == "dms" ]]; then
|
||||||
# For explicit dms selection, require tag_version
|
# Use github.ref if tag selected, otherwise auto-detect latest
|
||||||
if [[ -n "${{ github.event.inputs.tag_version }}" ]]; then
|
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then
|
||||||
VERSION="${{ github.event.inputs.tag_version }}"
|
VERSION="${GITHUB_REF#refs/tags/}"
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
echo "Using specified tag: $VERSION"
|
echo "Using tag from GITHUB_REF: $VERSION"
|
||||||
else
|
else
|
||||||
echo "ERROR: tag_version is required when package=dms"
|
# Auto-detect latest release for dms
|
||||||
echo "Please specify a tag version (e.g., v1.0.2) or use package=all for auto-detection"
|
LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "")
|
||||||
exit 1
|
if [[ -n "$LATEST_TAG" ]]; then
|
||||||
|
echo "version=$LATEST_TAG" >> $GITHUB_OUTPUT
|
||||||
|
echo "Auto-detected latest release: $LATEST_TAG"
|
||||||
|
else
|
||||||
|
echo "ERROR: Could not auto-detect latest release"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
elif [[ "${{ github.event.inputs.package }}" == "all" ]]; then
|
elif [[ "${{ github.event.inputs.package }}" == "all" ]]; then
|
||||||
# For "all", auto-detect if tag_version not specified
|
# Use github.ref if tag selected, otherwise auto-detect latest
|
||||||
if [[ -n "${{ github.event.inputs.tag_version }}" ]]; then
|
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then
|
||||||
VERSION="${{ github.event.inputs.tag_version }}"
|
VERSION="${GITHUB_REF#refs/tags/}"
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
echo "Using specified tag: $VERSION"
|
echo "Using tag from GITHUB_REF: $VERSION"
|
||||||
else
|
else
|
||||||
# Auto-detect latest release for "all"
|
# Auto-detect latest release for "all"
|
||||||
LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "")
|
LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "")
|
||||||
@@ -206,7 +229,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Use filtered packages from check-updates when package="all" and no rebuild/tag specified
|
# Use filtered packages from check-updates when package="all" and no rebuild/tag specified
|
||||||
if [[ "${{ github.event.inputs.package }}" == "all" ]] && [[ -z "${{ github.event.inputs.rebuild_release }}" ]] && [[ -z "${{ github.event.inputs.tag_version }}" ]]; then
|
if [[ "${{ github.event.inputs.package }}" == "all" ]] && [[ -z "${{ github.event.inputs.rebuild_release }}" ]] && [[ ! "${{ github.ref }}" =~ ^refs/tags/ ]]; then
|
||||||
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
|
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
|
||||||
echo "Manual trigger: all (filtered to: ${{ needs.check-updates.outputs.packages }})"
|
echo "Manual trigger: all (filtered to: ${{ needs.check-updates.outputs.packages }})"
|
||||||
else
|
else
|
||||||
@@ -215,6 +238,9 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
|
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
|
||||||
|
if [[ -n "${{ needs.check-updates.outputs.version }}" ]]; then
|
||||||
|
echo "version=${{ needs.check-updates.outputs.version }}" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Update dms-git spec version
|
- name: Update dms-git spec version
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ func checkWindowManagers() []checkResult {
|
|||||||
results = append(results, checkResult{
|
results = append(results, checkResult{
|
||||||
catCompositor, c.name, statusOK,
|
catCompositor, c.name, statusOK,
|
||||||
getVersionFromCommand(c.versionCmd, c.versionArg, c.versionRegex), details,
|
getVersionFromCommand(c.versionCmd, c.versionArg, c.versionRegex), details,
|
||||||
doctorDocsURL + "#compositor",
|
doctorDocsURL + "#compositor-checks",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +486,7 @@ func checkWindowManagers() []checkResult {
|
|||||||
catCompositor, "Compositor", statusError,
|
catCompositor, "Compositor", statusError,
|
||||||
"No supported Wayland compositor found",
|
"No supported Wayland compositor found",
|
||||||
"Install Hyprland, niri, Sway, River, or Wayfire",
|
"Install Hyprland, niri, Sway, River, or Wayfire",
|
||||||
doctorDocsURL + "#compositor",
|
doctorDocsURL + "#compositor-checks",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,19 +634,14 @@ func checkI2CAvailability() checkResult {
|
|||||||
return checkResult{catOptionalFeatures, "I2C/DDC", statusOK, fmt.Sprintf("%d monitor(s) detected", len(devices)), "External monitor brightness control", doctorDocsURL + "#optional-features"}
|
return checkResult{catOptionalFeatures, "I2C/DDC", statusOK, fmt.Sprintf("%d monitor(s) detected", len(devices)), "External monitor brightness control", doctorDocsURL + "#optional-features"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func detectNetworkBackend() string {
|
func detectNetworkBackend(stackResult *network.DetectResult) string {
|
||||||
result, err := network.DetectNetworkStack()
|
switch stackResult.Backend {
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
switch result.Backend {
|
|
||||||
case network.BackendNetworkManager:
|
case network.BackendNetworkManager:
|
||||||
return "NetworkManager"
|
return "NetworkManager"
|
||||||
case network.BackendIwd:
|
case network.BackendIwd:
|
||||||
return "iwd"
|
return "iwd"
|
||||||
case network.BackendNetworkd:
|
case network.BackendNetworkd:
|
||||||
if result.HasIwd {
|
if stackResult.HasIwd {
|
||||||
return "iwd + systemd-networkd"
|
return "iwd + systemd-networkd"
|
||||||
}
|
}
|
||||||
return "systemd-networkd"
|
return "systemd-networkd"
|
||||||
@@ -657,75 +652,73 @@ func detectNetworkBackend() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOptionalDBusStatus(busName string) (status, string) {
|
||||||
|
if utils.IsDBusServiceAvailable(busName) {
|
||||||
|
return statusOK, "Available"
|
||||||
|
} else {
|
||||||
|
return statusWarn, "Not available"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func checkOptionalDependencies() []checkResult {
|
func checkOptionalDependencies() []checkResult {
|
||||||
var results []checkResult
|
var results []checkResult
|
||||||
|
|
||||||
if utils.IsServiceActive("accounts-daemon", false) {
|
optionalFeaturesURL := doctorDocsURL + "#optional-features"
|
||||||
results = append(results, checkResult{catOptionalFeatures, "accountsservice", statusOK, "Running", "User accounts", doctorDocsURL + "#optional-features"})
|
|
||||||
} else {
|
|
||||||
results = append(results, checkResult{catOptionalFeatures, "accountsservice", statusWarn, "Not running", "User accounts", doctorDocsURL + "#optional-features"})
|
|
||||||
}
|
|
||||||
|
|
||||||
if utils.IsServiceActive("power-profiles-daemon", false) {
|
accountsStatus, accountsMsg := getOptionalDBusStatus("org.freedesktop.Accounts")
|
||||||
results = append(results, checkResult{catOptionalFeatures, "power-profiles-daemon", statusOK, "Running", "Power profile management", doctorDocsURL + "#optional-features"})
|
results = append(results, checkResult{catOptionalFeatures, "accountsservice", accountsStatus, accountsMsg, "User accounts", optionalFeaturesURL})
|
||||||
} else {
|
|
||||||
results = append(results, checkResult{catOptionalFeatures, "power-profiles-daemon", statusInfo, "Not running", "Power profile management", doctorDocsURL + "#optional-features"})
|
ppdStatus, ppdMsg := getOptionalDBusStatus("org.freedesktop.UPower.PowerProfiles")
|
||||||
}
|
results = append(results, checkResult{catOptionalFeatures, "power-profiles-daemon", ppdStatus, ppdMsg, "Power profile management", optionalFeaturesURL})
|
||||||
|
|
||||||
|
logindStatus, logindMsg := getOptionalDBusStatus("org.freedesktop.login1")
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "logind", logindStatus, logindMsg, "Session management", optionalFeaturesURL})
|
||||||
|
|
||||||
results = append(results, checkI2CAvailability())
|
results = append(results, checkI2CAvailability())
|
||||||
|
|
||||||
terminals := []string{"ghostty", "kitty", "alacritty", "foot", "wezterm"}
|
terminals := []string{"ghostty", "kitty", "alacritty", "foot", "wezterm"}
|
||||||
if idx := slices.IndexFunc(terminals, utils.CommandExists); idx >= 0 {
|
if idx := slices.IndexFunc(terminals, utils.CommandExists); idx >= 0 {
|
||||||
results = append(results, checkResult{catOptionalFeatures, "Terminal", statusOK, terminals[idx], "", doctorDocsURL + "#optional-features"})
|
results = append(results, checkResult{catOptionalFeatures, "Terminal", statusOK, terminals[idx], "", optionalFeaturesURL})
|
||||||
} else {
|
} else {
|
||||||
results = append(results, checkResult{catOptionalFeatures, "Terminal", statusWarn, "None found", "Install ghostty, kitty, or alacritty", doctorDocsURL + "#optional-features"})
|
results = append(results, checkResult{catOptionalFeatures, "Terminal", statusWarn, "None found", "Install ghostty, kitty, or alacritty", optionalFeaturesURL})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
networkResult, err := network.DetectNetworkStack()
|
||||||
|
networkStatus, networkMessage, networkDetails := statusOK, "Not available", "Network management"
|
||||||
|
|
||||||
|
if err == nil && networkResult.Backend != network.BackendNone {
|
||||||
|
networkMessage = detectNetworkBackend(networkResult)
|
||||||
|
if doctorVerbose {
|
||||||
|
networkDetails = networkResult.ChosenReason
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
networkStatus = statusInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, checkResult{catOptionalFeatures, "Network", networkStatus, networkMessage, networkDetails, optionalFeaturesURL})
|
||||||
|
|
||||||
deps := []struct {
|
deps := []struct {
|
||||||
name, cmd, altCmd, desc string
|
name, cmd, desc string
|
||||||
important bool
|
important bool
|
||||||
}{
|
}{
|
||||||
{"matugen", "matugen", "", "Dynamic theming", true},
|
{"matugen", "matugen", "Dynamic theming", true},
|
||||||
{"dgop", "dgop", "", "System monitoring", true},
|
{"dgop", "dgop", "System monitoring", true},
|
||||||
{"cava", "cava", "", "Audio visualizer", true},
|
{"cava", "cava", "Audio visualizer", true},
|
||||||
{"khal", "khal", "", "Calendar events", false},
|
{"khal", "khal", "Calendar events", false},
|
||||||
{"Network", "nmcli", "iwctl", "Network management", false},
|
{"danksearch", "dsearch", "File search", false},
|
||||||
{"danksearch", "dsearch", "", "File search", false},
|
{"fprintd", "fprintd-list", "Fingerprint auth", false},
|
||||||
{"loginctl", "loginctl", "", "Session management", false},
|
|
||||||
{"fprintd", "fprintd-list", "", "Fingerprint auth", false},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range deps {
|
for _, d := range deps {
|
||||||
found, foundCmd := utils.CommandExists(d.cmd), d.cmd
|
found := utils.CommandExists(d.cmd)
|
||||||
if !found && d.altCmd != "" && utils.CommandExists(d.altCmd) {
|
|
||||||
found, foundCmd = true, d.altCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case found:
|
case found:
|
||||||
message := "Installed"
|
results = append(results, checkResult{catOptionalFeatures, d.name, statusOK, "Installed", d.desc, optionalFeaturesURL})
|
||||||
details := d.desc
|
|
||||||
if d.name == "Network" {
|
|
||||||
result, err := network.DetectNetworkStack()
|
|
||||||
if err == nil && result.Backend != network.BackendNone {
|
|
||||||
message = detectNetworkBackend() + " (active)"
|
|
||||||
if doctorVerbose {
|
|
||||||
details = result.ChosenReason
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch foundCmd {
|
|
||||||
case "nmcli":
|
|
||||||
message = "NetworkManager (installed)"
|
|
||||||
case "iwctl":
|
|
||||||
message = "iwd (installed)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
results = append(results, checkResult{catOptionalFeatures, d.name, statusOK, message, details, doctorDocsURL + "#optional-features"})
|
|
||||||
case d.important:
|
case d.important:
|
||||||
results = append(results, checkResult{catOptionalFeatures, d.name, statusWarn, "Missing", d.desc, doctorDocsURL + "#optional-features"})
|
results = append(results, checkResult{catOptionalFeatures, d.name, statusWarn, "Missing", d.desc, optionalFeaturesURL})
|
||||||
default:
|
default:
|
||||||
results = append(results, checkResult{catOptionalFeatures, d.name, statusInfo, "Not installed", d.desc, doctorDocsURL + "#optional-features"})
|
results = append(results, checkResult{catOptionalFeatures, d.name, statusInfo, "Not installed", d.desc, optionalFeaturesURL})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -893,6 +886,10 @@ func printResultLine(r checkResult, styles tui.Styles) {
|
|||||||
if doctorVerbose && r.details != "" {
|
if doctorVerbose && r.details != "" {
|
||||||
fmt.Printf(" %s\n", styles.Subtle.Render("└─ "+r.details))
|
fmt.Printf(" %s\n", styles.Subtle.Render("└─ "+r.details))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r.status == statusError || r.status == statusWarn) && r.url != "" {
|
||||||
|
fmt.Printf(" %s\n", styles.Subtle.Render("→ "+r.url))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printSummary(results []checkResult, qsMissingFeatures bool) {
|
func printSummary(results []checkResult, qsMissingFeatures bool) {
|
||||||
|
|||||||
20
core/internal/utils/dbus.go
Normal file
20
core/internal/utils/dbus.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/godbus/dbus/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IsDBusServiceAvailable(busName string) bool {
|
||||||
|
conn, err := dbus.ConnectSystemBus()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
obj := conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
|
||||||
|
var owned bool
|
||||||
|
if err := obj.Call("org.freedesktop.DBus.NameHasOwner", 0, busName).Store(&owned); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return owned
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type AppChecker interface {
|
type AppChecker interface {
|
||||||
@@ -43,16 +42,3 @@ func AnyCommandExists(cmds ...string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsServiceActive(name string, userService bool) bool {
|
|
||||||
if !CommandExists("systemctl") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
args := []string{"is-active", name}
|
|
||||||
if userService {
|
|
||||||
args = []string{"--user", "is-active", name}
|
|
||||||
}
|
|
||||||
output, _ := exec.Command("systemctl", args...).Output()
|
|
||||||
return strings.EqualFold(strings.TrimSpace(string(output)), "active")
|
|
||||||
}
|
|
||||||
|
|||||||
14
flake.nix
14
flake.nix
@@ -61,11 +61,13 @@
|
|||||||
(builtins.substring 6 2 longDate)
|
(builtins.substring 6 2 longDate)
|
||||||
];
|
];
|
||||||
version =
|
version =
|
||||||
pkgs.lib.removePrefix "v" (pkgs.lib.trim (builtins.readFile ./quickshell/VERSION))
|
let
|
||||||
+ "+date="
|
rawVersion = pkgs.lib.removePrefix "v" (pkgs.lib.trim (builtins.readFile ./quickshell/VERSION));
|
||||||
+ mkDate (self.lastModifiedDate or "19700101")
|
cleanVersion = builtins.replaceStrings [ " " ] [ "" ] rawVersion;
|
||||||
+ "_"
|
dateSuffix = "+date=" + mkDate (self.lastModifiedDate or "19700101");
|
||||||
+ (self.shortRev or "dirty");
|
revSuffix = "_" + (self.shortRev or "dirty");
|
||||||
|
in
|
||||||
|
"${cleanVersion}${dateSuffix}${revSuffix}";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
dms-shell = pkgs.buildGoModule (
|
dms-shell = pkgs.buildGoModule (
|
||||||
@@ -83,7 +85,7 @@
|
|||||||
ldflags = [
|
ldflags = [
|
||||||
"-s"
|
"-s"
|
||||||
"-w"
|
"-w"
|
||||||
"-X main.Version=${version}"
|
"-X 'main.Version=${version}'"
|
||||||
];
|
];
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Spicy Miso
|
Saffron Bloom
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ Singleton {
|
|||||||
property bool controlCenterShowMicPercent: true
|
property bool controlCenterShowMicPercent: true
|
||||||
property bool controlCenterShowBatteryIcon: false
|
property bool controlCenterShowBatteryIcon: false
|
||||||
property bool controlCenterShowPrinterIcon: false
|
property bool controlCenterShowPrinterIcon: false
|
||||||
|
property bool controlCenterShowScreenSharingIcon: true
|
||||||
property bool showPrivacyButton: true
|
property bool showPrivacyButton: true
|
||||||
property bool privacyShowMicIcon: false
|
property bool privacyShowMicIcon: false
|
||||||
property bool privacyShowCameraIcon: false
|
property bool privacyShowCameraIcon: false
|
||||||
|
|||||||
@@ -904,7 +904,7 @@ Singleton {
|
|||||||
if (typeof SettingsData !== "undefined") {
|
if (typeof SettingsData !== "undefined") {
|
||||||
const skipTemplates = [];
|
const skipTemplates = [];
|
||||||
if (!SettingsData.runDmsMatugenTemplates) {
|
if (!SettingsData.runDmsMatugenTemplates) {
|
||||||
skipTemplates.push("gtk", "neovim", "niri", "qt5ct", "qt6ct", "firefox", "pywalfox", "zenbrowser", "vesktop", "equibop", "ghostty", "kitty", "foot", "alacritty", "wezterm", "dgop", "kcolorscheme", "vscode");
|
skipTemplates.push("gtk", "nvim", "niri", "qt5ct", "qt6ct", "firefox", "pywalfox", "zenbrowser", "vesktop", "equibop", "ghostty", "kitty", "foot", "alacritty", "wezterm", "dgop", "kcolorscheme", "vscode");
|
||||||
} else {
|
} else {
|
||||||
if (!SettingsData.matugenTemplateGtk)
|
if (!SettingsData.matugenTemplateGtk)
|
||||||
skipTemplates.push("gtk");
|
skipTemplates.push("gtk");
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ Singleton {
|
|||||||
showMicIcon: false,
|
showMicIcon: false,
|
||||||
showMicPercent: true,
|
showMicPercent: true,
|
||||||
showBatteryIcon: false,
|
showBatteryIcon: false,
|
||||||
showPrinterIcon: false
|
showPrinterIcon: false,
|
||||||
|
showScreenSharingIcon: true
|
||||||
};
|
};
|
||||||
leftModel.append(dummy);
|
leftModel.append(dummy);
|
||||||
centerModel.append(dummy);
|
centerModel.append(dummy);
|
||||||
@@ -84,6 +85,8 @@ Singleton {
|
|||||||
item.showBatteryIcon = order[i].showBatteryIcon;
|
item.showBatteryIcon = order[i].showBatteryIcon;
|
||||||
if (isObj && order[i].showPrinterIcon !== undefined)
|
if (isObj && order[i].showPrinterIcon !== undefined)
|
||||||
item.showPrinterIcon = order[i].showPrinterIcon;
|
item.showPrinterIcon = order[i].showPrinterIcon;
|
||||||
|
if (isObj && order[i].showScreenSharingIcon !== undefined)
|
||||||
|
item.showScreenSharingIcon = order[i].showScreenSharingIcon;
|
||||||
|
|
||||||
model.append(item);
|
model.append(item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ var SPEC = {
|
|||||||
controlCenterShowMicPercent: { def: false },
|
controlCenterShowMicPercent: { def: false },
|
||||||
controlCenterShowBatteryIcon: { def: false },
|
controlCenterShowBatteryIcon: { def: false },
|
||||||
controlCenterShowPrinterIcon: { def: false },
|
controlCenterShowPrinterIcon: { def: false },
|
||||||
|
controlCenterShowScreenSharingIcon: { def: true },
|
||||||
|
|
||||||
showPrivacyButton: { def: true },
|
showPrivacyButton: { def: true },
|
||||||
privacyShowMicIcon: { def: false },
|
privacyShowMicIcon: { def: false },
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
dockRecreateDebounce.start();
|
dockRecreateDebounce.start();
|
||||||
|
// Force PolkitService singleton to initialize
|
||||||
|
PolkitService.polkitAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
@@ -315,19 +317,44 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiPasswordModal {
|
LazyLoader {
|
||||||
id: wifiPasswordModal
|
id: wifiPasswordModalLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
PopoutService.wifiPasswordModal = wifiPasswordModal;
|
PopoutService.wifiPasswordModalLoader = wifiPasswordModalLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiPasswordModal {
|
||||||
|
id: wifiPasswordModalItem
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
PopoutService.wifiPasswordModal = wifiPasswordModalItem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PolkitAuthModal {
|
LazyLoader {
|
||||||
id: polkitAuthModal
|
id: polkitAuthModalLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
Component.onCompleted: {
|
PolkitAuthModal {
|
||||||
PopoutService.polkitAuthModal = polkitAuthModal;
|
id: polkitAuthModal
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
PopoutService.polkitAuthModal = polkitAuthModal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: PolkitService.agent
|
||||||
|
enabled: PolkitService.polkitAvailable
|
||||||
|
|
||||||
|
function onAuthenticationRequestStarted() {
|
||||||
|
polkitAuthModalLoader.active = true;
|
||||||
|
if (polkitAuthModalLoader.item)
|
||||||
|
polkitAuthModalLoader.item.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,17 +376,21 @@ Item {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const timeSinceLastPrompt = now - lastCredentialsTime;
|
const timeSinceLastPrompt = now - lastCredentialsTime;
|
||||||
|
|
||||||
if (wifiPasswordModal.visible && timeSinceLastPrompt < 1000) {
|
wifiPasswordModalLoader.active = true;
|
||||||
|
if (!wifiPasswordModalLoader.item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wifiPasswordModalLoader.item.visible && timeSinceLastPrompt < 1000) {
|
||||||
NetworkService.cancelCredentials(lastCredentialsToken);
|
NetworkService.cancelCredentials(lastCredentialsToken);
|
||||||
lastCredentialsToken = token;
|
lastCredentialsToken = token;
|
||||||
lastCredentialsTime = now;
|
lastCredentialsTime = now;
|
||||||
wifiPasswordModal.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fieldsInfo);
|
wifiPasswordModalLoader.item.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fieldsInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastCredentialsToken = token;
|
lastCredentialsToken = token;
|
||||||
lastCredentialsTime = now;
|
lastCredentialsTime = now;
|
||||||
wifiPasswordModal.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fieldsInfo);
|
wifiPasswordModalLoader.item.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fieldsInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,17 +473,15 @@ Item {
|
|||||||
PopoutService.settingsModalLoader = settingsModalLoader;
|
PopoutService.settingsModalLoader = settingsModalLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
onActiveChanged: {
|
|
||||||
if (active && item) {
|
|
||||||
PopoutService.settingsModal = item;
|
|
||||||
PopoutService._onSettingsModalLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsModal {
|
SettingsModal {
|
||||||
id: settingsModal
|
id: settingsModal
|
||||||
property bool wasShown: false
|
property bool wasShown: false
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
PopoutService.settingsModal = settingsModal;
|
||||||
|
PopoutService._onSettingsModalLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
wasShown = true;
|
wasShown = true;
|
||||||
|
|||||||
@@ -132,8 +132,11 @@ Item {
|
|||||||
case "media":
|
case "media":
|
||||||
root.dankDashPopoutLoader.item.currentTabIndex = 1;
|
root.dankDashPopoutLoader.item.currentTabIndex = 1;
|
||||||
break;
|
break;
|
||||||
|
case "wallpaper":
|
||||||
|
root.dankDashPopoutLoader.item.currentTabIndex = 2;
|
||||||
|
break;
|
||||||
case "weather":
|
case "weather":
|
||||||
root.dankDashPopoutLoader.item.currentTabIndex = SettingsData.weatherEnabled ? 2 : 0;
|
root.dankDashPopoutLoader.item.currentTabIndex = SettingsData.weatherEnabled ? 3 : 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
root.dankDashPopoutLoader.item.currentTabIndex = 0;
|
root.dankDashPopoutLoader.item.currentTabIndex = 0;
|
||||||
@@ -797,11 +800,9 @@ Item {
|
|||||||
const modal = PopoutService.settingsModal;
|
const modal = PopoutService.settingsModal;
|
||||||
if (modal) {
|
if (modal) {
|
||||||
if (type === "wallpaper") {
|
if (type === "wallpaper") {
|
||||||
modal.wallpaperBrowser.allowStacking = false;
|
modal.openWallpaperBrowser(false);
|
||||||
modal.wallpaperBrowser.open();
|
|
||||||
} else if (type === "profile") {
|
} else if (type === "profile") {
|
||||||
modal.profileBrowser.allowStacking = false;
|
modal.openProfileBrowser(false);
|
||||||
modal.profileBrowser.open();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PopoutService.openSettings();
|
PopoutService.openSettings();
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ FloatingWindow {
|
|||||||
iconName: "open_in_new"
|
iconName: "open_in_new"
|
||||||
backgroundColor: Theme.surfaceContainerHighest
|
backgroundColor: Theme.surfaceContainerHighest
|
||||||
textColor: Theme.surfaceText
|
textColor: Theme.surfaceText
|
||||||
onClicked: Qt.openUrlExternally("https://danklinux.com/blog/v1.2-release")
|
onClicked: Qt.openUrlExternally("https://danklinux.com/blog/v1-2-release")
|
||||||
}
|
}
|
||||||
|
|
||||||
DankButton {
|
DankButton {
|
||||||
|
|||||||
@@ -74,9 +74,7 @@ Rectangle {
|
|||||||
if (root.parentModal) {
|
if (root.parentModal) {
|
||||||
root.parentModal.allowFocusOverride = true;
|
root.parentModal.allowFocusOverride = true;
|
||||||
root.parentModal.shouldHaveFocus = false;
|
root.parentModal.shouldHaveFocus = false;
|
||||||
if (root.parentModal.profileBrowser) {
|
root.parentModal.openProfileBrowser();
|
||||||
root.parentModal.profileBrowser.open();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,26 @@ import qs.Widgets
|
|||||||
FloatingWindow {
|
FloatingWindow {
|
||||||
id: settingsModal
|
id: settingsModal
|
||||||
|
|
||||||
property alias profileBrowser: profileBrowser
|
property var profileBrowser: profileBrowserLoader.item
|
||||||
property alias wallpaperBrowser: wallpaperBrowser
|
property var wallpaperBrowser: wallpaperBrowserLoader.item
|
||||||
|
|
||||||
|
function openProfileBrowser(allowStacking) {
|
||||||
|
profileBrowserLoader.active = true;
|
||||||
|
if (!profileBrowserLoader.item)
|
||||||
|
return;
|
||||||
|
if (allowStacking !== undefined)
|
||||||
|
profileBrowserLoader.item.allowStacking = allowStacking;
|
||||||
|
profileBrowserLoader.item.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWallpaperBrowser(allowStacking) {
|
||||||
|
wallpaperBrowserLoader.active = true;
|
||||||
|
if (!wallpaperBrowserLoader.item)
|
||||||
|
return;
|
||||||
|
if (allowStacking !== undefined)
|
||||||
|
wallpaperBrowserLoader.item.allowStacking = allowStacking;
|
||||||
|
wallpaperBrowserLoader.item.open();
|
||||||
|
}
|
||||||
property alias sidebar: sidebar
|
property alias sidebar: sidebar
|
||||||
property int currentTabIndex: 0
|
property int currentTabIndex: 0
|
||||||
property bool shouldHaveFocus: visible
|
property bool shouldHaveFocus: visible
|
||||||
@@ -96,41 +114,51 @@ FloatingWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBrowserModal {
|
LazyLoader {
|
||||||
id: profileBrowser
|
id: profileBrowserLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
allowStacking: true
|
FileBrowserModal {
|
||||||
parentModal: settingsModal
|
id: profileBrowserItem
|
||||||
browserTitle: I18n.tr("Select Profile Image", "profile image file browser title")
|
|
||||||
browserIcon: "person"
|
allowStacking: true
|
||||||
browserType: "profile"
|
parentModal: settingsModal
|
||||||
showHiddenFiles: true
|
browserTitle: I18n.tr("Select Profile Image", "profile image file browser title")
|
||||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
browserIcon: "person"
|
||||||
onFileSelected: path => {
|
browserType: "profile"
|
||||||
PortalService.setProfileImage(path);
|
showHiddenFiles: true
|
||||||
close();
|
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||||
}
|
onFileSelected: path => {
|
||||||
onDialogClosed: () => {
|
PortalService.setProfileImage(path);
|
||||||
allowStacking = true;
|
close();
|
||||||
|
}
|
||||||
|
onDialogClosed: () => {
|
||||||
|
allowStacking = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBrowserModal {
|
LazyLoader {
|
||||||
id: wallpaperBrowser
|
id: wallpaperBrowserLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
allowStacking: true
|
FileBrowserModal {
|
||||||
parentModal: settingsModal
|
id: wallpaperBrowserItem
|
||||||
browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title")
|
|
||||||
browserIcon: "wallpaper"
|
allowStacking: true
|
||||||
browserType: "wallpaper"
|
parentModal: settingsModal
|
||||||
showHiddenFiles: true
|
browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title")
|
||||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
browserIcon: "wallpaper"
|
||||||
onFileSelected: path => {
|
browserType: "wallpaper"
|
||||||
SessionData.setWallpaper(path);
|
showHiddenFiles: true
|
||||||
close();
|
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||||
}
|
onFileSelected: path => {
|
||||||
onDialogClosed: () => {
|
SessionData.setWallpaper(path);
|
||||||
allowStacking = true;
|
close();
|
||||||
|
}
|
||||||
|
onDialogClosed: () => {
|
||||||
|
allowStacking = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -687,8 +687,8 @@ Rectangle {
|
|||||||
if (modelData.secured && !modelData.saved) {
|
if (modelData.secured && !modelData.saved) {
|
||||||
if (DMSService.apiVersion >= 7) {
|
if (DMSService.apiVersion >= 7) {
|
||||||
NetworkService.connectToWifi(modelData.ssid);
|
NetworkService.connectToWifi(modelData.ssid);
|
||||||
} else if (PopoutService.wifiPasswordModal) {
|
} else {
|
||||||
PopoutService.wifiPasswordModal.show(modelData.ssid);
|
PopoutService.showWifiPasswordModal(modelData.ssid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NetworkService.connectToWifi(modelData.ssid);
|
NetworkService.connectToWifi(modelData.ssid);
|
||||||
@@ -749,8 +749,8 @@ Rectangle {
|
|||||||
if (networkContextMenu.currentSecured && !networkContextMenu.currentSaved) {
|
if (networkContextMenu.currentSecured && !networkContextMenu.currentSaved) {
|
||||||
if (DMSService.apiVersion >= 7) {
|
if (DMSService.apiVersion >= 7) {
|
||||||
NetworkService.connectToWifi(networkContextMenu.currentSSID);
|
NetworkService.connectToWifi(networkContextMenu.currentSSID);
|
||||||
} else if (PopoutService.wifiPasswordModal) {
|
} else {
|
||||||
PopoutService.wifiPasswordModal.show(networkContextMenu.currentSSID);
|
PopoutService.showWifiPasswordModal(networkContextMenu.currentSSID);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NetworkService.connectToWifi(networkContextMenu.currentSSID);
|
NetworkService.connectToWifi(networkContextMenu.currentSSID);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ BasePill {
|
|||||||
property bool showMicPercent: widgetData?.showMicPercent !== undefined ? widgetData.showMicPercent : SettingsData.controlCenterShowMicPercent
|
property bool showMicPercent: widgetData?.showMicPercent !== undefined ? widgetData.showMicPercent : SettingsData.controlCenterShowMicPercent
|
||||||
property bool showBatteryIcon: widgetData?.showBatteryIcon !== undefined ? widgetData.showBatteryIcon : SettingsData.controlCenterShowBatteryIcon
|
property bool showBatteryIcon: widgetData?.showBatteryIcon !== undefined ? widgetData.showBatteryIcon : SettingsData.controlCenterShowBatteryIcon
|
||||||
property bool showPrinterIcon: widgetData?.showPrinterIcon !== undefined ? widgetData.showPrinterIcon : SettingsData.controlCenterShowPrinterIcon
|
property bool showPrinterIcon: widgetData?.showPrinterIcon !== undefined ? widgetData.showPrinterIcon : SettingsData.controlCenterShowPrinterIcon
|
||||||
|
property bool showScreenSharingIcon: widgetData?.showScreenSharingIcon !== undefined ? widgetData.showScreenSharingIcon : SettingsData.controlCenterShowScreenSharingIcon
|
||||||
property real touchpadThreshold: 100
|
property real touchpadThreshold: 100
|
||||||
property real micAccumulator: 0
|
property real micAccumulator: 0
|
||||||
property real volumeAccumulator: 0
|
property real volumeAccumulator: 0
|
||||||
@@ -213,7 +214,7 @@ BasePill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hasNoVisibleIcons() {
|
function hasNoVisibleIcons() {
|
||||||
return !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon && !root.showVpnIcon && !root.showBrightnessIcon && !root.showMicIcon && !root.showBatteryIcon && !root.showPrinterIcon;
|
return !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon && !root.showVpnIcon && !root.showBrightnessIcon && !root.showMicIcon && !root.showBatteryIcon && !root.showPrinterIcon && !root.showScreenSharingIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
@@ -227,6 +228,14 @@ BasePill {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "screen_record"
|
||||||
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
color: NiriService.hasActiveCast ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: root.showScreenSharingIcon && NiriService.hasCasts
|
||||||
|
}
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: root.getNetworkIconName()
|
name: root.getNetworkIconName()
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
@@ -402,6 +411,14 @@ BasePill {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "screen_record"
|
||||||
|
size: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
color: NiriService.hasActiveCast ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: root.showScreenSharingIcon && NiriService.hasCasts
|
||||||
|
}
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
id: networkIcon
|
id: networkIcon
|
||||||
name: root.getNetworkIconName()
|
name: root.getNetworkIconName()
|
||||||
|
|||||||
@@ -327,11 +327,12 @@ Item {
|
|||||||
clip: false
|
clip: false
|
||||||
visible: !_noneAvailable && (!showNoPlayerNow)
|
visible: !_noneAvailable && (!showNoPlayerNow)
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
x: 72
|
|
||||||
y: 20
|
|
||||||
width: 484
|
width: 484
|
||||||
height: 370
|
height: 370
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|||||||
@@ -1406,6 +1406,14 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: NetworkService.networkAvailable || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio)
|
visible: NetworkService.networkAvailable || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio)
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "screen_record"
|
||||||
|
size: Theme.iconSize - 2
|
||||||
|
color: NiriService.hasActiveCast ? "white" : Qt.rgba(255, 255, 255, 0.5)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: NiriService.hasCasts
|
||||||
|
}
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: {
|
name: {
|
||||||
if (NetworkService.wifiToggling)
|
if (NetworkService.wifiToggling)
|
||||||
|
|||||||
@@ -22,18 +22,38 @@ Item {
|
|||||||
readonly property var allInstances: SettingsData.desktopWidgetInstances || []
|
readonly property var allInstances: SettingsData.desktopWidgetInstances || []
|
||||||
readonly property var allGroups: SettingsData.desktopWidgetGroups || []
|
readonly property var allGroups: SettingsData.desktopWidgetGroups || []
|
||||||
|
|
||||||
DesktopWidgetBrowser {
|
function showWidgetBrowser() {
|
||||||
id: widgetBrowser
|
widgetBrowserLoader.active = true;
|
||||||
parentModal: root.parentModal
|
if (widgetBrowserLoader.item)
|
||||||
onWidgetAdded: widgetType => {
|
widgetBrowserLoader.item.show();
|
||||||
ToastService.showInfo(I18n.tr("Widget added"));
|
}
|
||||||
|
|
||||||
|
function showDesktopPluginBrowser() {
|
||||||
|
desktopPluginBrowserLoader.active = true;
|
||||||
|
if (desktopPluginBrowserLoader.item)
|
||||||
|
desktopPluginBrowserLoader.item.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyLoader {
|
||||||
|
id: widgetBrowserLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
DesktopWidgetBrowser {
|
||||||
|
parentModal: root.parentModal
|
||||||
|
onWidgetAdded: widgetType => {
|
||||||
|
ToastService.showInfo(I18n.tr("Widget added"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginBrowser {
|
LazyLoader {
|
||||||
id: desktopPluginBrowser
|
id: desktopPluginBrowserLoader
|
||||||
parentModal: root.parentModal
|
active: false
|
||||||
typeFilter: "desktop-widget"
|
|
||||||
|
PluginBrowser {
|
||||||
|
parentModal: root.parentModal
|
||||||
|
typeFilter: "desktop-widget"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankFlickable {
|
DankFlickable {
|
||||||
@@ -74,13 +94,13 @@ Item {
|
|||||||
DankButton {
|
DankButton {
|
||||||
text: I18n.tr("Add Widget")
|
text: I18n.tr("Add Widget")
|
||||||
iconName: "add"
|
iconName: "add"
|
||||||
onClicked: widgetBrowser.show()
|
onClicked: root.showWidgetBrowser()
|
||||||
}
|
}
|
||||||
|
|
||||||
DankButton {
|
DankButton {
|
||||||
text: I18n.tr("Browse Plugins")
|
text: I18n.tr("Browse Plugins")
|
||||||
iconName: "store"
|
iconName: "store"
|
||||||
onClicked: desktopPluginBrowser.show()
|
onClicked: root.showDesktopPluginBrowser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Modals.Common
|
import qs.Modals.Common
|
||||||
import qs.Modals.FileBrowser
|
import qs.Modals.FileBrowser
|
||||||
@@ -23,15 +24,25 @@ Item {
|
|||||||
NetworkService.removeRef();
|
NetworkService.removeRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBrowserModal {
|
function openVpnFileBrowser() {
|
||||||
id: vpnFileBrowser
|
vpnFileBrowserLoader.active = true;
|
||||||
browserTitle: I18n.tr("Import VPN")
|
if (vpnFileBrowserLoader.item)
|
||||||
browserIcon: "vpn_key"
|
vpnFileBrowserLoader.item.open();
|
||||||
browserType: "vpn"
|
}
|
||||||
fileExtensions: VPNService.getFileFilter()
|
|
||||||
|
|
||||||
onFileSelected: path => {
|
LazyLoader {
|
||||||
VPNService.importVpn(path.replace("file://", ""));
|
id: vpnFileBrowserLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
FileBrowserModal {
|
||||||
|
browserTitle: I18n.tr("Import VPN")
|
||||||
|
browserIcon: "vpn_key"
|
||||||
|
browserType: "vpn"
|
||||||
|
fileExtensions: VPNService.getFileFilter()
|
||||||
|
|
||||||
|
onFileSelected: path => {
|
||||||
|
VPNService.importVpn(path.replace("file://", ""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1520,7 +1531,7 @@ Item {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: VPNService.importing ? Qt.BusyCursor : Qt.PointingHandCursor
|
cursorShape: VPNService.importing ? Qt.BusyCursor : Qt.PointingHandCursor
|
||||||
enabled: !VPNService.importing
|
enabled: !VPNService.importing
|
||||||
onClicked: vpnFileBrowser.open()
|
onClicked: networkTab.openVpnFileBrowser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
@@ -209,7 +210,7 @@ FocusScope {
|
|||||||
iconName: "store"
|
iconName: "store"
|
||||||
enabled: DMSService.dmsAvailable
|
enabled: DMSService.dmsAvailable
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pluginBrowser.show();
|
showPluginBrowser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,9 +383,11 @@ FocusScope {
|
|||||||
Connections {
|
Connections {
|
||||||
target: DMSService
|
target: DMSService
|
||||||
function onPluginsListReceived(plugins) {
|
function onPluginsListReceived(plugins) {
|
||||||
pluginBrowser.isLoading = false;
|
if (!pluginBrowserLoader.item)
|
||||||
pluginBrowser.allPlugins = plugins;
|
return;
|
||||||
pluginBrowser.updateFilteredPlugins();
|
pluginBrowserLoader.item.isLoading = false;
|
||||||
|
pluginBrowserLoader.item.allPlugins = plugins;
|
||||||
|
pluginBrowserLoader.item.updateFilteredPlugins();
|
||||||
}
|
}
|
||||||
function onInstalledPluginsReceived(plugins) {
|
function onInstalledPluginsReceived(plugins) {
|
||||||
var pluginMap = {};
|
var pluginMap = {};
|
||||||
@@ -410,22 +413,36 @@ FocusScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
pluginBrowser.parentModal = pluginsTab.parentModal;
|
|
||||||
if (DMSService.dmsAvailable && DMSService.apiVersion >= 8)
|
if (DMSService.dmsAvailable && DMSService.apiVersion >= 8)
|
||||||
DMSService.listInstalled();
|
DMSService.listInstalled();
|
||||||
if (PopoutService.pendingPluginInstall)
|
if (PopoutService.pendingPluginInstall)
|
||||||
Qt.callLater(() => pluginBrowser.show());
|
Qt.callLater(showPluginBrowser);
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: PopoutService
|
target: PopoutService
|
||||||
function onPendingPluginInstallChanged() {
|
function onPendingPluginInstallChanged() {
|
||||||
if (PopoutService.pendingPluginInstall)
|
if (PopoutService.pendingPluginInstall)
|
||||||
pluginBrowser.show();
|
showPluginBrowser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginBrowser {
|
LazyLoader {
|
||||||
id: pluginBrowser
|
id: pluginBrowserLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
PluginBrowser {
|
||||||
|
id: pluginBrowserItem
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
pluginBrowserItem.parentModal = pluginsTab.parentModal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showPluginBrowser() {
|
||||||
|
pluginBrowserLoader.active = true;
|
||||||
|
if (pluginBrowserLoader.item)
|
||||||
|
pluginBrowserLoader.item.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ Item {
|
|||||||
if (DMSService.dmsAvailable)
|
if (DMSService.dmsAvailable)
|
||||||
DMSService.listInstalledThemes();
|
DMSService.listInstalledThemes();
|
||||||
if (PopoutService.pendingThemeInstall)
|
if (PopoutService.pendingThemeInstall)
|
||||||
Qt.callLater(() => themeBrowser.show());
|
Qt.callLater(() => showThemeBrowser());
|
||||||
templateCheckProcess.running = true;
|
templateCheckProcess.running = true;
|
||||||
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl)
|
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl)
|
||||||
checkCursorIncludeStatus();
|
checkCursorIncludeStatus();
|
||||||
@@ -169,7 +169,7 @@ Item {
|
|||||||
target: PopoutService
|
target: PopoutService
|
||||||
function onPendingThemeInstallChanged() {
|
function onPendingThemeInstallChanged() {
|
||||||
if (PopoutService.pendingThemeInstall)
|
if (PopoutService.pendingThemeInstall)
|
||||||
themeBrowser.show();
|
showThemeBrowser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -939,7 +939,7 @@ Item {
|
|||||||
text: I18n.tr("Browse Themes", "browse themes button")
|
text: I18n.tr("Browse Themes", "browse themes button")
|
||||||
iconName: "store"
|
iconName: "store"
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
onClicked: themeBrowser.show()
|
onClicked: showThemeBrowser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2041,7 +2041,18 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeBrowser {
|
LazyLoader {
|
||||||
id: themeBrowser
|
id: themeBrowserLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
ThemeBrowser {
|
||||||
|
id: themeBrowserItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showThemeBrowser() {
|
||||||
|
themeBrowserLoader.active = true;
|
||||||
|
if (themeBrowserLoader.item)
|
||||||
|
themeBrowserLoader.item.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: mainWallpaperBrowser.open()
|
onClicked: root.openMainWallpaperBrowser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,7 +476,7 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: lightWallpaperBrowser.open()
|
onClicked: root.openLightWallpaperBrowser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,7 +660,7 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: darkWallpaperBrowser.open()
|
onClicked: root.openDarkWallpaperBrowser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1242,53 +1242,83 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBrowserModal {
|
function openMainWallpaperBrowser() {
|
||||||
id: mainWallpaperBrowser
|
mainWallpaperBrowserLoader.active = true;
|
||||||
parentModal: root.parentModal
|
if (mainWallpaperBrowserLoader.item)
|
||||||
browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title")
|
mainWallpaperBrowserLoader.item.open();
|
||||||
browserIcon: "wallpaper"
|
}
|
||||||
browserType: "wallpaper"
|
|
||||||
showHiddenFiles: true
|
function openLightWallpaperBrowser() {
|
||||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
lightWallpaperBrowserLoader.active = true;
|
||||||
onFileSelected: path => {
|
if (lightWallpaperBrowserLoader.item)
|
||||||
if (SessionData.perMonitorWallpaper) {
|
lightWallpaperBrowserLoader.item.open();
|
||||||
SessionData.setMonitorWallpaper(selectedMonitorName, path);
|
}
|
||||||
} else {
|
|
||||||
SessionData.setWallpaper(path);
|
function openDarkWallpaperBrowser() {
|
||||||
|
darkWallpaperBrowserLoader.active = true;
|
||||||
|
if (darkWallpaperBrowserLoader.item)
|
||||||
|
darkWallpaperBrowserLoader.item.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyLoader {
|
||||||
|
id: mainWallpaperBrowserLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
FileBrowserModal {
|
||||||
|
parentModal: root.parentModal
|
||||||
|
browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title")
|
||||||
|
browserIcon: "wallpaper"
|
||||||
|
browserType: "wallpaper"
|
||||||
|
showHiddenFiles: true
|
||||||
|
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||||
|
onFileSelected: path => {
|
||||||
|
if (SessionData.perMonitorWallpaper) {
|
||||||
|
SessionData.setMonitorWallpaper(selectedMonitorName, path);
|
||||||
|
} else {
|
||||||
|
SessionData.setWallpaper(path);
|
||||||
|
}
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBrowserModal {
|
LazyLoader {
|
||||||
id: lightWallpaperBrowser
|
id: lightWallpaperBrowserLoader
|
||||||
parentModal: root.parentModal
|
active: false
|
||||||
browserTitle: I18n.tr("Select Wallpaper", "light mode wallpaper file browser title")
|
|
||||||
browserIcon: "light_mode"
|
FileBrowserModal {
|
||||||
browserType: "wallpaper"
|
parentModal: root.parentModal
|
||||||
showHiddenFiles: true
|
browserTitle: I18n.tr("Select Wallpaper", "light mode wallpaper file browser title")
|
||||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
browserIcon: "light_mode"
|
||||||
onFileSelected: path => {
|
browserType: "wallpaper"
|
||||||
SessionData.wallpaperPathLight = path;
|
showHiddenFiles: true
|
||||||
SessionData.syncWallpaperForCurrentMode();
|
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||||
SessionData.saveSettings();
|
onFileSelected: path => {
|
||||||
close();
|
SessionData.wallpaperPathLight = path;
|
||||||
|
SessionData.syncWallpaperForCurrentMode();
|
||||||
|
SessionData.saveSettings();
|
||||||
|
close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBrowserModal {
|
LazyLoader {
|
||||||
id: darkWallpaperBrowser
|
id: darkWallpaperBrowserLoader
|
||||||
parentModal: root.parentModal
|
active: false
|
||||||
browserTitle: I18n.tr("Select Wallpaper", "dark mode wallpaper file browser title")
|
|
||||||
browserIcon: "dark_mode"
|
FileBrowserModal {
|
||||||
browserType: "wallpaper"
|
parentModal: root.parentModal
|
||||||
showHiddenFiles: true
|
browserTitle: I18n.tr("Select Wallpaper", "dark mode wallpaper file browser title")
|
||||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
browserIcon: "dark_mode"
|
||||||
onFileSelected: path => {
|
browserType: "wallpaper"
|
||||||
SessionData.wallpaperPathDark = path;
|
showHiddenFiles: true
|
||||||
SessionData.syncWallpaperForCurrentMode();
|
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||||
SessionData.saveSettings();
|
onFileSelected: path => {
|
||||||
close();
|
SessionData.wallpaperPathDark = path;
|
||||||
|
SessionData.syncWallpaperForCurrentMode();
|
||||||
|
SessionData.saveSettings();
|
||||||
|
close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
@@ -382,6 +383,7 @@ Item {
|
|||||||
widgetObj.showMicPercent = SettingsData.controlCenterShowMicPercent;
|
widgetObj.showMicPercent = SettingsData.controlCenterShowMicPercent;
|
||||||
widgetObj.showBatteryIcon = SettingsData.controlCenterShowBatteryIcon;
|
widgetObj.showBatteryIcon = SettingsData.controlCenterShowBatteryIcon;
|
||||||
widgetObj.showPrinterIcon = SettingsData.controlCenterShowPrinterIcon;
|
widgetObj.showPrinterIcon = SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
widgetObj.showScreenSharingIcon = SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
}
|
}
|
||||||
if (widgetId === "diskUsage")
|
if (widgetId === "diskUsage")
|
||||||
widgetObj.mountPath = "/";
|
widgetObj.mountPath = "/";
|
||||||
@@ -442,6 +444,7 @@ Item {
|
|||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
}
|
}
|
||||||
widgets[i] = newWidget;
|
widgets[i] = newWidget;
|
||||||
break;
|
break;
|
||||||
@@ -498,6 +501,7 @@ Item {
|
|||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
}
|
}
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
@@ -576,6 +580,7 @@ Item {
|
|||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
}
|
}
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
@@ -607,7 +612,8 @@ Item {
|
|||||||
"showMicIcon": widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon,
|
"showMicIcon": widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon,
|
||||||
"showMicPercent": widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent,
|
"showMicPercent": widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent,
|
||||||
"showBatteryIcon": widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon,
|
"showBatteryIcon": widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon,
|
||||||
"showPrinterIcon": widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon
|
"showPrinterIcon": widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon,
|
||||||
|
"showScreenSharingIcon": widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon
|
||||||
};
|
};
|
||||||
newWidget[settingName] = value;
|
newWidget[settingName] = value;
|
||||||
|
|
||||||
@@ -674,6 +680,7 @@ Item {
|
|||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
}
|
}
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
@@ -734,6 +741,7 @@ Item {
|
|||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
}
|
}
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
@@ -794,6 +802,7 @@ Item {
|
|||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
}
|
}
|
||||||
widgets[i] = newWidget;
|
widgets[i] = newWidget;
|
||||||
widget = newWidget;
|
widget = newWidget;
|
||||||
@@ -866,6 +875,8 @@ Item {
|
|||||||
item.showBatteryIcon = widget.showBatteryIcon;
|
item.showBatteryIcon = widget.showBatteryIcon;
|
||||||
if (widget.showPrinterIcon !== undefined)
|
if (widget.showPrinterIcon !== undefined)
|
||||||
item.showPrinterIcon = widget.showPrinterIcon;
|
item.showPrinterIcon = widget.showPrinterIcon;
|
||||||
|
if (widget.showScreenSharingIcon !== undefined)
|
||||||
|
item.showScreenSharingIcon = widget.showScreenSharingIcon;
|
||||||
if (widget.minimumWidth !== undefined)
|
if (widget.minimumWidth !== undefined)
|
||||||
item.minimumWidth = widget.minimumWidth;
|
item.minimumWidth = widget.minimumWidth;
|
||||||
if (widget.showSwap !== undefined)
|
if (widget.showSwap !== undefined)
|
||||||
@@ -916,14 +927,28 @@ Item {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetSelectionPopup {
|
LazyLoader {
|
||||||
id: widgetSelectionPopup
|
id: widgetSelectionPopupLoader
|
||||||
parentModal: widgetsTab.parentModal
|
active: false
|
||||||
onWidgetSelected: (widgetId, targetSection) => {
|
|
||||||
widgetsTab.addWidgetToSection(widgetId, targetSection);
|
WidgetSelectionPopup {
|
||||||
|
id: widgetSelectionPopupItem
|
||||||
|
parentModal: widgetsTab.parentModal
|
||||||
|
onWidgetSelected: (widgetId, targetSection) => {
|
||||||
|
widgetsTab.addWidgetToSection(widgetId, targetSection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showWidgetSelectionPopup(sectionId) {
|
||||||
|
widgetSelectionPopupLoader.active = true;
|
||||||
|
if (!widgetSelectionPopupLoader.item)
|
||||||
|
return;
|
||||||
|
widgetSelectionPopupLoader.item.targetSection = sectionId;
|
||||||
|
widgetSelectionPopupLoader.item.allWidgets = widgetsTab.getWidgetsForPopup();
|
||||||
|
widgetSelectionPopupLoader.item.show();
|
||||||
|
}
|
||||||
|
|
||||||
DankFlickable {
|
DankFlickable {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
@@ -1113,9 +1138,7 @@ Item {
|
|||||||
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
||||||
}
|
}
|
||||||
onAddWidget: sectionId => {
|
onAddWidget: sectionId => {
|
||||||
widgetSelectionPopup.targetSection = sectionId;
|
showWidgetSelectionPopup(sectionId);
|
||||||
widgetSelectionPopup.allWidgets = widgetsTab.getWidgetsForPopup();
|
|
||||||
widgetSelectionPopup.show();
|
|
||||||
}
|
}
|
||||||
onRemoveWidget: (sectionId, index) => {
|
onRemoveWidget: (sectionId, index) => {
|
||||||
widgetsTab.removeWidgetFromSection(sectionId, index);
|
widgetsTab.removeWidgetFromSection(sectionId, index);
|
||||||
@@ -1170,9 +1193,7 @@ Item {
|
|||||||
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
||||||
}
|
}
|
||||||
onAddWidget: sectionId => {
|
onAddWidget: sectionId => {
|
||||||
widgetSelectionPopup.targetSection = sectionId;
|
showWidgetSelectionPopup(sectionId);
|
||||||
widgetSelectionPopup.allWidgets = widgetsTab.getWidgetsForPopup();
|
|
||||||
widgetSelectionPopup.show();
|
|
||||||
}
|
}
|
||||||
onRemoveWidget: (sectionId, index) => {
|
onRemoveWidget: (sectionId, index) => {
|
||||||
widgetsTab.removeWidgetFromSection(sectionId, index);
|
widgetsTab.removeWidgetFromSection(sectionId, index);
|
||||||
@@ -1227,9 +1248,7 @@ Item {
|
|||||||
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
||||||
}
|
}
|
||||||
onAddWidget: sectionId => {
|
onAddWidget: sectionId => {
|
||||||
widgetSelectionPopup.targetSection = sectionId;
|
showWidgetSelectionPopup(sectionId);
|
||||||
widgetSelectionPopup.allWidgets = widgetsTab.getWidgetsForPopup();
|
|
||||||
widgetSelectionPopup.show();
|
|
||||||
}
|
}
|
||||||
onRemoveWidget: (sectionId, index) => {
|
onRemoveWidget: (sectionId, index) => {
|
||||||
widgetsTab.removeWidgetFromSection(sectionId, index);
|
widgetsTab.removeWidgetFromSection(sectionId, index);
|
||||||
|
|||||||
@@ -875,6 +875,11 @@ Column {
|
|||||||
icon: "print",
|
icon: "print",
|
||||||
label: I18n.tr("Printer"),
|
label: I18n.tr("Printer"),
|
||||||
setting: "showPrinterIcon"
|
setting: "showPrinterIcon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "screen_record",
|
||||||
|
label: I18n.tr("Screen Sharing"),
|
||||||
|
setting: "showScreenSharingIcon"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -907,6 +912,8 @@ Column {
|
|||||||
return wd?.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
return wd?.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
||||||
case "showPrinterIcon":
|
case "showPrinterIcon":
|
||||||
return wd?.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
return wd?.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
||||||
|
case "showScreenSharingIcon":
|
||||||
|
return wd?.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Singleton {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property string currentVersion: "1.2"
|
readonly property string currentVersion: "1.2"
|
||||||
readonly property bool changelogEnabled: true
|
readonly property bool changelogEnabled: false
|
||||||
|
|
||||||
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation)) + "/DankMaterialShell"
|
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation)) + "/DankMaterialShell"
|
||||||
readonly property string changelogMarkerPath: configDir + "/.changelog-" + currentVersion
|
readonly property string changelogMarkerPath: configDir + "/.changelog-" + currentVersion
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ Singleton {
|
|||||||
|
|
||||||
property bool inOverview: false
|
property bool inOverview: false
|
||||||
|
|
||||||
|
property var casts: []
|
||||||
|
property bool hasCasts: casts.length > 0
|
||||||
|
property bool hasActiveCast: casts.some(c => c.is_active)
|
||||||
|
|
||||||
property int currentKeyboardLayoutIndex: 0
|
property int currentKeyboardLayoutIndex: 0
|
||||||
property var keyboardLayoutNames: []
|
property var keyboardLayoutNames: []
|
||||||
|
|
||||||
@@ -356,6 +360,15 @@ Singleton {
|
|||||||
case 'ScreenshotCaptured':
|
case 'ScreenshotCaptured':
|
||||||
handleScreenshotCaptured(event.ScreenshotCaptured);
|
handleScreenshotCaptured(event.ScreenshotCaptured);
|
||||||
break;
|
break;
|
||||||
|
case 'CastsChanged':
|
||||||
|
handleCastsChanged(event.CastsChanged);
|
||||||
|
break;
|
||||||
|
case 'CastStartedOrChanged':
|
||||||
|
handleCastStartedOrChanged(event.CastStartedOrChanged);
|
||||||
|
break;
|
||||||
|
case 'CastStopped':
|
||||||
|
handleCastStopped(event.CastStopped);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,6 +662,28 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCastsChanged(data) {
|
||||||
|
casts = data.casts || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCastStartedOrChanged(data) {
|
||||||
|
if (!data.cast)
|
||||||
|
return;
|
||||||
|
const cast = data.cast;
|
||||||
|
const existingIndex = casts.findIndex(c => c.stream_id === cast.stream_id);
|
||||||
|
if (existingIndex >= 0) {
|
||||||
|
const updatedCasts = [...casts];
|
||||||
|
updatedCasts[existingIndex] = cast;
|
||||||
|
casts = updatedCasts;
|
||||||
|
} else {
|
||||||
|
casts = [...casts, cast];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCastStopped(data) {
|
||||||
|
casts = casts.filter(c => c.stream_id !== data.stream_id);
|
||||||
|
}
|
||||||
|
|
||||||
function updateCurrentOutputWorkspaces() {
|
function updateCurrentOutputWorkspaces() {
|
||||||
if (!currentOutput) {
|
if (!currentOutput) {
|
||||||
currentOutputWorkspaces = allWorkspaces;
|
currentOutputWorkspaces = allWorkspaces;
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ Singleton {
|
|||||||
property var colorPickerModal: null
|
property var colorPickerModal: null
|
||||||
property var notificationModal: null
|
property var notificationModal: null
|
||||||
property var wifiPasswordModal: null
|
property var wifiPasswordModal: null
|
||||||
|
property var wifiPasswordModalLoader: null
|
||||||
property var polkitAuthModal: null
|
property var polkitAuthModal: null
|
||||||
|
property var polkitAuthModalLoader: null
|
||||||
property var bluetoothPairingModal: null
|
property var bluetoothPairingModal: null
|
||||||
property var networkInfoModal: null
|
property var networkInfoModal: null
|
||||||
|
|
||||||
@@ -416,11 +418,17 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showWifiPasswordModal(ssid) {
|
function showWifiPasswordModal(ssid) {
|
||||||
wifiPasswordModal?.show(ssid);
|
if (wifiPasswordModalLoader)
|
||||||
|
wifiPasswordModalLoader.active = true;
|
||||||
|
if (wifiPasswordModal)
|
||||||
|
wifiPasswordModal.show(ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showHiddenNetworkModal() {
|
function showHiddenNetworkModal() {
|
||||||
wifiPasswordModal?.showHidden();
|
if (wifiPasswordModalLoader)
|
||||||
|
wifiPasswordModalLoader.active = true;
|
||||||
|
if (wifiPasswordModal)
|
||||||
|
wifiPasswordModal.showHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideWifiPasswordModal() {
|
function hideWifiPasswordModal() {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v1.2.0
|
v1.4-unstable
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -240,7 +240,7 @@
|
|||||||
"All displays": "Tutti gli schermi"
|
"All displays": "Tutti gli schermi"
|
||||||
},
|
},
|
||||||
"Allow clicks to pass through the widget": {
|
"Allow clicks to pass through the widget": {
|
||||||
"Allow clicks to pass through the widget": ""
|
"Allow clicks to pass through the widget": "Consenti il passaggio dei clic attraverso il widget"
|
||||||
},
|
},
|
||||||
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
|
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
|
||||||
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Indietro • F1/I: File Info • F10: Aiuto • Esc: Chiudi"
|
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Indietro • F1/I: File Info • F10: Aiuto • Esc: Chiudi"
|
||||||
@@ -279,7 +279,7 @@
|
|||||||
"Anonymous Identity (optional)": "Identità anonima (facoltativa)"
|
"Anonymous Identity (optional)": "Identità anonima (facoltativa)"
|
||||||
},
|
},
|
||||||
"App ID Substitutions": {
|
"App ID Substitutions": {
|
||||||
"App ID Substitutions": ""
|
"App ID Substitutions": "Sostituzioni App ID"
|
||||||
},
|
},
|
||||||
"App Launcher": {
|
"App Launcher": {
|
||||||
"App Launcher": "App Launcher"
|
"App Launcher": "App Launcher"
|
||||||
@@ -729,7 +729,7 @@
|
|||||||
"Click Import to add a .ovpn or .conf": "Clicca su Importa per aggiungere un file .ovpn o .conf"
|
"Click Import to add a .ovpn or .conf": "Clicca su Importa per aggiungere un file .ovpn o .conf"
|
||||||
},
|
},
|
||||||
"Click Through": {
|
"Click Through": {
|
||||||
"Click Through": ""
|
"Click Through": "Clic passanti"
|
||||||
},
|
},
|
||||||
"Click any shortcut to edit. Changes save to %1": {
|
"Click any shortcut to edit. Changes save to %1": {
|
||||||
"Click any shortcut to edit. Changes save to %1": "Clicca su qualsiasi scorciatoia per modificare. Le modifiche vengono salvate in %1"
|
"Click any shortcut to edit. Changes save to %1": "Clicca su qualsiasi scorciatoia per modificare. Le modifiche vengono salvate in %1"
|
||||||
@@ -1797,7 +1797,7 @@
|
|||||||
"Grid Columns": "Colonne Griglia"
|
"Grid Columns": "Colonne Griglia"
|
||||||
},
|
},
|
||||||
"Group": {
|
"Group": {
|
||||||
"Group": ""
|
"Group": "Gruppo"
|
||||||
},
|
},
|
||||||
"Group Workspace Apps": {
|
"Group Workspace Apps": {
|
||||||
"Group Workspace Apps": "Raggruppa App per Spazio di Lavoro"
|
"Group Workspace Apps": "Raggruppa App per Spazio di Lavoro"
|
||||||
@@ -1809,13 +1809,13 @@
|
|||||||
"Group multiple windows of the same app together with a window count indicator": "Raggruppa molteplici finestre della stessa app con un indicatore del numero di finestre"
|
"Group multiple windows of the same app together with a window count indicator": "Raggruppa molteplici finestre della stessa app con un indicatore del numero di finestre"
|
||||||
},
|
},
|
||||||
"Group removed": {
|
"Group removed": {
|
||||||
"Group removed": ""
|
"Group removed": "Gruppo rimosso"
|
||||||
},
|
},
|
||||||
"Group repeated application icons in unfocused workspaces": {
|
"Group repeated application icons in unfocused workspaces": {
|
||||||
"Group repeated application icons in unfocused workspaces": "Raggruppa le icone delle applicazioni duplicate negli spazi di lavoro non attivi"
|
"Group repeated application icons in unfocused workspaces": "Raggruppa le icone delle applicazioni duplicate negli spazi di lavoro non attivi"
|
||||||
},
|
},
|
||||||
"Groups": {
|
"Groups": {
|
||||||
"Groups": ""
|
"Groups": "Gruppi"
|
||||||
},
|
},
|
||||||
"HDR (EDID)": {
|
"HDR (EDID)": {
|
||||||
"HDR (EDID)": "HDR (EDID)"
|
"HDR (EDID)": "HDR (EDID)"
|
||||||
@@ -2214,7 +2214,7 @@
|
|||||||
"Manual Show/Hide": "Mostra/Nascondi Manuale"
|
"Manual Show/Hide": "Mostra/Nascondi Manuale"
|
||||||
},
|
},
|
||||||
"Map window class names to icon names for proper icon display": {
|
"Map window class names to icon names for proper icon display": {
|
||||||
"Map window class names to icon names for proper icon display": ""
|
"Map window class names to icon names for proper icon display": "Associa i nomi delle classi delle finestre ai nomi delle icone per una corretta visualizzazione"
|
||||||
},
|
},
|
||||||
"Margin": {
|
"Margin": {
|
||||||
"Margin": "Margini"
|
"Margin": "Margini"
|
||||||
@@ -2439,7 +2439,7 @@
|
|||||||
"New York, NY": "New York, NY"
|
"New York, NY": "New York, NY"
|
||||||
},
|
},
|
||||||
"New group name...": {
|
"New group name...": {
|
||||||
"New group name...": ""
|
"New group name...": "Nome del nuovo gruppo..."
|
||||||
},
|
},
|
||||||
"Next Transition": {
|
"Next Transition": {
|
||||||
"Next Transition": "Prossima Transizione"
|
"Next Transition": "Prossima Transizione"
|
||||||
@@ -2673,7 +2673,7 @@
|
|||||||
"Options": "Opzioni"
|
"Options": "Opzioni"
|
||||||
},
|
},
|
||||||
"Organize widgets into collapsible groups": {
|
"Organize widgets into collapsible groups": {
|
||||||
"Organize widgets into collapsible groups": ""
|
"Organize widgets into collapsible groups": "Organizza i widget in gruppi comprimibili"
|
||||||
},
|
},
|
||||||
"Other": {
|
"Other": {
|
||||||
"Other": "Altro"
|
"Other": "Altro"
|
||||||
@@ -2748,7 +2748,7 @@
|
|||||||
"Password": "Password"
|
"Password": "Password"
|
||||||
},
|
},
|
||||||
"Pattern": {
|
"Pattern": {
|
||||||
"Pattern": ""
|
"Pattern": "Pattern"
|
||||||
},
|
},
|
||||||
"Pause": {
|
"Pause": {
|
||||||
"Pause": "Pausa"
|
"Pause": "Pausa"
|
||||||
@@ -3012,7 +3012,7 @@
|
|||||||
"Repeat": "Ripetizione"
|
"Repeat": "Ripetizione"
|
||||||
},
|
},
|
||||||
"Replacement": {
|
"Replacement": {
|
||||||
"Replacement": ""
|
"Replacement": "Sostituzione"
|
||||||
},
|
},
|
||||||
"Report": {
|
"Report": {
|
||||||
"Report": "Riepilogo"
|
"Report": "Riepilogo"
|
||||||
@@ -3648,7 +3648,7 @@
|
|||||||
"Sync Mode with Portal": "Modalità Sync con Portale"
|
"Sync Mode with Portal": "Modalità Sync con Portale"
|
||||||
},
|
},
|
||||||
"Sync Position Across Screens": {
|
"Sync Position Across Screens": {
|
||||||
"Sync Position Across Screens": ""
|
"Sync Position Across Screens": "Sincronizza la posizione tra gli schermi"
|
||||||
},
|
},
|
||||||
"Sync dark mode with settings portals for system-wide theme hints": {
|
"Sync dark mode with settings portals for system-wide theme hints": {
|
||||||
"Sync dark mode with settings portals for system-wide theme hints": "Sincronizza tema scuro con impostazioni di sistema"
|
"Sync dark mode with settings portals for system-wide theme hints": "Sincronizza tema scuro con impostazioni di sistema"
|
||||||
@@ -3876,7 +3876,7 @@
|
|||||||
"Unfocused Color": "Colore Inattivo"
|
"Unfocused Color": "Colore Inattivo"
|
||||||
},
|
},
|
||||||
"Ungrouped": {
|
"Ungrouped": {
|
||||||
"Ungrouped": ""
|
"Ungrouped": "Non Raggruppato"
|
||||||
},
|
},
|
||||||
"Uninstall Plugin": {
|
"Uninstall Plugin": {
|
||||||
"Uninstall Plugin": "Disinstalla Plugin"
|
"Uninstall Plugin": "Disinstalla Plugin"
|
||||||
@@ -3978,13 +3978,13 @@
|
|||||||
"Use light theme instead of dark theme": "Usa tema chiaro invece del tema scuro"
|
"Use light theme instead of dark theme": "Usa tema chiaro invece del tema scuro"
|
||||||
},
|
},
|
||||||
"Use smaller notification cards": {
|
"Use smaller notification cards": {
|
||||||
"Use smaller notification cards": ""
|
"Use smaller notification cards": "Usa schede di notifica più piccole"
|
||||||
},
|
},
|
||||||
"Use sound theme from system settings": {
|
"Use sound theme from system settings": {
|
||||||
"Use sound theme from system settings": "Usa tema di suoni dalle impostazioni di sistema"
|
"Use sound theme from system settings": "Usa tema di suoni dalle impostazioni di sistema"
|
||||||
},
|
},
|
||||||
"Use the same position and size on all displays": {
|
"Use the same position and size on all displays": {
|
||||||
"Use the same position and size on all displays": ""
|
"Use the same position and size on all displays": "Usa la stessa posizione e dimensione su tutti gli schermi"
|
||||||
},
|
},
|
||||||
"Use trigger prefix to activate": {
|
"Use trigger prefix to activate": {
|
||||||
"Use trigger prefix to activate": "Usa il prefisso attivatore per attivare"
|
"Use trigger prefix to activate": "Usa il prefisso attivatore per attivare"
|
||||||
@@ -4553,7 +4553,7 @@
|
|||||||
"No wallpaper selected": "Nessuno sfondo selezionato"
|
"No wallpaper selected": "Nessuno sfondo selezionato"
|
||||||
},
|
},
|
||||||
"notification center tab": {
|
"notification center tab": {
|
||||||
"Current": "Attuale",
|
"Current": "Attuali",
|
||||||
"History": "Cronologia"
|
"History": "Cronologia"
|
||||||
},
|
},
|
||||||
"notification history filter": {
|
"notification history filter": {
|
||||||
|
|||||||
@@ -240,7 +240,7 @@
|
|||||||
"All displays": "所有显示器"
|
"All displays": "所有显示器"
|
||||||
},
|
},
|
||||||
"Allow clicks to pass through the widget": {
|
"Allow clicks to pass through the widget": {
|
||||||
"Allow clicks to pass through the widget": ""
|
"Allow clicks to pass through the widget": "允许鼠标穿透部件"
|
||||||
},
|
},
|
||||||
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
|
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
|
||||||
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/退格: 返回 • F1/I: 文件信息 • F10: 帮助 • Esc: 关闭"
|
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/退格: 返回 • F1/I: 文件信息 • F10: 帮助 • Esc: 关闭"
|
||||||
@@ -279,7 +279,7 @@
|
|||||||
"Anonymous Identity (optional)": "匿名身份(可选)"
|
"Anonymous Identity (optional)": "匿名身份(可选)"
|
||||||
},
|
},
|
||||||
"App ID Substitutions": {
|
"App ID Substitutions": {
|
||||||
"App ID Substitutions": ""
|
"App ID Substitutions": "应用ID替换"
|
||||||
},
|
},
|
||||||
"App Launcher": {
|
"App Launcher": {
|
||||||
"App Launcher": "启动器"
|
"App Launcher": "启动器"
|
||||||
@@ -729,7 +729,7 @@
|
|||||||
"Click Import to add a .ovpn or .conf": "点击导入添加 .ovpn 或 .conf 文件"
|
"Click Import to add a .ovpn or .conf": "点击导入添加 .ovpn 或 .conf 文件"
|
||||||
},
|
},
|
||||||
"Click Through": {
|
"Click Through": {
|
||||||
"Click Through": ""
|
"Click Through": "鼠标穿透"
|
||||||
},
|
},
|
||||||
"Click any shortcut to edit. Changes save to %1": {
|
"Click any shortcut to edit. Changes save to %1": {
|
||||||
"Click any shortcut to edit. Changes save to %1": "点击任意快捷方式以编辑。更改将保存至%1。"
|
"Click any shortcut to edit. Changes save to %1": "点击任意快捷方式以编辑。更改将保存至%1。"
|
||||||
@@ -1797,7 +1797,7 @@
|
|||||||
"Grid Columns": "网格列"
|
"Grid Columns": "网格列"
|
||||||
},
|
},
|
||||||
"Group": {
|
"Group": {
|
||||||
"Group": ""
|
"Group": "分组"
|
||||||
},
|
},
|
||||||
"Group Workspace Apps": {
|
"Group Workspace Apps": {
|
||||||
"Group Workspace Apps": "分组工作区应用"
|
"Group Workspace Apps": "分组工作区应用"
|
||||||
@@ -1809,13 +1809,13 @@
|
|||||||
"Group multiple windows of the same app together with a window count indicator": "将同一应用的多个窗口合并显示,并标注窗口数量"
|
"Group multiple windows of the same app together with a window count indicator": "将同一应用的多个窗口合并显示,并标注窗口数量"
|
||||||
},
|
},
|
||||||
"Group removed": {
|
"Group removed": {
|
||||||
"Group removed": ""
|
"Group removed": "分组已移除"
|
||||||
},
|
},
|
||||||
"Group repeated application icons in unfocused workspaces": {
|
"Group repeated application icons in unfocused workspaces": {
|
||||||
"Group repeated application icons in unfocused workspaces": "在不聚焦的工作区中将重复应用图标分组"
|
"Group repeated application icons in unfocused workspaces": "在不聚焦的工作区中将重复应用图标分组"
|
||||||
},
|
},
|
||||||
"Groups": {
|
"Groups": {
|
||||||
"Groups": ""
|
"Groups": "分组"
|
||||||
},
|
},
|
||||||
"HDR (EDID)": {
|
"HDR (EDID)": {
|
||||||
"HDR (EDID)": "HDR(EDID)"
|
"HDR (EDID)": "HDR(EDID)"
|
||||||
@@ -2214,7 +2214,7 @@
|
|||||||
"Manual Show/Hide": "手动显示/隐藏"
|
"Manual Show/Hide": "手动显示/隐藏"
|
||||||
},
|
},
|
||||||
"Map window class names to icon names for proper icon display": {
|
"Map window class names to icon names for proper icon display": {
|
||||||
"Map window class names to icon names for proper icon display": ""
|
"Map window class names to icon names for proper icon display": "将窗口类名称映射到图标名称以实现正确的图标显示"
|
||||||
},
|
},
|
||||||
"Margin": {
|
"Margin": {
|
||||||
"Margin": "边距"
|
"Margin": "边距"
|
||||||
@@ -2439,7 +2439,7 @@
|
|||||||
"New York, NY": "纽约,美国纽约州"
|
"New York, NY": "纽约,美国纽约州"
|
||||||
},
|
},
|
||||||
"New group name...": {
|
"New group name...": {
|
||||||
"New group name...": ""
|
"New group name...": "新分组名..."
|
||||||
},
|
},
|
||||||
"Next Transition": {
|
"Next Transition": {
|
||||||
"Next Transition": "下一过渡"
|
"Next Transition": "下一过渡"
|
||||||
@@ -2673,7 +2673,7 @@
|
|||||||
"Options": "选项"
|
"Options": "选项"
|
||||||
},
|
},
|
||||||
"Organize widgets into collapsible groups": {
|
"Organize widgets into collapsible groups": {
|
||||||
"Organize widgets into collapsible groups": ""
|
"Organize widgets into collapsible groups": "将部件组织成可折叠分组"
|
||||||
},
|
},
|
||||||
"Other": {
|
"Other": {
|
||||||
"Other": "其他"
|
"Other": "其他"
|
||||||
@@ -2748,7 +2748,7 @@
|
|||||||
"Password": "密码"
|
"Password": "密码"
|
||||||
},
|
},
|
||||||
"Pattern": {
|
"Pattern": {
|
||||||
"Pattern": ""
|
"Pattern": "模式"
|
||||||
},
|
},
|
||||||
"Pause": {
|
"Pause": {
|
||||||
"Pause": "暂停"
|
"Pause": "暂停"
|
||||||
@@ -3012,7 +3012,7 @@
|
|||||||
"Repeat": "重复"
|
"Repeat": "重复"
|
||||||
},
|
},
|
||||||
"Replacement": {
|
"Replacement": {
|
||||||
"Replacement": ""
|
"Replacement": "替换"
|
||||||
},
|
},
|
||||||
"Report": {
|
"Report": {
|
||||||
"Report": "报告"
|
"Report": "报告"
|
||||||
@@ -3648,7 +3648,7 @@
|
|||||||
"Sync Mode with Portal": "同步系统深色模式"
|
"Sync Mode with Portal": "同步系统深色模式"
|
||||||
},
|
},
|
||||||
"Sync Position Across Screens": {
|
"Sync Position Across Screens": {
|
||||||
"Sync Position Across Screens": ""
|
"Sync Position Across Screens": "在显示器间同步位置"
|
||||||
},
|
},
|
||||||
"Sync dark mode with settings portals for system-wide theme hints": {
|
"Sync dark mode with settings portals for system-wide theme hints": {
|
||||||
"Sync dark mode with settings portals for system-wide theme hints": "随系统设置开启深色模式,以适配全局主题"
|
"Sync dark mode with settings portals for system-wide theme hints": "随系统设置开启深色模式,以适配全局主题"
|
||||||
@@ -3876,7 +3876,7 @@
|
|||||||
"Unfocused Color": "未聚焦颜色"
|
"Unfocused Color": "未聚焦颜色"
|
||||||
},
|
},
|
||||||
"Ungrouped": {
|
"Ungrouped": {
|
||||||
"Ungrouped": ""
|
"Ungrouped": "已解除分组"
|
||||||
},
|
},
|
||||||
"Uninstall Plugin": {
|
"Uninstall Plugin": {
|
||||||
"Uninstall Plugin": "卸载插件"
|
"Uninstall Plugin": "卸载插件"
|
||||||
@@ -3978,13 +3978,13 @@
|
|||||||
"Use light theme instead of dark theme": "使用浅色主题替代深色主题"
|
"Use light theme instead of dark theme": "使用浅色主题替代深色主题"
|
||||||
},
|
},
|
||||||
"Use smaller notification cards": {
|
"Use smaller notification cards": {
|
||||||
"Use smaller notification cards": ""
|
"Use smaller notification cards": "使用更小的通知卡"
|
||||||
},
|
},
|
||||||
"Use sound theme from system settings": {
|
"Use sound theme from system settings": {
|
||||||
"Use sound theme from system settings": "使用系统设置中的声音主题"
|
"Use sound theme from system settings": "使用系统设置中的声音主题"
|
||||||
},
|
},
|
||||||
"Use the same position and size on all displays": {
|
"Use the same position and size on all displays": {
|
||||||
"Use the same position and size on all displays": ""
|
"Use the same position and size on all displays": "在所有显示器上使用同样的位置与大小"
|
||||||
},
|
},
|
||||||
"Use trigger prefix to activate": {
|
"Use trigger prefix to activate": {
|
||||||
"Use trigger prefix to activate": "使用触发前缀以激活"
|
"Use trigger prefix to activate": "使用触发前缀以激活"
|
||||||
|
|||||||
Reference in New Issue
Block a user