mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-05-13 07:42:46 -04:00
Compare commits
33 Commits
c024c1b8e4
...
v1.2.3
| Author | SHA1 | Date | |
|---|---|---|---|
| a7cdb39b0b | |||
| 0ceba92a23 | |||
| 4daa7a4c88 | |||
| cc4a6a5899 | |||
| 994947477c | |||
| 311817ee97 | |||
| b80c73f9b9 | |||
| a85101c099 | |||
| 3513d57e06 | |||
| 1234847abb | |||
| 0ed595b43d | |||
| 060cbefc79 | |||
| e022c04519 | |||
| f534384e5e | |||
| a25cdb43d5 | |||
| 4e9b4ca400 | |||
| 5bab1c98b1 | |||
| 2284bb002f | |||
| b0611d6104 | |||
| 27965862d6 | |||
| e74a901e05 | |||
| 77794deb2c | |||
| 1c10746e50 | |||
| 8ecb7282b9 | |||
| 9b3fa804ab | |||
| b2ad31a27e | |||
| db17e4cb14 | |||
| 1b7dcf56a8 | |||
| 502bb88e92 | |||
| b76d0ce97d | |||
| fa66d330cf | |||
| 157eab2d07 | |||
| f50ad2dc22 |
@@ -87,6 +87,8 @@ var (
|
|||||||
swayVersionRegex = regexp.MustCompile(`sway version (\d+\.\d+)`)
|
swayVersionRegex = regexp.MustCompile(`sway version (\d+\.\d+)`)
|
||||||
riverVersionRegex = regexp.MustCompile(`river (\d+\.\d+)`)
|
riverVersionRegex = regexp.MustCompile(`river (\d+\.\d+)`)
|
||||||
wayfireVersionRegex = regexp.MustCompile(`wayfire (\d+\.\d+)`)
|
wayfireVersionRegex = regexp.MustCompile(`wayfire (\d+\.\d+)`)
|
||||||
|
labwcVersionRegex = regexp.MustCompile(`labwc (\d+\.\d+\.\d+)`)
|
||||||
|
mangowcVersionRegex = regexp.MustCompile(`mango (\d+\.\d+\.\d+)`)
|
||||||
)
|
)
|
||||||
|
|
||||||
var doctorCmd = &cobra.Command{
|
var doctorCmd = &cobra.Command{
|
||||||
@@ -448,11 +450,13 @@ func checkWindowManagers() []checkResult {
|
|||||||
versionRegex *regexp.Regexp
|
versionRegex *regexp.Regexp
|
||||||
commands []string
|
commands []string
|
||||||
}{
|
}{
|
||||||
{"Hyprland", "hyprctl", "version", hyprlandVersionRegex, []string{"hyprland", "Hyprland"}},
|
{"Hyprland", "Hyprland", "--version", hyprlandVersionRegex, []string{"hyprland", "Hyprland"}},
|
||||||
{"niri", "niri", "--version", niriVersionRegex, []string{"niri"}},
|
{"niri", "niri", "--version", niriVersionRegex, []string{"niri"}},
|
||||||
{"Sway", "sway", "--version", swayVersionRegex, []string{"sway"}},
|
{"Sway", "sway", "--version", swayVersionRegex, []string{"sway"}},
|
||||||
{"River", "river", "-version", riverVersionRegex, []string{"river"}},
|
{"River", "river", "-version", riverVersionRegex, []string{"river"}},
|
||||||
{"Wayfire", "wayfire", "--version", wayfireVersionRegex, []string{"wayfire"}},
|
{"Wayfire", "wayfire", "--version", wayfireVersionRegex, []string{"wayfire"}},
|
||||||
|
{"labwc", "labwc", "--version", labwcVersionRegex, []string{"labwc"}},
|
||||||
|
{"mangowc", "mango", "-v", mangowcVersionRegex, []string{"mango"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
var results []checkResult
|
var results []checkResult
|
||||||
@@ -477,7 +481,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 +490,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",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,8 +502,8 @@ func checkWindowManagers() []checkResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getVersionFromCommand(cmd, arg string, regex *regexp.Regexp) string {
|
func getVersionFromCommand(cmd, arg string, regex *regexp.Regexp) string {
|
||||||
output, err := exec.Command(cmd, arg).Output()
|
output, err := exec.Command(cmd, arg).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil && len(output) == 0 {
|
||||||
return "installed"
|
return "installed"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,19 +638,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 +656,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 +890,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) {
|
||||||
|
|||||||
@@ -108,7 +108,6 @@ func (o *OpenSUSEDistribution) GetPackageMappingWithVariants(wm deps.WindowManag
|
|||||||
packages := map[string]PackageMapping{
|
packages := map[string]PackageMapping{
|
||||||
// Standard zypper packages
|
// Standard zypper packages
|
||||||
"git": {Name: "git", Repository: RepoTypeSystem},
|
"git": {Name: "git", Repository: RepoTypeSystem},
|
||||||
"ghostty": {Name: "ghostty", Repository: RepoTypeSystem},
|
|
||||||
"kitty": {Name: "kitty", Repository: RepoTypeSystem},
|
"kitty": {Name: "kitty", Repository: RepoTypeSystem},
|
||||||
"alacritty": {Name: "alacritty", Repository: RepoTypeSystem},
|
"alacritty": {Name: "alacritty", Repository: RepoTypeSystem},
|
||||||
"xdg-desktop-portal-gtk": {Name: "xdg-desktop-portal-gtk", Repository: RepoTypeSystem},
|
"xdg-desktop-portal-gtk": {Name: "xdg-desktop-portal-gtk", Repository: RepoTypeSystem},
|
||||||
@@ -117,6 +116,7 @@ func (o *OpenSUSEDistribution) GetPackageMappingWithVariants(wm deps.WindowManag
|
|||||||
// DMS packages from OBS
|
// DMS packages from OBS
|
||||||
"dms (DankMaterialShell)": o.getDmsMapping(variants["dms (DankMaterialShell)"]),
|
"dms (DankMaterialShell)": o.getDmsMapping(variants["dms (DankMaterialShell)"]),
|
||||||
"quickshell": o.getQuickshellMapping(variants["quickshell"]),
|
"quickshell": o.getQuickshellMapping(variants["quickshell"]),
|
||||||
|
"ghostty": {Name: "ghostty", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
|
||||||
"matugen": {Name: "matugen", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
|
"matugen": {Name: "matugen", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
|
||||||
"dgop": {Name: "dgop", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
|
"dgop": {Name: "dgop", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,12 +11,18 @@ let
|
|||||||
|
|
||||||
inherit (config.services.greetd.settings.default_session) user;
|
inherit (config.services.greetd.settings.default_session) user;
|
||||||
|
|
||||||
|
compositorPackage =
|
||||||
|
let
|
||||||
|
configured = lib.attrByPath [ "programs" cfg.compositor.name "package" ] null config;
|
||||||
|
in
|
||||||
|
if configured != null then configured else builtins.getAttr cfg.compositor.name pkgs;
|
||||||
|
|
||||||
cacheDir = "/var/lib/dms-greeter";
|
cacheDir = "/var/lib/dms-greeter";
|
||||||
greeterScript = pkgs.writeShellScriptBin "dms-greeter" ''
|
greeterScript = pkgs.writeShellScriptBin "dms-greeter" ''
|
||||||
export PATH=$PATH:${
|
export PATH=$PATH:${
|
||||||
lib.makeBinPath [
|
lib.makeBinPath [
|
||||||
cfg.quickshell.package
|
cfg.quickshell.package
|
||||||
config.programs.${cfg.compositor.name}.package
|
compositorPackage
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
${
|
${
|
||||||
@@ -64,6 +70,7 @@ in
|
|||||||
"niri"
|
"niri"
|
||||||
"hyprland"
|
"hyprland"
|
||||||
"sway"
|
"sway"
|
||||||
|
"labwc"
|
||||||
];
|
];
|
||||||
description = "Compositor to run greeter in";
|
description = "Compositor to run greeter in";
|
||||||
};
|
};
|
||||||
|
|||||||
+10
-3
@@ -73,6 +73,13 @@ in
|
|||||||
default = hasPluginSettings;
|
default = hasPluginSettings;
|
||||||
description = ''Whether to manage plugin settings. Automatically enabled if any plugins have settings configured.'';
|
description = ''Whether to manage plugin settings. Automatically enabled if any plugins have settings configured.'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.target = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = config.wayland.systemd.target;
|
||||||
|
defaultText = lib.literalExpression "config.wayland.systemd.target";
|
||||||
|
description = "Systemd target to bind to.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
@@ -84,8 +91,8 @@ in
|
|||||||
systemd.user.services.dms = lib.mkIf cfg.systemd.enable {
|
systemd.user.services.dms = lib.mkIf cfg.systemd.enable {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "DankMaterialShell";
|
Description = "DankMaterialShell";
|
||||||
PartOf = [ config.wayland.systemd.target ];
|
PartOf = [ cfg.systemd.target ];
|
||||||
After = [ config.wayland.systemd.target ];
|
After = [ cfg.systemd.target ];
|
||||||
};
|
};
|
||||||
|
|
||||||
Service = {
|
Service = {
|
||||||
@@ -93,7 +100,7 @@ in
|
|||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
|
|
||||||
Install.WantedBy = [ config.wayland.systemd.target ];
|
Install.WantedBy = [ cfg.systemd.target ];
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg.stateFile."DankMaterialShell/session.json" = lib.mkIf (cfg.session != { }) {
|
xdg.stateFile."DankMaterialShell/session.json" = lib.mkIf (cfg.session != { }) {
|
||||||
|
|||||||
@@ -20,15 +20,19 @@ in
|
|||||||
imports = [
|
imports = [
|
||||||
(import ./options.nix args)
|
(import ./options.nix args)
|
||||||
];
|
];
|
||||||
|
options.programs.dank-material-shell.systemd.target = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Systemd target to bind to.";
|
||||||
|
default = "graphical-session.target";
|
||||||
|
};
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
systemd.user.services.dms = lib.mkIf cfg.systemd.enable {
|
systemd.user.services.dms = lib.mkIf cfg.systemd.enable {
|
||||||
description = "DankMaterialShell";
|
description = "DankMaterialShell";
|
||||||
path = lib.mkForce [ ];
|
path = lib.mkForce [ ];
|
||||||
|
|
||||||
partOf = [ "graphical-session.target" ];
|
partOf = [ cfg.systemd.target ];
|
||||||
after = [ "graphical-session.target" ];
|
after = [ cfg.systemd.target ];
|
||||||
wantedBy = [ "graphical-session.target" ];
|
wantedBy = [ cfg.systemd.target ];
|
||||||
restartIfChanged = cfg.systemd.restartIfChanged;
|
restartIfChanged = cfg.systemd.restartIfChanged;
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
|||||||
@@ -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; [
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ Singleton {
|
|||||||
Quickshell.execDetached(["cp", strip(from), strip(to)]);
|
Quickshell.execDetached(["cp", strip(from), strip(to)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isSteamApp(appId: string): bool {
|
||||||
|
return appId && /^steam_app_\d+$/.test(appId);
|
||||||
|
}
|
||||||
|
|
||||||
function moddedAppId(appId: string): string {
|
function moddedAppId(appId: string): string {
|
||||||
const subs = SettingsData.appIdSubstitutions || [];
|
const subs = SettingsData.appIdSubstitutions || [];
|
||||||
for (let i = 0; i < subs.length; i++) {
|
for (let i = 0; i < subs.length; i++) {
|
||||||
@@ -60,6 +64,9 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const steamMatch = appId.match(/^steam_app_(\d+)$/);
|
||||||
|
if (steamMatch)
|
||||||
|
return `steam_icon_${steamMatch[1]}`;
|
||||||
return appId;
|
return appId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,15 +82,19 @@ Singleton {
|
|||||||
popoutOpening();
|
popoutOpening();
|
||||||
}
|
}
|
||||||
|
|
||||||
let justClosedSamePopout = false;
|
let movedFromOtherScreen = false;
|
||||||
for (const otherScreenName in currentPopoutsByScreen) {
|
for (const otherScreenName in currentPopoutsByScreen) {
|
||||||
if (otherScreenName === screenName)
|
if (otherScreenName === screenName)
|
||||||
continue;
|
continue;
|
||||||
const otherPopout = currentPopoutsByScreen[otherScreenName];
|
const otherPopout = currentPopoutsByScreen[otherScreenName];
|
||||||
if (!otherPopout)
|
if (!otherPopout)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (otherPopout === popout) {
|
if (otherPopout === popout) {
|
||||||
justClosedSamePopout = true;
|
movedFromOtherScreen = true;
|
||||||
|
currentPopoutsByScreen[otherScreenName] = null;
|
||||||
|
currentPopoutTriggers[otherScreenName] = null;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (otherPopout.dashVisible !== undefined) {
|
if (otherPopout.dashVisible !== undefined) {
|
||||||
@@ -112,7 +116,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPopout === popout && popout.shouldBeVisible) {
|
if (currentPopout === popout && popout.shouldBeVisible && !movedFromOtherScreen) {
|
||||||
if (triggerId !== undefined && currentPopoutTriggers[screenName] === triggerId) {
|
if (triggerId !== undefined && currentPopoutTriggers[screenName] === triggerId) {
|
||||||
if (popout.dashVisible !== undefined) {
|
if (popout.dashVisible !== undefined) {
|
||||||
popout.dashVisible = false;
|
popout.dashVisible = false;
|
||||||
@@ -139,6 +143,7 @@ Singleton {
|
|||||||
popout.currentTabIndex = tabIndex;
|
popout.currentTabIndex = tabIndex;
|
||||||
}
|
}
|
||||||
currentPopoutTriggers[screenName] = triggerId;
|
currentPopoutTriggers[screenName] = triggerId;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentPopoutTriggers[screenName] = triggerId;
|
currentPopoutTriggers[screenName] = triggerId;
|
||||||
@@ -153,16 +158,8 @@ Singleton {
|
|||||||
ModalManager.closeAllModalsExcept(null);
|
ModalManager.closeAllModalsExcept(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (justClosedSamePopout) {
|
if (movedFromOtherScreen) {
|
||||||
Qt.callLater(() => {
|
popout.open();
|
||||||
if (popout.dashVisible !== undefined) {
|
|
||||||
popout.dashVisible = true;
|
|
||||||
} else if (popout.notificationHistoryVisible !== undefined) {
|
|
||||||
popout.notificationHistoryVisible = true;
|
|
||||||
} else {
|
|
||||||
popout.open();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
if (popout.dashVisible !== undefined) {
|
if (popout.dashVisible !== undefined) {
|
||||||
popout.dashVisible = true;
|
popout.dashVisible = true;
|
||||||
|
|||||||
@@ -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 },
|
||||||
|
|||||||
+46
-17
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,21 @@ Rectangle {
|
|||||||
contentHeight: audioColumn.height
|
contentHeight: audioColumn.height
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
property int maxPinnedInputs: 3
|
||||||
|
|
||||||
|
function normalizePinList(value) {
|
||||||
|
if (Array.isArray(value))
|
||||||
|
return value.filter(v => v)
|
||||||
|
if (typeof value === "string" && value.length > 0)
|
||||||
|
return [value]
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPinnedInputs() {
|
||||||
|
const pins = SettingsData.audioInputDevicePins || {}
|
||||||
|
return normalizePinList(pins["preferredInput"])
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: audioColumn
|
id: audioColumn
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -133,16 +148,20 @@ Rectangle {
|
|||||||
const nodes = Pipewire.nodes.values.filter(node => {
|
const nodes = Pipewire.nodes.values.filter(node => {
|
||||||
return node.audio && !node.isSink && !node.isStream;
|
return node.audio && !node.isSink && !node.isStream;
|
||||||
});
|
});
|
||||||
const pins = SettingsData.audioInputDevicePins || {};
|
const pinnedList = audioContent.getPinnedInputs();
|
||||||
const pinnedName = pins["preferredInput"];
|
|
||||||
|
|
||||||
let sorted = [...nodes];
|
let sorted = [...nodes];
|
||||||
sorted.sort((a, b) => {
|
sorted.sort((a, b) => {
|
||||||
// Pinned device first
|
// Pinned device first
|
||||||
if (a.name === pinnedName && b.name !== pinnedName)
|
const aPinnedIndex = pinnedList.indexOf(a.name)
|
||||||
return -1;
|
const bPinnedIndex = pinnedList.indexOf(b.name)
|
||||||
if (b.name === pinnedName && a.name !== pinnedName)
|
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||||
return 1;
|
if (aPinnedIndex === -1)
|
||||||
|
return 1
|
||||||
|
if (bPinnedIndex === -1)
|
||||||
|
return -1
|
||||||
|
return aPinnedIndex - bPinnedIndex
|
||||||
|
}
|
||||||
// Then active device
|
// Then active device
|
||||||
if (a === AudioService.source && b !== AudioService.source)
|
if (a === AudioService.source && b !== AudioService.source)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -224,7 +243,7 @@ Rectangle {
|
|||||||
height: 28
|
height: 28
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +256,7 @@ Rectangle {
|
|||||||
name: "push_pin"
|
name: "push_pin"
|
||||||
size: 16
|
size: 16
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -245,12 +264,12 @@ Rectangle {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -261,16 +280,24 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}));
|
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}))
|
||||||
const isCurrentlyPinned = pins["preferredInput"] === modelData.name;
|
let pinnedList = audioContent.normalizePinList(pins["preferredInput"])
|
||||||
|
const pinIndex = pinnedList.indexOf(modelData.name)
|
||||||
|
|
||||||
if (isCurrentlyPinned) {
|
if (pinIndex !== -1) {
|
||||||
delete pins["preferredInput"];
|
pinnedList.splice(pinIndex, 1)
|
||||||
} else {
|
} else {
|
||||||
pins["preferredInput"] = modelData.name;
|
pinnedList.unshift(modelData.name)
|
||||||
|
if (pinnedList.length > audioContent.maxPinnedInputs)
|
||||||
|
pinnedList = pinnedList.slice(0, audioContent.maxPinnedInputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsData.set("audioInputDevicePins", pins);
|
if (pinnedList.length > 0)
|
||||||
|
pins["preferredInput"] = pinnedList
|
||||||
|
else
|
||||||
|
delete pins["preferredInput"]
|
||||||
|
|
||||||
|
SettingsData.set("audioInputDevicePins", pins)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,21 @@ Rectangle {
|
|||||||
contentHeight: audioColumn.height
|
contentHeight: audioColumn.height
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
property int maxPinnedOutputs: 3
|
||||||
|
|
||||||
|
function normalizePinList(value) {
|
||||||
|
if (Array.isArray(value))
|
||||||
|
return value.filter(v => v)
|
||||||
|
if (typeof value === "string" && value.length > 0)
|
||||||
|
return [value]
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPinnedOutputs() {
|
||||||
|
const pins = SettingsData.audioOutputDevicePins || {}
|
||||||
|
return normalizePinList(pins["preferredOutput"])
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: audioColumn
|
id: audioColumn
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -143,16 +158,20 @@ Rectangle {
|
|||||||
const nodes = Pipewire.nodes.values.filter(node => {
|
const nodes = Pipewire.nodes.values.filter(node => {
|
||||||
return node.audio && node.isSink && !node.isStream;
|
return node.audio && node.isSink && !node.isStream;
|
||||||
});
|
});
|
||||||
const pins = SettingsData.audioOutputDevicePins || {};
|
const pinnedList = audioContent.getPinnedOutputs();
|
||||||
const pinnedName = pins["preferredOutput"];
|
|
||||||
|
|
||||||
let sorted = [...nodes];
|
let sorted = [...nodes];
|
||||||
sorted.sort((a, b) => {
|
sorted.sort((a, b) => {
|
||||||
// Pinned device first
|
// Pinned device first
|
||||||
if (a.name === pinnedName && b.name !== pinnedName)
|
const aPinnedIndex = pinnedList.indexOf(a.name)
|
||||||
return -1;
|
const bPinnedIndex = pinnedList.indexOf(b.name)
|
||||||
if (b.name === pinnedName && a.name !== pinnedName)
|
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||||
return 1;
|
if (aPinnedIndex === -1)
|
||||||
|
return 1
|
||||||
|
if (bPinnedIndex === -1)
|
||||||
|
return -1
|
||||||
|
return aPinnedIndex - bPinnedIndex
|
||||||
|
}
|
||||||
// Then active device
|
// Then active device
|
||||||
if (a === AudioService.sink && b !== AudioService.sink)
|
if (a === AudioService.sink && b !== AudioService.sink)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -236,7 +255,7 @@ Rectangle {
|
|||||||
height: 28
|
height: 28
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +268,7 @@ Rectangle {
|
|||||||
name: "push_pin"
|
name: "push_pin"
|
||||||
size: 16
|
size: 16
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -257,12 +276,12 @@ Rectangle {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -273,16 +292,24 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {}));
|
const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {}))
|
||||||
const isCurrentlyPinned = pins["preferredOutput"] === modelData.name;
|
let pinnedList = audioContent.normalizePinList(pins["preferredOutput"])
|
||||||
|
const pinIndex = pinnedList.indexOf(modelData.name)
|
||||||
|
|
||||||
if (isCurrentlyPinned) {
|
if (pinIndex !== -1) {
|
||||||
delete pins["preferredOutput"];
|
pinnedList.splice(pinIndex, 1)
|
||||||
} else {
|
} else {
|
||||||
pins["preferredOutput"] = modelData.name;
|
pinnedList.unshift(modelData.name)
|
||||||
|
if (pinnedList.length > audioContent.maxPinnedOutputs)
|
||||||
|
pinnedList = pinnedList.slice(0, audioContent.maxPinnedOutputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsData.set("audioOutputDevicePins", pins);
|
if (pinnedList.length > 0)
|
||||||
|
pins["preferredOutput"] = pinnedList
|
||||||
|
else
|
||||||
|
delete pins["preferredOutput"]
|
||||||
|
|
||||||
|
SettingsData.set("audioOutputDevicePins", pins)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,21 @@ Rectangle {
|
|||||||
contentHeight: bluetoothColumn.height
|
contentHeight: bluetoothColumn.height
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
property int maxPinnedDevices: 3
|
||||||
|
|
||||||
|
function normalizePinList(value) {
|
||||||
|
if (Array.isArray(value))
|
||||||
|
return value.filter(v => v)
|
||||||
|
if (typeof value === "string" && value.length > 0)
|
||||||
|
return [value]
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPinnedDevices() {
|
||||||
|
const pins = SettingsData.bluetoothDevicePins || {}
|
||||||
|
return normalizePinList(pins["preferredDevice"])
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: bluetoothColumn
|
id: bluetoothColumn
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -162,14 +177,18 @@ Rectangle {
|
|||||||
if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
|
if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
const pins = SettingsData.bluetoothDevicePins || {}
|
const pinnedList = bluetoothContent.getPinnedDevices()
|
||||||
const pinnedAddr = pins["preferredDevice"]
|
|
||||||
|
|
||||||
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
|
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
|
||||||
devices.sort((a, b) => {
|
devices.sort((a, b) => {
|
||||||
// Pinned device first
|
// Pinned device first
|
||||||
if (a.address === pinnedAddr && b.address !== pinnedAddr) return -1
|
const aPinnedIndex = pinnedList.indexOf(a.address)
|
||||||
if (b.address === pinnedAddr && a.address !== pinnedAddr) return 1
|
const bPinnedIndex = pinnedList.indexOf(b.address)
|
||||||
|
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||||
|
if (aPinnedIndex === -1) return 1
|
||||||
|
if (bPinnedIndex === -1) return -1
|
||||||
|
return aPinnedIndex - bPinnedIndex
|
||||||
|
}
|
||||||
// Then connected devices
|
// Then connected devices
|
||||||
if (a.connected && !b.connected) return -1
|
if (a.connected && !b.connected) return -1
|
||||||
if (!a.connected && b.connected) return 1
|
if (!a.connected && b.connected) return 1
|
||||||
@@ -302,7 +321,7 @@ Rectangle {
|
|||||||
height: 28
|
height: 28
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05)
|
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +334,7 @@ Rectangle {
|
|||||||
name: "push_pin"
|
name: "push_pin"
|
||||||
size: 16
|
size: 16
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -323,12 +342,12 @@ Rectangle {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||||
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin")
|
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin")
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: {
|
color: {
|
||||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -340,14 +359,22 @@ Rectangle {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
const pins = JSON.parse(JSON.stringify(SettingsData.bluetoothDevicePins || {}))
|
const pins = JSON.parse(JSON.stringify(SettingsData.bluetoothDevicePins || {}))
|
||||||
const isCurrentlyPinned = pins["preferredDevice"] === modelData.address
|
let pinnedList = bluetoothContent.normalizePinList(pins["preferredDevice"])
|
||||||
|
const pinIndex = pinnedList.indexOf(modelData.address)
|
||||||
|
|
||||||
if (isCurrentlyPinned) {
|
if (pinIndex !== -1) {
|
||||||
delete pins["preferredDevice"]
|
pinnedList.splice(pinIndex, 1)
|
||||||
} else {
|
} else {
|
||||||
pins["preferredDevice"] = modelData.address
|
pinnedList.unshift(modelData.address)
|
||||||
|
if (pinnedList.length > bluetoothContent.maxPinnedDevices)
|
||||||
|
pinnedList = pinnedList.slice(0, bluetoothContent.maxPinnedDevices)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pinnedList.length > 0)
|
||||||
|
pins["preferredDevice"] = pinnedList
|
||||||
|
else
|
||||||
|
delete pins["preferredDevice"]
|
||||||
|
|
||||||
SettingsData.set("bluetoothDevicePins", pins)
|
SettingsData.set("bluetoothDevicePins", pins)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -463,20 +463,39 @@ Rectangle {
|
|||||||
contentHeight: wifiColumn.height
|
contentHeight: wifiColumn.height
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
property int maxPinnedNetworks: 3
|
||||||
|
|
||||||
|
function normalizePinList(value) {
|
||||||
|
if (Array.isArray(value))
|
||||||
|
return value.filter(v => v)
|
||||||
|
if (typeof value === "string" && value.length > 0)
|
||||||
|
return [value]
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPinnedNetworks() {
|
||||||
|
const pins = SettingsData.wifiNetworkPins || {}
|
||||||
|
return normalizePinList(pins["preferredWifi"])
|
||||||
|
}
|
||||||
|
|
||||||
property var frozenNetworks: []
|
property var frozenNetworks: []
|
||||||
property bool menuOpen: false
|
property bool menuOpen: false
|
||||||
property var sortedNetworks: {
|
property var sortedNetworks: {
|
||||||
const ssid = NetworkService.currentWifiSSID;
|
const ssid = NetworkService.currentWifiSSID;
|
||||||
const networks = NetworkService.wifiNetworks;
|
const networks = NetworkService.wifiNetworks;
|
||||||
const pins = SettingsData.wifiNetworkPins || {};
|
const pinnedList = getPinnedNetworks()
|
||||||
const pinnedSSID = pins["preferredWifi"];
|
|
||||||
|
|
||||||
let sorted = [...networks];
|
let sorted = [...networks];
|
||||||
sorted.sort((a, b) => {
|
sorted.sort((a, b) => {
|
||||||
if (a.ssid === pinnedSSID && b.ssid !== pinnedSSID)
|
const aPinnedIndex = pinnedList.indexOf(a.ssid)
|
||||||
return -1;
|
const bPinnedIndex = pinnedList.indexOf(b.ssid)
|
||||||
if (b.ssid === pinnedSSID && a.ssid !== pinnedSSID)
|
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||||
return 1;
|
if (aPinnedIndex === -1)
|
||||||
|
return 1
|
||||||
|
if (bPinnedIndex === -1)
|
||||||
|
return -1
|
||||||
|
return aPinnedIndex - bPinnedIndex
|
||||||
|
}
|
||||||
if (a.ssid === ssid)
|
if (a.ssid === ssid)
|
||||||
return -1;
|
return -1;
|
||||||
if (b.ssid === ssid)
|
if (b.ssid === ssid)
|
||||||
@@ -625,7 +644,7 @@ Rectangle {
|
|||||||
height: 28
|
height: 28
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
color: {
|
color: {
|
||||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||||
return isThisNetworkPinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
return isThisNetworkPinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +657,7 @@ Rectangle {
|
|||||||
name: "push_pin"
|
name: "push_pin"
|
||||||
size: 16
|
size: 16
|
||||||
color: {
|
color: {
|
||||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||||
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
|
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -646,12 +665,12 @@ Rectangle {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||||
return isThisNetworkPinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
return isThisNetworkPinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: {
|
color: {
|
||||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||||
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
|
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -662,16 +681,24 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}));
|
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}))
|
||||||
const isCurrentlyPinned = pins["preferredWifi"] === modelData.ssid;
|
let pinnedList = wifiContent.normalizePinList(pins["preferredWifi"])
|
||||||
|
const pinIndex = pinnedList.indexOf(modelData.ssid)
|
||||||
|
|
||||||
if (isCurrentlyPinned) {
|
if (pinIndex !== -1) {
|
||||||
delete pins["preferredWifi"];
|
pinnedList.splice(pinIndex, 1)
|
||||||
} else {
|
} else {
|
||||||
pins["preferredWifi"] = modelData.ssid;
|
pinnedList.unshift(modelData.ssid)
|
||||||
|
if (pinnedList.length > wifiContent.maxPinnedNetworks)
|
||||||
|
pinnedList = pinnedList.slice(0, wifiContent.maxPinnedNetworks)
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsData.set("wifiNetworkPins", pins);
|
if (pinnedList.length > 0)
|
||||||
|
pins["preferredWifi"] = pinnedList
|
||||||
|
else
|
||||||
|
delete pins["preferredWifi"]
|
||||||
|
|
||||||
|
SettingsData.set("wifiNetworkPins", pins)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -687,8 +714,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 +776,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,10 +24,12 @@ 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
|
||||||
property real brightnessAccumulator: 0
|
property real brightnessAccumulator: 0
|
||||||
|
readonly property real vIconSize: Theme.barIconSize(root.barThickness, -4)
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
active: root.showPrinterIcon
|
active: root.showPrinterIcon
|
||||||
@@ -213,7 +215,25 @@ BasePill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hasNoVisibleIcons() {
|
function hasNoVisibleIcons() {
|
||||||
return !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon && !root.showVpnIcon && !root.showBrightnessIcon && !root.showMicIcon && !root.showBatteryIcon && !root.showPrinterIcon;
|
if (root.showScreenSharingIcon && NiriService.hasCasts)
|
||||||
|
return false;
|
||||||
|
if (root.showNetworkIcon && NetworkService.networkAvailable)
|
||||||
|
return false;
|
||||||
|
if (root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected)
|
||||||
|
return false;
|
||||||
|
if (root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled)
|
||||||
|
return false;
|
||||||
|
if (root.showAudioIcon)
|
||||||
|
return false;
|
||||||
|
if (root.showMicIcon)
|
||||||
|
return false;
|
||||||
|
if (root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice())
|
||||||
|
return false;
|
||||||
|
if (root.showBatteryIcon && BatteryService.batteryAvailable)
|
||||||
|
return false;
|
||||||
|
if (root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
@@ -224,48 +244,74 @@ BasePill {
|
|||||||
Column {
|
Column {
|
||||||
id: controlColumn
|
id: controlColumn
|
||||||
visible: root.isVerticalOrientation
|
visible: root.isVerticalOrientation
|
||||||
anchors.centerIn: parent
|
width: root.vIconSize
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankIcon {
|
Item {
|
||||||
name: root.getNetworkIconName()
|
width: root.vIconSize
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
height: root.vIconSize
|
||||||
color: root.getNetworkIconColor()
|
visible: root.showScreenSharingIcon && NiriService.hasCasts
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
DankIcon {
|
||||||
|
name: "screen_record"
|
||||||
|
size: root.vIconSize
|
||||||
|
color: NiriService.hasActiveCast ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: root.vIconSize
|
||||||
|
height: root.vIconSize
|
||||||
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: root.getNetworkIconName()
|
||||||
|
size: root.vIconSize
|
||||||
|
color: root.getNetworkIconColor()
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
Item {
|
||||||
name: "vpn_lock"
|
width: root.vIconSize
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
height: root.vIconSize
|
||||||
color: NetworkService.vpnConnected ? Theme.primary : Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected
|
visible: root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "vpn_lock"
|
||||||
|
size: root.vIconSize
|
||||||
|
color: NetworkService.vpnConnected ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
Item {
|
||||||
name: "bluetooth"
|
width: root.vIconSize
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
height: root.vIconSize
|
||||||
color: BluetoothService.connected ? Theme.primary : Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "bluetooth"
|
||||||
|
size: root.vIconSize
|
||||||
|
color: BluetoothService.connected ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
width: audioIconV.implicitWidth + 4
|
width: root.vIconSize
|
||||||
height: audioIconV.implicitHeight + (root.showAudioPercent ? audioPercentV.implicitHeight : 0) + 4
|
height: root.vIconSize + (root.showAudioPercent ? audioPercentV.implicitHeight + 2 : 0)
|
||||||
color: "transparent"
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showAudioIcon
|
visible: root.showAudioIcon
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
id: audioIconV
|
id: audioIconV
|
||||||
name: root.getVolumeIconName()
|
name: root.getVolumeIconName()
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
size: root.vIconSize
|
||||||
color: Theme.widgetIconColor
|
color: Theme.widgetIconColor
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -292,21 +338,18 @@ BasePill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
width: micIconV.implicitWidth + 4
|
width: root.vIconSize
|
||||||
height: micIconV.implicitHeight + (root.showAudioPercent ? micPercentV.implicitHeight : 0) + 4
|
height: root.vIconSize + (root.showMicPercent ? micPercentV.implicitHeight + 2 : 0)
|
||||||
color: "transparent"
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showMicIcon
|
visible: root.showMicIcon
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
id: micIconV
|
id: micIconV
|
||||||
name: root.getMicIconName()
|
name: root.getMicIconName()
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
size: root.vIconSize
|
||||||
color: root.getMicIconColor()
|
color: root.getMicIconColor()
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -333,21 +376,18 @@ BasePill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
width: brightnessIconV.implicitWidth + 4
|
width: root.vIconSize
|
||||||
height: brightnessIconV.implicitHeight + (root.showBrightnessPercent ? brightnessPercentV.implicitHeight : 0) + 4
|
height: root.vIconSize + (root.showBrightnessPercent ? brightnessPercentV.implicitHeight + 2 : 0)
|
||||||
color: "transparent"
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice()
|
visible: root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice()
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
id: brightnessIconV
|
id: brightnessIconV
|
||||||
name: root.getBrightnessIconName()
|
name: root.getBrightnessIconName()
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
size: root.vIconSize
|
||||||
color: Theme.widgetIconColor
|
color: Theme.widgetIconColor
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -371,28 +411,43 @@ BasePill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
Item {
|
||||||
name: Theme.getBatteryIcon(BatteryService.batteryLevel, BatteryService.isCharging, BatteryService.batteryAvailable)
|
width: root.vIconSize
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
height: root.vIconSize
|
||||||
color: root.getBatteryIconColor()
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showBatteryIcon && BatteryService.batteryAvailable
|
visible: root.showBatteryIcon && BatteryService.batteryAvailable
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: Theme.getBatteryIcon(BatteryService.batteryLevel, BatteryService.isCharging, BatteryService.batteryAvailable)
|
||||||
|
size: root.vIconSize
|
||||||
|
color: root.getBatteryIconColor()
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
Item {
|
||||||
name: "print"
|
width: root.vIconSize
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
height: root.vIconSize
|
||||||
color: Theme.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs()
|
visible: root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs()
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "print"
|
||||||
|
size: root.vIconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
Item {
|
||||||
name: "settings"
|
width: root.vIconSize
|
||||||
size: Theme.barIconSize(root.barThickness, -4)
|
height: root.vIconSize
|
||||||
color: root.isActive ? Theme.primary : Theme.widgetIconColor
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: root.hasNoVisibleIcons()
|
visible: root.hasNoVisibleIcons()
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "settings"
|
||||||
|
size: root.vIconSize
|
||||||
|
color: root.isActive ? Theme.primary : Theme.widgetIconColor
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,6 +457,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()
|
||||||
|
|||||||
@@ -155,9 +155,17 @@ BasePill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
size: 18
|
||||||
|
name: "sports_esports"
|
||||||
|
color: Theme.widgetTextColor
|
||||||
|
visible: root.isVerticalOrientation && activeWindow && activeWindow.appId && appIcon.status !== Image.Ready && Paths.isSteamApp(activeWindow.appId)
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: root.isVerticalOrientation && activeWindow && activeWindow.appId && appIcon.status !== Image.Ready
|
visible: root.isVerticalOrientation && activeWindow && activeWindow.appId && appIcon.status !== Image.Ready && !Paths.isSteamApp(activeWindow.appId)
|
||||||
text: {
|
text: {
|
||||||
if (!activeWindow || !activeWindow.appId)
|
if (!activeWindow || !activeWindow.appId)
|
||||||
return "?";
|
return "?";
|
||||||
|
|||||||
@@ -393,9 +393,19 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: (widgetData?.runningAppsCompactMode !== undefined ? widgetData.runningAppsCompactMode : SettingsData.runningAppsCompactMode) ? Math.round((parent.width - Theme.barIconSize(root.barThickness)) / 2) : Theme.spacingXS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
name: "sports_esports"
|
||||||
|
color: Theme.widgetTextColor
|
||||||
|
visible: !iconImg.visible && Paths.isSteamApp(appId)
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !iconImg.visible
|
visible: !iconImg.visible && !Paths.isSteamApp(appId)
|
||||||
text: {
|
text: {
|
||||||
root._desktopEntriesUpdateTrigger;
|
root._desktopEntriesUpdateTrigger;
|
||||||
if (!appId)
|
if (!appId)
|
||||||
@@ -628,9 +638,19 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: (widgetData?.runningAppsCompactMode !== undefined ? widgetData.runningAppsCompactMode : SettingsData.runningAppsCompactMode) ? Math.round((parent.width - Theme.barIconSize(root.barThickness)) / 2) : Theme.spacingXS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
size: Theme.barIconSize(root.barThickness)
|
||||||
|
name: "sports_esports"
|
||||||
|
color: Theme.widgetTextColor
|
||||||
|
visible: !iconImg.visible && Paths.isSteamApp(appId)
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !iconImg.visible
|
visible: !iconImg.visible && !Paths.isSteamApp(appId)
|
||||||
text: {
|
text: {
|
||||||
root._desktopEntriesUpdateTrigger;
|
root._desktopEntriesUpdateTrigger;
|
||||||
if (!appId)
|
if (!appId)
|
||||||
|
|||||||
@@ -265,6 +265,7 @@ Item {
|
|||||||
|
|
||||||
if (!byApp[key]) {
|
if (!byApp[key]) {
|
||||||
const isQuickshell = keyBase === "org.quickshell";
|
const isQuickshell = keyBase === "org.quickshell";
|
||||||
|
const isSteamApp = Paths.isSteamApp(keyBase);
|
||||||
const moddedId = Paths.moddedAppId(keyBase);
|
const moddedId = Paths.moddedAppId(keyBase);
|
||||||
const desktopEntry = DesktopEntries.heuristicLookup(moddedId);
|
const desktopEntry = DesktopEntries.heuristicLookup(moddedId);
|
||||||
const icon = Paths.getAppIcon(keyBase, desktopEntry);
|
const icon = Paths.getAppIcon(keyBase, desktopEntry);
|
||||||
@@ -272,6 +273,7 @@ Item {
|
|||||||
"type": "icon",
|
"type": "icon",
|
||||||
"icon": icon,
|
"icon": icon,
|
||||||
"isQuickshell": isQuickshell,
|
"isQuickshell": isQuickshell,
|
||||||
|
"isSteamApp": isSteamApp,
|
||||||
"active": !!((w.activated || w.is_focused) || (CompositorService.isNiri && w.is_focused)),
|
"active": !!((w.activated || w.is_focused) || (CompositorService.isNiri && w.is_focused)),
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"windowId": w.address || w.id,
|
"windowId": w.address || w.id,
|
||||||
@@ -1135,7 +1137,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: modelData.icon
|
source: modelData.icon
|
||||||
opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6
|
opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6
|
||||||
visible: !modelData.isQuickshell
|
visible: !modelData.isQuickshell && !modelData.isSteamApp
|
||||||
}
|
}
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
@@ -1151,6 +1153,22 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: modelData.icon
|
||||||
|
opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6
|
||||||
|
visible: modelData.isSteamApp && modelData.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
size: root.appIconSize
|
||||||
|
name: "sports_esports"
|
||||||
|
color: Theme.widgetTextColor
|
||||||
|
opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6
|
||||||
|
visible: modelData.isSteamApp && !modelData.icon
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: rowAppMouseArea
|
id: rowAppMouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -1229,7 +1247,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: modelData.icon
|
source: modelData.icon
|
||||||
opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6
|
opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6
|
||||||
visible: !modelData.isQuickshell
|
visible: !modelData.isQuickshell && !modelData.isSteamApp
|
||||||
}
|
}
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
@@ -1245,6 +1263,22 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: modelData.icon
|
||||||
|
opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6
|
||||||
|
visible: modelData.isSteamApp && modelData.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
size: root.appIconSize
|
||||||
|
name: "sports_esports"
|
||||||
|
color: Theme.widgetTextColor
|
||||||
|
opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6
|
||||||
|
visible: modelData.isSteamApp && !modelData.icon
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: colAppMouseArea
|
id: colAppMouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ Item {
|
|||||||
width: actualIconSize
|
width: actualIconSize
|
||||||
height: actualIconSize
|
height: actualIconSize
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: iconImg.status !== Image.Ready
|
visible: iconImg.status !== Image.Ready && appData && appData.appId && !Paths.isSteamApp(appData.appId)
|
||||||
color: Theme.surfaceLight
|
color: Theme.surfaceLight
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 1
|
border.width: 1
|
||||||
@@ -425,6 +425,14 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
size: actualIconSize
|
||||||
|
name: "sports_esports"
|
||||||
|
color: Theme.surfaceText
|
||||||
|
visible: iconImg.status !== Image.Ready && appData && appData.appId && Paths.isSteamApp(appData.appId)
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.horizontalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.horizontalCenter
|
anchors.horizontalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.horizontalCenter
|
||||||
anchors.verticalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? parent.verticalCenter : undefined
|
anchors.verticalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? parent.verticalCenter : undefined
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export WLR_DRM_DEVICES=/dev/dri/card1
|
|
||||||
|
|
||||||
COMPOSITOR=""
|
COMPOSITOR=""
|
||||||
COMPOSITOR_CONFIG=""
|
COMPOSITOR_CONFIG=""
|
||||||
DMS_PATH="dms-greeter"
|
DMS_PATH="dms-greeter"
|
||||||
@@ -16,7 +14,7 @@ dms-greeter - DankMaterialShell greeter launcher
|
|||||||
Usage: dms-greeter --command COMPOSITOR [OPTIONS]
|
Usage: dms-greeter --command COMPOSITOR [OPTIONS]
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
--command COMPOSITOR Compositor to use (niri, hyprland, sway, scroll or mangowc)
|
--command COMPOSITOR Compositor to use (niri, hyprland, sway, scroll, mangowc, or labwc)
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-C, --config PATH Custom compositor config file
|
-C, --config PATH Custom compositor config file
|
||||||
@@ -33,6 +31,7 @@ Examples:
|
|||||||
dms-greeter --command scroll -p /home/user/.config/quickshell/custom-dms
|
dms-greeter --command scroll -p /home/user/.config/quickshell/custom-dms
|
||||||
dms-greeter --command niri --cache-dir /tmp/dmsgreeter
|
dms-greeter --command niri --cache-dir /tmp/dmsgreeter
|
||||||
dms-greeter --command mangowc
|
dms-greeter --command mangowc
|
||||||
|
dms-greeter --command labwc
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +230,15 @@ SCROLL_EOF
|
|||||||
exec scroll -c "$COMPOSITOR_CONFIG"
|
exec scroll -c "$COMPOSITOR_CONFIG"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
||||||
|
labwc)
|
||||||
|
if [[ -n "$COMPOSITOR_CONFIG" ]]; then
|
||||||
|
exec labwc --config "$COMPOSITOR_CONFIG" --session "$QS_CMD"
|
||||||
|
else
|
||||||
|
exec labwc --session "$QS_CMD"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
mangowc)
|
mangowc)
|
||||||
if [[ -n "$COMPOSITOR_CONFIG" ]]; then
|
if [[ -n "$COMPOSITOR_CONFIG" ]]; then
|
||||||
exec mango -c "$COMPOSITOR_CONFIG" -s "$QS_CMD && mmsg -d quit"
|
exec mango -c "$COMPOSITOR_CONFIG" -s "$QS_CMD && mmsg -d quit"
|
||||||
@@ -241,7 +249,7 @@ SCROLL_EOF
|
|||||||
|
|
||||||
*)
|
*)
|
||||||
echo "Error: Unsupported compositor: $COMPOSITOR" >&2
|
echo "Error: Unsupported compositor: $COMPOSITOR" >&2
|
||||||
echo "Supported compositors: niri, hyprland, sway, mangowc" >&2
|
echo "Supported compositors: niri, hyprland, sway, scroll, mangowc, labwc" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -262,9 +262,7 @@ DankOSD {
|
|||||||
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
|
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
|
||||||
|
|
||||||
function onVolumeChanged() {
|
function onVolumeChanged() {
|
||||||
if (!vertSlider.dragging) {
|
vertSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
|
||||||
vertSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,10 +177,11 @@ Item {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
if (!SystemUpdateService.shellVersion)
|
if (!SystemUpdateService.shellVersion && !DMSService.cliVersion)
|
||||||
return "dms";
|
return "dms";
|
||||||
|
|
||||||
let version = SystemUpdateService.shellVersion;
|
let version = SystemUpdateService.shellVersion || "";
|
||||||
|
let cliVersion = DMSService.cliVersion || "";
|
||||||
|
|
||||||
// Debian/Ubuntu/OpenSUSE git format: 1.0.3+git2264.c5c5ce84
|
// Debian/Ubuntu/OpenSUSE git format: 1.0.3+git2264.c5c5ce84
|
||||||
let match = version.match(/^([\d.]+)\+git(\d+)\./);
|
let match = version.match(/^([\d.]+)\+git(\d+)\./);
|
||||||
@@ -191,7 +192,25 @@ Item {
|
|||||||
// Fedora COPR git format: 0.0.git.2267.d430cae9
|
// Fedora COPR git format: 0.0.git.2267.d430cae9
|
||||||
match = version.match(/^[\d.]+\.git\.(\d+)\./);
|
match = version.match(/^[\d.]+\.git\.(\d+)\./);
|
||||||
if (match) {
|
if (match) {
|
||||||
return `dms (git) v1.0.3-${match[1]}`;
|
function extractBaseVersion(value) {
|
||||||
|
if (!value)
|
||||||
|
return "";
|
||||||
|
let baseMatch = value.match(/(\d+\.\d+\.\d+)/);
|
||||||
|
if (baseMatch)
|
||||||
|
return baseMatch[1];
|
||||||
|
baseMatch = value.match(/(\d+\.\d+)/);
|
||||||
|
if (baseMatch)
|
||||||
|
return baseMatch[1];
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
let baseVersion = extractBaseVersion(cliVersion);
|
||||||
|
if (!baseVersion)
|
||||||
|
baseVersion = extractBaseVersion(SystemUpdateService.semverVersion);
|
||||||
|
if (baseVersion) {
|
||||||
|
return `dms (git) v${baseVersion}-${match[1]}`;
|
||||||
|
}
|
||||||
|
return `dms (git) v${match[1]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stable release format: 1.0.3
|
// Stable release format: 1.0.3
|
||||||
@@ -200,6 +219,18 @@ Item {
|
|||||||
return `dms v${match[1]}`;
|
return `dms v${match[1]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!version && cliVersion) {
|
||||||
|
match = cliVersion.match(/^([\d.]+)\+git(\d+)\./);
|
||||||
|
if (match) {
|
||||||
|
return `dms (git) v${match[1]}-${match[2]}`;
|
||||||
|
}
|
||||||
|
match = cliVersion.match(/^([\d.]+)$/);
|
||||||
|
if (match) {
|
||||||
|
return `dms v${match[1]}`;
|
||||||
|
}
|
||||||
|
return `dms ${cliVersion}`;
|
||||||
|
}
|
||||||
|
|
||||||
return `dms ${version}`;
|
return `dms ${version}`;
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeXLarge
|
font.pixelSize: Theme.fontSizeXLarge
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ Item {
|
|||||||
SettingsButtonGroupRow {
|
SettingsButtonGroupRow {
|
||||||
text: I18n.tr("Position")
|
text: I18n.tr("Position")
|
||||||
model: ["Top", "Bottom", "Left", "Right"]
|
model: ["Top", "Bottom", "Left", "Right"]
|
||||||
|
buttonPadding: Theme.spacingS
|
||||||
|
minButtonWidth: 44
|
||||||
|
textSize: Theme.fontSizeSmall
|
||||||
currentIndex: {
|
currentIndex: {
|
||||||
switch (SettingsData.dockPosition) {
|
switch (SettingsData.dockPosition) {
|
||||||
case SettingsData.Position.Top:
|
case SettingsData.Position.Top:
|
||||||
@@ -129,6 +132,9 @@ Item {
|
|||||||
tags: ["dock", "indicator", "style", "circle", "line"]
|
tags: ["dock", "indicator", "style", "circle", "line"]
|
||||||
text: I18n.tr("Indicator Style")
|
text: I18n.tr("Indicator Style")
|
||||||
model: ["Circle", "Line"]
|
model: ["Circle", "Line"]
|
||||||
|
buttonPadding: Theme.spacingS
|
||||||
|
minButtonWidth: 44
|
||||||
|
textSize: Theme.fontSizeSmall
|
||||||
currentIndex: SettingsData.dockIndicatorStyle === "circle" ? 0 : 1
|
currentIndex: SettingsData.dockIndicatorStyle === "circle" ? 0 : 1
|
||||||
onSelectionChanged: (index, selected) => {
|
onSelectionChanged: (index, selected) => {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
@@ -225,6 +231,9 @@ Item {
|
|||||||
description: I18n.tr("Choose the border accent color")
|
description: I18n.tr("Choose the border accent color")
|
||||||
visible: SettingsData.dockBorderEnabled
|
visible: SettingsData.dockBorderEnabled
|
||||||
model: ["Surface", "Secondary", "Primary"]
|
model: ["Surface", "Secondary", "Primary"]
|
||||||
|
buttonPadding: Theme.spacingS
|
||||||
|
minButtonWidth: 44
|
||||||
|
textSize: Theme.fontSizeSmall
|
||||||
currentIndex: {
|
currentIndex: {
|
||||||
switch (SettingsData.dockBorderColor) {
|
switch (SettingsData.dockBorderColor) {
|
||||||
case "surfaceText":
|
case "surfaceText":
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -14,6 +15,7 @@ Item {
|
|||||||
property string expandedVpnUuid: ""
|
property string expandedVpnUuid: ""
|
||||||
property string expandedWifiSsid: ""
|
property string expandedWifiSsid: ""
|
||||||
property string expandedEthDevice: ""
|
property string expandedEthDevice: ""
|
||||||
|
property int maxPinnedWifiNetworks: 3
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
NetworkService.addRef();
|
NetworkService.addRef();
|
||||||
@@ -23,15 +25,59 @@ 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 => {
|
function normalizePinList(value) {
|
||||||
VPNService.importVpn(path.replace("file://", ""));
|
if (Array.isArray(value))
|
||||||
|
return value.filter(v => v)
|
||||||
|
if (typeof value === "string" && value.length > 0)
|
||||||
|
return [value]
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPinnedWifiNetworks() {
|
||||||
|
const pins = SettingsData.wifiNetworkPins || {}
|
||||||
|
return normalizePinList(pins["preferredWifi"])
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleWifiPin(ssid) {
|
||||||
|
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}))
|
||||||
|
let pinnedList = normalizePinList(pins["preferredWifi"])
|
||||||
|
const pinIndex = pinnedList.indexOf(ssid)
|
||||||
|
|
||||||
|
if (pinIndex !== -1) {
|
||||||
|
pinnedList.splice(pinIndex, 1)
|
||||||
|
} else {
|
||||||
|
pinnedList.unshift(ssid)
|
||||||
|
if (pinnedList.length > maxPinnedWifiNetworks)
|
||||||
|
pinnedList = pinnedList.slice(0, maxPinnedWifiNetworks)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinnedList.length > 0)
|
||||||
|
pins["preferredWifi"] = pinnedList
|
||||||
|
else
|
||||||
|
delete pins["preferredWifi"]
|
||||||
|
|
||||||
|
SettingsData.set("wifiNetworkPins", pins)
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyLoader {
|
||||||
|
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://", ""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1014,15 +1060,19 @@ Item {
|
|||||||
model: {
|
model: {
|
||||||
const ssid = NetworkService.currentWifiSSID;
|
const ssid = NetworkService.currentWifiSSID;
|
||||||
const networks = NetworkService.wifiNetworks || [];
|
const networks = NetworkService.wifiNetworks || [];
|
||||||
const pins = SettingsData.wifiNetworkPins || {};
|
const pinnedList = networkTab.getPinnedWifiNetworks();
|
||||||
const pinnedSSID = pins["preferredWifi"];
|
|
||||||
|
|
||||||
let sorted = [...networks];
|
let sorted = [...networks];
|
||||||
sorted.sort((a, b) => {
|
sorted.sort((a, b) => {
|
||||||
if (a.ssid === pinnedSSID && b.ssid !== pinnedSSID)
|
const aPinnedIndex = pinnedList.indexOf(a.ssid)
|
||||||
return -1;
|
const bPinnedIndex = pinnedList.indexOf(b.ssid)
|
||||||
if (b.ssid === pinnedSSID && a.ssid !== pinnedSSID)
|
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||||
return 1;
|
if (aPinnedIndex === -1)
|
||||||
|
return 1
|
||||||
|
if (bPinnedIndex === -1)
|
||||||
|
return -1
|
||||||
|
return aPinnedIndex - bPinnedIndex
|
||||||
|
}
|
||||||
if (a.ssid === ssid)
|
if (a.ssid === ssid)
|
||||||
return -1;
|
return -1;
|
||||||
if (b.ssid === ssid)
|
if (b.ssid === ssid)
|
||||||
@@ -1038,7 +1088,7 @@ Item {
|
|||||||
required property int index
|
required property int index
|
||||||
|
|
||||||
readonly property bool isConnected: modelData.ssid === NetworkService.currentWifiSSID
|
readonly property bool isConnected: modelData.ssid === NetworkService.currentWifiSSID
|
||||||
readonly property bool isPinned: (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid
|
readonly property bool isPinned: networkTab.getPinnedWifiNetworks().includes(modelData.ssid)
|
||||||
readonly property bool isExpanded: networkTab.expandedWifiSsid === modelData.ssid
|
readonly property bool isExpanded: networkTab.expandedWifiSsid === modelData.ssid
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -1213,13 +1263,7 @@ Item {
|
|||||||
buttonSize: 28
|
buttonSize: 28
|
||||||
iconColor: isPinned ? Theme.primary : Theme.surfaceVariantText
|
iconColor: isPinned ? Theme.primary : Theme.surfaceVariantText
|
||||||
onClicked: {
|
onClicked: {
|
||||||
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}));
|
networkTab.toggleWifiPin(modelData.ssid)
|
||||||
if (isPinned) {
|
|
||||||
delete pins["preferredWifi"];
|
|
||||||
} else {
|
|
||||||
pins["preferredWifi"] = modelData.ssid;
|
|
||||||
}
|
|
||||||
SettingsData.set("wifiNetworkPins", pins);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1520,7 +1564,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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -270,7 +270,9 @@ FloatingWindow {
|
|||||||
root.updateFilteredPlugins();
|
root.updateFilteredPlugins();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
thirdPartyConfirmModal.visible = true;
|
thirdPartyConfirmLoader.active = true;
|
||||||
|
if (thirdPartyConfirmLoader.item)
|
||||||
|
thirdPartyConfirmLoader.item.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,119 +670,132 @@ FloatingWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingWindow {
|
LazyLoader {
|
||||||
id: thirdPartyConfirmModal
|
id: thirdPartyConfirmLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
objectName: "thirdPartyConfirm"
|
FloatingWindow {
|
||||||
title: I18n.tr("Third-Party Plugin Warning")
|
id: thirdPartyConfirmModal
|
||||||
implicitWidth: 500
|
|
||||||
implicitHeight: 350
|
|
||||||
color: Theme.surfaceContainer
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
FocusScope {
|
function show() {
|
||||||
anchors.fill: parent
|
visible = true;
|
||||||
focus: true
|
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
thirdPartyConfirmModal.visible = false;
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
function hide() {
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
objectName: "thirdPartyConfirm"
|
||||||
|
title: I18n.tr("Third-Party Plugin Warning")
|
||||||
|
implicitWidth: 500
|
||||||
|
implicitHeight: 350
|
||||||
|
color: Theme.surfaceContainer
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
focus: true
|
||||||
spacing: Theme.spacingL
|
|
||||||
|
|
||||||
Row {
|
Keys.onPressed: event => {
|
||||||
width: parent.width
|
if (event.key === Qt.Key_Escape) {
|
||||||
spacing: Theme.spacingM
|
thirdPartyConfirmModal.hide();
|
||||||
|
event.accepted = true;
|
||||||
DankIcon {
|
|
||||||
name: "warning"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.warning
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Third-Party Plugin Warning")
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: parent.width - parent.spacing * 2 - Theme.iconSize - parent.children[1].implicitWidth - closeConfirmBtn.width
|
|
||||||
height: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
id: closeConfirmBtn
|
|
||||||
iconName: "close"
|
|
||||||
iconSize: Theme.iconSize - 2
|
|
||||||
iconColor: Theme.outline
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: thirdPartyConfirmModal.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
width: parent.width
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
anchors.fill: parent
|
||||||
spacing: Theme.spacingS
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
StyledText {
|
Row {
|
||||||
text: I18n.tr("• Plugins may contain bugs or security issues")
|
width: parent.width
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
spacing: Theme.spacingM
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
|
DankIcon {
|
||||||
|
name: "warning"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.warning
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Third-Party Plugin Warning")
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width - parent.spacing * 2 - Theme.iconSize - parent.children[1].implicitWidth - closeConfirmBtn.width
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
id: closeConfirmBtn
|
||||||
|
iconName: "close"
|
||||||
|
iconSize: Theme.iconSize - 2
|
||||||
|
iconColor: Theme.outline
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: thirdPartyConfirmModal.hide()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: I18n.tr("• Review code before installation when possible")
|
width: parent.width
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
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.")
|
||||||
color: Theme.surfaceVariantText
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
Column {
|
||||||
text: I18n.tr("• Install only from trusted sources")
|
width: parent.width
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
spacing: Theme.spacingS
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
StyledText {
|
||||||
width: parent.width
|
text: I18n.tr("• Plugins may contain bugs or security issues")
|
||||||
height: parent.height - parent.spacing * 3 - y
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
}
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
StyledText {
|
||||||
anchors.right: parent.right
|
text: I18n.tr("• Review code before installation when possible")
|
||||||
spacing: Theme.spacingM
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
DankButton {
|
StyledText {
|
||||||
text: I18n.tr("Cancel")
|
text: I18n.tr("• Install only from trusted sources")
|
||||||
iconName: "close"
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
onClicked: thirdPartyConfirmModal.visible = false
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankButton {
|
Item {
|
||||||
text: I18n.tr("I Understand")
|
width: parent.width
|
||||||
iconName: "check"
|
height: parent.height - parent.spacing * 3 - y
|
||||||
onClicked: {
|
}
|
||||||
SessionData.setShowThirdPartyPlugins(true);
|
|
||||||
root.updateFilteredPlugins();
|
Row {
|
||||||
thirdPartyConfirmModal.visible = false;
|
anchors.right: parent.right
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankButton {
|
||||||
|
text: I18n.tr("Cancel")
|
||||||
|
iconName: "close"
|
||||||
|
onClicked: thirdPartyConfirmModal.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
DankButton {
|
||||||
|
text: I18n.tr("I Understand")
|
||||||
|
iconName: "check"
|
||||||
|
onClicked: {
|
||||||
|
SessionData.setShowThirdPartyPlugins(true);
|
||||||
|
root.updateFilteredPlugins();
|
||||||
|
thirdPartyConfirmModal.hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ StyledRect {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
id: headerIcon
|
id: headerIcon
|
||||||
@@ -69,6 +70,8 @@ StyledRect {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: root.title !== ""
|
visible: root.title !== ""
|
||||||
|
width: parent.width - (headerIcon.visible ? headerIcon.width + parent.spacing : 0)
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 = "/";
|
||||||
@@ -400,6 +402,24 @@ Item {
|
|||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cloneWidgetData(widget) {
|
||||||
|
if (typeof widget === "string")
|
||||||
|
return {
|
||||||
|
"id": widget,
|
||||||
|
"enabled": true
|
||||||
|
};
|
||||||
|
var result = {
|
||||||
|
"id": widget.id,
|
||||||
|
"enabled": widget.enabled
|
||||||
|
};
|
||||||
|
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "minimumWidth", "showSwap", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon"];
|
||||||
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
if (widget[keys[i]] !== undefined)
|
||||||
|
result[keys[i]] = widget[keys[i]];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function handleItemEnabledChanged(sectionId, itemId, enabled) {
|
function handleItemEnabledChanged(sectionId, itemId, enabled) {
|
||||||
var widgets = getWidgetsForSection(sectionId).slice();
|
var widgets = getWidgetsForSection(sectionId).slice();
|
||||||
for (var i = 0; i < widgets.length; i++) {
|
for (var i = 0; i < widgets.length; i++) {
|
||||||
@@ -407,42 +427,8 @@ Item {
|
|||||||
var widgetId = typeof widget === "string" ? widget : widget.id;
|
var widgetId = typeof widget === "string" ? widget : widget.id;
|
||||||
if (widgetId !== itemId)
|
if (widgetId !== itemId)
|
||||||
continue;
|
continue;
|
||||||
|
var newWidget = cloneWidgetData(widget);
|
||||||
if (typeof widget === "string") {
|
newWidget.enabled = enabled;
|
||||||
widgets[i] = {
|
|
||||||
"id": widget,
|
|
||||||
"enabled": enabled
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": enabled
|
|
||||||
};
|
|
||||||
if (widget.size !== undefined)
|
|
||||||
newWidget.size = widget.size;
|
|
||||||
if (widget.selectedGpuIndex !== undefined)
|
|
||||||
newWidget.selectedGpuIndex = widget.selectedGpuIndex;
|
|
||||||
else if (widget.id === "gpuTemp")
|
|
||||||
newWidget.selectedGpuIndex = 0;
|
|
||||||
if (widget.pciId !== undefined)
|
|
||||||
newWidget.pciId = widget.pciId;
|
|
||||||
else if (widget.id === "gpuTemp")
|
|
||||||
newWidget.pciId = "";
|
|
||||||
if (widget.id === "controlCenterButton") {
|
|
||||||
newWidget.showNetworkIcon = widget.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon;
|
|
||||||
newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon;
|
|
||||||
newWidget.showAudioIcon = widget.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon;
|
|
||||||
newWidget.showAudioPercent = widget.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent;
|
|
||||||
newWidget.showVpnIcon = widget.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon;
|
|
||||||
newWidget.showBrightnessIcon = widget.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon;
|
|
||||||
newWidget.showBrightnessPercent = widget.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent;
|
|
||||||
newWidget.showMicIcon = widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon;
|
|
||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
|
||||||
}
|
|
||||||
widgets[i] = newWidget;
|
widgets[i] = newWidget;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -455,128 +441,36 @@ Item {
|
|||||||
|
|
||||||
function handleSpacerSizeChanged(sectionId, widgetIndex, newSize) {
|
function handleSpacerSizeChanged(sectionId, widgetIndex, newSize) {
|
||||||
var widgets = getWidgetsForSection(sectionId).slice();
|
var widgets = getWidgetsForSection(sectionId).slice();
|
||||||
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
|
if (widgetIndex < 0 || widgetIndex >= widgets.length)
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var widget = widgets[widgetIndex];
|
var widget = widgets[widgetIndex];
|
||||||
var widgetId = typeof widget === "string" ? widget : widget.id;
|
var widgetId = typeof widget === "string" ? widget : widget.id;
|
||||||
if (widgetId !== "spacer") {
|
if (widgetId !== "spacer")
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
return;
|
||||||
}
|
var newWidget = cloneWidgetData(widget);
|
||||||
|
newWidget.size = newSize;
|
||||||
if (typeof widget === "string") {
|
|
||||||
widgets[widgetIndex] = {
|
|
||||||
"id": widget,
|
|
||||||
"enabled": true,
|
|
||||||
"size": newSize
|
|
||||||
};
|
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": widget.enabled,
|
|
||||||
"size": newSize
|
|
||||||
};
|
|
||||||
if (widget.selectedGpuIndex !== undefined)
|
|
||||||
newWidget.selectedGpuIndex = widget.selectedGpuIndex;
|
|
||||||
if (widget.pciId !== undefined)
|
|
||||||
newWidget.pciId = widget.pciId;
|
|
||||||
if (widget.id === "controlCenterButton") {
|
|
||||||
newWidget.showNetworkIcon = widget.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon;
|
|
||||||
newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon;
|
|
||||||
newWidget.showAudioIcon = widget.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon;
|
|
||||||
newWidget.showAudioPercent = widget.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent;
|
|
||||||
newWidget.showVpnIcon = widget.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon;
|
|
||||||
newWidget.showBrightnessIcon = widget.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon;
|
|
||||||
newWidget.showBrightnessPercent = widget.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent;
|
|
||||||
newWidget.showMicIcon = widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon;
|
|
||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
|
||||||
}
|
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGpuSelectionChanged(sectionId, widgetIndex, selectedGpuIndex) {
|
function handleGpuSelectionChanged(sectionId, widgetIndex, selectedGpuIndex) {
|
||||||
var widgets = getWidgetsForSection(sectionId).slice();
|
var widgets = getWidgetsForSection(sectionId).slice();
|
||||||
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
|
if (widgetIndex < 0 || widgetIndex >= widgets.length)
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var pciId = DgopService.availableGpus && DgopService.availableGpus.length > selectedGpuIndex ? DgopService.availableGpus[selectedGpuIndex].pciId : "";
|
var pciId = DgopService.availableGpus && DgopService.availableGpus.length > selectedGpuIndex ? DgopService.availableGpus[selectedGpuIndex].pciId : "";
|
||||||
var widget = widgets[widgetIndex];
|
var newWidget = cloneWidgetData(widgets[widgetIndex]);
|
||||||
if (typeof widget === "string") {
|
newWidget.selectedGpuIndex = selectedGpuIndex;
|
||||||
widgets[widgetIndex] = {
|
newWidget.pciId = pciId;
|
||||||
"id": widget,
|
|
||||||
"enabled": true,
|
|
||||||
"selectedGpuIndex": selectedGpuIndex,
|
|
||||||
"pciId": pciId
|
|
||||||
};
|
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": widget.enabled,
|
|
||||||
"selectedGpuIndex": selectedGpuIndex,
|
|
||||||
"pciId": pciId
|
|
||||||
};
|
|
||||||
if (widget.size !== undefined)
|
|
||||||
newWidget.size = widget.size;
|
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDiskMountSelectionChanged(sectionId, widgetIndex, mountPath) {
|
function handleDiskMountSelectionChanged(sectionId, widgetIndex, mountPath) {
|
||||||
var widgets = getWidgetsForSection(sectionId).slice();
|
var widgets = getWidgetsForSection(sectionId).slice();
|
||||||
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
|
if (widgetIndex < 0 || widgetIndex >= widgets.length)
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
return;
|
||||||
}
|
var newWidget = cloneWidgetData(widgets[widgetIndex]);
|
||||||
|
newWidget.mountPath = mountPath;
|
||||||
var widget = widgets[widgetIndex];
|
|
||||||
if (typeof widget === "string") {
|
|
||||||
widgets[widgetIndex] = {
|
|
||||||
"id": widget,
|
|
||||||
"enabled": true,
|
|
||||||
"mountPath": mountPath
|
|
||||||
};
|
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": widget.enabled,
|
|
||||||
"mountPath": mountPath
|
|
||||||
};
|
|
||||||
if (widget.size !== undefined)
|
|
||||||
newWidget.size = widget.size;
|
|
||||||
if (widget.selectedGpuIndex !== undefined)
|
|
||||||
newWidget.selectedGpuIndex = widget.selectedGpuIndex;
|
|
||||||
if (widget.pciId !== undefined)
|
|
||||||
newWidget.pciId = widget.pciId;
|
|
||||||
if (widget.id === "controlCenterButton") {
|
|
||||||
newWidget.showNetworkIcon = widget.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon;
|
|
||||||
newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon;
|
|
||||||
newWidget.showAudioIcon = widget.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon;
|
|
||||||
newWidget.showAudioPercent = widget.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent;
|
|
||||||
newWidget.showVpnIcon = widget.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon;
|
|
||||||
newWidget.showBrightnessIcon = widget.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon;
|
|
||||||
newWidget.showBrightnessPercent = widget.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent;
|
|
||||||
newWidget.showMicIcon = widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon;
|
|
||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
|
||||||
}
|
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
@@ -585,32 +479,8 @@ Item {
|
|||||||
var widgets = getWidgetsForSection(sectionId).slice();
|
var widgets = getWidgetsForSection(sectionId).slice();
|
||||||
if (widgetIndex < 0 || widgetIndex >= widgets.length)
|
if (widgetIndex < 0 || widgetIndex >= widgets.length)
|
||||||
return;
|
return;
|
||||||
|
var newWidget = cloneWidgetData(widgets[widgetIndex]);
|
||||||
var widget = widgets[widgetIndex];
|
|
||||||
if (typeof widget === "string") {
|
|
||||||
widget = {
|
|
||||||
"id": widget,
|
|
||||||
"enabled": true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": widget.enabled !== undefined ? widget.enabled : true,
|
|
||||||
"showNetworkIcon": widget.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon,
|
|
||||||
"showBluetoothIcon": widget.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon,
|
|
||||||
"showAudioIcon": widget.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon,
|
|
||||||
"showAudioPercent": widget.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent,
|
|
||||||
"showVpnIcon": widget.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon,
|
|
||||||
"showBrightnessIcon": widget.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon,
|
|
||||||
"showBrightnessPercent": widget.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent,
|
|
||||||
"showMicIcon": widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon,
|
|
||||||
"showMicPercent": widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent,
|
|
||||||
"showBatteryIcon": widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon,
|
|
||||||
"showPrinterIcon": widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon
|
|
||||||
};
|
|
||||||
newWidget[settingName] = value;
|
newWidget[settingName] = value;
|
||||||
|
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
@@ -635,46 +505,8 @@ Item {
|
|||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var newWidget = cloneWidgetData(widgets[widgetIndex]);
|
||||||
var widget = widgets[widgetIndex];
|
newWidget.minimumWidth = enabled;
|
||||||
if (typeof widget === "string") {
|
|
||||||
widgets[widgetIndex] = {
|
|
||||||
"id": widget,
|
|
||||||
"enabled": true,
|
|
||||||
"minimumWidth": enabled
|
|
||||||
};
|
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": widget.enabled,
|
|
||||||
"minimumWidth": enabled
|
|
||||||
};
|
|
||||||
if (widget.size !== undefined)
|
|
||||||
newWidget.size = widget.size;
|
|
||||||
if (widget.selectedGpuIndex !== undefined)
|
|
||||||
newWidget.selectedGpuIndex = widget.selectedGpuIndex;
|
|
||||||
if (widget.pciId !== undefined)
|
|
||||||
newWidget.pciId = widget.pciId;
|
|
||||||
if (widget.mountPath !== undefined)
|
|
||||||
newWidget.mountPath = widget.mountPath;
|
|
||||||
if (widget.showSwap !== undefined)
|
|
||||||
newWidget.showSwap = widget.showSwap;
|
|
||||||
if (widget.id === "controlCenterButton") {
|
|
||||||
newWidget.showNetworkIcon = widget.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon;
|
|
||||||
newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon;
|
|
||||||
newWidget.showAudioIcon = widget.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon;
|
|
||||||
newWidget.showAudioPercent = widget.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent;
|
|
||||||
newWidget.showVpnIcon = widget.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon;
|
|
||||||
newWidget.showBrightnessIcon = widget.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon;
|
|
||||||
newWidget.showBrightnessPercent = widget.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent;
|
|
||||||
newWidget.showMicIcon = widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon;
|
|
||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
|
||||||
}
|
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
@@ -685,141 +517,41 @@ Item {
|
|||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var newWidget = cloneWidgetData(widgets[widgetIndex]);
|
||||||
var widget = widgets[widgetIndex];
|
newWidget.showSwap = enabled;
|
||||||
if (typeof widget === "string") {
|
|
||||||
widgets[widgetIndex] = {
|
|
||||||
"id": widget,
|
|
||||||
"enabled": true,
|
|
||||||
"showSwap": enabled
|
|
||||||
};
|
|
||||||
setWidgetsForSection(sectionId, widgets);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": widget.enabled,
|
|
||||||
"showSwap": enabled
|
|
||||||
};
|
|
||||||
if (widget.size !== undefined)
|
|
||||||
newWidget.size = widget.size;
|
|
||||||
if (widget.selectedGpuIndex !== undefined)
|
|
||||||
newWidget.selectedGpuIndex = widget.selectedGpuIndex;
|
|
||||||
if (widget.pciId !== undefined)
|
|
||||||
newWidget.pciId = widget.pciId;
|
|
||||||
if (widget.mountPath !== undefined)
|
|
||||||
newWidget.mountPath = widget.mountPath;
|
|
||||||
if (widget.minimumWidth !== undefined)
|
|
||||||
newWidget.minimumWidth = widget.minimumWidth;
|
|
||||||
if (widget.mediaSize !== undefined)
|
|
||||||
newWidget.mediaSize = widget.mediaSize;
|
|
||||||
if (widget.clockCompactMode !== undefined)
|
|
||||||
newWidget.clockCompactMode = widget.clockCompactMode;
|
|
||||||
if (widget.focusedWindowCompactMode !== undefined)
|
|
||||||
newWidget.focusedWindowCompactMode = widget.focusedWindowCompactMode;
|
|
||||||
if (widget.runningAppsCompactMode !== undefined)
|
|
||||||
newWidget.runningAppsCompactMode = widget.runningAppsCompactMode;
|
|
||||||
if (widget.keyboardLayoutNameCompactMode !== undefined)
|
|
||||||
newWidget.keyboardLayoutNameCompactMode = widget.keyboardLayoutNameCompactMode;
|
|
||||||
if (widget.id === "controlCenterButton") {
|
|
||||||
newWidget.showNetworkIcon = widget.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon;
|
|
||||||
newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon;
|
|
||||||
newWidget.showAudioIcon = widget.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon;
|
|
||||||
newWidget.showAudioPercent = widget.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent;
|
|
||||||
newWidget.showVpnIcon = widget.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon;
|
|
||||||
newWidget.showBrightnessIcon = widget.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon;
|
|
||||||
newWidget.showBrightnessPercent = widget.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent;
|
|
||||||
newWidget.showMicIcon = widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon;
|
|
||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
|
||||||
}
|
|
||||||
widgets[widgetIndex] = newWidget;
|
widgets[widgetIndex] = newWidget;
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCompactModeChanged(sectionId, widgetId, value) {
|
function handleCompactModeChanged(sectionId, widgetId, value) {
|
||||||
var widgets = getWidgetsForSection(sectionId).slice();
|
var widgets = getWidgetsForSection(sectionId).slice();
|
||||||
|
|
||||||
for (var i = 0; i < widgets.length; i++) {
|
for (var i = 0; i < widgets.length; i++) {
|
||||||
var widget = widgets[i];
|
var widget = widgets[i];
|
||||||
var currentId = typeof widget === "string" ? widget : widget.id;
|
var currentId = typeof widget === "string" ? widget : widget.id;
|
||||||
|
|
||||||
if (currentId !== widgetId)
|
if (currentId !== widgetId)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (typeof widget === "string") {
|
var newWidget = cloneWidgetData(widget);
|
||||||
widgets[i] = {
|
|
||||||
"id": widget,
|
|
||||||
"enabled": true
|
|
||||||
};
|
|
||||||
widget = widgets[i];
|
|
||||||
} else {
|
|
||||||
var newWidget = {
|
|
||||||
"id": widget.id,
|
|
||||||
"enabled": widget.enabled
|
|
||||||
};
|
|
||||||
if (widget.size !== undefined)
|
|
||||||
newWidget.size = widget.size;
|
|
||||||
if (widget.selectedGpuIndex !== undefined)
|
|
||||||
newWidget.selectedGpuIndex = widget.selectedGpuIndex;
|
|
||||||
if (widget.pciId !== undefined)
|
|
||||||
newWidget.pciId = widget.pciId;
|
|
||||||
if (widget.mountPath !== undefined)
|
|
||||||
newWidget.mountPath = widget.mountPath;
|
|
||||||
if (widget.minimumWidth !== undefined)
|
|
||||||
newWidget.minimumWidth = widget.minimumWidth;
|
|
||||||
if (widget.showSwap !== undefined)
|
|
||||||
newWidget.showSwap = widget.showSwap;
|
|
||||||
if (widget.mediaSize !== undefined)
|
|
||||||
newWidget.mediaSize = widget.mediaSize;
|
|
||||||
if (widget.clockCompactMode !== undefined)
|
|
||||||
newWidget.clockCompactMode = widget.clockCompactMode;
|
|
||||||
if (widget.focusedWindowCompactMode !== undefined)
|
|
||||||
newWidget.focusedWindowCompactMode = widget.focusedWindowCompactMode;
|
|
||||||
if (widget.runningAppsCompactMode !== undefined)
|
|
||||||
newWidget.runningAppsCompactMode = widget.runningAppsCompactMode;
|
|
||||||
if (widget.keyboardLayoutNameCompactMode !== undefined)
|
|
||||||
newWidget.keyboardLayoutNameCompactMode = widget.keyboardLayoutNameCompactMode;
|
|
||||||
if (widget.id === "controlCenterButton") {
|
|
||||||
newWidget.showNetworkIcon = widget.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon;
|
|
||||||
newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon;
|
|
||||||
newWidget.showAudioIcon = widget.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon;
|
|
||||||
newWidget.showAudioPercent = widget.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent;
|
|
||||||
newWidget.showVpnIcon = widget.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon;
|
|
||||||
newWidget.showBrightnessIcon = widget.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon;
|
|
||||||
newWidget.showBrightnessPercent = widget.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent;
|
|
||||||
newWidget.showMicIcon = widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon;
|
|
||||||
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
|
|
||||||
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
|
|
||||||
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
|
|
||||||
}
|
|
||||||
widgets[i] = newWidget;
|
|
||||||
widget = newWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (widgetId) {
|
switch (widgetId) {
|
||||||
case "music":
|
case "music":
|
||||||
widget.mediaSize = value;
|
newWidget.mediaSize = value;
|
||||||
break;
|
break;
|
||||||
case "clock":
|
case "clock":
|
||||||
widget.clockCompactMode = value;
|
newWidget.clockCompactMode = value;
|
||||||
break;
|
break;
|
||||||
case "focusedWindow":
|
case "focusedWindow":
|
||||||
widget.focusedWindowCompactMode = value;
|
newWidget.focusedWindowCompactMode = value;
|
||||||
break;
|
break;
|
||||||
case "runningApps":
|
case "runningApps":
|
||||||
widget.runningAppsCompactMode = value;
|
newWidget.runningAppsCompactMode = value;
|
||||||
break;
|
break;
|
||||||
case "keyboard_layout_name":
|
case "keyboard_layout_name":
|
||||||
widget.keyboardLayoutNameCompactMode = value;
|
newWidget.keyboardLayoutNameCompactMode = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
widgets[i] = newWidget;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
setWidgetsForSection(sectionId, widgets);
|
setWidgetsForSection(sectionId, widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,6 +598,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 +650,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 +861,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 +916,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 +971,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);
|
||||||
|
|||||||
@@ -31,6 +31,19 @@ Column {
|
|||||||
signal minimumWidthChanged(string sectionId, int widgetIndex, bool enabled)
|
signal minimumWidthChanged(string sectionId, int widgetIndex, bool enabled)
|
||||||
signal showSwapChanged(string sectionId, int widgetIndex, bool enabled)
|
signal showSwapChanged(string sectionId, int widgetIndex, bool enabled)
|
||||||
|
|
||||||
|
function cloneWidgetData(widget) {
|
||||||
|
var result = {
|
||||||
|
"id": widget.id,
|
||||||
|
"enabled": widget.enabled
|
||||||
|
};
|
||||||
|
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "minimumWidth", "showSwap", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon"];
|
||||||
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
if (widget[keys[i]] !== undefined)
|
||||||
|
result[keys[i]] = widget[keys[i]];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: implicitHeight
|
height: implicitHeight
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
@@ -727,13 +740,7 @@ Column {
|
|||||||
var newItems = root.items.slice();
|
var newItems = root.items.slice();
|
||||||
var draggedItem = newItems.splice(index, 1)[0];
|
var draggedItem = newItems.splice(index, 1)[0];
|
||||||
newItems.splice(newIndex, 0, draggedItem);
|
newItems.splice(newIndex, 0, draggedItem);
|
||||||
root.itemOrderChanged(newItems.map(item => {
|
root.itemOrderChanged(newItems.map(item => root.cloneWidgetData(item)));
|
||||||
return ({
|
|
||||||
"id": item.id,
|
|
||||||
"enabled": item.enabled,
|
|
||||||
"size": item.size
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegateItem.x = 0;
|
delegateItem.x = 0;
|
||||||
@@ -875,6 +882,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 +919,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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,15 +63,15 @@ Item {
|
|||||||
onToggled: checked => SettingsData.set("showWorkspaceApps", checked)
|
onToggled: checked => SettingsData.set("showWorkspaceApps", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Item {
|
||||||
width: parent.width - Theme.spacingL
|
width: parent.width
|
||||||
spacing: Theme.spacingL
|
height: maxAppsColumn.height
|
||||||
visible: SettingsData.showWorkspaceApps
|
visible: SettingsData.showWorkspaceApps
|
||||||
opacity: visible ? 1 : 0
|
opacity: visible ? 1 : 0
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingL
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
id: maxAppsColumn
|
||||||
|
x: Theme.spacingL
|
||||||
width: 120
|
width: 120
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
@@ -80,14 +80,15 @@ Item {
|
|||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
DankTextField {
|
DankTextField {
|
||||||
width: 100
|
width: 100
|
||||||
height: 28
|
height: 28
|
||||||
placeholderText: "#ffffff"
|
placeholderText: "3"
|
||||||
text: SettingsData.maxWorkspaceIcons
|
text: SettingsData.maxWorkspaceIcons
|
||||||
maximumLength: 7
|
maximumLength: 2
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
topPadding: Theme.spacingXS
|
topPadding: Theme.spacingXS
|
||||||
bottomPadding: Theme.spacingXS
|
bottomPadding: Theme.spacingXS
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -287,11 +287,14 @@ Singleton {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MODIFICATION: Treat Launchers as persistent instances like Daemons
|
if (isDaemon) {
|
||||||
if (isDaemon || isLauncher) {
|
const newDaemons = Object.assign({}, pluginDaemonComponents);
|
||||||
|
newDaemons[pluginId] = comp;
|
||||||
|
pluginDaemonComponents = newDaemons;
|
||||||
|
} else if (isLauncher) {
|
||||||
const instance = comp.createObject(root, {
|
const instance = comp.createObject(root, {
|
||||||
"pluginId": pluginId,
|
"pluginId": pluginId,
|
||||||
"pluginService": root // Inject PluginService
|
"pluginService": root
|
||||||
});
|
});
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
console.error("PluginService: failed to instantiate plugin:", pluginId, comp.errorString());
|
console.error("PluginService: failed to instantiate plugin:", pluginId, comp.errorString());
|
||||||
@@ -302,15 +305,9 @@ Singleton {
|
|||||||
newInstances[pluginId] = instance;
|
newInstances[pluginId] = instance;
|
||||||
pluginInstances = newInstances;
|
pluginInstances = newInstances;
|
||||||
|
|
||||||
if (isDaemon) {
|
const newLaunchers = Object.assign({}, pluginLauncherComponents);
|
||||||
const newDaemons = Object.assign({}, pluginDaemonComponents);
|
newLaunchers[pluginId] = comp;
|
||||||
newDaemons[pluginId] = comp;
|
pluginLauncherComponents = newLaunchers;
|
||||||
pluginDaemonComponents = newDaemons;
|
|
||||||
} else {
|
|
||||||
const newLaunchers = Object.assign({}, pluginLauncherComponents);
|
|
||||||
newLaunchers[pluginId] = comp;
|
|
||||||
pluginLauncherComponents = newLaunchers;
|
|
||||||
}
|
|
||||||
} else if (isDesktop) {
|
} else if (isDesktop) {
|
||||||
const newDesktop = Object.assign({}, pluginDesktopComponents);
|
const newDesktop = Object.assign({}, pluginDesktopComponents);
|
||||||
newDesktop[pluginId] = comp;
|
newDesktop[pluginId] = comp;
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -754,7 +754,7 @@ Singleton {
|
|||||||
"humidity": Math.round(hourly.relative_humidity_2m?.[i] || 0),
|
"humidity": Math.round(hourly.relative_humidity_2m?.[i] || 0),
|
||||||
"wind": Math.round(hourly.wind_speed_10m?.[i] || 0),
|
"wind": Math.round(hourly.wind_speed_10m?.[i] || 0),
|
||||||
"pressure": Math.round(hourly.surface_pressure?.[i] || 0),
|
"pressure": Math.round(hourly.surface_pressure?.[i] || 0),
|
||||||
"precipitationProbability": Math.round(hourly.precipitation_probability_max?.[0] || 0),
|
"precipitationProbability": Math.round(hourly.precipitation_probability?.[i] || 0),
|
||||||
"visibility": Math.round(hourly.visibility?.[i] || 0),
|
"visibility": Math.round(hourly.visibility?.[i] || 0),
|
||||||
"isDay": isDay
|
"isDay": isDay
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
v1.2.0
|
v1.2.3
|
||||||
|
|||||||
+182
-182
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