mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
Compare commits
31 Commits
c60cd3a341
...
v1.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b76d0ce97d | ||
|
|
fa66d330cf | ||
|
|
157eab2d07 | ||
|
|
f50ad2dc22 | ||
|
|
cd9d92d884 | ||
|
|
1b69a5e62b | ||
|
|
61d311b157 | ||
|
|
6b76b86930 | ||
|
|
dcfb947c36 | ||
|
|
59893b7f44 | ||
|
|
d2c62f5533 | ||
|
|
2bbe9a0c45 | ||
|
|
4e2ce82c0a | ||
|
|
104762186f | ||
|
|
f1233ab1e3 | ||
|
|
d6b407ec37 | ||
|
|
022b4b4bb3 | ||
|
|
49b322582d | ||
|
|
1280bd047d | ||
|
|
6f206d7523 | ||
|
|
2e58283859 | ||
|
|
99a5721fe8 | ||
|
|
5302ebd840 | ||
|
|
fa427ea1ac | ||
|
|
7027bd1646 | ||
|
|
3c38e17472 | ||
|
|
510ea5d2e4 | ||
|
|
bb2234d328 | ||
|
|
edbdeb0fb8 | ||
|
|
19541fc573 | ||
|
|
7c936cacfb |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -109,3 +109,4 @@ bin/
|
||||
.envrc
|
||||
.direnv/
|
||||
quickshell/dms-plugins
|
||||
__pycache__
|
||||
|
||||
@@ -8,6 +8,7 @@ bind = SUPER, N, exec, dms ipc call notifications toggle
|
||||
bind = SUPER SHIFT, N, exec, dms ipc call notepad toggle
|
||||
bind = SUPER, Y, exec, dms ipc call dankdash wallpaper
|
||||
bind = SUPER, TAB, exec, dms ipc call hypr toggleOverview
|
||||
bind = SUPER, X, exec, dms ipc call powermenu toggle
|
||||
|
||||
# === Cheat sheet
|
||||
bind = SUPER SHIFT, Slash, exec, dms ipc call keybinds toggle hyprland
|
||||
|
||||
@@ -15,6 +15,8 @@ binds {
|
||||
Mod+M hotkey-overlay-title="Task Manager" {
|
||||
spawn "dms" "ipc" "call" "processlist" "focusOrToggle";
|
||||
}
|
||||
|
||||
Super+X hotkey-overlay-title="Power Menu: Toggle" { spawn "dms" "ipc" "call" "powermenu" "toggle"; }
|
||||
Mod+Comma hotkey-overlay-title="Settings" {
|
||||
spawn "dms" "ipc" "call" "settings" "focusOrToggle";
|
||||
}
|
||||
|
||||
@@ -325,24 +325,30 @@ func (n *NiriProvider) buildActionFromNode(bindNode *document.Node) string {
|
||||
}
|
||||
|
||||
actionNode := bindNode.Children[0]
|
||||
|
||||
kdlStr := strings.TrimSpace(actionNode.String())
|
||||
if kdlStr == "" {
|
||||
actionName := actionNode.Name.String()
|
||||
if actionName == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return n.kdlActionToInternal(kdlStr)
|
||||
}
|
||||
|
||||
func (n *NiriProvider) kdlActionToInternal(kdlAction string) string {
|
||||
parts := n.parseActionParts(kdlAction)
|
||||
if len(parts) == 0 {
|
||||
return kdlAction
|
||||
parts := []string{actionName}
|
||||
for _, arg := range actionNode.Arguments {
|
||||
val := arg.ValueString()
|
||||
if val == "" {
|
||||
parts = append(parts, `""`)
|
||||
} else {
|
||||
parts = append(parts, val)
|
||||
}
|
||||
}
|
||||
|
||||
for i, part := range parts {
|
||||
if part == "" {
|
||||
parts[i] = `""`
|
||||
if actionNode.Properties != nil {
|
||||
if val, ok := actionNode.Properties.Get("focus"); ok {
|
||||
parts = append(parts, "focus="+val.String())
|
||||
}
|
||||
if val, ok := actionNode.Properties.Get("show-pointer"); ok {
|
||||
parts = append(parts, "show-pointer="+val.String())
|
||||
}
|
||||
if val, ok := actionNode.Properties.Get("write-to-disk"); ok {
|
||||
parts = append(parts, "write-to-disk="+val.String())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -314,6 +314,7 @@ output_path = '%s'
|
||||
appendVSCodeConfig(cfgFile, "codeoss", filepath.Join(homeDir, ".config/Code - OSS/extensions"), opts.ShellDir)
|
||||
appendVSCodeConfig(cfgFile, "cursor", filepath.Join(homeDir, ".cursor/extensions"), opts.ShellDir)
|
||||
appendVSCodeConfig(cfgFile, "windsurf", filepath.Join(homeDir, ".windsurf/extensions"), opts.ShellDir)
|
||||
appendVSCodeConfig(cfgFile, "vscode-insiders", filepath.Join(homeDir, ".vscode-insiders/extensions"), opts.ShellDir)
|
||||
default:
|
||||
appendConfig(opts, cfgFile, tmpl.Commands, tmpl.Flatpaks, tmpl.ConfigFile)
|
||||
}
|
||||
|
||||
@@ -124,27 +124,23 @@ func (sc *SharedContext) eventDispatcher() {
|
||||
}
|
||||
|
||||
for {
|
||||
sc.drainCmdQueue()
|
||||
|
||||
select {
|
||||
case <-sc.stopChan:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
sc.drainCmdQueue()
|
||||
|
||||
n, err := unix.Poll(pollFds, 50)
|
||||
if err != nil {
|
||||
if err == unix.EINTR {
|
||||
continue
|
||||
}
|
||||
_, err := unix.Poll(pollFds, -1)
|
||||
switch {
|
||||
case err == unix.EINTR:
|
||||
continue
|
||||
case err != nil:
|
||||
log.Errorf("Poll error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if pollFds[1].Revents&unix.POLLIN != 0 {
|
||||
var buf [64]byte
|
||||
if _, err := unix.Read(sc.wakeR, buf[:]); err != nil && err != unix.EAGAIN {
|
||||
@@ -152,13 +148,13 @@ func (sc *SharedContext) eventDispatcher() {
|
||||
}
|
||||
}
|
||||
|
||||
if pollFds[0].Revents&unix.POLLIN != 0 {
|
||||
if err := ctx.Dispatch(); err != nil {
|
||||
if !os.IsTimeout(err) {
|
||||
log.Errorf("Wayland connection error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if pollFds[0].Revents&unix.POLLIN == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := ctx.Dispatch(); err != nil && !os.IsTimeout(err) {
|
||||
log.Errorf("Wayland connection error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,12 +172,16 @@ func (sc *SharedContext) drainCmdQueue() {
|
||||
|
||||
func (sc *SharedContext) Close() {
|
||||
close(sc.stopChan)
|
||||
if _, err := unix.Write(sc.wakeW, []byte{1}); err != nil && err != unix.EAGAIN {
|
||||
log.Errorf("wake pipe write error on close: %v", err)
|
||||
}
|
||||
sc.wg.Wait()
|
||||
|
||||
unix.Close(sc.wakeR)
|
||||
unix.Close(sc.wakeW)
|
||||
|
||||
if sc.display != nil {
|
||||
sc.display.Context().Close()
|
||||
if sc.display == nil {
|
||||
return
|
||||
}
|
||||
sc.display.Context().Close()
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ in
|
||||
]
|
||||
++ lib.optional cfg.enableDynamicTheming pkgs.matugen
|
||||
++ lib.optional cfg.enableAudioWavelength pkgs.cava
|
||||
++ lib.optional cfg.enableCalendarEvents pkgs.khal;
|
||||
++ lib.optional cfg.enableCalendarEvents pkgs.khal
|
||||
++ lib.optional cfg.enableClipboardPaste pkgs.wtype;
|
||||
|
||||
plugins = lib.mapAttrs (name: plugin: {
|
||||
source = plugin.src;
|
||||
|
||||
@@ -70,6 +70,12 @@ in
|
||||
description = "Add calendar events support via khal";
|
||||
};
|
||||
|
||||
enableClipboardPaste = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Adds needed dependencies for directly pasting items from the clipboard history.";
|
||||
};
|
||||
|
||||
quickshell = {
|
||||
package = lib.mkPackageOption dmsPkgs "quickshell" {
|
||||
extraDescription = "The quickshell package to use (defaults to be built from source, due to unreleased features used by DMS).";
|
||||
|
||||
14
flake.nix
14
flake.nix
@@ -61,11 +61,13 @@
|
||||
(builtins.substring 6 2 longDate)
|
||||
];
|
||||
version =
|
||||
pkgs.lib.removePrefix "v" (pkgs.lib.trim (builtins.readFile ./quickshell/VERSION))
|
||||
+ "+date="
|
||||
+ mkDate (self.lastModifiedDate or "19700101")
|
||||
+ "_"
|
||||
+ (self.shortRev or "dirty");
|
||||
let
|
||||
rawVersion = pkgs.lib.removePrefix "v" (pkgs.lib.trim (builtins.readFile ./quickshell/VERSION));
|
||||
cleanVersion = builtins.replaceStrings [ " " ] [ "" ] rawVersion;
|
||||
dateSuffix = "+date=" + mkDate (self.lastModifiedDate or "19700101");
|
||||
revSuffix = "_" + (self.shortRev or "dirty");
|
||||
in
|
||||
"${cleanVersion}${dateSuffix}${revSuffix}";
|
||||
in
|
||||
{
|
||||
dms-shell = pkgs.buildGoModule (
|
||||
@@ -83,7 +85,7 @@
|
||||
ldflags = [
|
||||
"-s"
|
||||
"-w"
|
||||
"-X main.Version=${version}"
|
||||
"-X 'main.Version=${version}'"
|
||||
];
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
|
||||
@@ -450,10 +450,7 @@ const NIRI_ACTION_ARGS = {
|
||||
]
|
||||
},
|
||||
"screenshot-window": {
|
||||
args: [
|
||||
{ name: "show-pointer", type: "bool", label: "Show pointer" },
|
||||
{ name: "write-to-disk", type: "bool", label: "Save to disk" }
|
||||
]
|
||||
args: [{ name: "write-to-disk", type: "bool", label: "Save to disk" }]
|
||||
}
|
||||
};
|
||||
|
||||
@@ -841,7 +838,7 @@ function getActionType(action) {
|
||||
return "compositor";
|
||||
if (action.startsWith("spawn dms ipc call "))
|
||||
return "dms";
|
||||
if (action.startsWith("spawn sh -c ") || action.startsWith("spawn bash -c ") || action.startsWith("spawn_shell "))
|
||||
if (/^spawn \w+ -c /.test(action) || action.startsWith("spawn_shell "))
|
||||
return "shell";
|
||||
if (action.startsWith("spawn "))
|
||||
return "spawn";
|
||||
@@ -888,12 +885,13 @@ function buildSpawnAction(command, args) {
|
||||
return "spawn " + parts.join(" ");
|
||||
}
|
||||
|
||||
function buildShellAction(compositor, shellCmd) {
|
||||
function buildShellAction(compositor, shellCmd, shell) {
|
||||
if (!shellCmd)
|
||||
return "";
|
||||
if (compositor === "mangowc")
|
||||
return "spawn_shell " + shellCmd;
|
||||
return "spawn sh -c \"" + shellCmd.replace(/"/g, "\\\"") + "\"";
|
||||
var shellBin = shell || "sh";
|
||||
return "spawn " + shellBin + " -c \"" + shellCmd.replace(/"/g, "\\\"") + "\"";
|
||||
}
|
||||
|
||||
function parseSpawnCommand(action) {
|
||||
@@ -910,8 +908,9 @@ function parseSpawnCommand(action) {
|
||||
function parseShellCommand(action) {
|
||||
if (!action)
|
||||
return "";
|
||||
if (action.startsWith("spawn sh -c ")) {
|
||||
var content = action.slice(12);
|
||||
var match = action.match(/^spawn (\w+) -c (.+)$/);
|
||||
if (match) {
|
||||
var content = match[2];
|
||||
if ((content.startsWith('"') && content.endsWith('"')) || (content.startsWith("'") && content.endsWith("'")))
|
||||
content = content.slice(1, -1);
|
||||
return content.replace(/\\"/g, "\"");
|
||||
@@ -921,6 +920,13 @@ function parseShellCommand(action) {
|
||||
return "";
|
||||
}
|
||||
|
||||
function getShellFromAction(action) {
|
||||
if (!action)
|
||||
return "sh";
|
||||
var match = action.match(/^spawn (\w+) -c /);
|
||||
return match ? match[1] : "sh";
|
||||
}
|
||||
|
||||
function getActionArgConfig(compositor, action) {
|
||||
if (!action)
|
||||
return null;
|
||||
@@ -1107,12 +1113,27 @@ function buildCompositorAction(compositor, base, args) {
|
||||
parts.push("focus=false");
|
||||
break;
|
||||
default:
|
||||
if (base.startsWith("screenshot")) {
|
||||
switch (base) {
|
||||
case "screenshot":
|
||||
if (args["show-pointer"] === true)
|
||||
parts.push("show-pointer=true");
|
||||
else if (args["show-pointer"] === false)
|
||||
parts.push("show-pointer=false");
|
||||
break;
|
||||
case "screenshot-screen":
|
||||
if (args["show-pointer"] === true)
|
||||
parts.push("show-pointer=true");
|
||||
else if (args["show-pointer"] === false)
|
||||
parts.push("show-pointer=false");
|
||||
if (args["write-to-disk"] === true)
|
||||
parts.push("write-to-disk=true");
|
||||
} else if (args.value) {
|
||||
break;
|
||||
case "screenshot-window":
|
||||
if (args["write-to-disk"] === true)
|
||||
parts.push("write-to-disk=true");
|
||||
break;
|
||||
}
|
||||
if (args.value) {
|
||||
parts.push(args.value);
|
||||
} else if (args.index) {
|
||||
parts.push(args.index);
|
||||
|
||||
@@ -13,17 +13,16 @@ Singleton {
|
||||
property var currentModalsByScreen: ({})
|
||||
|
||||
function openModal(modal) {
|
||||
if (!modal.allowStacking) {
|
||||
closeAllModalsExcept(modal);
|
||||
}
|
||||
if (!modal.keepPopoutsOpen) {
|
||||
PopoutManager.closeAllPopouts();
|
||||
}
|
||||
TrayMenuManager.closeAllMenus();
|
||||
|
||||
const screenName = modal.effectiveScreen?.name ?? "unknown";
|
||||
currentModalsByScreen[screenName] = modal;
|
||||
modalChanged();
|
||||
Qt.callLater(() => {
|
||||
if (!modal.allowStacking)
|
||||
closeAllModalsExcept(modal);
|
||||
if (!modal.keepPopoutsOpen)
|
||||
PopoutManager.closeAllPopouts();
|
||||
TrayMenuManager.closeAllMenus();
|
||||
});
|
||||
}
|
||||
|
||||
function closeModal(modal) {
|
||||
|
||||
@@ -46,22 +46,20 @@ Singleton {
|
||||
}
|
||||
|
||||
function moddedAppId(appId: string): string {
|
||||
if (appId === "Spotify")
|
||||
return "spotify";
|
||||
if (appId === "beepertexts")
|
||||
return "beeper";
|
||||
if (appId === "home assistant desktop")
|
||||
return "homeassistant-desktop";
|
||||
if (appId.includes("com.transmissionbt.transmission")) {
|
||||
if (DesktopEntries.heuristicLookup("transmission-gtk"))
|
||||
return "transmission-gtk";
|
||||
if (DesktopEntries.heuristicLookup("transmission"))
|
||||
return "transmission";
|
||||
return "transmission-gtk";
|
||||
const subs = SettingsData.appIdSubstitutions || [];
|
||||
for (let i = 0; i < subs.length; i++) {
|
||||
const sub = subs[i];
|
||||
if (sub.type === "exact" && appId === sub.pattern) {
|
||||
return sub.replacement;
|
||||
} else if (sub.type === "contains" && appId.includes(sub.pattern)) {
|
||||
return sub.replacement;
|
||||
} else if (sub.type === "regex") {
|
||||
const match = appId.match(new RegExp(sub.pattern));
|
||||
if (match) {
|
||||
return sub.replacement.replace(/\$(\d+)/g, (_, n) => match[n] || "");
|
||||
}
|
||||
}
|
||||
}
|
||||
const steamMatch = appId.match(/^steam_app_(\d+)$/);
|
||||
if (steamMatch)
|
||||
return `steam_icon_${steamMatch[1]}`;
|
||||
return appId;
|
||||
}
|
||||
|
||||
@@ -71,7 +69,7 @@ Singleton {
|
||||
}
|
||||
|
||||
const moddedId = moddedAppId(appId);
|
||||
if (moddedId.startsWith("steam_icon_")) {
|
||||
if (moddedId !== appId) {
|
||||
return Quickshell.iconPath(moddedId, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -221,6 +221,7 @@ Singleton {
|
||||
property bool keyboardLayoutNameCompactMode: false
|
||||
property bool runningAppsCurrentWorkspace: false
|
||||
property bool runningAppsGroupByApp: false
|
||||
property var appIdSubstitutions: []
|
||||
property string centeringMode: "index"
|
||||
property string clockDateFormat: ""
|
||||
property string lockDateFormat: ""
|
||||
@@ -403,6 +404,7 @@ Singleton {
|
||||
property int notificationTimeoutLow: 5000
|
||||
property int notificationTimeoutNormal: 5000
|
||||
property int notificationTimeoutCritical: 0
|
||||
property bool notificationCompactMode: false
|
||||
property int notificationPopupPosition: SettingsData.Position.Top
|
||||
property bool notificationHistoryEnabled: true
|
||||
property int notificationHistoryMaxCount: 50
|
||||
@@ -536,6 +538,7 @@ Singleton {
|
||||
property var desktopWidgetPositions: ({})
|
||||
property var desktopWidgetGridSettings: ({})
|
||||
property var desktopWidgetInstances: []
|
||||
property var desktopWidgetGroups: []
|
||||
|
||||
function getDesktopWidgetGridSetting(screenKey, property, defaultValue) {
|
||||
const val = desktopWidgetGridSettings?.[screenKey]?.[property];
|
||||
@@ -687,6 +690,38 @@ Singleton {
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function syncDesktopWidgetPositionToAllScreens(instanceId) {
|
||||
const instances = JSON.parse(JSON.stringify(desktopWidgetInstances || []));
|
||||
const idx = instances.findIndex(inst => inst.id === instanceId);
|
||||
if (idx === -1)
|
||||
return;
|
||||
const positions = instances[idx].positions || {};
|
||||
const screenKeys = Object.keys(positions).filter(k => k !== "_synced");
|
||||
if (screenKeys.length === 0)
|
||||
return;
|
||||
const sourceKey = screenKeys[0];
|
||||
const sourcePos = positions[sourceKey];
|
||||
if (!sourcePos)
|
||||
return;
|
||||
const screen = Array.from(Quickshell.screens.values()).find(s => getScreenDisplayName(s) === sourceKey);
|
||||
if (!screen)
|
||||
return;
|
||||
const screenW = screen.width;
|
||||
const screenH = screen.height;
|
||||
const synced = {};
|
||||
if (sourcePos.x !== undefined)
|
||||
synced.x = sourcePos.x / screenW;
|
||||
if (sourcePos.y !== undefined)
|
||||
synced.y = sourcePos.y / screenH;
|
||||
if (sourcePos.width !== undefined)
|
||||
synced.width = sourcePos.width;
|
||||
if (sourcePos.height !== undefined)
|
||||
synced.height = sourcePos.height;
|
||||
instances[idx].positions["_synced"] = synced;
|
||||
desktopWidgetInstances = instances;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function duplicateDesktopWidgetInstance(instanceId) {
|
||||
const source = getDesktopWidgetInstance(instanceId);
|
||||
if (!source)
|
||||
@@ -719,6 +754,110 @@ Singleton {
|
||||
return (desktopWidgetInstances || []).filter(inst => inst.enabled);
|
||||
}
|
||||
|
||||
function moveDesktopWidgetInstance(instanceId, direction) {
|
||||
const instances = JSON.parse(JSON.stringify(desktopWidgetInstances || []));
|
||||
const idx = instances.findIndex(inst => inst.id === instanceId);
|
||||
if (idx === -1)
|
||||
return false;
|
||||
const targetIdx = direction === "up" ? idx - 1 : idx + 1;
|
||||
if (targetIdx < 0 || targetIdx >= instances.length)
|
||||
return false;
|
||||
const temp = instances[idx];
|
||||
instances[idx] = instances[targetIdx];
|
||||
instances[targetIdx] = temp;
|
||||
desktopWidgetInstances = instances;
|
||||
saveSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
function reorderDesktopWidgetInstance(instanceId, newIndex) {
|
||||
const instances = JSON.parse(JSON.stringify(desktopWidgetInstances || []));
|
||||
const idx = instances.findIndex(inst => inst.id === instanceId);
|
||||
if (idx === -1 || newIndex < 0 || newIndex >= instances.length)
|
||||
return false;
|
||||
const [item] = instances.splice(idx, 1);
|
||||
instances.splice(newIndex, 0, item);
|
||||
desktopWidgetInstances = instances;
|
||||
saveSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
function reorderDesktopWidgetInstanceInGroup(instanceId, groupId, newIndexInGroup) {
|
||||
const instances = JSON.parse(JSON.stringify(desktopWidgetInstances || []));
|
||||
const groups = desktopWidgetGroups || [];
|
||||
const groupMatches = inst => {
|
||||
if (groupId === null)
|
||||
return !inst.group || !groups.some(g => g.id === inst.group);
|
||||
return inst.group === groupId;
|
||||
};
|
||||
const groupInstances = instances.filter(groupMatches);
|
||||
const currentGroupIdx = groupInstances.findIndex(inst => inst.id === instanceId);
|
||||
if (currentGroupIdx === -1 || currentGroupIdx === newIndexInGroup)
|
||||
return false;
|
||||
if (newIndexInGroup < 0 || newIndexInGroup >= groupInstances.length)
|
||||
return false;
|
||||
const globalIdx = instances.findIndex(inst => inst.id === instanceId);
|
||||
if (globalIdx === -1)
|
||||
return false;
|
||||
const [item] = instances.splice(globalIdx, 1);
|
||||
const targetInstance = groupInstances[newIndexInGroup];
|
||||
let targetGlobalIdx = instances.findIndex(inst => inst.id === targetInstance.id);
|
||||
if (newIndexInGroup > currentGroupIdx)
|
||||
targetGlobalIdx++;
|
||||
instances.splice(targetGlobalIdx, 0, item);
|
||||
desktopWidgetInstances = instances;
|
||||
saveSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
function createDesktopWidgetGroup(name) {
|
||||
const id = "dwg_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
||||
const group = {
|
||||
id: id,
|
||||
name: name,
|
||||
collapsed: false
|
||||
};
|
||||
const groups = JSON.parse(JSON.stringify(desktopWidgetGroups || []));
|
||||
groups.push(group);
|
||||
desktopWidgetGroups = groups;
|
||||
saveSettings();
|
||||
return group;
|
||||
}
|
||||
|
||||
function updateDesktopWidgetGroup(groupId, updates) {
|
||||
const groups = JSON.parse(JSON.stringify(desktopWidgetGroups || []));
|
||||
const idx = groups.findIndex(g => g.id === groupId);
|
||||
if (idx === -1)
|
||||
return;
|
||||
Object.assign(groups[idx], updates);
|
||||
desktopWidgetGroups = groups;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function removeDesktopWidgetGroup(groupId) {
|
||||
const instances = JSON.parse(JSON.stringify(desktopWidgetInstances || []));
|
||||
for (let i = 0; i < instances.length; i++) {
|
||||
if (instances[i].group === groupId)
|
||||
instances[i].group = null;
|
||||
}
|
||||
desktopWidgetInstances = instances;
|
||||
const groups = (desktopWidgetGroups || []).filter(g => g.id !== groupId);
|
||||
desktopWidgetGroups = groups;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function getDesktopWidgetGroup(groupId) {
|
||||
return (desktopWidgetGroups || []).find(g => g.id === groupId) || null;
|
||||
}
|
||||
|
||||
function getDesktopWidgetInstancesByGroup(groupId) {
|
||||
return (desktopWidgetInstances || []).filter(inst => inst.group === groupId);
|
||||
}
|
||||
|
||||
function getUngroupedDesktopWidgetInstances() {
|
||||
return (desktopWidgetInstances || []).filter(inst => !inst.group);
|
||||
}
|
||||
|
||||
signal forceDankBarLayoutRefresh
|
||||
signal forceDockLayoutRefresh
|
||||
signal widgetDataChanged
|
||||
@@ -1842,6 +1981,48 @@ Singleton {
|
||||
return workspaceNameIcons[workspaceName] || null;
|
||||
}
|
||||
|
||||
function addAppIdSubstitution(pattern, replacement, type) {
|
||||
var subs = JSON.parse(JSON.stringify(appIdSubstitutions));
|
||||
subs.push({
|
||||
pattern: pattern,
|
||||
replacement: replacement,
|
||||
type: type
|
||||
});
|
||||
appIdSubstitutions = subs;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function updateAppIdSubstitution(index, pattern, replacement, type) {
|
||||
var subs = JSON.parse(JSON.stringify(appIdSubstitutions));
|
||||
if (index < 0 || index >= subs.length)
|
||||
return;
|
||||
subs[index] = {
|
||||
pattern: pattern,
|
||||
replacement: replacement,
|
||||
type: type
|
||||
};
|
||||
appIdSubstitutions = subs;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function removeAppIdSubstitution(index) {
|
||||
var subs = JSON.parse(JSON.stringify(appIdSubstitutions));
|
||||
if (index < 0 || index >= subs.length)
|
||||
return;
|
||||
subs.splice(index, 1);
|
||||
appIdSubstitutions = subs;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function getDefaultAppIdSubstitutions() {
|
||||
return Spec.SPEC.appIdSubstitutions.def;
|
||||
}
|
||||
|
||||
function resetAppIdSubstitutions() {
|
||||
appIdSubstitutions = JSON.parse(JSON.stringify(Spec.SPEC.appIdSubstitutions.def));
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function getRegistryThemeVariant(themeId, defaultVariant) {
|
||||
var stored = registryThemeVariants[themeId];
|
||||
if (typeof stored === "string")
|
||||
|
||||
@@ -115,6 +115,13 @@ var SPEC = {
|
||||
keyboardLayoutNameCompactMode: { def: false },
|
||||
runningAppsCurrentWorkspace: { def: false },
|
||||
runningAppsGroupByApp: { def: false },
|
||||
appIdSubstitutions: { def: [
|
||||
{ pattern: "Spotify", replacement: "spotify", type: "exact" },
|
||||
{ pattern: "beepertexts", replacement: "beeper", type: "exact" },
|
||||
{ pattern: "home assistant desktop", replacement: "homeassistant-desktop", type: "exact" },
|
||||
{ pattern: "com.transmissionbt.transmission", replacement: "transmission-gtk", type: "contains" },
|
||||
{ pattern: "^steam_app_(\\d+)$", replacement: "steam_icon_$1", type: "regex" }
|
||||
]},
|
||||
centeringMode: { def: "index" },
|
||||
clockDateFormat: { def: "" },
|
||||
lockDateFormat: { def: "" },
|
||||
@@ -261,6 +268,7 @@ var SPEC = {
|
||||
notificationTimeoutLow: { def: 5000 },
|
||||
notificationTimeoutNormal: { def: 5000 },
|
||||
notificationTimeoutCritical: { def: 0 },
|
||||
notificationCompactMode: { def: false },
|
||||
notificationPopupPosition: { def: 0 },
|
||||
notificationHistoryEnabled: { def: true },
|
||||
notificationHistoryMaxCount: { def: 50 },
|
||||
@@ -394,6 +402,8 @@ var SPEC = {
|
||||
|
||||
desktopWidgetInstances: { def: [] },
|
||||
|
||||
desktopWidgetGroups: { def: [] },
|
||||
|
||||
builtInPluginSettings: { def: {} }
|
||||
};
|
||||
|
||||
|
||||
@@ -442,17 +442,15 @@ Item {
|
||||
PopoutService.settingsModalLoader = settingsModalLoader;
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
PopoutService.settingsModal = item;
|
||||
PopoutService._onSettingsModalLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
SettingsModal {
|
||||
id: settingsModal
|
||||
property bool wasShown: false
|
||||
|
||||
Component.onCompleted: {
|
||||
PopoutService.settingsModal = settingsModal;
|
||||
PopoutService._onSettingsModalLoaded();
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
wasShown = true;
|
||||
|
||||
@@ -797,11 +797,9 @@ Item {
|
||||
const modal = PopoutService.settingsModal;
|
||||
if (modal) {
|
||||
if (type === "wallpaper") {
|
||||
modal.wallpaperBrowser.allowStacking = false;
|
||||
modal.wallpaperBrowser.open();
|
||||
modal.openWallpaperBrowser(false);
|
||||
} else if (type === "profile") {
|
||||
modal.profileBrowser.allowStacking = false;
|
||||
modal.profileBrowser.open();
|
||||
modal.openProfileBrowser(false);
|
||||
}
|
||||
} else {
|
||||
PopoutService.openSettings();
|
||||
@@ -1068,7 +1066,7 @@ Item {
|
||||
const instances = SettingsData.desktopWidgetInstances || [];
|
||||
if (instances.length === 0)
|
||||
return "No desktop widgets configured";
|
||||
return instances.map(i => `${i.id} [${i.widgetType}] ${i.name || i.widgetType}`).join("\n");
|
||||
return instances.map(i => `${i.id} [${i.widgetType}] ${i.name || i.widgetType} ${i.enabled ? "[enabled]" : "[disabled]"}`).join("\n");
|
||||
}
|
||||
|
||||
function status(instanceId: string): string {
|
||||
@@ -1079,9 +1077,115 @@ Item {
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
const enabled = instance.enabled ?? true;
|
||||
const overlay = instance.config?.showOnOverlay ?? false;
|
||||
const overview = instance.config?.showOnOverview ?? false;
|
||||
return `overlay: ${overlay}, overview: ${overview}`;
|
||||
const clickThrough = instance.config?.clickThrough ?? false;
|
||||
const syncPosition = instance.config?.syncPositionAcrossScreens ?? false;
|
||||
return `enabled: ${enabled}, overlay: ${overlay}, overview: ${overview}, clickThrough: ${clickThrough}, syncPosition: ${syncPosition}`;
|
||||
}
|
||||
|
||||
function enable(instanceId: string): string {
|
||||
if (!instanceId)
|
||||
return "ERROR: No instance ID specified";
|
||||
|
||||
const instance = SettingsData.getDesktopWidgetInstance(instanceId);
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
SettingsData.updateDesktopWidgetInstance(instanceId, {
|
||||
enabled: true
|
||||
});
|
||||
return `DESKTOP_WIDGET_ENABLED: ${instanceId}`;
|
||||
}
|
||||
|
||||
function disable(instanceId: string): string {
|
||||
if (!instanceId)
|
||||
return "ERROR: No instance ID specified";
|
||||
|
||||
const instance = SettingsData.getDesktopWidgetInstance(instanceId);
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
SettingsData.updateDesktopWidgetInstance(instanceId, {
|
||||
enabled: false
|
||||
});
|
||||
return `DESKTOP_WIDGET_DISABLED: ${instanceId}`;
|
||||
}
|
||||
|
||||
function toggleEnabled(instanceId: string): string {
|
||||
if (!instanceId)
|
||||
return "ERROR: No instance ID specified";
|
||||
|
||||
const instance = SettingsData.getDesktopWidgetInstance(instanceId);
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
const currentValue = instance.enabled ?? true;
|
||||
SettingsData.updateDesktopWidgetInstance(instanceId, {
|
||||
enabled: !currentValue
|
||||
});
|
||||
return !currentValue ? `DESKTOP_WIDGET_ENABLED: ${instanceId}` : `DESKTOP_WIDGET_DISABLED: ${instanceId}`;
|
||||
}
|
||||
|
||||
function toggleClickThrough(instanceId: string): string {
|
||||
if (!instanceId)
|
||||
return "ERROR: No instance ID specified";
|
||||
|
||||
const instance = SettingsData.getDesktopWidgetInstance(instanceId);
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
const currentValue = instance.config?.clickThrough ?? false;
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(instanceId, {
|
||||
clickThrough: !currentValue
|
||||
});
|
||||
return !currentValue ? `DESKTOP_WIDGET_CLICK_THROUGH_ENABLED: ${instanceId}` : `DESKTOP_WIDGET_CLICK_THROUGH_DISABLED: ${instanceId}`;
|
||||
}
|
||||
|
||||
function setClickThrough(instanceId: string, enabled: string): string {
|
||||
if (!instanceId)
|
||||
return "ERROR: No instance ID specified";
|
||||
|
||||
const instance = SettingsData.getDesktopWidgetInstance(instanceId);
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
const enabledBool = enabled === "true" || enabled === "1";
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(instanceId, {
|
||||
clickThrough: enabledBool
|
||||
});
|
||||
return enabledBool ? `DESKTOP_WIDGET_CLICK_THROUGH_ENABLED: ${instanceId}` : `DESKTOP_WIDGET_CLICK_THROUGH_DISABLED: ${instanceId}`;
|
||||
}
|
||||
|
||||
function toggleSyncPosition(instanceId: string): string {
|
||||
if (!instanceId)
|
||||
return "ERROR: No instance ID specified";
|
||||
|
||||
const instance = SettingsData.getDesktopWidgetInstance(instanceId);
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
const currentValue = instance.config?.syncPositionAcrossScreens ?? false;
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(instanceId, {
|
||||
syncPositionAcrossScreens: !currentValue
|
||||
});
|
||||
return !currentValue ? `DESKTOP_WIDGET_SYNC_POSITION_ENABLED: ${instanceId}` : `DESKTOP_WIDGET_SYNC_POSITION_DISABLED: ${instanceId}`;
|
||||
}
|
||||
|
||||
function setSyncPosition(instanceId: string, enabled: string): string {
|
||||
if (!instanceId)
|
||||
return "ERROR: No instance ID specified";
|
||||
|
||||
const instance = SettingsData.getDesktopWidgetInstance(instanceId);
|
||||
if (!instance)
|
||||
return `DESKTOP_WIDGET_NOT_FOUND: ${instanceId}`;
|
||||
|
||||
const enabledBool = enabled === "true" || enabled === "1";
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(instanceId, {
|
||||
syncPositionAcrossScreens: enabledBool
|
||||
});
|
||||
return enabledBool ? `DESKTOP_WIDGET_SYNC_POSITION_ENABLED: ${instanceId}` : `DESKTOP_WIDGET_SYNC_POSITION_DISABLED: ${instanceId}`;
|
||||
}
|
||||
|
||||
target: "desktopWidget"
|
||||
|
||||
@@ -128,7 +128,7 @@ FloatingWindow {
|
||||
iconName: "open_in_new"
|
||||
backgroundColor: Theme.surfaceContainerHighest
|
||||
textColor: Theme.surfaceText
|
||||
onClicked: Qt.openUrlExternally("https://danklinux.com/blog/dms-1-2-spicy-miso")
|
||||
onClicked: Qt.openUrlExternally("https://danklinux.com/blog/v1-2-release")
|
||||
}
|
||||
|
||||
DankButton {
|
||||
|
||||
@@ -58,7 +58,6 @@ Item {
|
||||
property bool animationsEnabled: true
|
||||
|
||||
function open() {
|
||||
ModalManager.openModal(root);
|
||||
closeTimer.stop();
|
||||
const focusedScreen = CompositorService.getFocusedScreen();
|
||||
if (focusedScreen) {
|
||||
@@ -66,6 +65,7 @@ Item {
|
||||
if (!useSingleWindow)
|
||||
clickCatcher.screen = focusedScreen;
|
||||
}
|
||||
ModalManager.openModal(root);
|
||||
shouldBeVisible = true;
|
||||
if (!useSingleWindow)
|
||||
clickCatcher.visible = true;
|
||||
@@ -302,7 +302,7 @@ Item {
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: root.useSingleWindow
|
||||
enabled: root.useSingleWindow && root.shouldBeVisible
|
||||
hoverEnabled: false
|
||||
acceptedButtons: Qt.AllButtons
|
||||
onPressed: mouse.accepted = true
|
||||
|
||||
@@ -74,9 +74,7 @@ Rectangle {
|
||||
if (root.parentModal) {
|
||||
root.parentModal.allowFocusOverride = true;
|
||||
root.parentModal.shouldHaveFocus = false;
|
||||
if (root.parentModal.profileBrowser) {
|
||||
root.parentModal.profileBrowser.open();
|
||||
}
|
||||
root.parentModal.openProfileBrowser();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,26 @@ import qs.Widgets
|
||||
FloatingWindow {
|
||||
id: settingsModal
|
||||
|
||||
property alias profileBrowser: profileBrowser
|
||||
property alias wallpaperBrowser: wallpaperBrowser
|
||||
property var profileBrowser: profileBrowserLoader.item
|
||||
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 int currentTabIndex: 0
|
||||
property bool shouldHaveFocus: visible
|
||||
@@ -96,41 +114,51 @@ FloatingWindow {
|
||||
}
|
||||
}
|
||||
|
||||
FileBrowserModal {
|
||||
id: profileBrowser
|
||||
LazyLoader {
|
||||
id: profileBrowserLoader
|
||||
active: false
|
||||
|
||||
allowStacking: true
|
||||
parentModal: settingsModal
|
||||
browserTitle: I18n.tr("Select Profile Image", "profile image file browser title")
|
||||
browserIcon: "person"
|
||||
browserType: "profile"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
PortalService.setProfileImage(path);
|
||||
close();
|
||||
}
|
||||
onDialogClosed: () => {
|
||||
allowStacking = true;
|
||||
FileBrowserModal {
|
||||
id: profileBrowserItem
|
||||
|
||||
allowStacking: true
|
||||
parentModal: settingsModal
|
||||
browserTitle: I18n.tr("Select Profile Image", "profile image file browser title")
|
||||
browserIcon: "person"
|
||||
browserType: "profile"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
PortalService.setProfileImage(path);
|
||||
close();
|
||||
}
|
||||
onDialogClosed: () => {
|
||||
allowStacking = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileBrowserModal {
|
||||
id: wallpaperBrowser
|
||||
LazyLoader {
|
||||
id: wallpaperBrowserLoader
|
||||
active: false
|
||||
|
||||
allowStacking: true
|
||||
parentModal: settingsModal
|
||||
browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title")
|
||||
browserIcon: "wallpaper"
|
||||
browserType: "wallpaper"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
SessionData.setWallpaper(path);
|
||||
close();
|
||||
}
|
||||
onDialogClosed: () => {
|
||||
allowStacking = true;
|
||||
FileBrowserModal {
|
||||
id: wallpaperBrowserItem
|
||||
|
||||
allowStacking: true
|
||||
parentModal: settingsModal
|
||||
browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title")
|
||||
browserIcon: "wallpaper"
|
||||
browserType: "wallpaper"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
SessionData.setWallpaper(path);
|
||||
close();
|
||||
}
|
||||
onDialogClosed: () => {
|
||||
allowStacking = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,8 +347,8 @@ FloatingWindow {
|
||||
visible: settingsModal.isCompactMode ? settingsModal.menuVisible : true
|
||||
parentModal: settingsModal
|
||||
currentIndex: settingsModal.currentTabIndex
|
||||
onCurrentIndexChanged: {
|
||||
settingsModal.currentTabIndex = currentIndex;
|
||||
onTabChangeRequested: tabIndex => {
|
||||
settingsModal.currentTabIndex = tabIndex;
|
||||
if (settingsModal.isCompactMode) {
|
||||
settingsModal.enableAnimations = true;
|
||||
settingsModal.menuVisible = false;
|
||||
|
||||
@@ -15,6 +15,8 @@ Rectangle {
|
||||
|
||||
property int currentIndex: 0
|
||||
property var parentModal: null
|
||||
|
||||
signal tabChangeRequested(int tabIndex)
|
||||
property var expandedCategories: ({})
|
||||
property var autoExpandedCategories: ({})
|
||||
property bool searchActive: searchField.text.length > 0
|
||||
@@ -55,8 +57,9 @@ Rectangle {
|
||||
if (keyboardHighlightIndex < 0)
|
||||
return;
|
||||
var oldIndex = currentIndex;
|
||||
currentIndex = keyboardHighlightIndex;
|
||||
autoCollapseIfNeeded(oldIndex, currentIndex);
|
||||
var newIndex = keyboardHighlightIndex;
|
||||
tabChangeRequested(newIndex);
|
||||
autoCollapseIfNeeded(oldIndex, newIndex);
|
||||
keyboardHighlightIndex = -1;
|
||||
Qt.callLater(searchField.forceActiveFocus);
|
||||
}
|
||||
@@ -398,28 +401,32 @@ Rectangle {
|
||||
var flatItems = getFlatNavigableItems();
|
||||
var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
|
||||
var oldIndex = currentIndex;
|
||||
var newIndex;
|
||||
if (currentPos === -1) {
|
||||
currentIndex = flatItems[0]?.tabIndex ?? 0;
|
||||
newIndex = flatItems[0]?.tabIndex ?? 0;
|
||||
} else {
|
||||
var nextPos = (currentPos + 1) % flatItems.length;
|
||||
currentIndex = flatItems[nextPos].tabIndex;
|
||||
newIndex = flatItems[nextPos].tabIndex;
|
||||
}
|
||||
autoCollapseIfNeeded(oldIndex, currentIndex);
|
||||
autoExpandForTab(currentIndex);
|
||||
tabChangeRequested(newIndex);
|
||||
autoCollapseIfNeeded(oldIndex, newIndex);
|
||||
autoExpandForTab(newIndex);
|
||||
}
|
||||
|
||||
function navigatePrevious() {
|
||||
var flatItems = getFlatNavigableItems();
|
||||
var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
|
||||
var oldIndex = currentIndex;
|
||||
var newIndex;
|
||||
if (currentPos === -1) {
|
||||
currentIndex = flatItems[0]?.tabIndex ?? 0;
|
||||
newIndex = flatItems[0]?.tabIndex ?? 0;
|
||||
} else {
|
||||
var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length;
|
||||
currentIndex = flatItems[prevPos].tabIndex;
|
||||
newIndex = flatItems[prevPos].tabIndex;
|
||||
}
|
||||
autoCollapseIfNeeded(oldIndex, currentIndex);
|
||||
autoExpandForTab(currentIndex);
|
||||
tabChangeRequested(newIndex);
|
||||
autoCollapseIfNeeded(oldIndex, newIndex);
|
||||
autoExpandForTab(newIndex);
|
||||
}
|
||||
|
||||
function getFlatNavigableItems() {
|
||||
@@ -488,7 +495,7 @@ Rectangle {
|
||||
SettingsSearchService.navigateToSection(result.section);
|
||||
}
|
||||
var oldIndex = root.currentIndex;
|
||||
root.currentIndex = result.tabIndex;
|
||||
tabChangeRequested(result.tabIndex);
|
||||
autoCollapseIfNeeded(oldIndex, result.tabIndex);
|
||||
autoExpandForTab(result.tabIndex);
|
||||
searchField.text = "";
|
||||
@@ -807,7 +814,7 @@ Rectangle {
|
||||
if (categoryDelegate.modelData.children) {
|
||||
root.toggleCategory(categoryDelegate.modelData.id);
|
||||
} else if (categoryDelegate.modelData.tabIndex !== undefined) {
|
||||
root.currentIndex = categoryDelegate.modelData.tabIndex;
|
||||
root.tabChangeRequested(categoryDelegate.modelData.tabIndex);
|
||||
}
|
||||
Qt.callLater(searchField.forceActiveFocus);
|
||||
}
|
||||
@@ -882,7 +889,7 @@ Rectangle {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.keyboardHighlightIndex = -1;
|
||||
root.currentIndex = childDelegate.modelData.tabIndex;
|
||||
root.tabChangeRequested(childDelegate.modelData.tabIndex);
|
||||
Qt.callLater(searchField.forceActiveFocus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,10 @@ DankModal {
|
||||
isClosing = false;
|
||||
resetContent();
|
||||
spotlightOpen = true;
|
||||
if (spotlightContent?.appLauncher)
|
||||
spotlightContent.appLauncher.ensureInitialized();
|
||||
open();
|
||||
|
||||
Qt.callLater(() => {
|
||||
if (spotlightContent?.appLauncher)
|
||||
spotlightContent.appLauncher.ensureInitialized();
|
||||
if (spotlightContent?.searchField)
|
||||
spotlightContent.searchField.forceActiveFocus();
|
||||
});
|
||||
@@ -53,15 +52,14 @@ DankModal {
|
||||
isClosing = false;
|
||||
resetContent();
|
||||
spotlightOpen = true;
|
||||
if (spotlightContent?.appLauncher) {
|
||||
spotlightContent.appLauncher.ensureInitialized();
|
||||
spotlightContent.appLauncher.searchQuery = query;
|
||||
}
|
||||
if (spotlightContent?.searchField)
|
||||
spotlightContent.searchField.text = query;
|
||||
open();
|
||||
|
||||
Qt.callLater(() => {
|
||||
if (spotlightContent?.appLauncher) {
|
||||
spotlightContent.appLauncher.ensureInitialized();
|
||||
spotlightContent.appLauncher.searchQuery = query;
|
||||
}
|
||||
if (spotlightContent?.searchField)
|
||||
spotlightContent.searchField.forceActiveFocus();
|
||||
});
|
||||
|
||||
@@ -37,6 +37,10 @@ Rectangle {
|
||||
NetworkService.removeRef();
|
||||
}
|
||||
|
||||
property bool hasEthernetAvailable: (NetworkService.ethernetDevices?.length ?? 0) > 0
|
||||
property bool hasWifiAvailable: (NetworkService.wifiDevices?.length ?? 0) > 0
|
||||
property bool hasBothConnectionTypes: hasEthernetAvailable && hasWifiAvailable
|
||||
|
||||
property int currentPreferenceIndex: {
|
||||
if (DMSService.apiVersion < 5) {
|
||||
return 1;
|
||||
@@ -46,19 +50,24 @@ Rectangle {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const pref = NetworkService.userPreference;
|
||||
const status = NetworkService.networkStatus;
|
||||
let index = 1;
|
||||
|
||||
if (pref === "ethernet") {
|
||||
index = 0;
|
||||
} else if (pref === "wifi") {
|
||||
index = 1;
|
||||
} else {
|
||||
index = status === "ethernet" ? 0 : 1;
|
||||
if (!hasEthernetAvailable) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
if (!hasWifiAvailable) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const pref = NetworkService.userPreference;
|
||||
const status = NetworkService.networkStatus;
|
||||
|
||||
if (pref === "ethernet") {
|
||||
return 0;
|
||||
}
|
||||
if (pref === "wifi") {
|
||||
return 1;
|
||||
}
|
||||
return status === "ethernet" ? 0 : 1;
|
||||
}
|
||||
|
||||
Row {
|
||||
@@ -117,7 +126,7 @@ Rectangle {
|
||||
DankButtonGroup {
|
||||
id: preferenceControls
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: NetworkService.backend === "networkmanager" && DMSService.apiVersion > 10
|
||||
visible: hasBothConnectionTypes && NetworkService.backend === "networkmanager" && DMSService.apiVersion > 10
|
||||
buttonHeight: 28
|
||||
textSize: Theme.fontSizeSmall
|
||||
|
||||
|
||||
@@ -56,6 +56,13 @@ BasePill {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsData
|
||||
function onAppIdSubstitutionsChanged() {
|
||||
root.updateDesktopEntry();
|
||||
}
|
||||
}
|
||||
|
||||
function updateDesktopEntry() {
|
||||
if (activeWindow && activeWindow.appId) {
|
||||
const moddedId = Paths.moddedAppId(activeWindow.appId);
|
||||
|
||||
@@ -19,7 +19,7 @@ BasePill {
|
||||
anchors.centerIn: parent
|
||||
name: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
||||
size: Theme.barIconSize(root.barThickness, -4)
|
||||
color: SessionData.doNotDisturb ? Theme.error : (root.isActive ? Theme.primary : Theme.widgetIconColor)
|
||||
color: SessionData.doNotDisturb ? Theme.primary : (root.isActive ? Theme.primary : Theme.widgetIconColor)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -35,6 +35,6 @@ BasePill {
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
||||
SessionData.setDoNotDisturb(!SessionData.doNotDisturb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ Item {
|
||||
|
||||
property int _desktopEntriesUpdateTrigger: 0
|
||||
property int _toplevelsUpdateTrigger: 0
|
||||
property int _appIdSubstitutionsTrigger: 0
|
||||
|
||||
readonly property var sortedToplevels: {
|
||||
_toplevelsUpdateTrigger;
|
||||
@@ -95,6 +96,13 @@ Item {
|
||||
_desktopEntriesUpdateTrigger++;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsData
|
||||
function onAppIdSubstitutionsChanged() {
|
||||
_appIdSubstitutionsTrigger++;
|
||||
}
|
||||
}
|
||||
readonly property var groupedWindows: {
|
||||
if (!SettingsData.runningAppsGroupByApp) {
|
||||
return [];
|
||||
@@ -364,6 +372,7 @@ Item {
|
||||
height: Theme.barIconSize(root.barThickness)
|
||||
source: {
|
||||
root._desktopEntriesUpdateTrigger;
|
||||
root._appIdSubstitutionsTrigger;
|
||||
if (!appId)
|
||||
return "";
|
||||
const moddedId = Paths.moddedAppId(appId);
|
||||
@@ -484,8 +493,10 @@ Item {
|
||||
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, 0);
|
||||
const screenX = root.parentScreen ? root.parentScreen.x : 0;
|
||||
const relativeX = globalPos.x - screenX;
|
||||
const yPos = root.barThickness + root.barSpacing - 7;
|
||||
windowContextMenuLoader.item.showAt(relativeX, yPos, false, "top");
|
||||
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height;
|
||||
const isBottom = root.axis?.edge === "bottom";
|
||||
const yPos = isBottom ? (screenHeight - root.barThickness - root.barSpacing - 32 - Theme.spacingXS) : (root.barThickness + root.barSpacing + Theme.spacingXS);
|
||||
windowContextMenuLoader.item.showAt(relativeX, yPos, false, root.axis?.edge);
|
||||
}
|
||||
}
|
||||
} else if (mouse.button === Qt.MiddleButton) {
|
||||
@@ -596,6 +607,7 @@ Item {
|
||||
height: Theme.barIconSize(root.barThickness)
|
||||
source: {
|
||||
root._desktopEntriesUpdateTrigger;
|
||||
root._appIdSubstitutionsTrigger;
|
||||
if (!appId)
|
||||
return "";
|
||||
const moddedId = Paths.moddedAppId(appId);
|
||||
@@ -716,8 +728,10 @@ Item {
|
||||
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, 0);
|
||||
const screenX = root.parentScreen ? root.parentScreen.x : 0;
|
||||
const relativeX = globalPos.x - screenX;
|
||||
const yPos = root.barThickness + root.barSpacing - 7;
|
||||
windowContextMenuLoader.item.showAt(relativeX, yPos, false, "top");
|
||||
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height;
|
||||
const isBottom = root.axis?.edge === "bottom";
|
||||
const yPos = isBottom ? (screenHeight - root.barThickness - root.barSpacing - 32 - Theme.spacingXS) : (root.barThickness + root.barSpacing + Theme.spacingXS);
|
||||
windowContextMenuLoader.item.showAt(relativeX, yPos, false, root.axis?.edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,7 +1208,7 @@ Item {
|
||||
visible: entryStack.count === 0
|
||||
width: parent.width
|
||||
height: 28
|
||||
radius: 0
|
||||
radius: Theme.cornerRadius
|
||||
color: visibilityToggleArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.withAlpha(Theme.surfaceContainer, 0)
|
||||
|
||||
StyledText {
|
||||
@@ -1261,7 +1261,7 @@ Item {
|
||||
visible: entryStack.count > 0
|
||||
width: parent.width
|
||||
height: 28
|
||||
radius: 0
|
||||
radius: Theme.cornerRadius
|
||||
color: backArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.withAlpha(Theme.surfaceContainer, 0)
|
||||
|
||||
Row {
|
||||
@@ -1309,11 +1309,10 @@ Item {
|
||||
|
||||
width: menuColumn.width
|
||||
height: menuEntry?.isSeparator ? 1 : 28
|
||||
radius: 0
|
||||
radius: menuEntry?.isSeparator ? 0 : Theme.cornerRadius
|
||||
color: {
|
||||
if (menuEntry?.isSeparator) {
|
||||
if (menuEntry?.isSeparator)
|
||||
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2);
|
||||
}
|
||||
return itemArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.withAlpha(Theme.surfaceContainer, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +265,8 @@ Item {
|
||||
|
||||
if (!byApp[key]) {
|
||||
const isQuickshell = keyBase === "org.quickshell";
|
||||
const desktopEntry = DesktopEntries.heuristicLookup(keyBase);
|
||||
const moddedId = Paths.moddedAppId(keyBase);
|
||||
const desktopEntry = DesktopEntries.heuristicLookup(moddedId);
|
||||
const icon = Paths.getAppIcon(keyBase, desktopEntry);
|
||||
byApp[key] = {
|
||||
"type": "icon",
|
||||
@@ -1367,6 +1368,9 @@ Item {
|
||||
function onWorkspaceNameIconsChanged() {
|
||||
delegateRoot.updateAllData();
|
||||
}
|
||||
function onAppIdSubstitutionsChanged() {
|
||||
delegateRoot.updateAllData();
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: DwlService
|
||||
|
||||
@@ -20,7 +20,19 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
readonly property string dateText: (daily ? root.forecastData?.day : root.forecastData?.time) ?? "--"
|
||||
readonly property string dateText: {
|
||||
if (daily)
|
||||
return root.forecastData?.day ?? "--";
|
||||
if (!root.forecastData?.rawTime)
|
||||
return root.forecastData?.time ?? "--";
|
||||
try {
|
||||
const date = new Date(root.forecastData.rawTime);
|
||||
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP";
|
||||
return date.toLocaleTimeString(Qt.locale(), format);
|
||||
} catch (e) {
|
||||
return root.forecastData?.time ?? "--";
|
||||
}
|
||||
}
|
||||
|
||||
readonly property var minTemp: WeatherService.formatTemp(root.forecastData?.tempMin)
|
||||
readonly property var maxTemp: WeatherService.formatTemp(root.forecastData?.tempMax)
|
||||
@@ -4,7 +4,6 @@ import QtQuick.Shapes
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.DankBar.Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -261,7 +260,17 @@ Item {
|
||||
|
||||
StyledText {
|
||||
id: sunriseText
|
||||
text: WeatherService.weather.sunrise || ""
|
||||
text: {
|
||||
if (!WeatherService.weather.rawSunrise)
|
||||
return WeatherService.weather.sunrise || "";
|
||||
try {
|
||||
const date = new Date(WeatherService.weather.rawSunrise);
|
||||
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP";
|
||||
return date.toLocaleTimeString(Qt.locale(), format);
|
||||
} catch (e) {
|
||||
return WeatherService.weather.sunrise || "";
|
||||
}
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
|
||||
anchors.left: sunriseIcon.right
|
||||
@@ -285,7 +294,17 @@ Item {
|
||||
|
||||
StyledText {
|
||||
id: sunsetText
|
||||
text: WeatherService.weather.sunset || ""
|
||||
text: {
|
||||
if (!WeatherService.weather.rawSunset)
|
||||
return WeatherService.weather.sunset || "";
|
||||
try {
|
||||
const date = new Date(WeatherService.weather.rawSunset);
|
||||
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP";
|
||||
return date.toLocaleTimeString(Qt.locale(), format);
|
||||
} catch (e) {
|
||||
return WeatherService.weather.sunset || "";
|
||||
}
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
|
||||
anchors.left: sunsetIcon.right
|
||||
@@ -324,14 +343,14 @@ Item {
|
||||
break;
|
||||
}
|
||||
}
|
||||
readonly property var splitDate: Qt.formatDateTime(dateStepper.currentDate, "yyyy.MM.dd.hh.mm.AP").split('.')
|
||||
readonly property var splitDate: Qt.formatDateTime(dateStepper.currentDate, SettingsData.use24HourClock ? "yyyy.MM.dd.HH.mm" : "yyyy.MM.dd.hh.mm.AP").split('.')
|
||||
|
||||
Item {
|
||||
id: dateStepperInner
|
||||
anchors.fill: parent
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
readonly property var space: Theme.spacingXS
|
||||
width: yearStepper.width + monthStepper.width + dayStepper.width + hourStepper.width + minuteStepper.width + suffix.width + 10.5 * space + 2 * dateStepperInnerPadding.width
|
||||
width: yearStepper.width + monthStepper.width + dayStepper.width + hourStepper.width + minuteStepper.width + (suffix.visible ? suffix.width : 0) + 10.5 * space + 2 * dateStepperInnerPadding.width
|
||||
|
||||
Item {
|
||||
id: dateStepperInnerPadding
|
||||
@@ -420,13 +439,14 @@ Item {
|
||||
}
|
||||
Rectangle {
|
||||
id: suffix
|
||||
visible: !SettingsData.use24HourClock
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: minuteStepper.right
|
||||
anchors.leftMargin: 2 * parent.space
|
||||
StyledText {
|
||||
isMonospace: true
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: dateStepper.splitDate[5]
|
||||
text: dateStepper.splitDate[5] ?? ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
x: -Theme.fontSizeSmall / 2
|
||||
y: -Theme.fontSizeSmall / 2
|
||||
|
||||
@@ -49,6 +49,13 @@ Item {
|
||||
updateDesktopEntry();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsData
|
||||
function onAppIdSubstitutionsChanged() {
|
||||
updateDesktopEntry();
|
||||
}
|
||||
}
|
||||
property bool isWindowFocused: {
|
||||
if (!appData) {
|
||||
return false;
|
||||
|
||||
@@ -10,9 +10,17 @@ Rectangle {
|
||||
required property var historyItem
|
||||
property bool isSelected: false
|
||||
property bool keyboardNavigationActive: false
|
||||
property bool descriptionExpanded: NotificationService.expandedMessages[historyItem?.id ? (historyItem.id + "_hist") : ""] || false
|
||||
|
||||
readonly property bool compactMode: SettingsData.notificationCompactMode
|
||||
readonly property real cardPadding: compactMode ? Theme.spacingS : Theme.spacingM
|
||||
readonly property real iconSize: compactMode ? 48 : 63
|
||||
readonly property real contentSpacing: compactMode ? Theme.spacingXS : Theme.spacingS
|
||||
readonly property real collapsedContentHeight: iconSize + cardPadding
|
||||
readonly property real baseCardHeight: cardPadding * 2 + collapsedContentHeight
|
||||
|
||||
width: parent ? parent.width : 400
|
||||
height: 116
|
||||
height: baseCardHeight + contentItem.extraHeight
|
||||
radius: Theme.cornerRadius
|
||||
clip: true
|
||||
|
||||
@@ -65,23 +73,28 @@ Rectangle {
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
|
||||
readonly property real expandedTextHeight: descriptionText.contentHeight
|
||||
readonly property real twoLineHeight: descriptionText.font.pixelSize * 1.2 * 2
|
||||
readonly property real extraHeight: (descriptionExpanded && expandedTextHeight > twoLineHeight + 2) ? (expandedTextHeight - twoLineHeight) : 0
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 12
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 56
|
||||
height: 92
|
||||
anchors.topMargin: cardPadding
|
||||
anchors.leftMargin: Theme.spacingL
|
||||
anchors.rightMargin: Theme.spacingL + (compactMode ? 32 : 40)
|
||||
height: collapsedContentHeight + extraHeight
|
||||
|
||||
DankCircularImage {
|
||||
id: iconContainer
|
||||
readonly property bool hasNotificationImage: historyItem.image && historyItem.image !== ""
|
||||
|
||||
width: 63
|
||||
height: 63
|
||||
width: iconSize
|
||||
height: iconSize
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 14
|
||||
|
||||
imageSource: {
|
||||
if (hasNotificationImage)
|
||||
@@ -116,60 +129,79 @@ Rectangle {
|
||||
|
||||
Rectangle {
|
||||
anchors.left: iconContainer.right
|
||||
anchors.leftMargin: 12
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
anchors.bottomMargin: contentSpacing
|
||||
color: "transparent"
|
||||
|
||||
Item {
|
||||
Column {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: -2
|
||||
spacing: compactMode ? 1 : 2
|
||||
|
||||
Column {
|
||||
StyledText {
|
||||
width: parent.width
|
||||
spacing: 2
|
||||
text: {
|
||||
const timeStr = NotificationService.formatHistoryTime(historyItem.timestamp);
|
||||
const appName = historyItem.appName || "";
|
||||
return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName;
|
||||
}
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: {
|
||||
const timeStr = NotificationService.formatHistoryTime(historyItem.timestamp);
|
||||
const appName = historyItem.appName || "";
|
||||
return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName;
|
||||
StyledText {
|
||||
text: historyItem.summary || ""
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: descriptionText
|
||||
property bool hasMoreText: truncated
|
||||
|
||||
text: historyItem.htmlBody || historyItem.body || ""
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
width: parent.width
|
||||
elide: descriptionExpanded ? Text.ElideNone : Text.ElideRight
|
||||
maximumLineCount: descriptionExpanded ? -1 : (compactMode ? 1 : 2)
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text.length > 0
|
||||
linkColor: Theme.primary
|
||||
onLinkActivated: link => Qt.openUrlExternally(link)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (parent.hasMoreText || descriptionExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
|
||||
onClicked: mouse => {
|
||||
if (!parent.hoveredLink && (parent.hasMoreText || descriptionExpanded)) {
|
||||
const messageId = historyItem?.id ? (historyItem.id + "_hist") : "";
|
||||
NotificationService.toggleMessageExpansion(messageId);
|
||||
}
|
||||
}
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: historyItem.summary || ""
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: descriptionText
|
||||
text: historyItem.htmlBody || historyItem.body || ""
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text.length > 0
|
||||
linkColor: Theme.primary
|
||||
onLinkActivated: link => Qt.openUrlExternally(link)
|
||||
propagateComposedEvents: true
|
||||
onPressed: mouse => {
|
||||
if (parent.hoveredLink)
|
||||
mouse.accepted = false;
|
||||
}
|
||||
onReleased: mouse => {
|
||||
if (parent.hoveredLink)
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,11 +211,11 @@ Rectangle {
|
||||
DankActionButton {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 12
|
||||
anchors.rightMargin: 16
|
||||
anchors.topMargin: cardPadding
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
iconName: "close"
|
||||
iconSize: 18
|
||||
buttonSize: 28
|
||||
iconSize: compactMode ? 16 : 18
|
||||
buttonSize: compactMode ? 24 : 28
|
||||
onClicked: NotificationService.removeFromHistory(historyItem.id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,23 +83,54 @@ Item {
|
||||
}
|
||||
|
||||
readonly property var allFilters: [
|
||||
{ label: I18n.tr("All", "notification history filter"), key: "all", maxDays: 0 },
|
||||
{ label: I18n.tr("Last hour", "notification history filter"), key: "1h", maxDays: 1 },
|
||||
{ label: I18n.tr("Today", "notification history filter"), key: "today", maxDays: 1 },
|
||||
{ label: I18n.tr("Yesterday", "notification history filter"), key: "yesterday", maxDays: 2 },
|
||||
{ label: I18n.tr("7 days", "notification history filter"), key: "7d", maxDays: 7 },
|
||||
{ label: I18n.tr("30 days", "notification history filter"), key: "30d", maxDays: 30 },
|
||||
{ label: I18n.tr("Older", "notification history filter for content older than other filters"), key: "older", maxDays: 0 }
|
||||
{
|
||||
label: I18n.tr("All", "notification history filter"),
|
||||
key: "all",
|
||||
maxDays: 0
|
||||
},
|
||||
{
|
||||
label: I18n.tr("Last hour", "notification history filter"),
|
||||
key: "1h",
|
||||
maxDays: 1
|
||||
},
|
||||
{
|
||||
label: I18n.tr("Today", "notification history filter"),
|
||||
key: "today",
|
||||
maxDays: 1
|
||||
},
|
||||
{
|
||||
label: I18n.tr("Yesterday", "notification history filter"),
|
||||
key: "yesterday",
|
||||
maxDays: 2
|
||||
},
|
||||
{
|
||||
label: I18n.tr("7 days", "notification history filter"),
|
||||
key: "7d",
|
||||
maxDays: 7
|
||||
},
|
||||
{
|
||||
label: I18n.tr("30 days", "notification history filter"),
|
||||
key: "30d",
|
||||
maxDays: 30
|
||||
},
|
||||
{
|
||||
label: I18n.tr("Older", "notification history filter for content older than other filters"),
|
||||
key: "older",
|
||||
maxDays: 0
|
||||
}
|
||||
]
|
||||
|
||||
function filterRelevantForRetention(filter) {
|
||||
const retention = SettingsData.notificationHistoryMaxAgeDays;
|
||||
if (filter.key === "older") {
|
||||
if (retention === 0) return true;
|
||||
if (retention === 0)
|
||||
return true;
|
||||
return retention > 2 && retention < 7 || retention > 30;
|
||||
}
|
||||
if (retention === 0) return true;
|
||||
if (filter.maxDays === 0) return true;
|
||||
if (retention === 0)
|
||||
return true;
|
||||
if (filter.maxDays === 0)
|
||||
return true;
|
||||
return filter.maxDays <= retention;
|
||||
}
|
||||
|
||||
@@ -119,10 +150,15 @@ Item {
|
||||
const retention = SettingsData.notificationHistoryMaxAgeDays;
|
||||
for (let i = 0; i < allFilters.length; i++) {
|
||||
const f = allFilters[i];
|
||||
if (!filterRelevantForRetention(f)) continue;
|
||||
if (!filterRelevantForRetention(f))
|
||||
continue;
|
||||
const count = countForFilter(f.key);
|
||||
if (f.key === "all" || count > 0) {
|
||||
result.push({ label: f.label, key: f.key, count: count });
|
||||
result.push({
|
||||
label: f.label,
|
||||
key: f.key,
|
||||
count: count
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -165,6 +201,14 @@ Item {
|
||||
function enableAutoScroll() {
|
||||
}
|
||||
|
||||
function removeWithScrollPreserve(itemId) {
|
||||
historyListView.savedY = historyListView.contentY;
|
||||
NotificationService.removeFromHistory(itemId);
|
||||
Qt.callLater(() => {
|
||||
historyListView.forceLayout();
|
||||
});
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
spacing: Theme.spacingS
|
||||
@@ -201,14 +245,66 @@ Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
delegate: HistoryNotificationCard {
|
||||
delegate: Item {
|
||||
id: delegateRoot
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
property real swipeOffset: 0
|
||||
property bool isDismissing: false
|
||||
readonly property real dismissThreshold: width * 0.35
|
||||
|
||||
width: ListView.view.width
|
||||
historyItem: modelData
|
||||
isSelected: root.keyboardActive && root.selectedIndex === index
|
||||
keyboardNavigationActive: root.keyboardActive
|
||||
height: historyCard.height
|
||||
clip: true
|
||||
|
||||
HistoryNotificationCard {
|
||||
id: historyCard
|
||||
width: parent.width
|
||||
x: delegateRoot.swipeOffset
|
||||
historyItem: modelData
|
||||
isSelected: root.keyboardActive && root.selectedIndex === index
|
||||
keyboardNavigationActive: root.keyboardActive
|
||||
opacity: 1 - Math.abs(delegateRoot.swipeOffset) / (delegateRoot.width * 0.5)
|
||||
|
||||
Behavior on x {
|
||||
enabled: !swipeDragHandler.active
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DragHandler {
|
||||
id: swipeDragHandler
|
||||
target: null
|
||||
yAxis.enabled: false
|
||||
xAxis.enabled: true
|
||||
|
||||
onActiveChanged: {
|
||||
if (active || delegateRoot.isDismissing)
|
||||
return;
|
||||
if (Math.abs(delegateRoot.swipeOffset) > delegateRoot.dismissThreshold) {
|
||||
delegateRoot.isDismissing = true;
|
||||
root.removeWithScrollPreserve(delegateRoot.modelData?.id || "");
|
||||
} else {
|
||||
delegateRoot.swipeOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onTranslationChanged: {
|
||||
if (delegateRoot.isDismissing)
|
||||
return;
|
||||
delegateRoot.swipeOffset = translation.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ Rectangle {
|
||||
property int selectedNotificationIndex: -1
|
||||
property bool keyboardNavigationActive: false
|
||||
|
||||
readonly property bool compactMode: SettingsData.notificationCompactMode
|
||||
readonly property real cardPadding: compactMode ? Theme.spacingS : Theme.spacingM
|
||||
readonly property real iconSize: compactMode ? 48 : 63
|
||||
readonly property real contentSpacing: compactMode ? Theme.spacingXS : Theme.spacingS
|
||||
readonly property real badgeSize: compactMode ? 16 : 18
|
||||
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
||||
readonly property real collapsedContentHeight: iconSize
|
||||
readonly property real baseCardHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + contentSpacing
|
||||
|
||||
width: parent ? parent.width : 400
|
||||
height: {
|
||||
if (expanded) {
|
||||
return expandedContent.height + 28;
|
||||
}
|
||||
const baseHeight = 116;
|
||||
if (descriptionExpanded) {
|
||||
return baseHeight + descriptionText.contentHeight - (descriptionText.font.pixelSize * 1.2 * 2);
|
||||
}
|
||||
return baseHeight;
|
||||
}
|
||||
height: expanded ? (expandedContent.height + cardPadding * 2) : (baseCardHeight + collapsedContent.extraHeight)
|
||||
radius: Theme.cornerRadius
|
||||
|
||||
Behavior on border.color {
|
||||
@@ -97,24 +97,28 @@ Rectangle {
|
||||
|
||||
Item {
|
||||
id: collapsedContent
|
||||
|
||||
readonly property real expandedTextHeight: descriptionText.contentHeight
|
||||
readonly property real twoLineHeight: descriptionText.font.pixelSize * 1.2 * 2
|
||||
readonly property real extraHeight: (descriptionExpanded && expandedTextHeight > twoLineHeight + 2) ? (expandedTextHeight - twoLineHeight) : 0
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 12
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 56
|
||||
height: 92
|
||||
anchors.topMargin: cardPadding
|
||||
anchors.leftMargin: Theme.spacingL
|
||||
anchors.rightMargin: Theme.spacingL + (compactMode ? 32 : 40)
|
||||
height: collapsedContentHeight + extraHeight
|
||||
visible: !expanded
|
||||
|
||||
DankCircularImage {
|
||||
id: iconContainer
|
||||
readonly property bool hasNotificationImage: notificationGroup?.latestNotification?.image && notificationGroup.latestNotification.image !== ""
|
||||
|
||||
width: 63
|
||||
height: 63
|
||||
width: iconSize
|
||||
height: iconSize
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 14
|
||||
|
||||
imageSource: {
|
||||
if (hasNotificationImage)
|
||||
@@ -147,9 +151,9 @@ Rectangle {
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 18
|
||||
height: 18
|
||||
radius: 9
|
||||
width: badgeSize
|
||||
height: badgeSize
|
||||
radius: badgeSize / 2
|
||||
color: Theme.primary
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
@@ -161,7 +165,7 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
text: (notificationGroup?.count || 0) > 99 ? "99+" : (notificationGroup?.count || 0).toString()
|
||||
color: Theme.primaryText
|
||||
font.pixelSize: 9
|
||||
font.pixelSize: compactMode ? 8 : 9
|
||||
font.weight: Font.Bold
|
||||
}
|
||||
}
|
||||
@@ -171,87 +175,79 @@ Rectangle {
|
||||
id: textContainer
|
||||
|
||||
anchors.left: iconContainer.right
|
||||
anchors.leftMargin: 12
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
anchors.bottomMargin: contentSpacing
|
||||
color: "transparent"
|
||||
|
||||
Item {
|
||||
Column {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: -2
|
||||
spacing: compactMode ? 1 : 2
|
||||
|
||||
Column {
|
||||
StyledText {
|
||||
width: parent.width
|
||||
spacing: 2
|
||||
text: {
|
||||
const timeStr = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.timeStr) || "";
|
||||
const appName = (notificationGroup && notificationGroup.appName) || "";
|
||||
return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName;
|
||||
}
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: {
|
||||
const timeStr = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.timeStr) || "";
|
||||
const appName = (notificationGroup && notificationGroup.appName) || "";
|
||||
return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName;
|
||||
StyledText {
|
||||
text: (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.summary) || ""
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: descriptionText
|
||||
property string fullText: (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.htmlBody) || ""
|
||||
property bool hasMoreText: truncated
|
||||
|
||||
text: fullText
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: descriptionExpanded ? -1 : (compactMode ? 1 : 2)
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text.length > 0
|
||||
linkColor: Theme.primary
|
||||
onLinkActivated: link => Qt.openUrlExternally(link)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (parent.hasMoreText || descriptionExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
|
||||
onClicked: mouse => {
|
||||
if (!parent.hoveredLink && (parent.hasMoreText || descriptionExpanded)) {
|
||||
const messageId = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification && notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : "";
|
||||
NotificationService.toggleMessageExpansion(messageId);
|
||||
}
|
||||
}
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.summary) || ""
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: descriptionText
|
||||
property string fullText: (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.htmlBody) || ""
|
||||
property bool hasMoreText: truncated
|
||||
|
||||
text: fullText
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: descriptionExpanded ? -1 : 2
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text.length > 0
|
||||
linkColor: Theme.primary
|
||||
onLinkActivated: link => Qt.openUrlExternally(link)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (parent.hasMoreText || descriptionExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
|
||||
onClicked: mouse => {
|
||||
if (!parent.hoveredLink && (parent.hasMoreText || descriptionExpanded)) {
|
||||
const messageId = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification && notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : "";
|
||||
NotificationService.toggleMessageExpansion(messageId);
|
||||
}
|
||||
}
|
||||
|
||||
propagateComposedEvents: true
|
||||
onPressed: mouse => {
|
||||
if (parent.hoveredLink) {
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
onReleased: mouse => {
|
||||
if (parent.hoveredLink) {
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
propagateComposedEvents: true
|
||||
onPressed: mouse => {
|
||||
if (parent.hoveredLink)
|
||||
mouse.accepted = false;
|
||||
}
|
||||
onReleased: mouse => {
|
||||
if (parent.hoveredLink)
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,21 +261,20 @@ Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 14
|
||||
anchors.bottomMargin: 14
|
||||
anchors.topMargin: cardPadding
|
||||
anchors.leftMargin: Theme.spacingL
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
spacing: -1
|
||||
spacing: compactMode ? Theme.spacingXS : Theme.spacingS
|
||||
visible: expanded
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 40
|
||||
height: compactMode ? 32 : 40
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 56
|
||||
anchors.rightMargin: Theme.spacingL + (compactMode ? 32 : 40)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingS
|
||||
|
||||
@@ -294,9 +289,9 @@ Rectangle {
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 18
|
||||
height: 18
|
||||
radius: 9
|
||||
width: badgeSize
|
||||
height: badgeSize
|
||||
radius: badgeSize / 2
|
||||
color: Theme.primary
|
||||
visible: (notificationGroup?.count || 0) > 1
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -305,7 +300,7 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
text: (notificationGroup?.count || 0) > 99 ? "99+" : (notificationGroup?.count || 0).toString()
|
||||
color: Theme.primaryText
|
||||
font.pixelSize: 9
|
||||
font.pixelSize: compactMode ? 8 : 9
|
||||
font.weight: Font.Bold
|
||||
}
|
||||
}
|
||||
@@ -314,7 +309,7 @@ Rectangle {
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: 16
|
||||
spacing: compactMode ? Theme.spacingS : Theme.spacingL
|
||||
|
||||
Repeater {
|
||||
id: notificationRepeater
|
||||
@@ -328,23 +323,23 @@ Rectangle {
|
||||
required property int index
|
||||
readonly property bool messageExpanded: NotificationService.expandedMessages[modelData?.notification?.id] || false
|
||||
readonly property bool isSelected: root.selectedNotificationIndex === index
|
||||
readonly property real expandedIconSize: compactMode ? 40 : 48
|
||||
readonly property real expandedItemPadding: compactMode ? Theme.spacingS : Theme.spacingM
|
||||
readonly property real expandedBaseHeight: expandedItemPadding * 2 + expandedIconSize + actionButtonHeight + contentSpacing * 2
|
||||
|
||||
width: parent.width
|
||||
height: {
|
||||
const baseHeight = 120;
|
||||
if (messageExpanded) {
|
||||
const twoLineHeight = bodyText.font.pixelSize * 1.2 * 2;
|
||||
if (bodyText.implicitHeight > twoLineHeight + 2) {
|
||||
const extraHeight = bodyText.implicitHeight - twoLineHeight;
|
||||
return baseHeight + extraHeight;
|
||||
}
|
||||
}
|
||||
return baseHeight;
|
||||
if (!messageExpanded)
|
||||
return expandedBaseHeight;
|
||||
const twoLineHeight = bodyText.font.pixelSize * 1.2 * 2;
|
||||
if (bodyText.implicitHeight > twoLineHeight + 2)
|
||||
return expandedBaseHeight + bodyText.implicitHeight - twoLineHeight;
|
||||
return expandedBaseHeight;
|
||||
}
|
||||
radius: Theme.cornerRadius
|
||||
color: isSelected ? Theme.primaryPressed : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
||||
border.color: isSelected ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05)
|
||||
border.width: isSelected ? 1 : 1
|
||||
border.width: 1
|
||||
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
@@ -359,19 +354,19 @@ Rectangle {
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.bottomMargin: 8
|
||||
anchors.margins: compactMode ? Theme.spacingS : Theme.spacingM
|
||||
anchors.bottomMargin: contentSpacing
|
||||
|
||||
DankCircularImage {
|
||||
id: messageIcon
|
||||
|
||||
readonly property bool hasNotificationImage: modelData?.image && modelData.image !== ""
|
||||
|
||||
width: 48
|
||||
height: 48
|
||||
width: expandedIconSize
|
||||
height: expandedIconSize
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 32
|
||||
anchors.topMargin: compactMode ? Theme.spacingM : Theme.spacingXL
|
||||
|
||||
imageSource: {
|
||||
if (hasNotificationImage)
|
||||
@@ -397,9 +392,9 @@ Rectangle {
|
||||
|
||||
Item {
|
||||
anchors.left: messageIcon.right
|
||||
anchors.leftMargin: 12
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 12
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
@@ -408,8 +403,8 @@ Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: buttonArea.top
|
||||
anchors.bottomMargin: 4
|
||||
spacing: 2
|
||||
anchors.bottomMargin: contentSpacing
|
||||
spacing: compactMode ? 1 : 2
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
@@ -477,12 +472,12 @@ Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: 30
|
||||
height: actionButtonHeight + contentSpacing
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
spacing: 8
|
||||
spacing: contentSpacing
|
||||
|
||||
Repeater {
|
||||
model: modelData?.actions || []
|
||||
@@ -490,18 +485,17 @@ Rectangle {
|
||||
Rectangle {
|
||||
property bool isHovered: false
|
||||
|
||||
width: Math.max(actionText.implicitWidth + 12, 50)
|
||||
height: 24
|
||||
radius: 4
|
||||
width: Math.max(actionText.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
|
||||
|
||||
StyledText {
|
||||
id: actionText
|
||||
text: {
|
||||
const baseText = modelData.text || "View";
|
||||
if (keyboardNavigationActive && (isGroupSelected || selectedNotificationIndex >= 0)) {
|
||||
if (keyboardNavigationActive && (isGroupSelected || selectedNotificationIndex >= 0))
|
||||
return `${baseText} (${index + 1})`;
|
||||
}
|
||||
return baseText;
|
||||
}
|
||||
color: parent.isHovered ? Theme.primary : Theme.surfaceVariantText
|
||||
@@ -518,9 +512,8 @@ Rectangle {
|
||||
onEntered: parent.isHovered = true
|
||||
onExited: parent.isHovered = false
|
||||
onClicked: {
|
||||
if (modelData && modelData.invoke) {
|
||||
if (modelData && modelData.invoke)
|
||||
modelData.invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,9 +522,9 @@ Rectangle {
|
||||
Rectangle {
|
||||
property bool isHovered: false
|
||||
|
||||
width: Math.max(clearText.implicitWidth + 12, 50)
|
||||
height: 24
|
||||
radius: 4
|
||||
width: Math.max(clearText.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
|
||||
|
||||
StyledText {
|
||||
@@ -563,11 +556,11 @@ Rectangle {
|
||||
|
||||
Row {
|
||||
visible: !expanded
|
||||
anchors.right: clearButton.left
|
||||
anchors.rightMargin: 8
|
||||
anchors.right: clearButton.visible ? clearButton.left : parent.right
|
||||
anchors.rightMargin: clearButton.visible ? contentSpacing : Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
spacing: 8
|
||||
anchors.bottomMargin: contentSpacing
|
||||
spacing: contentSpacing
|
||||
|
||||
Repeater {
|
||||
model: notificationGroup?.latestNotification?.actions || []
|
||||
@@ -575,9 +568,9 @@ Rectangle {
|
||||
Rectangle {
|
||||
property bool isHovered: false
|
||||
|
||||
width: Math.max(actionText.implicitWidth + 12, 50)
|
||||
height: 24
|
||||
radius: 4
|
||||
width: Math.max(actionText.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
|
||||
|
||||
StyledText {
|
||||
@@ -616,15 +609,16 @@ Rectangle {
|
||||
id: clearButton
|
||||
|
||||
property bool isHovered: false
|
||||
readonly property int actionCount: (notificationGroup?.latestNotification?.actions || []).length
|
||||
|
||||
visible: !expanded
|
||||
visible: !expanded && actionCount < 3
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 16
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
width: Math.max(clearText.implicitWidth + 12, 50)
|
||||
height: 24
|
||||
radius: 4
|
||||
anchors.bottomMargin: contentSpacing
|
||||
width: Math.max(clearText.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
|
||||
|
||||
StyledText {
|
||||
@@ -660,18 +654,18 @@ Rectangle {
|
||||
id: fixedControls
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 12
|
||||
anchors.rightMargin: 16
|
||||
width: 60
|
||||
height: 28
|
||||
anchors.topMargin: cardPadding
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
width: compactMode ? 52 : 60
|
||||
height: compactMode ? 24 : 28
|
||||
|
||||
DankActionButton {
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
visible: (notificationGroup?.count || 0) > 1
|
||||
iconName: expanded ? "expand_less" : "expand_more"
|
||||
iconSize: 18
|
||||
buttonSize: 28
|
||||
iconSize: compactMode ? 16 : 18
|
||||
buttonSize: compactMode ? 24 : 28
|
||||
onClicked: {
|
||||
root.userInitiatedExpansion = true;
|
||||
NotificationService.toggleGroupExpansion(notificationGroup?.key || "");
|
||||
@@ -682,8 +676,8 @@ Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
iconName: "close"
|
||||
iconSize: 18
|
||||
buttonSize: 28
|
||||
iconSize: compactMode ? 16 : 18
|
||||
buttonSize: compactMode ? 24 : 28
|
||||
onClicked: NotificationService.dismissGroup(notificationGroup?.key || "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,15 @@ PanelWindow {
|
||||
property bool _isDestroying: false
|
||||
property bool _finalized: false
|
||||
readonly property string clearText: I18n.tr("Dismiss")
|
||||
property bool descriptionExpanded: false
|
||||
|
||||
readonly property bool compactMode: SettingsData.notificationCompactMode
|
||||
readonly property real cardPadding: compactMode ? Theme.spacingS : Theme.spacingM
|
||||
readonly property real popupIconSize: compactMode ? 48 : 63
|
||||
readonly property real contentSpacing: compactMode ? Theme.spacingXS : Theme.spacingS
|
||||
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
||||
readonly property real collapsedContentHeight: popupIconSize
|
||||
readonly property real basePopupHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + Theme.spacingS
|
||||
|
||||
signal entered
|
||||
signal exitStarted
|
||||
@@ -92,7 +101,15 @@ PanelWindow {
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
color: "transparent"
|
||||
implicitWidth: 400
|
||||
implicitHeight: 122
|
||||
implicitHeight: {
|
||||
if (!descriptionExpanded)
|
||||
return basePopupHeight;
|
||||
const bodyTextHeight = bodyText.contentHeight || 0;
|
||||
const twoLineHeight = Theme.fontSizeSmall * 1.2 * 2;
|
||||
if (bodyTextHeight > twoLineHeight + 2)
|
||||
return basePopupHeight + bodyTextHeight - twoLineHeight;
|
||||
return basePopupHeight;
|
||||
}
|
||||
onHasValidDataChanged: {
|
||||
if (!hasValidData && !exiting && !_isDestroying) {
|
||||
forceExit();
|
||||
@@ -352,13 +369,17 @@ PanelWindow {
|
||||
Item {
|
||||
id: notificationContent
|
||||
|
||||
readonly property real expandedTextHeight: bodyText.contentHeight || 0
|
||||
readonly property real twoLineHeight: Theme.fontSizeSmall * 1.2 * 2
|
||||
readonly property real extraHeight: (descriptionExpanded && expandedTextHeight > twoLineHeight + 2) ? (expandedTextHeight - twoLineHeight) : 0
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 12
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 56
|
||||
height: 98
|
||||
anchors.topMargin: cardPadding
|
||||
anchors.leftMargin: Theme.spacingL
|
||||
anchors.rightMargin: Theme.spacingL + (compactMode ? 32 : 40)
|
||||
height: collapsedContentHeight + extraHeight
|
||||
|
||||
DankCircularImage {
|
||||
id: iconContainer
|
||||
@@ -366,10 +387,10 @@ PanelWindow {
|
||||
readonly property bool hasNotificationImage: notificationData && notificationData.image && notificationData.image !== ""
|
||||
readonly property bool needsImagePersist: hasNotificationImage && notificationData.image.startsWith("image://qsimage/") && !notificationData.persistedImagePath
|
||||
|
||||
width: 63
|
||||
height: 63
|
||||
width: popupIconSize
|
||||
height: popupIconSize
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.top: parent.top
|
||||
|
||||
imageSource: {
|
||||
if (!notificationData)
|
||||
@@ -412,81 +433,78 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Column {
|
||||
id: textContainer
|
||||
|
||||
anchors.left: iconContainer.right
|
||||
anchors.leftMargin: 12
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
color: "transparent"
|
||||
spacing: compactMode ? 1 : 2
|
||||
|
||||
Item {
|
||||
StyledText {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: -2
|
||||
text: {
|
||||
if (!notificationData)
|
||||
return "";
|
||||
const appName = notificationData.appName || "";
|
||||
const timeStr = notificationData.timeStr || "";
|
||||
return timeStr.length > 0 ? appName + " • " + timeStr : appName;
|
||||
}
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: 2
|
||||
StyledText {
|
||||
text: notificationData ? (notificationData.summary || "") : ""
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: {
|
||||
if (!notificationData)
|
||||
return "";
|
||||
StyledText {
|
||||
id: bodyText
|
||||
property bool hasMoreText: truncated
|
||||
|
||||
const appName = notificationData.appName || "";
|
||||
const timeStr = notificationData.timeStr || "";
|
||||
if (timeStr.length > 0)
|
||||
return appName + " • " + timeStr;
|
||||
else
|
||||
return appName;
|
||||
}
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
maximumLineCount: 1
|
||||
text: notificationData ? (notificationData.htmlBody || "") : ""
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
width: parent.width
|
||||
elide: descriptionExpanded ? Text.ElideNone : Text.ElideRight
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
maximumLineCount: descriptionExpanded ? -1 : (compactMode ? 1 : 2)
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text.length > 0
|
||||
linkColor: Theme.primary
|
||||
onLinkActivated: link => Qt.openUrlExternally(link)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (bodyText.hasMoreText || descriptionExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
|
||||
onClicked: mouse => {
|
||||
if (!parent.hoveredLink && (bodyText.hasMoreText || descriptionExpanded))
|
||||
win.descriptionExpanded = !win.descriptionExpanded;
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: notificationData ? (notificationData.summary || "") : ""
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
maximumLineCount: 1
|
||||
visible: text.length > 0
|
||||
propagateComposedEvents: true
|
||||
onPressed: mouse => {
|
||||
if (parent.hoveredLink)
|
||||
mouse.accepted = false;
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: notificationData ? (notificationData.htmlBody || "") : ""
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
visible: text.length > 0
|
||||
linkColor: Theme.primary
|
||||
onLinkActivated: link => {
|
||||
return Qt.openUrlExternally(link);
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
onReleased: mouse => {
|
||||
if (parent.hoveredLink)
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -498,11 +516,11 @@ PanelWindow {
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 12
|
||||
anchors.rightMargin: 16
|
||||
anchors.topMargin: cardPadding
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
iconName: "close"
|
||||
iconSize: 18
|
||||
buttonSize: 28
|
||||
iconSize: compactMode ? 16 : 18
|
||||
buttonSize: compactMode ? 24 : 28
|
||||
z: 15
|
||||
onClicked: {
|
||||
if (notificationData && !win.exiting)
|
||||
@@ -511,11 +529,11 @@ PanelWindow {
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.right: clearButton.left
|
||||
anchors.rightMargin: 8
|
||||
anchors.right: clearButton.visible ? clearButton.left : parent.right
|
||||
anchors.rightMargin: clearButton.visible ? contentSpacing : Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
spacing: 8
|
||||
anchors.bottomMargin: contentSpacing
|
||||
spacing: contentSpacing
|
||||
z: 20
|
||||
|
||||
Repeater {
|
||||
@@ -524,9 +542,9 @@ PanelWindow {
|
||||
Rectangle {
|
||||
property bool isHovered: false
|
||||
|
||||
width: Math.max(actionText.implicitWidth + 12, 50)
|
||||
height: 24
|
||||
radius: 4
|
||||
width: Math.max(actionText.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
|
||||
|
||||
StyledText {
|
||||
@@ -550,7 +568,6 @@ PanelWindow {
|
||||
onClicked: {
|
||||
if (modelData && modelData.invoke)
|
||||
modelData.invoke();
|
||||
|
||||
if (notificationData && !win.exiting)
|
||||
notificationData.popup = false;
|
||||
}
|
||||
@@ -563,14 +580,16 @@ PanelWindow {
|
||||
id: clearButton
|
||||
|
||||
property bool isHovered: false
|
||||
readonly property int actionCount: notificationData ? (notificationData.actions || []).length : 0
|
||||
|
||||
visible: actionCount < 3
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 16
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
width: Math.max(clearTextLabel.implicitWidth + 12, 50)
|
||||
height: 24
|
||||
radius: 4
|
||||
anchors.bottomMargin: contentSpacing
|
||||
width: Math.max(clearTextLabel.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
|
||||
z: 20
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
|
||||
QtObject {
|
||||
@@ -6,7 +7,12 @@ QtObject {
|
||||
|
||||
property var modelData
|
||||
property int topMargin: 0
|
||||
property int baseNotificationHeight: 120
|
||||
readonly property bool compactMode: SettingsData.notificationCompactMode
|
||||
readonly property real cardPadding: compactMode ? Theme.spacingS : Theme.spacingM
|
||||
readonly property real popupIconSize: compactMode ? 48 : 63
|
||||
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
||||
readonly property real popupSpacing: 4
|
||||
readonly property int baseNotificationHeight: cardPadding * 2 + popupIconSize + actionButtonHeight + Theme.spacingS + popupSpacing
|
||||
property int maxTargetNotifications: 4
|
||||
property var popupWindows: [] // strong refs to windows (live until exitFinished)
|
||||
property var destroyingWindows: new Set()
|
||||
|
||||
@@ -26,6 +26,8 @@ Item {
|
||||
readonly property bool showOnOverview: instanceData?.config?.showOnOverview ?? false
|
||||
readonly property bool showOnOverviewOnly: instanceData?.config?.showOnOverviewOnly ?? false
|
||||
readonly property bool overviewActive: CompositorService.isNiri && NiriService.inOverview
|
||||
readonly property bool clickThrough: instanceData?.config?.clickThrough ?? false
|
||||
readonly property bool syncPositionAcrossScreens: instanceData?.config?.syncPositionAcrossScreens ?? false
|
||||
|
||||
Connections {
|
||||
target: PluginService
|
||||
@@ -83,6 +85,7 @@ Item {
|
||||
}
|
||||
}
|
||||
readonly property string screenKey: SettingsData.getScreenDisplayName(screen)
|
||||
readonly property string positionKey: syncPositionAcrossScreens ? "_synced" : screenKey
|
||||
|
||||
readonly property int screenWidth: screen?.width ?? 1920
|
||||
readonly property int screenHeight: screen?.height ?? 1080
|
||||
@@ -96,53 +99,114 @@ Item {
|
||||
|
||||
readonly property bool hasSavedPosition: {
|
||||
if (isInstance)
|
||||
return instanceData?.positions?.[screenKey]?.x !== undefined;
|
||||
return instanceData?.positions?.[positionKey]?.x !== undefined;
|
||||
if (usePluginService)
|
||||
return pluginService.loadPluginData(pluginId, "desktopX_" + screenKey, null) !== null;
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, screenKey, "x", null) !== null;
|
||||
return pluginService.loadPluginData(pluginId, "desktopX_" + positionKey, null) !== null;
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, positionKey, "x", null) !== null;
|
||||
}
|
||||
|
||||
readonly property bool hasSavedSize: {
|
||||
if (isInstance)
|
||||
return instanceData?.positions?.[screenKey]?.width !== undefined;
|
||||
return instanceData?.positions?.[positionKey]?.width !== undefined;
|
||||
if (usePluginService)
|
||||
return pluginService.loadPluginData(pluginId, "desktopWidth_" + screenKey, null) !== null;
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, screenKey, "width", null) !== null;
|
||||
return pluginService.loadPluginData(pluginId, "desktopWidth_" + positionKey, null) !== null;
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, positionKey, "width", null) !== null;
|
||||
}
|
||||
|
||||
property real savedX: {
|
||||
if (isInstance)
|
||||
return instanceData?.positions?.[screenKey]?.x ?? (screenWidth / 2 - savedWidth / 2);
|
||||
if (usePluginService)
|
||||
return pluginService.loadPluginData(pluginId, "desktopX_" + screenKey, screenWidth / 2 - savedWidth / 2);
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, screenKey, "x", screenWidth / 2 - savedWidth / 2);
|
||||
if (isInstance) {
|
||||
const val = instanceData?.positions?.[positionKey]?.x;
|
||||
if (val === undefined)
|
||||
return screenWidth / 2 - savedWidth / 2;
|
||||
return syncPositionAcrossScreens ? val * screenWidth : val;
|
||||
}
|
||||
if (usePluginService) {
|
||||
const val = pluginService.loadPluginData(pluginId, "desktopX_" + positionKey, null);
|
||||
if (val === null)
|
||||
return screenWidth / 2 - savedWidth / 2;
|
||||
return syncPositionAcrossScreens ? val * screenWidth : val;
|
||||
}
|
||||
const val = SettingsData.getDesktopWidgetPosition(pluginId, positionKey, "x", null);
|
||||
if (val === null)
|
||||
return screenWidth / 2 - savedWidth / 2;
|
||||
return syncPositionAcrossScreens ? val * screenWidth : val;
|
||||
}
|
||||
property real savedY: {
|
||||
if (isInstance)
|
||||
return instanceData?.positions?.[screenKey]?.y ?? (screenHeight / 2 - savedHeight / 2);
|
||||
if (usePluginService)
|
||||
return pluginService.loadPluginData(pluginId, "desktopY_" + screenKey, screenHeight / 2 - savedHeight / 2);
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, screenKey, "y", screenHeight / 2 - savedHeight / 2);
|
||||
if (isInstance) {
|
||||
const val = instanceData?.positions?.[positionKey]?.y;
|
||||
if (val === undefined)
|
||||
return screenHeight / 2 - savedHeight / 2;
|
||||
return syncPositionAcrossScreens ? val * screenHeight : val;
|
||||
}
|
||||
if (usePluginService) {
|
||||
const val = pluginService.loadPluginData(pluginId, "desktopY_" + positionKey, null);
|
||||
if (val === null)
|
||||
return screenHeight / 2 - savedHeight / 2;
|
||||
return syncPositionAcrossScreens ? val * screenHeight : val;
|
||||
}
|
||||
const val = SettingsData.getDesktopWidgetPosition(pluginId, positionKey, "y", null);
|
||||
if (val === null)
|
||||
return screenHeight / 2 - savedHeight / 2;
|
||||
return syncPositionAcrossScreens ? val * screenHeight : val;
|
||||
}
|
||||
property real savedWidth: {
|
||||
if (isInstance)
|
||||
return instanceData?.positions?.[screenKey]?.width ?? 280;
|
||||
if (usePluginService)
|
||||
return pluginService.loadPluginData(pluginId, "desktopWidth_" + screenKey, 200);
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, screenKey, "width", 280);
|
||||
if (isInstance) {
|
||||
const val = instanceData?.positions?.[positionKey]?.width;
|
||||
if (val === undefined)
|
||||
return 280;
|
||||
return val;
|
||||
}
|
||||
if (usePluginService) {
|
||||
const val = pluginService.loadPluginData(pluginId, "desktopWidth_" + positionKey, null);
|
||||
if (val === null)
|
||||
return 200;
|
||||
return val;
|
||||
}
|
||||
const val = SettingsData.getDesktopWidgetPosition(pluginId, positionKey, "width", null);
|
||||
if (val === null)
|
||||
return 280;
|
||||
return val;
|
||||
}
|
||||
property real savedHeight: {
|
||||
if (isInstance)
|
||||
return instanceData?.positions?.[screenKey]?.height ?? 180;
|
||||
if (usePluginService)
|
||||
return pluginService.loadPluginData(pluginId, "desktopHeight_" + screenKey, 200);
|
||||
return SettingsData.getDesktopWidgetPosition(pluginId, screenKey, "height", 180);
|
||||
if (isInstance) {
|
||||
const val = instanceData?.positions?.[positionKey]?.height;
|
||||
if (val === undefined)
|
||||
return forceSquare ? savedWidth : 180;
|
||||
return forceSquare ? savedWidth : val;
|
||||
}
|
||||
if (usePluginService) {
|
||||
const val = pluginService.loadPluginData(pluginId, "desktopHeight_" + positionKey, null);
|
||||
if (val === null)
|
||||
return forceSquare ? savedWidth : 200;
|
||||
return forceSquare ? savedWidth : val;
|
||||
}
|
||||
const val = SettingsData.getDesktopWidgetPosition(pluginId, positionKey, "height", null);
|
||||
if (val === null)
|
||||
return forceSquare ? savedWidth : 180;
|
||||
return forceSquare ? savedWidth : val;
|
||||
}
|
||||
|
||||
property real widgetX: Math.max(0, Math.min(savedX, screenWidth - widgetWidth))
|
||||
property real widgetY: Math.max(0, Math.min(savedY, screenHeight - widgetHeight))
|
||||
property real widgetWidth: Math.max(minWidth, Math.min(savedWidth, screenWidth))
|
||||
property real widgetHeight: Math.max(minHeight, Math.min(savedHeight, screenHeight))
|
||||
property real dragOverrideX: -1
|
||||
property real dragOverrideY: -1
|
||||
property real dragOverrideW: -1
|
||||
property real dragOverrideH: -1
|
||||
|
||||
readonly property real effectiveX: dragOverrideX >= 0 ? dragOverrideX : savedX
|
||||
readonly property real effectiveY: dragOverrideY >= 0 ? dragOverrideY : savedY
|
||||
readonly property real effectiveW: dragOverrideW >= 0 ? dragOverrideW : savedWidth
|
||||
readonly property real effectiveH: dragOverrideH >= 0 ? dragOverrideH : savedHeight
|
||||
|
||||
readonly property real widgetX: Math.max(0, Math.min(effectiveX, screenWidth - widgetWidth))
|
||||
readonly property real widgetY: Math.max(0, Math.min(effectiveY, screenHeight - widgetHeight))
|
||||
readonly property real widgetWidth: Math.max(minWidth, Math.min(effectiveW, screenWidth))
|
||||
readonly property real widgetHeight: Math.max(minHeight, Math.min(effectiveH, screenHeight))
|
||||
|
||||
function clearDragOverrides() {
|
||||
dragOverrideX = -1;
|
||||
dragOverrideY = -1;
|
||||
dragOverrideW = -1;
|
||||
dragOverrideH = -1;
|
||||
}
|
||||
|
||||
property real minWidth: contentLoader.item?.minWidth ?? 100
|
||||
property real minHeight: contentLoader.item?.minHeight ?? 100
|
||||
@@ -163,41 +227,45 @@ Item {
|
||||
return Math.round(value / gridSize) * gridSize;
|
||||
}
|
||||
|
||||
function savePosition() {
|
||||
function savePosition(finalX, finalY) {
|
||||
const xVal = syncPositionAcrossScreens ? finalX / screenWidth : finalX;
|
||||
const yVal = syncPositionAcrossScreens ? finalY / screenHeight : finalY;
|
||||
if (isInstance && instanceData) {
|
||||
SettingsData.updateDesktopWidgetInstancePosition(instanceId, screenKey, {
|
||||
x: root.widgetX,
|
||||
y: root.widgetY
|
||||
SettingsData.updateDesktopWidgetInstancePosition(instanceId, positionKey, {
|
||||
x: xVal,
|
||||
y: yVal
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (usePluginService) {
|
||||
pluginService.savePluginData(pluginId, "desktopX_" + screenKey, root.widgetX);
|
||||
pluginService.savePluginData(pluginId, "desktopY_" + screenKey, root.widgetY);
|
||||
pluginService.savePluginData(pluginId, "desktopX_" + positionKey, xVal);
|
||||
pluginService.savePluginData(pluginId, "desktopY_" + positionKey, yVal);
|
||||
return;
|
||||
}
|
||||
SettingsData.updateDesktopWidgetPosition(pluginId, screenKey, {
|
||||
x: root.widgetX,
|
||||
y: root.widgetY
|
||||
SettingsData.updateDesktopWidgetPosition(pluginId, positionKey, {
|
||||
x: xVal,
|
||||
y: yVal
|
||||
});
|
||||
}
|
||||
|
||||
function saveSize() {
|
||||
function saveSize(finalW, finalH) {
|
||||
const sizeVal = forceSquare ? Math.max(finalW, finalH) : finalW;
|
||||
const heightVal = forceSquare ? sizeVal : finalH;
|
||||
if (isInstance && instanceData) {
|
||||
SettingsData.updateDesktopWidgetInstancePosition(instanceId, screenKey, {
|
||||
width: root.widgetWidth,
|
||||
height: root.widgetHeight
|
||||
SettingsData.updateDesktopWidgetInstancePosition(instanceId, positionKey, {
|
||||
width: sizeVal,
|
||||
height: heightVal
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (usePluginService) {
|
||||
pluginService.savePluginData(pluginId, "desktopWidth_" + screenKey, root.widgetWidth);
|
||||
pluginService.savePluginData(pluginId, "desktopHeight_" + screenKey, root.widgetHeight);
|
||||
pluginService.savePluginData(pluginId, "desktopWidth_" + positionKey, sizeVal);
|
||||
pluginService.savePluginData(pluginId, "desktopHeight_" + positionKey, heightVal);
|
||||
return;
|
||||
}
|
||||
SettingsData.updateDesktopWidgetPosition(pluginId, screenKey, {
|
||||
width: root.widgetWidth,
|
||||
height: root.widgetHeight
|
||||
SettingsData.updateDesktopWidgetPosition(pluginId, positionKey, {
|
||||
width: sizeVal,
|
||||
height: heightVal
|
||||
});
|
||||
}
|
||||
|
||||
@@ -213,6 +281,12 @@ Item {
|
||||
}
|
||||
color: "transparent"
|
||||
|
||||
Region {
|
||||
id: emptyMask
|
||||
}
|
||||
|
||||
mask: root.clickThrough ? emptyMask : null
|
||||
|
||||
WlrLayershell.namespace: "quickshell:desktop-widget:" + root.pluginId + (root.instanceId ? ":" + root.instanceId : "")
|
||||
WlrLayershell.layer: {
|
||||
if (root.isInteracting && !CompositorService.useHyprlandFocusGrab)
|
||||
@@ -315,12 +389,14 @@ Item {
|
||||
if (!root.hasSavedSize) {
|
||||
const defW = item.defaultWidth ?? item.widgetWidth ?? 280;
|
||||
const defH = item.defaultHeight ?? item.widgetHeight ?? 180;
|
||||
root.widgetWidth = Math.max(root.minWidth, Math.min(defW, root.screenWidth));
|
||||
root.widgetHeight = Math.max(root.minHeight, Math.min(defH, root.screenHeight));
|
||||
const finalW = Math.max(root.minWidth, Math.min(defW, root.screenWidth));
|
||||
const finalH = Math.max(root.minHeight, Math.min(defH, root.screenHeight));
|
||||
root.saveSize(finalW, finalH);
|
||||
}
|
||||
if (!root.hasSavedPosition) {
|
||||
root.widgetX = Math.max(0, Math.min(root.screenWidth / 2 - root.widgetWidth / 2, root.screenWidth - root.widgetWidth));
|
||||
root.widgetY = Math.max(0, Math.min(root.screenHeight / 2 - root.widgetHeight / 2, root.screenHeight - root.widgetHeight));
|
||||
const finalX = Math.max(0, Math.min(root.screenWidth / 2 - root.widgetWidth / 2, root.screenWidth - root.widgetWidth));
|
||||
const finalY = Math.max(0, Math.min(root.screenHeight / 2 - root.widgetHeight / 2, root.screenHeight - root.widgetHeight));
|
||||
root.savePosition(finalX, finalY);
|
||||
}
|
||||
if (item.widgetWidth !== undefined)
|
||||
item.widgetWidth = Qt.binding(() => contentLoader.width);
|
||||
@@ -355,6 +431,7 @@ Item {
|
||||
id: dragArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton
|
||||
enabled: !root.clickThrough
|
||||
cursorShape: pressed ? Qt.ClosedHandCursor : Qt.ArrowCursor
|
||||
|
||||
property point startPos
|
||||
@@ -367,6 +444,8 @@ Item {
|
||||
startY = root.widgetY;
|
||||
root.previewX = root.widgetX;
|
||||
root.previewY = root.widgetY;
|
||||
root.dragOverrideX = root.widgetX;
|
||||
root.dragOverrideY = root.widgetY;
|
||||
}
|
||||
|
||||
onPositionChanged: mouse => {
|
||||
@@ -384,16 +463,15 @@ Item {
|
||||
root.previewY = newY;
|
||||
return;
|
||||
}
|
||||
root.widgetX = newX;
|
||||
root.widgetY = newY;
|
||||
root.dragOverrideX = newX;
|
||||
root.dragOverrideY = newY;
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (root.useGhostPreview) {
|
||||
root.widgetX = root.previewX;
|
||||
root.widgetY = root.previewY;
|
||||
}
|
||||
root.savePosition();
|
||||
const finalX = root.useGhostPreview ? root.previewX : root.dragOverrideX;
|
||||
const finalY = root.useGhostPreview ? root.previewY : root.dragOverrideY;
|
||||
root.savePosition(finalX, finalY);
|
||||
root.clearDragOverrides();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +482,7 @@ Item {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
acceptedButtons: Qt.RightButton
|
||||
enabled: !root.clickThrough
|
||||
cursorShape: pressed ? Qt.SizeFDiagCursor : Qt.ArrowCursor
|
||||
|
||||
property point startPos
|
||||
@@ -416,6 +495,8 @@ Item {
|
||||
startHeight = root.widgetHeight;
|
||||
root.previewWidth = root.widgetWidth;
|
||||
root.previewHeight = root.widgetHeight;
|
||||
root.dragOverrideW = root.widgetWidth;
|
||||
root.dragOverrideH = root.widgetHeight;
|
||||
}
|
||||
|
||||
onPositionChanged: mouse => {
|
||||
@@ -438,16 +519,15 @@ Item {
|
||||
root.previewHeight = newH;
|
||||
return;
|
||||
}
|
||||
root.widgetWidth = newW;
|
||||
root.widgetHeight = newH;
|
||||
root.dragOverrideW = newW;
|
||||
root.dragOverrideH = newH;
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (root.useGhostPreview) {
|
||||
root.widgetWidth = root.previewWidth;
|
||||
root.widgetHeight = root.previewHeight;
|
||||
}
|
||||
root.saveSize();
|
||||
const finalW = root.useGhostPreview ? root.previewWidth : root.dragOverrideW;
|
||||
const finalH = root.useGhostPreview ? root.previewHeight : root.dragOverrideH;
|
||||
root.saveSize(finalW, finalH);
|
||||
root.clearDragOverrides();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,13 @@ SettingsCard {
|
||||
DankActionButton {
|
||||
id: menuButton
|
||||
iconName: "more_vert"
|
||||
onClicked: actionsMenu.open()
|
||||
onClicked: {
|
||||
if (actionsMenu.opened) {
|
||||
actionsMenu.close();
|
||||
return;
|
||||
}
|
||||
actionsMenu.open();
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: actionsMenu
|
||||
@@ -71,7 +77,7 @@ SettingsCard {
|
||||
y: parent.height + Theme.spacingXS
|
||||
width: 160
|
||||
padding: Theme.spacingXS
|
||||
modal: true
|
||||
modal: false
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
@@ -218,6 +224,73 @@ SettingsCard {
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: groupRow.height + Theme.spacingM * 2
|
||||
visible: (SettingsData.desktopWidgetGroups || []).length > 0
|
||||
|
||||
Row {
|
||||
id: groupRow
|
||||
x: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Group")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 80
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
id: groupDropdown
|
||||
width: parent.width - 80 - Theme.spacingM
|
||||
compactMode: true
|
||||
|
||||
property var groupsData: {
|
||||
const groups = SettingsData.desktopWidgetGroups || [];
|
||||
const items = [
|
||||
{
|
||||
value: "",
|
||||
label: I18n.tr("None")
|
||||
}
|
||||
];
|
||||
for (const g of groups) {
|
||||
items.push({
|
||||
value: g.id,
|
||||
label: g.name
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
options: groupsData.map(g => g.label)
|
||||
currentValue: {
|
||||
const currentGroup = root.instanceData?.group ?? "";
|
||||
const item = groupsData.find(g => g.value === currentGroup);
|
||||
return item?.label ?? I18n.tr("None");
|
||||
}
|
||||
|
||||
onValueChanged: value => {
|
||||
if (!root.instanceId)
|
||||
return;
|
||||
const item = groupsData.find(g => g.label === value);
|
||||
const groupId = item?.value ?? "";
|
||||
SettingsData.updateDesktopWidgetInstance(root.instanceId, {
|
||||
group: groupId || null
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: (SettingsData.desktopWidgetGroups || []).length > 0
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Show on Overlay")
|
||||
checked: instanceData?.config?.showOnOverlay ?? false
|
||||
@@ -266,6 +339,38 @@ SettingsCard {
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Click Through")
|
||||
description: I18n.tr("Allow clicks to pass through the widget")
|
||||
checked: instanceData?.config?.clickThrough ?? false
|
||||
onToggled: isChecked => {
|
||||
if (!root.instanceId)
|
||||
return;
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(root.instanceId, {
|
||||
clickThrough: isChecked
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Sync Position Across Screens")
|
||||
description: I18n.tr("Use the same position and size on all displays")
|
||||
checked: instanceData?.config?.syncPositionAcrossScreens ?? false
|
||||
onToggled: isChecked => {
|
||||
if (!root.instanceId)
|
||||
return;
|
||||
if (isChecked)
|
||||
SettingsData.syncDesktopWidgetPositionToAllScreens(root.instanceId);
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(root.instanceId, {
|
||||
syncPositionAcrossScreens: isChecked
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: ipcColumn.height + Theme.spacingM * 2
|
||||
|
||||
@@ -14,20 +14,46 @@ Item {
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
property var expandedStates: ({})
|
||||
property var groupCollapsedStates: ({})
|
||||
property var parentModal: null
|
||||
property string editingGroupId: ""
|
||||
property string newGroupName: ""
|
||||
|
||||
DesktopWidgetBrowser {
|
||||
id: widgetBrowser
|
||||
parentModal: root.parentModal
|
||||
onWidgetAdded: widgetType => {
|
||||
ToastService.showInfo(I18n.tr("Widget added"));
|
||||
readonly property var allInstances: SettingsData.desktopWidgetInstances || []
|
||||
readonly property var allGroups: SettingsData.desktopWidgetGroups || []
|
||||
|
||||
function showWidgetBrowser() {
|
||||
widgetBrowserLoader.active = true;
|
||||
if (widgetBrowserLoader.item)
|
||||
widgetBrowserLoader.item.show();
|
||||
}
|
||||
|
||||
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 {
|
||||
id: desktopPluginBrowser
|
||||
parentModal: root.parentModal
|
||||
typeFilter: "desktop-widget"
|
||||
LazyLoader {
|
||||
id: desktopPluginBrowserLoader
|
||||
active: false
|
||||
|
||||
PluginBrowser {
|
||||
parentModal: root.parentModal
|
||||
typeFilter: "desktop-widget"
|
||||
}
|
||||
}
|
||||
|
||||
DankFlickable {
|
||||
@@ -68,66 +94,512 @@ Item {
|
||||
DankButton {
|
||||
text: I18n.tr("Add Widget")
|
||||
iconName: "add"
|
||||
onClicked: widgetBrowser.show()
|
||||
onClicked: root.showWidgetBrowser()
|
||||
}
|
||||
|
||||
DankButton {
|
||||
text: I18n.tr("Browse Plugins")
|
||||
iconName: "store"
|
||||
onClicked: desktopPluginBrowser.show()
|
||||
onClicked: root.showDesktopPluginBrowser()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
iconName: "folder"
|
||||
title: I18n.tr("Groups")
|
||||
collapsible: true
|
||||
expanded: root.allGroups.length > 0
|
||||
|
||||
Column {
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
x: Theme.spacingM
|
||||
spacing: Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Organize widgets into collapsible groups")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
width: parent.width
|
||||
|
||||
DankTextField {
|
||||
id: newGroupField
|
||||
width: parent.width - addGroupBtn.width - Theme.spacingS
|
||||
placeholderText: I18n.tr("New group name...")
|
||||
text: root.newGroupName
|
||||
onTextChanged: root.newGroupName = text
|
||||
onAccepted: {
|
||||
if (!text.trim())
|
||||
return;
|
||||
SettingsData.createDesktopWidgetGroup(text.trim());
|
||||
root.newGroupName = "";
|
||||
text = "";
|
||||
}
|
||||
}
|
||||
|
||||
DankButton {
|
||||
id: addGroupBtn
|
||||
iconName: "add"
|
||||
text: I18n.tr("Add")
|
||||
enabled: root.newGroupName.trim().length > 0
|
||||
onClicked: {
|
||||
SettingsData.createDesktopWidgetGroup(root.newGroupName.trim());
|
||||
root.newGroupName = "";
|
||||
newGroupField.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingXS
|
||||
visible: root.allGroups.length > 0
|
||||
|
||||
Repeater {
|
||||
model: root.allGroups
|
||||
|
||||
Rectangle {
|
||||
id: groupItem
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
width: parent.width
|
||||
height: 40
|
||||
radius: Theme.cornerRadius
|
||||
color: groupMouseArea.containsMouse ? Theme.surfaceHover : Theme.surfaceContainer
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankIcon {
|
||||
name: "folder"
|
||||
size: Theme.iconSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: root.editingGroupId === groupItem.modelData.id
|
||||
width: active ? parent.width - Theme.iconSizeSmall - deleteGroupBtn.width - Theme.spacingS * 3 : 0
|
||||
height: active ? 32 : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
sourceComponent: DankTextField {
|
||||
text: groupItem.modelData.name
|
||||
onAccepted: {
|
||||
if (!text.trim())
|
||||
return;
|
||||
SettingsData.updateDesktopWidgetGroup(groupItem.modelData.id, {
|
||||
name: text.trim()
|
||||
});
|
||||
root.editingGroupId = "";
|
||||
}
|
||||
onEditingFinished: {
|
||||
if (!text.trim())
|
||||
return;
|
||||
SettingsData.updateDesktopWidgetGroup(groupItem.modelData.id, {
|
||||
name: text.trim()
|
||||
});
|
||||
root.editingGroupId = "";
|
||||
}
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
visible: root.editingGroupId !== groupItem.modelData.id
|
||||
text: groupItem.modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
elide: Text.ElideRight
|
||||
width: parent.width - Theme.iconSizeSmall - deleteGroupBtn.width - Theme.spacingS * 3
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: deleteGroupBtn
|
||||
iconName: "delete"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onClicked: {
|
||||
SettingsData.removeDesktopWidgetGroup(groupItem.modelData.id);
|
||||
ToastService.showInfo(I18n.tr("Group removed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: groupMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onDoubleClicked: root.editingGroupId = groupItem.modelData.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.allGroups
|
||||
|
||||
Column {
|
||||
id: groupSection
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
readonly property string groupId: modelData.id
|
||||
readonly property var groupInstances: root.allInstances.filter(inst => inst.group === groupId)
|
||||
|
||||
width: mainColumn.width
|
||||
spacing: Theme.spacingM
|
||||
visible: groupInstances.length > 0
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 44
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainer
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankIcon {
|
||||
name: (root.groupCollapsedStates[groupSection.groupId] ?? false) ? "expand_more" : "expand_less"
|
||||
size: Theme.iconSize
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
name: "folder"
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: groupSection.modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "(" + groupSection.groupInstances.length + ")"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
var states = Object.assign({}, root.groupCollapsedStates);
|
||||
states[groupSection.groupId] = !(states[groupSection.groupId] ?? false);
|
||||
root.groupCollapsedStates = states;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
visible: !(root.groupCollapsedStates[groupSection.groupId] ?? false)
|
||||
leftPadding: Theme.spacingM
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
objectProp: "id"
|
||||
values: groupSection.groupInstances
|
||||
}
|
||||
|
||||
Item {
|
||||
id: groupDelegateItem
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
property bool held: groupDragArea.pressed
|
||||
property real originalY: y
|
||||
|
||||
readonly property string instanceIdRef: modelData.id
|
||||
readonly property var liveInstanceData: {
|
||||
const instances = root.allInstances;
|
||||
return instances.find(inst => inst.id === instanceIdRef) ?? modelData;
|
||||
}
|
||||
|
||||
width: groupSection.width - Theme.spacingM
|
||||
height: groupCard.height
|
||||
z: held ? 2 : 1
|
||||
|
||||
DesktopWidgetInstanceCard {
|
||||
id: groupCard
|
||||
width: parent.width
|
||||
headerLeftPadding: 20
|
||||
instanceData: groupDelegateItem.liveInstanceData
|
||||
isExpanded: root.expandedStates[groupDelegateItem.instanceIdRef] ?? false
|
||||
|
||||
onExpandedChanged: {
|
||||
if (expanded === (root.expandedStates[groupDelegateItem.instanceIdRef] ?? false))
|
||||
return;
|
||||
var states = Object.assign({}, root.expandedStates);
|
||||
states[groupDelegateItem.instanceIdRef] = expanded;
|
||||
root.expandedStates = states;
|
||||
}
|
||||
|
||||
onDuplicateRequested: SettingsData.duplicateDesktopWidgetInstance(groupDelegateItem.instanceIdRef)
|
||||
|
||||
onDeleteRequested: {
|
||||
SettingsData.removeDesktopWidgetInstance(groupDelegateItem.instanceIdRef);
|
||||
ToastService.showInfo(I18n.tr("Widget removed"));
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: groupDragArea
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
width: 40
|
||||
height: 50
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.SizeVerCursor
|
||||
drag.target: groupDelegateItem.held ? groupDelegateItem : undefined
|
||||
drag.axis: Drag.YAxis
|
||||
preventStealing: true
|
||||
|
||||
onPressed: {
|
||||
groupDelegateItem.z = 2;
|
||||
groupDelegateItem.originalY = groupDelegateItem.y;
|
||||
}
|
||||
onReleased: {
|
||||
groupDelegateItem.z = 1;
|
||||
if (!drag.active) {
|
||||
groupDelegateItem.y = groupDelegateItem.originalY;
|
||||
return;
|
||||
}
|
||||
const spacing = Theme.spacingM;
|
||||
const itemH = groupDelegateItem.height + spacing;
|
||||
var newIndex = Math.round(groupDelegateItem.y / itemH);
|
||||
newIndex = Math.max(0, Math.min(newIndex, groupSection.groupInstances.length - 1));
|
||||
if (newIndex !== groupDelegateItem.index)
|
||||
SettingsData.reorderDesktopWidgetInstanceInGroup(groupDelegateItem.instanceIdRef, groupSection.groupId, newIndex);
|
||||
groupDelegateItem.y = groupDelegateItem.originalY;
|
||||
}
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
x: Theme.spacingL - 2
|
||||
y: Theme.spacingL + (Theme.iconSize / 2) - (size / 2)
|
||||
name: "drag_indicator"
|
||||
size: 18
|
||||
color: Theme.outline
|
||||
opacity: groupDragArea.containsMouse || groupDragArea.pressed ? 1 : 0.5
|
||||
}
|
||||
|
||||
Behavior on y {
|
||||
enabled: !groupDragArea.pressed && !groupDragArea.drag.active
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: instancesColumn
|
||||
id: ungroupedSection
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
visible: SettingsData.desktopWidgetInstances.length > 0
|
||||
visible: ungroupedInstances.length > 0
|
||||
|
||||
Repeater {
|
||||
id: instanceRepeater
|
||||
model: ScriptModel {
|
||||
id: instancesModel
|
||||
objectProp: "id"
|
||||
values: SettingsData.desktopWidgetInstances
|
||||
readonly property var ungroupedInstances: root.allInstances.filter(inst => {
|
||||
if (!inst.group)
|
||||
return true;
|
||||
return !root.allGroups.some(g => g.id === inst.group);
|
||||
})
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 44
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainer
|
||||
visible: root.allGroups.length > 0
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankIcon {
|
||||
name: (root.groupCollapsedStates["_ungrouped"] ?? false) ? "expand_more" : "expand_less"
|
||||
size: Theme.iconSize
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
name: "widgets"
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Ungrouped")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "(" + ungroupedSection.ungroupedInstances.length + ")"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DesktopWidgetInstanceCard {
|
||||
required property var modelData
|
||||
required property int index
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
var states = Object.assign({}, root.groupCollapsedStates);
|
||||
states["_ungrouped"] = !(states["_ungrouped"] ?? false);
|
||||
root.groupCollapsedStates = states;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property string instanceIdRef: modelData.id
|
||||
readonly property var liveInstanceData: {
|
||||
const instances = SettingsData.desktopWidgetInstances || [];
|
||||
return instances.find(inst => inst.id === instanceIdRef) ?? modelData;
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
visible: !(root.groupCollapsedStates["_ungrouped"] ?? false)
|
||||
leftPadding: root.allGroups.length > 0 ? Theme.spacingM : 0
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
objectProp: "id"
|
||||
values: ungroupedSection.ungroupedInstances
|
||||
}
|
||||
|
||||
width: instancesColumn.width
|
||||
instanceData: liveInstanceData
|
||||
isExpanded: root.expandedStates[instanceIdRef] ?? false
|
||||
Item {
|
||||
id: ungroupedDelegateItem
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
onExpandedChanged: {
|
||||
if (expanded === (root.expandedStates[instanceIdRef] ?? false))
|
||||
return;
|
||||
var states = Object.assign({}, root.expandedStates);
|
||||
states[instanceIdRef] = expanded;
|
||||
root.expandedStates = states;
|
||||
}
|
||||
property bool held: ungroupedDragArea.pressed
|
||||
property real originalY: y
|
||||
|
||||
onDuplicateRequested: SettingsData.duplicateDesktopWidgetInstance(instanceIdRef)
|
||||
readonly property string instanceIdRef: modelData.id
|
||||
readonly property var liveInstanceData: {
|
||||
const instances = root.allInstances;
|
||||
return instances.find(inst => inst.id === instanceIdRef) ?? modelData;
|
||||
}
|
||||
|
||||
onDeleteRequested: {
|
||||
SettingsData.removeDesktopWidgetInstance(instanceIdRef);
|
||||
ToastService.showInfo(I18n.tr("Widget removed"));
|
||||
width: ungroupedSection.width - (root.allGroups.length > 0 ? Theme.spacingM : 0)
|
||||
height: ungroupedCard.height
|
||||
z: held ? 2 : 1
|
||||
|
||||
DesktopWidgetInstanceCard {
|
||||
id: ungroupedCard
|
||||
width: parent.width
|
||||
headerLeftPadding: 20
|
||||
instanceData: ungroupedDelegateItem.liveInstanceData
|
||||
isExpanded: root.expandedStates[ungroupedDelegateItem.instanceIdRef] ?? false
|
||||
|
||||
onExpandedChanged: {
|
||||
if (expanded === (root.expandedStates[ungroupedDelegateItem.instanceIdRef] ?? false))
|
||||
return;
|
||||
var states = Object.assign({}, root.expandedStates);
|
||||
states[ungroupedDelegateItem.instanceIdRef] = expanded;
|
||||
root.expandedStates = states;
|
||||
}
|
||||
|
||||
onDuplicateRequested: SettingsData.duplicateDesktopWidgetInstance(ungroupedDelegateItem.instanceIdRef)
|
||||
|
||||
onDeleteRequested: {
|
||||
SettingsData.removeDesktopWidgetInstance(ungroupedDelegateItem.instanceIdRef);
|
||||
ToastService.showInfo(I18n.tr("Widget removed"));
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: ungroupedDragArea
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
width: 40
|
||||
height: 50
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.SizeVerCursor
|
||||
drag.target: ungroupedDelegateItem.held ? ungroupedDelegateItem : undefined
|
||||
drag.axis: Drag.YAxis
|
||||
preventStealing: true
|
||||
|
||||
onPressed: {
|
||||
ungroupedDelegateItem.z = 2;
|
||||
ungroupedDelegateItem.originalY = ungroupedDelegateItem.y;
|
||||
}
|
||||
onReleased: {
|
||||
ungroupedDelegateItem.z = 1;
|
||||
if (!drag.active) {
|
||||
ungroupedDelegateItem.y = ungroupedDelegateItem.originalY;
|
||||
return;
|
||||
}
|
||||
const spacing = Theme.spacingM;
|
||||
const itemH = ungroupedDelegateItem.height + spacing;
|
||||
var newIndex = Math.round(ungroupedDelegateItem.y / itemH);
|
||||
newIndex = Math.max(0, Math.min(newIndex, ungroupedSection.ungroupedInstances.length - 1));
|
||||
if (newIndex !== ungroupedDelegateItem.index)
|
||||
SettingsData.reorderDesktopWidgetInstanceInGroup(ungroupedDelegateItem.instanceIdRef, null, newIndex);
|
||||
ungroupedDelegateItem.y = ungroupedDelegateItem.originalY;
|
||||
}
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
x: Theme.spacingL - 2
|
||||
y: Theme.spacingL + (Theme.iconSize / 2) - (size / 2)
|
||||
name: "drag_indicator"
|
||||
size: 18
|
||||
color: Theme.outline
|
||||
opacity: ungroupedDragArea.containsMouse || ungroupedDragArea.pressed ? 1 : 0.5
|
||||
}
|
||||
|
||||
Behavior on y {
|
||||
enabled: !ungroupedDragArea.pressed && !ungroupedDragArea.drag.active
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
visible: SettingsData.desktopWidgetInstances.length === 0
|
||||
visible: root.allInstances.length === 0
|
||||
text: I18n.tr("No widgets added. Click \"Add Widget\" to get started.")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
|
||||
@@ -144,6 +144,15 @@ Item {
|
||||
checked: SettingsData.notificationOverlayEnabled
|
||||
onToggled: checked => SettingsData.set("notificationOverlayEnabled", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
settingKey: "notificationCompactMode"
|
||||
tags: ["notification", "compact", "size", "display", "mode"]
|
||||
text: I18n.tr("Compact")
|
||||
description: I18n.tr("Use smaller notification cards")
|
||||
checked: SettingsData.notificationCompactMode
|
||||
onToggled: checked => SettingsData.set("notificationCompactMode", checked)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
@@ -209,7 +210,7 @@ FocusScope {
|
||||
iconName: "store"
|
||||
enabled: DMSService.dmsAvailable
|
||||
onClicked: {
|
||||
pluginBrowser.show();
|
||||
showPluginBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,9 +383,11 @@ FocusScope {
|
||||
Connections {
|
||||
target: DMSService
|
||||
function onPluginsListReceived(plugins) {
|
||||
pluginBrowser.isLoading = false;
|
||||
pluginBrowser.allPlugins = plugins;
|
||||
pluginBrowser.updateFilteredPlugins();
|
||||
if (!pluginBrowserLoader.item)
|
||||
return;
|
||||
pluginBrowserLoader.item.isLoading = false;
|
||||
pluginBrowserLoader.item.allPlugins = plugins;
|
||||
pluginBrowserLoader.item.updateFilteredPlugins();
|
||||
}
|
||||
function onInstalledPluginsReceived(plugins) {
|
||||
var pluginMap = {};
|
||||
@@ -410,22 +413,36 @@ FocusScope {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
pluginBrowser.parentModal = pluginsTab.parentModal;
|
||||
if (DMSService.dmsAvailable && DMSService.apiVersion >= 8)
|
||||
DMSService.listInstalled();
|
||||
if (PopoutService.pendingPluginInstall)
|
||||
Qt.callLater(() => pluginBrowser.show());
|
||||
Qt.callLater(showPluginBrowser);
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: PopoutService
|
||||
function onPendingPluginInstallChanged() {
|
||||
if (PopoutService.pendingPluginInstall)
|
||||
pluginBrowser.show();
|
||||
showPluginBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
PluginBrowser {
|
||||
id: pluginBrowser
|
||||
LazyLoader {
|
||||
id: pluginBrowserLoader
|
||||
active: false
|
||||
|
||||
PluginBrowser {
|
||||
id: pluginBrowserItem
|
||||
|
||||
Component.onCompleted: {
|
||||
pluginBrowserItem.parentModal = pluginsTab.parentModal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showPluginBrowser() {
|
||||
pluginBrowserLoader.active = true;
|
||||
if (pluginBrowserLoader.item)
|
||||
pluginBrowserLoader.item.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,159 @@ Item {
|
||||
onToggled: checked => SettingsData.set("runningAppsCurrentWorkspace", checked)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
iconName: "find_replace"
|
||||
title: I18n.tr("App ID Substitutions")
|
||||
settingKey: "appIdSubstitutions"
|
||||
tags: ["app", "icon", "substitution", "replacement", "pattern", "window", "class", "regex"]
|
||||
|
||||
headerActions: [
|
||||
DankActionButton {
|
||||
buttonSize: 36
|
||||
iconName: "restart_alt"
|
||||
iconSize: 20
|
||||
visible: JSON.stringify(SettingsData.appIdSubstitutions) !== JSON.stringify(SettingsData.getDefaultAppIdSubstitutions())
|
||||
backgroundColor: Theme.surfaceContainer
|
||||
iconColor: Theme.surfaceVariantText
|
||||
onClicked: SettingsData.resetAppIdSubstitutions()
|
||||
},
|
||||
DankActionButton {
|
||||
buttonSize: 36
|
||||
iconName: "add"
|
||||
iconSize: 20
|
||||
backgroundColor: Theme.surfaceContainer
|
||||
iconColor: Theme.primary
|
||||
onClicked: SettingsData.addAppIdSubstitution("", "", "exact")
|
||||
}
|
||||
]
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Map window class names to icon names for proper icon display")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
bottomPadding: Theme.spacingS
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: SettingsData.appIdSubstitutions
|
||||
|
||||
delegate: Rectangle {
|
||||
id: subItem
|
||||
width: parent.width
|
||||
height: subColumn.implicitHeight + Theme.spacingM
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.withAlpha(Theme.surfaceContainer, 0.5)
|
||||
|
||||
Column {
|
||||
id: subColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingS
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Column {
|
||||
width: (parent.width - deleteBtn.width - Theme.spacingS) / 2
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Pattern")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
id: patternField
|
||||
width: parent.width
|
||||
text: modelData.pattern
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
onEditingFinished: SettingsData.updateAppIdSubstitution(index, text, replacementField.text, modelData.type)
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: (parent.width - deleteBtn.width - Theme.spacingS) / 2
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Replacement")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
id: replacementField
|
||||
width: parent.width
|
||||
text: modelData.replacement
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
onEditingFinished: SettingsData.updateAppIdSubstitution(index, patternField.text, text, modelData.type)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: deleteBtn
|
||||
width: 32
|
||||
height: 40
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Theme.cornerRadius
|
||||
color: deleteArea.containsMouse ? Theme.withAlpha(Theme.error, 0.2) : "transparent"
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: "delete"
|
||||
size: 18
|
||||
color: deleteArea.containsMouse ? Theme.error : Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: deleteArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: SettingsData.removeAppIdSubstitution(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: 120
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Type")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
width: parent.width
|
||||
compactMode: true
|
||||
dropdownWidth: 120
|
||||
currentValue: modelData.type
|
||||
options: ["exact", "contains", "regex"]
|
||||
onValueChanged: value => SettingsData.updateAppIdSubstitution(index, modelData.pattern, modelData.replacement, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ Item {
|
||||
if (DMSService.dmsAvailable)
|
||||
DMSService.listInstalledThemes();
|
||||
if (PopoutService.pendingThemeInstall)
|
||||
Qt.callLater(() => themeBrowser.show());
|
||||
Qt.callLater(() => showThemeBrowser());
|
||||
templateCheckProcess.running = true;
|
||||
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl)
|
||||
checkCursorIncludeStatus();
|
||||
@@ -169,7 +169,7 @@ Item {
|
||||
target: PopoutService
|
||||
function onPendingThemeInstallChanged() {
|
||||
if (PopoutService.pendingThemeInstall)
|
||||
themeBrowser.show();
|
||||
showThemeBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ Item {
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: genericColorGrid.implicitHeight
|
||||
height: genericColorGrid.implicitHeight + Math.ceil(genericColorGrid.dotSize * 0.05)
|
||||
visible: Theme.currentThemeCategory === "generic" && Theme.currentTheme !== Theme.dynamic && Theme.currentThemeName !== "custom"
|
||||
|
||||
Grid {
|
||||
@@ -939,7 +939,7 @@ Item {
|
||||
text: I18n.tr("Browse Themes", "browse themes button")
|
||||
iconName: "store"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
onClicked: themeBrowser.show()
|
||||
onClicked: showThemeBrowser()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2041,7 +2041,18 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
ThemeBrowser {
|
||||
id: themeBrowser
|
||||
LazyLoader {
|
||||
id: themeBrowserLoader
|
||||
active: false
|
||||
|
||||
ThemeBrowser {
|
||||
id: themeBrowserItem
|
||||
}
|
||||
}
|
||||
|
||||
function showThemeBrowser() {
|
||||
themeBrowserLoader.active = true;
|
||||
if (themeBrowserLoader.item)
|
||||
themeBrowserLoader.item.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ Item {
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: mainWallpaperBrowser.open()
|
||||
onClicked: root.openMainWallpaperBrowser()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,7 +476,7 @@ Item {
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: lightWallpaperBrowser.open()
|
||||
onClicked: root.openLightWallpaperBrowser()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,7 +660,7 @@ Item {
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: darkWallpaperBrowser.open()
|
||||
onClicked: root.openDarkWallpaperBrowser()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1242,53 +1242,83 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
FileBrowserModal {
|
||||
id: mainWallpaperBrowser
|
||||
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);
|
||||
function openMainWallpaperBrowser() {
|
||||
mainWallpaperBrowserLoader.active = true;
|
||||
if (mainWallpaperBrowserLoader.item)
|
||||
mainWallpaperBrowserLoader.item.open();
|
||||
}
|
||||
|
||||
function openLightWallpaperBrowser() {
|
||||
lightWallpaperBrowserLoader.active = true;
|
||||
if (lightWallpaperBrowserLoader.item)
|
||||
lightWallpaperBrowserLoader.item.open();
|
||||
}
|
||||
|
||||
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 {
|
||||
id: lightWallpaperBrowser
|
||||
parentModal: root.parentModal
|
||||
browserTitle: I18n.tr("Select Wallpaper", "light mode wallpaper file browser title")
|
||||
browserIcon: "light_mode"
|
||||
browserType: "wallpaper"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
SessionData.wallpaperPathLight = path;
|
||||
SessionData.syncWallpaperForCurrentMode();
|
||||
SessionData.saveSettings();
|
||||
close();
|
||||
LazyLoader {
|
||||
id: lightWallpaperBrowserLoader
|
||||
active: false
|
||||
|
||||
FileBrowserModal {
|
||||
parentModal: root.parentModal
|
||||
browserTitle: I18n.tr("Select Wallpaper", "light mode wallpaper file browser title")
|
||||
browserIcon: "light_mode"
|
||||
browserType: "wallpaper"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
SessionData.wallpaperPathLight = path;
|
||||
SessionData.syncWallpaperForCurrentMode();
|
||||
SessionData.saveSettings();
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileBrowserModal {
|
||||
id: darkWallpaperBrowser
|
||||
parentModal: root.parentModal
|
||||
browserTitle: I18n.tr("Select Wallpaper", "dark mode wallpaper file browser title")
|
||||
browserIcon: "dark_mode"
|
||||
browserType: "wallpaper"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
SessionData.wallpaperPathDark = path;
|
||||
SessionData.syncWallpaperForCurrentMode();
|
||||
SessionData.saveSettings();
|
||||
close();
|
||||
LazyLoader {
|
||||
id: darkWallpaperBrowserLoader
|
||||
active: false
|
||||
|
||||
FileBrowserModal {
|
||||
parentModal: root.parentModal
|
||||
browserTitle: I18n.tr("Select Wallpaper", "dark mode wallpaper file browser title")
|
||||
browserIcon: "dark_mode"
|
||||
browserType: "wallpaper"
|
||||
showHiddenFiles: true
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: path => {
|
||||
SessionData.wallpaperPathDark = path;
|
||||
SessionData.syncWallpaperForCurrentMode();
|
||||
SessionData.saveSettings();
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ StyledRect {
|
||||
property string iconName: ""
|
||||
property bool collapsible: false
|
||||
property bool expanded: true
|
||||
property real headerLeftPadding: 0
|
||||
|
||||
default property alias content: contentColumn.children
|
||||
property alias headerActions: headerActionsRow.children
|
||||
@@ -115,6 +116,7 @@ StyledRect {
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.headerLeftPadding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
@@ -142,7 +144,7 @@ StyledRect {
|
||||
|
||||
Row {
|
||||
id: headerActionsRow
|
||||
anchors.right: caretIcon.left
|
||||
anchors.right: root.collapsible ? caretIcon.left : parent.right
|
||||
anchors.rightMargin: root.collapsible ? Theme.spacingS : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingXS
|
||||
@@ -172,6 +174,7 @@ StyledRect {
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
visible: root.collapsible
|
||||
anchors.left: caretIcon.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
@@ -916,14 +917,28 @@ Item {
|
||||
});
|
||||
}
|
||||
|
||||
WidgetSelectionPopup {
|
||||
id: widgetSelectionPopup
|
||||
parentModal: widgetsTab.parentModal
|
||||
onWidgetSelected: (widgetId, targetSection) => {
|
||||
widgetsTab.addWidgetToSection(widgetId, targetSection);
|
||||
LazyLoader {
|
||||
id: widgetSelectionPopupLoader
|
||||
active: false
|
||||
|
||||
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 {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
@@ -1113,9 +1128,7 @@ Item {
|
||||
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
||||
}
|
||||
onAddWidget: sectionId => {
|
||||
widgetSelectionPopup.targetSection = sectionId;
|
||||
widgetSelectionPopup.allWidgets = widgetsTab.getWidgetsForPopup();
|
||||
widgetSelectionPopup.show();
|
||||
showWidgetSelectionPopup(sectionId);
|
||||
}
|
||||
onRemoveWidget: (sectionId, index) => {
|
||||
widgetsTab.removeWidgetFromSection(sectionId, index);
|
||||
@@ -1170,9 +1183,7 @@ Item {
|
||||
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
||||
}
|
||||
onAddWidget: sectionId => {
|
||||
widgetSelectionPopup.targetSection = sectionId;
|
||||
widgetSelectionPopup.allWidgets = widgetsTab.getWidgetsForPopup();
|
||||
widgetSelectionPopup.show();
|
||||
showWidgetSelectionPopup(sectionId);
|
||||
}
|
||||
onRemoveWidget: (sectionId, index) => {
|
||||
widgetsTab.removeWidgetFromSection(sectionId, index);
|
||||
@@ -1227,9 +1238,7 @@ Item {
|
||||
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
|
||||
}
|
||||
onAddWidget: sectionId => {
|
||||
widgetSelectionPopup.targetSection = sectionId;
|
||||
widgetSelectionPopup.allWidgets = widgetsTab.getWidgetsForPopup();
|
||||
widgetSelectionPopup.show();
|
||||
showWidgetSelectionPopup(sectionId);
|
||||
}
|
||||
onRemoveWidget: (sectionId, index) => {
|
||||
widgetsTab.removeWidgetFromSection(sectionId, index);
|
||||
|
||||
@@ -14,7 +14,7 @@ Scope {
|
||||
property bool isClosing: false
|
||||
property bool releaseKeyboard: false
|
||||
readonly property bool spotlightModalOpen: PopoutService.spotlightModal?.spotlightOpen ?? false
|
||||
property bool overlayActive: (NiriService.inOverview && !spotlightModalOpen) || searchActive
|
||||
property bool overlayActive: NiriService.inOverview || searchActive
|
||||
|
||||
function showSpotlight(screenName) {
|
||||
isClosing = false;
|
||||
|
||||
@@ -33,8 +33,8 @@ Item {
|
||||
|
||||
property var iconToWindowRatio: 0.25
|
||||
property var iconToWindowRatioCompact: 0.45
|
||||
property var entry: DesktopEntries.heuristicLookup(windowData?.class)
|
||||
property var iconPath: Quickshell.iconPath(entry?.icon ?? windowData?.class ?? "application-x-executable", "image-missing")
|
||||
property var entry: DesktopEntries.heuristicLookup(Paths.moddedAppId(windowData?.class ?? ""))
|
||||
property var iconPath: Paths.getAppIcon(windowData?.class ?? "", entry) || Quickshell.iconPath("application-x-executable", "image-missing")
|
||||
property bool compactMode: Theme.fontSizeSmall * 4 > targetWindowHeight || Theme.fontSizeSmall * 4 > targetWindowWidth
|
||||
|
||||
x: initX
|
||||
|
||||
@@ -11,7 +11,7 @@ Singleton {
|
||||
id: root
|
||||
|
||||
readonly property string currentVersion: "1.2"
|
||||
readonly property bool changelogEnabled: false
|
||||
readonly property bool changelogEnabled: true
|
||||
|
||||
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation)) + "/DankMaterialShell"
|
||||
readonly property string changelogMarkerPath: configDir + "/.changelog-" + currentVersion
|
||||
@@ -37,7 +37,27 @@ Singleton {
|
||||
Component.onCompleted: {
|
||||
if (!changelogEnabled)
|
||||
return;
|
||||
changelogCheckProcess.running = true;
|
||||
if (FirstLaunchService.checkComplete)
|
||||
handleFirstLaunchResult();
|
||||
}
|
||||
|
||||
function handleFirstLaunchResult() {
|
||||
if (FirstLaunchService.isFirstLaunch) {
|
||||
checkComplete = true;
|
||||
changelogDismissed = true;
|
||||
touchMarkerProcess.running = true;
|
||||
} else {
|
||||
changelogCheckProcess.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: FirstLaunchService
|
||||
|
||||
function onCheckCompleteChanged() {
|
||||
if (FirstLaunchService.checkComplete && root.changelogEnabled && !root.checkComplete)
|
||||
root.handleFirstLaunchResult();
|
||||
}
|
||||
}
|
||||
|
||||
function showChangelog() {
|
||||
@@ -66,9 +86,7 @@ Singleton {
|
||||
root.changelogDismissed = true;
|
||||
break;
|
||||
case "show":
|
||||
if (typeof FirstLaunchService === "undefined" || !FirstLaunchService.isFirstLaunch) {
|
||||
root.changelogRequested();
|
||||
}
|
||||
root.changelogRequested();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,15 +316,16 @@ Singleton {
|
||||
const totalKB = mem.total || 0;
|
||||
const availableKB = mem.available || 0;
|
||||
const freeKB = mem.free || 0;
|
||||
const usedKB = mem.used !== undefined ? mem.used : (totalKB - availableKB);
|
||||
|
||||
totalMemoryMB = totalKB / 1024;
|
||||
availableMemoryMB = availableKB / 1024;
|
||||
freeMemoryMB = freeKB / 1024;
|
||||
usedMemoryMB = totalMemoryMB - availableMemoryMB;
|
||||
memoryUsage = totalKB > 0 ? ((totalKB - availableKB) / totalKB) * 100 : 0;
|
||||
usedMemoryMB = usedKB / 1024;
|
||||
memoryUsage = mem.usedPercent !== undefined ? mem.usedPercent : (totalKB > 0 ? ((totalKB - availableKB) / totalKB) * 100 : 0);
|
||||
|
||||
totalMemoryKB = totalKB;
|
||||
usedMemoryKB = totalKB - availableKB;
|
||||
usedMemoryKB = usedKB;
|
||||
totalSwapKB = mem.swaptotal || 0;
|
||||
usedSwapKB = (mem.swaptotal || 0) - (mem.swapfree || 0);
|
||||
|
||||
|
||||
@@ -74,12 +74,10 @@ Singleton {
|
||||
stdout: SplitParser {
|
||||
onRead: data => {
|
||||
const result = data.trim();
|
||||
root.checkComplete = true;
|
||||
|
||||
if (result === "first") {
|
||||
root.isFirstLaunch = true;
|
||||
console.info("FirstLaunchService: First launch detected, greeter will be shown");
|
||||
root.greeterRequested();
|
||||
} else if (result === "existing_user") {
|
||||
root.isFirstLaunch = false;
|
||||
console.info("FirstLaunchService: Existing user detected, silently creating marker");
|
||||
@@ -87,6 +85,11 @@ Singleton {
|
||||
} else {
|
||||
root.isFirstLaunch = false;
|
||||
}
|
||||
|
||||
root.checkComplete = true;
|
||||
|
||||
if (root.isFirstLaunch)
|
||||
root.greeterRequested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,8 +501,12 @@ Singleton {
|
||||
return Actions.buildSpawnAction(command, args);
|
||||
}
|
||||
|
||||
function buildShellAction(shellCmd) {
|
||||
return Actions.buildShellAction(currentProvider, shellCmd);
|
||||
function buildShellAction(shellCmd, shell) {
|
||||
return Actions.buildShellAction(currentProvider, shellCmd, shell);
|
||||
}
|
||||
|
||||
function getShellFromAction(action) {
|
||||
return Actions.getShellFromAction(action);
|
||||
}
|
||||
|
||||
function parseSpawnCommand(action) {
|
||||
|
||||
@@ -32,7 +32,6 @@ Singleton {
|
||||
property int maxIngressPerSecond: 20
|
||||
property double _lastIngressSec: 0
|
||||
property int _ingressCountThisSec: 0
|
||||
property int maxStoredNotifications: SettingsData.notificationHistoryMaxCount
|
||||
|
||||
property var _dismissQueue: []
|
||||
property int _dismissBatchSize: 8
|
||||
@@ -340,30 +339,6 @@ Singleton {
|
||||
historyFileView.writeAdapter();
|
||||
}
|
||||
|
||||
function _trimStored() {
|
||||
if (notifications.length > maxStoredNotifications) {
|
||||
const overflow = notifications.length - maxStoredNotifications;
|
||||
const toDrop = [];
|
||||
for (var i = notifications.length - 1; i >= 0 && toDrop.length < overflow; --i) {
|
||||
const w = notifications[i];
|
||||
if (w && w.notification && w.urgency !== NotificationUrgency.Critical) {
|
||||
toDrop.push(w);
|
||||
}
|
||||
}
|
||||
for (var i = notifications.length - 1; i >= 0 && toDrop.length < overflow; --i) {
|
||||
const w = notifications[i];
|
||||
if (w && w.notification && toDrop.indexOf(w) === -1) {
|
||||
toDrop.push(w);
|
||||
}
|
||||
}
|
||||
for (const w of toDrop) {
|
||||
try {
|
||||
w.notification.dismiss();
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onOverlayOpen() {
|
||||
popupsDisabled = true;
|
||||
addGate.stop();
|
||||
@@ -493,7 +468,6 @@ Singleton {
|
||||
root.allWrappers.push(wrapper);
|
||||
if (!isTransient) {
|
||||
root.notifications.push(wrapper);
|
||||
_trimStored();
|
||||
if (_shouldSaveToHistory(notif.urgency)) {
|
||||
root.addToHistory(wrapper);
|
||||
}
|
||||
@@ -529,10 +503,8 @@ Singleton {
|
||||
|
||||
readonly property Timer timer: Timer {
|
||||
interval: {
|
||||
if (!wrapper.notification) {
|
||||
if (!wrapper.notification)
|
||||
return 5000;
|
||||
}
|
||||
|
||||
switch (wrapper.notification.urgency) {
|
||||
case NotificationUrgency.Low:
|
||||
return SettingsData.notificationTimeoutLow;
|
||||
@@ -601,37 +573,38 @@ Singleton {
|
||||
}
|
||||
|
||||
required property Notification notification
|
||||
readonly property string summary: notification.summary
|
||||
readonly property string body: notification.body
|
||||
readonly property string summary: notification?.summary ?? ""
|
||||
readonly property string body: notification?.body ?? ""
|
||||
readonly property string htmlBody: {
|
||||
if (body && (body.includes('<') && body.includes('>'))) {
|
||||
if (!body)
|
||||
return "";
|
||||
if (body.includes('<') && body.includes('>'))
|
||||
return body;
|
||||
}
|
||||
return Markdown2Html.markdownToHtml(body);
|
||||
}
|
||||
readonly property string appIcon: notification.appIcon
|
||||
readonly property string appIcon: notification?.appIcon ?? ""
|
||||
readonly property string appName: {
|
||||
if (!notification)
|
||||
return "app";
|
||||
if (notification.appName == "") {
|
||||
const entry = DesktopEntries.heuristicLookup(notification.desktopEntry);
|
||||
if (entry && entry.name) {
|
||||
if (entry && entry.name)
|
||||
return entry.name.toLowerCase();
|
||||
}
|
||||
}
|
||||
return notification.appName || "app";
|
||||
}
|
||||
readonly property string desktopEntry: notification.desktopEntry
|
||||
readonly property string image: notification.image
|
||||
readonly property string desktopEntry: notification?.desktopEntry ?? ""
|
||||
readonly property string image: notification?.image ?? ""
|
||||
readonly property string cleanImage: {
|
||||
if (!image) {
|
||||
if (!image)
|
||||
return "";
|
||||
}
|
||||
return Paths.strip(image);
|
||||
}
|
||||
readonly property int urgency: notification.urgency
|
||||
readonly property list<NotificationAction> actions: notification.actions
|
||||
readonly property int urgency: notification?.urgency ?? 1
|
||||
readonly property list<NotificationAction> actions: notification?.actions ?? []
|
||||
|
||||
readonly property Connections conn: Connections {
|
||||
target: wrapper.notification.Retainable
|
||||
target: wrapper.notification?.Retainable ?? null
|
||||
|
||||
function onDropped(): void {
|
||||
root.allWrappers = root.allWrappers.filter(w => w !== wrapper);
|
||||
@@ -743,6 +716,8 @@ Singleton {
|
||||
}
|
||||
|
||||
const next = notificationQueue.shift();
|
||||
if (!next)
|
||||
return;
|
||||
|
||||
next.seq = ++seqCounter;
|
||||
visibleNotifications = [...visibleNotifications, next];
|
||||
@@ -805,7 +780,7 @@ Singleton {
|
||||
const groups = {};
|
||||
|
||||
for (const notif of notifications) {
|
||||
if (!notif)
|
||||
if (!notif || !notif.notification)
|
||||
continue;
|
||||
const groupKey = getGroupKey(notif);
|
||||
if (!groups[groupKey]) {
|
||||
@@ -823,14 +798,15 @@ Singleton {
|
||||
groups[groupKey].latestNotification = groups[groupKey].notifications[0];
|
||||
groups[groupKey].count = groups[groupKey].notifications.length;
|
||||
|
||||
if (notif.notification.hasInlineReply) {
|
||||
if (notif.notification?.hasInlineReply)
|
||||
groups[groupKey].hasInlineReply = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Object.values(groups).sort((a, b) => {
|
||||
const aUrgency = a.latestNotification.urgency || NotificationUrgency.Low;
|
||||
const bUrgency = b.latestNotification.urgency || NotificationUrgency.Low;
|
||||
if (!a.latestNotification || !b.latestNotification)
|
||||
return 0;
|
||||
const aUrgency = a.latestNotification.urgency ?? NotificationUrgency.Low;
|
||||
const bUrgency = b.latestNotification.urgency ?? NotificationUrgency.Low;
|
||||
if (aUrgency !== bUrgency) {
|
||||
return bUrgency - aUrgency;
|
||||
}
|
||||
@@ -842,7 +818,7 @@ Singleton {
|
||||
const groups = {};
|
||||
|
||||
for (const notif of popups) {
|
||||
if (!notif)
|
||||
if (!notif || !notif.notification)
|
||||
continue;
|
||||
const groupKey = getGroupKey(notif);
|
||||
if (!groups[groupKey]) {
|
||||
@@ -860,12 +836,13 @@ Singleton {
|
||||
groups[groupKey].latestNotification = groups[groupKey].notifications[0];
|
||||
groups[groupKey].count = groups[groupKey].notifications.length;
|
||||
|
||||
if (notif.notification.hasInlineReply) {
|
||||
if (notif.notification?.hasInlineReply)
|
||||
groups[groupKey].hasInlineReply = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Object.values(groups).sort((a, b) => {
|
||||
if (!a.latestNotification || !b.latestNotification)
|
||||
return 0;
|
||||
return b.latestNotification.time.getTime() - a.latestNotification.time.getTime();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ Singleton {
|
||||
"paru": archBasedPMSettings,
|
||||
"dnf": fedoraBasedPMSettings
|
||||
}
|
||||
readonly property list<string> supportedDistributions: ["arch", "cachyos", "manjaro", "endeavouros", "fedora"]
|
||||
readonly property list<string> supportedDistributions: ["arch", "artix", "cachyos", "manjaro", "endeavouros", "fedora"]
|
||||
readonly property int updateCount: availableUpdates.length
|
||||
readonly property bool helperAvailable: pkgManager !== "" && distributionSupported
|
||||
|
||||
|
||||
@@ -745,6 +745,7 @@ Singleton {
|
||||
|
||||
hourly_forecast.push({
|
||||
"time": formatTime(hourly.time[i]),
|
||||
"rawTime": hourly.time[i],
|
||||
"temp": Math.round(tempC),
|
||||
"tempF": Math.round(tempF),
|
||||
"feelsLike": Math.round(feelsLikeC),
|
||||
@@ -778,7 +779,9 @@ Singleton {
|
||||
"tempMaxF": Math.round(tempMaxF),
|
||||
"precipitationProbability": Math.round(daily.precipitation_probability_max?.[i] || 0),
|
||||
"sunrise": daily.sunrise?.[i] ? formatTime(daily.sunrise[i]) : "",
|
||||
"sunset": daily.sunset?.[i] ? formatTime(daily.sunset[i]) : ""
|
||||
"sunset": daily.sunset?.[i] ? formatTime(daily.sunset[i]) : "",
|
||||
"rawSunrise": daily.sunrise?.[i] || "",
|
||||
"rawSunset": daily.sunset?.[i] || ""
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -805,6 +808,8 @@ Singleton {
|
||||
"wind": Math.round(current.wind_speed_10m || 0) + " " + (currentUnits.wind_speed_10m || 'm/s'),
|
||||
"sunrise": formatTime(daily.sunrise?.[0]) || "06:00",
|
||||
"sunset": formatTime(daily.sunset?.[0]) || "18:00",
|
||||
"rawSunrise": daily.sunrise?.[0] || "",
|
||||
"rawSunset": daily.sunset?.[0] || "",
|
||||
"uv": 0,
|
||||
"pressure": Math.round(current.surface_pressure || 0),
|
||||
"precipitationProbability": Math.round(daily.precipitation_probability_max?.[0] || 0),
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.2-unstable
|
||||
v1.2.1
|
||||
|
||||
@@ -34,7 +34,10 @@ Image {
|
||||
return;
|
||||
}
|
||||
Paths.mkdir(Paths.imagecache);
|
||||
source = cachePath || encodedImagePath;
|
||||
const hash = djb2Hash(imagePath);
|
||||
const cPath = hash ? `${Paths.stringify(Paths.imagecache)}/${hash}@${maxCacheSize}x${maxCacheSize}.png` : "";
|
||||
const encoded = "file://" + imagePath.split('/').map(s => encodeURIComponent(s)).join('/');
|
||||
source = cPath || encoded;
|
||||
}
|
||||
|
||||
onStatusChanged: {
|
||||
|
||||
@@ -94,10 +94,10 @@ Flow {
|
||||
border.color: "transparent"
|
||||
border.width: 0
|
||||
|
||||
topLeftRadius: (visualFirst || selected) ? Theme.cornerRadius : 4
|
||||
bottomLeftRadius: (visualFirst || selected) ? Theme.cornerRadius : 4
|
||||
topRightRadius: (visualLast || selected) ? Theme.cornerRadius : 4
|
||||
bottomRightRadius: (visualLast || selected) ? Theme.cornerRadius : 4
|
||||
topLeftRadius: (visualFirst || selected) ? Theme.cornerRadius : Math.min(4, Theme.cornerRadius)
|
||||
bottomLeftRadius: (visualFirst || selected) ? Theme.cornerRadius : Math.min(4, Theme.cornerRadius)
|
||||
topRightRadius: (visualLast || selected) ? Theme.cornerRadius : Math.min(4, Theme.cornerRadius)
|
||||
bottomRightRadius: (visualLast || selected) ? Theme.cornerRadius : Math.min(4, Theme.cornerRadius)
|
||||
|
||||
Behavior on width {
|
||||
enabled: root.userInteracted
|
||||
|
||||
@@ -26,6 +26,8 @@ Item {
|
||||
"endeavouros": "\u{f322}",
|
||||
"manjaro": "\u{f160a}",
|
||||
"opensuse": "\u{f314}",
|
||||
"artix": "\u{f31f}",
|
||||
"void": "\u{f32e}",
|
||||
|
||||
// --- special types ---
|
||||
"folder": "\u{F024B}",
|
||||
|
||||
@@ -1273,6 +1273,7 @@ Item {
|
||||
spacing: Theme.spacingM
|
||||
|
||||
RowLayout {
|
||||
visible: optionsRow.argConfig?.base !== "screenshot-window"
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
DankToggle {
|
||||
@@ -1441,8 +1442,9 @@ Item {
|
||||
onTextChanged: {
|
||||
if (root._actionType !== "shell")
|
||||
return;
|
||||
var shell = Actions.getShellFromAction(root.editAction);
|
||||
root.updateEdit({
|
||||
"action": Actions.buildShellAction(KeybindsService.currentProvider, text)
|
||||
"action": Actions.buildShellAction(KeybindsService.currentProvider, text, shell)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
[templates.dmsmango]
|
||||
input_path = 'SHELL_DIR/matugen/templates/mango-colors.conf'
|
||||
output_path = 'CONFIG_DIR/mango/dms/colors.conf'
|
||||
post_hook = 'sh -c "mmsg -d reload_config 2>&1 || true"'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
|
||||
ABBREVIATIONS = {
|
||||
@@ -153,11 +153,49 @@ SEARCHABLE_COMPONENTS = [
|
||||
"SettingsToggleCard",
|
||||
]
|
||||
|
||||
STOPWORDS = {
|
||||
"the",
|
||||
"and",
|
||||
"for",
|
||||
"with",
|
||||
"from",
|
||||
"this",
|
||||
"that",
|
||||
"are",
|
||||
"was",
|
||||
"will",
|
||||
"can",
|
||||
"has",
|
||||
"have",
|
||||
"been",
|
||||
"when",
|
||||
"your",
|
||||
"use",
|
||||
"used",
|
||||
"using",
|
||||
"instead",
|
||||
"like",
|
||||
"such",
|
||||
"also",
|
||||
"only",
|
||||
"which",
|
||||
"each",
|
||||
"other",
|
||||
"some",
|
||||
"into",
|
||||
"than",
|
||||
"then",
|
||||
"them",
|
||||
"these",
|
||||
"those",
|
||||
}
|
||||
|
||||
|
||||
def enrich_keywords(label, description, category, existing_tags):
|
||||
keywords = set(existing_tags)
|
||||
|
||||
label_lower = label.lower()
|
||||
label_words = re.split(r'[\s\-_&/]+', label_lower)
|
||||
label_words = re.split(r"[\s\-_&/]+", label_lower)
|
||||
keywords.update(w for w in label_words if len(w) > 2)
|
||||
|
||||
for term, aliases in ABBREVIATIONS.items():
|
||||
@@ -166,7 +204,7 @@ def enrich_keywords(label, description, category, existing_tags):
|
||||
|
||||
if description:
|
||||
desc_lower = description.lower()
|
||||
desc_words = re.split(r'[\s\-_&/,.]+', desc_lower)
|
||||
desc_words = re.split(r"[\s\-_&/,.]+", desc_lower)
|
||||
keywords.update(w for w in desc_words if len(w) > 3 and w.isalpha())
|
||||
for term, aliases in ABBREVIATIONS.items():
|
||||
if term in desc_lower:
|
||||
@@ -176,17 +214,13 @@ def enrich_keywords(label, description, category, existing_tags):
|
||||
keywords.update(CATEGORY_KEYWORDS[category])
|
||||
|
||||
cat_lower = category.lower()
|
||||
cat_words = re.split(r'[\s\-_&/]+', cat_lower)
|
||||
cat_words = re.split(r"[\s\-_&/]+", cat_lower)
|
||||
keywords.update(w for w in cat_words if len(w) > 2)
|
||||
|
||||
stopwords = {'the', 'and', 'for', 'with', 'from', 'this', 'that', 'are', 'was',
|
||||
'will', 'can', 'has', 'have', 'been', 'when', 'your', 'use', 'used',
|
||||
'using', 'instead', 'like', 'such', 'also', 'only', 'which', 'each',
|
||||
'other', 'some', 'into', 'than', 'then', 'them', 'these', 'those'}
|
||||
keywords = {k for k in keywords if k not in stopwords and len(k) > 1}
|
||||
|
||||
keywords = {k for k in keywords if k not in STOPWORDS and len(k) > 1}
|
||||
return sorted(keywords)
|
||||
|
||||
|
||||
def extract_i18n_string(value):
|
||||
match = re.search(r'I18n\.tr\(["\']([^"\']+)["\']', value)
|
||||
if match:
|
||||
@@ -196,38 +230,42 @@ def extract_i18n_string(value):
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
|
||||
def extract_tags(value):
|
||||
match = re.search(r'\[([^\]]+)\]', value)
|
||||
match = re.search(r"\[([^\]]+)\]", value)
|
||||
if not match:
|
||||
return []
|
||||
content = match.group(1)
|
||||
tags = re.findall(r'["\']([^"\']+)["\']', content)
|
||||
return tags
|
||||
|
||||
|
||||
def parse_component_block(content, start_pos, component_name):
|
||||
brace_count = 0
|
||||
started = False
|
||||
block_start = start_pos
|
||||
|
||||
for i in range(start_pos, len(content)):
|
||||
if content[i] == '{':
|
||||
if content[i] == "{":
|
||||
if not started:
|
||||
block_start = i
|
||||
started = True
|
||||
brace_count += 1
|
||||
elif content[i] == '}':
|
||||
elif content[i] == "}":
|
||||
brace_count -= 1
|
||||
if started and brace_count == 0:
|
||||
return content[block_start:i+1]
|
||||
return content[block_start : i + 1]
|
||||
return ""
|
||||
|
||||
|
||||
def extract_property(block, prop_name):
|
||||
pattern = rf'{prop_name}\s*:\s*([^\n]+)'
|
||||
pattern = rf"{prop_name}\s*:\s*([^\n]+)"
|
||||
match = re.search(pattern, block)
|
||||
if match:
|
||||
return match.group(1).strip()
|
||||
return None
|
||||
|
||||
|
||||
def find_settings_components(content, filename):
|
||||
results = []
|
||||
tab_index = TAB_INDEX_MAP.get(filename, -1)
|
||||
@@ -236,7 +274,7 @@ def find_settings_components(content, filename):
|
||||
return results
|
||||
|
||||
for component in SEARCHABLE_COMPONENTS:
|
||||
pattern = rf'\b{component}\s*\{{'
|
||||
pattern = rf"\b{component}\s*\{{"
|
||||
for match in re.finditer(pattern, content):
|
||||
block = parse_component_block(content, match.start(), component)
|
||||
if not block:
|
||||
@@ -244,7 +282,7 @@ def find_settings_components(content, filename):
|
||||
|
||||
setting_key = extract_property(block, "settingKey")
|
||||
if setting_key:
|
||||
setting_key = setting_key.strip('"\'')
|
||||
setting_key = setting_key.strip("\"'")
|
||||
|
||||
if not setting_key:
|
||||
continue
|
||||
@@ -263,7 +301,7 @@ def find_settings_components(content, filename):
|
||||
icon_raw = extract_property(block, "iconName")
|
||||
icon = None
|
||||
if icon_raw:
|
||||
icon = icon_raw.strip('"\'')
|
||||
icon = icon_raw.strip("\"'")
|
||||
if icon.startswith("{") or "?" in icon:
|
||||
icon = None
|
||||
|
||||
@@ -321,6 +359,95 @@ def find_settings_components(content, filename):
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def parse_tabs_from_sidebar(sidebar_file):
|
||||
with open(sidebar_file, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
pattern = r'"text"\s*:\s*I18n\.tr\("([^"]+)"(?:,\s*"[^"]+")?\).*?"icon"\s*:\s*"([^"]+)".*?"tabIndex"\s*:\s*(\d+)'
|
||||
tabs = []
|
||||
|
||||
for match in re.finditer(pattern, content, re.DOTALL):
|
||||
label, icon, tab_idx = match.group(1), match.group(2), int(match.group(3))
|
||||
|
||||
before_text = content[: match.start()]
|
||||
parent_match = re.search(
|
||||
r'"text"\s*:\s*I18n\.tr\("([^"]+)"\)[^{]*"children"[^[]*\[[^{]*$',
|
||||
before_text,
|
||||
)
|
||||
parent = parent_match.group(1) if parent_match else None
|
||||
|
||||
cond = None
|
||||
after_pos = match.end()
|
||||
snippet = content[match.start() : min(after_pos + 200, len(content))]
|
||||
for qml_cond, key in [
|
||||
("shortcutsOnly", "keybindsAvailable"),
|
||||
("soundsOnly", "soundsAvailable"),
|
||||
("cupsOnly", "cupsAvailable"),
|
||||
("dmsOnly", "dmsConnected"),
|
||||
("hyprlandNiriOnly", "isHyprlandOrNiri"),
|
||||
("clipboardOnly", "dmsConnected"),
|
||||
]:
|
||||
if f'"{qml_cond}": true' in snippet:
|
||||
cond = key
|
||||
break
|
||||
|
||||
tabs.append(
|
||||
{
|
||||
"tabIndex": tab_idx,
|
||||
"label": label,
|
||||
"icon": icon,
|
||||
"parent": parent,
|
||||
"conditionKey": cond,
|
||||
}
|
||||
)
|
||||
|
||||
return tabs
|
||||
|
||||
|
||||
def generate_tab_entries(sidebar_file):
|
||||
tabs = parse_tabs_from_sidebar(sidebar_file)
|
||||
|
||||
label_counts = Counter([t["label"] for t in tabs])
|
||||
|
||||
entries = []
|
||||
for tab in tabs:
|
||||
label = (
|
||||
f"{tab['parent']}: {tab['label']}"
|
||||
if label_counts[tab["label"]] > 1 and tab["parent"]
|
||||
else tab["label"]
|
||||
)
|
||||
category = TAB_CATEGORY_MAP.get(tab["tabIndex"], "Settings")
|
||||
|
||||
keywords = enrich_keywords(tab["label"], None, category, [])
|
||||
|
||||
if tab["parent"]:
|
||||
parent_keywords = [
|
||||
w for w in re.split(r"[\s\-_&/]+", tab["parent"].lower()) if len(w) > 2
|
||||
]
|
||||
keywords = sorted(
|
||||
set(
|
||||
keywords
|
||||
+ parent_keywords
|
||||
+ [k for p in parent_keywords for k in ABBREVIATIONS.get(p, [])]
|
||||
)
|
||||
)
|
||||
|
||||
entry = {
|
||||
"section": f"_tab_{tab['tabIndex']}",
|
||||
"label": label,
|
||||
"tabIndex": tab["tabIndex"],
|
||||
"category": category,
|
||||
"keywords": keywords,
|
||||
"icon": tab["icon"],
|
||||
}
|
||||
if tab["conditionKey"]:
|
||||
entry["conditionKey"] = tab["conditionKey"]
|
||||
entries.append(entry)
|
||||
|
||||
return entries
|
||||
|
||||
|
||||
def extract_settings_index(root_dir):
|
||||
settings_dir = Path(root_dir) / "Modules" / "Settings"
|
||||
all_entries = []
|
||||
@@ -330,7 +457,7 @@ def extract_settings_index(root_dir):
|
||||
if not qml_file.name.endswith("Tab.qml"):
|
||||
continue
|
||||
|
||||
with open(qml_file, 'r', encoding='utf-8') as f:
|
||||
with open(qml_file, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
entries = find_settings_components(content, qml_file.name)
|
||||
@@ -342,29 +469,37 @@ def extract_settings_index(root_dir):
|
||||
|
||||
return all_entries
|
||||
|
||||
|
||||
def main():
|
||||
script_dir = Path(__file__).parent
|
||||
root_dir = script_dir.parent
|
||||
sidebar_file = root_dir / "Modals" / "Settings" / "SettingsSidebar.qml"
|
||||
|
||||
print("Extracting settings search index...")
|
||||
entries = extract_settings_index(root_dir)
|
||||
settings_entries = extract_settings_index(root_dir)
|
||||
tab_entries = generate_tab_entries(sidebar_file)
|
||||
|
||||
entries.sort(key=lambda x: (x["tabIndex"], x["label"]))
|
||||
all_entries = tab_entries + settings_entries
|
||||
|
||||
all_entries.sort(key=lambda x: (x["tabIndex"], x["label"]))
|
||||
|
||||
output_path = script_dir / "settings_search_index.json"
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(entries, f, indent=2, ensure_ascii=False)
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
json.dump(all_entries, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"Found {len(entries)} searchable settings")
|
||||
print(f"Found {len(settings_entries)} searchable settings")
|
||||
print(f"Found {len(tab_entries)} tab entries")
|
||||
print(f"Total: {len(all_entries)} entries")
|
||||
print(f"Output: {output_path}")
|
||||
|
||||
conditions = set()
|
||||
for entry in entries:
|
||||
for entry in all_entries:
|
||||
if "conditionKey" in entry:
|
||||
conditions.add(entry["conditionKey"])
|
||||
|
||||
if conditions:
|
||||
print(f"Condition keys found: {', '.join(sorted(conditions))}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "Todas las pantallas"
|
||||
},
|
||||
"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: Atrás • F1/I: Información del archivo • F10: Ayuda • Esc: Cerrar+"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "Identidad anónima (opcional)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "Lanzador de aplicaciones"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "Clic en importar para añadir un archivo .ovpn o .conf"
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "Columnas de cuadrícula"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": "Aplicaciones del espacio de trabajo en grupo"
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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": "Mostrar número de ventanas agrupadas en el icono de la aplicación"
|
||||
},
|
||||
"Group removed": {
|
||||
"Group removed": ""
|
||||
},
|
||||
"Group repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": "Agrupar iconos de aplicaciones repetidos en espacios de trabajo desenfocados"
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR (EDID)"
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"Manual Show/Hide": {
|
||||
"Manual Show/Hide": "Mostrar/Ocultar manualmente"
|
||||
},
|
||||
"Map window class names to icon names for proper icon display": {
|
||||
"Map window class names to icon names for proper icon display": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "Margen"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "New York, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "Siguiente transicion"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "Opciones"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "Otro"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "Contraseña"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "Pausar"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "Reporte"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "Sincronizar modo con los portales"
|
||||
},
|
||||
"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": "Sincronizar el tema oscuro con las preferencias globales del sistema"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "Desinstalar complemento"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "Usar tema claro en lugar del tema oscuro"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"Use sound theme from system settings": {
|
||||
"Use sound theme from system settings": "Usar tema de sonidos del sistema"
|
||||
},
|
||||
"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": ""
|
||||
},
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "همه نمایشگرها"
|
||||
},
|
||||
"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: بازگشت • F1/I: اطلاعات فایل • F10: راهنما • Esc: بستن"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "هویت ناشناس (اختیاری)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "لانچر برنامه"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "برای افزودن یک فایل .conf یا .ovpn کلیک کنید"
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "ستونهای جدول"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": "گروهبندی برنامههای workspace"
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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 repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": "برنامههای تکرارشده در workspaceهای فوکوس نشده را گروهبندی کن"
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR (EDID)"
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"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": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "فاصله بیرونی"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "New York, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "گذار بعدی"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "گزینهها"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "دیگر"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "گذرواژه"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "توقف"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "گزارش"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "همگامسازی حالت با پورتال"
|
||||
},
|
||||
"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": "همگامسازی حالت تاریک با پورتال سیستم برای هماهنگی تم در سطح سیستم"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "حذف افزونه"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "استفاده از تم روشن به جای تم تاریک"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"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 trigger prefix to activate": {
|
||||
"Use trigger prefix to activate": ""
|
||||
},
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "כל המסכים"
|
||||
},
|
||||
"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: חזרה • F1/I: מידע על הקובץ • F10: עזרה • Esc: סגירה"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "זהות אנונימית (אופציונלי)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "משגר אפליקציות"
|
||||
},
|
||||
@@ -549,7 +555,7 @@
|
||||
"Bottom Section": "קטע תחתון"
|
||||
},
|
||||
"Bottom dock for pinned and running applications": {
|
||||
"Bottom dock for pinned and running applications": "Dock תחתון לאפליקציות נעוצות ופעילות"
|
||||
"Bottom dock for pinned and running applications": "הצגת Dock תחתון לאפליקציות נעוצות ופעילות"
|
||||
},
|
||||
"Brightness": {
|
||||
"Brightness": "בהירות"
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "לחץ/י על ייבוא כדי להוסיף קובץ ovpn. או conf."
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "עמודות רשת"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": ""
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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 repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": ""
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": ""
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"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": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "שוליים"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "ניו יורק, ניו יורק"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": ""
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": ""
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "אחר"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "סיסמה"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "השהיה"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "דיווח"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "סנכרון מצב עם הפורטל"
|
||||
},
|
||||
"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": "סנכרון מצב כהה עם פורטלי ההגדרות לרמזי ערכת נושא ברמת המערכת"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "הסר/י תוסף"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "השתמש/י בערכת נושא בהירה במקום כהה"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"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 trigger prefix to activate": {
|
||||
"Use trigger prefix to activate": ""
|
||||
},
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"%1 connected": "%1 csatlakoztatva"
|
||||
},
|
||||
"%1 days ago": {
|
||||
"%1 days ago": ""
|
||||
"%1 days ago": "%1 nappal ezelőtt"
|
||||
},
|
||||
"%1 display(s)": {
|
||||
"%1 display(s)": "%1 kijelző"
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "Összes kijelző"
|
||||
},
|
||||
"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: Vissza • F1/I: Fájlinfó • F10: Súgó • Esc: Bezárás"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "Névtelen azonosító (opcionális)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "Alkalmazásindító"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "Kattints az importálás gombra .ovpn vagy .conf fájl hozzáadásához"
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "Rácsos oszlopok"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": ""
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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": "Ugyanazon alkalmazás több ablakának csoportosítása egy ablakszám jelzővel"
|
||||
},
|
||||
"Group removed": {
|
||||
"Group removed": ""
|
||||
},
|
||||
"Group repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": ""
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR (EDID)"
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"Manual Show/Hide": {
|
||||
"Manual Show/Hide": "Manuális megjelenítés/elrejtés"
|
||||
},
|
||||
"Map window class names to icon names for proper icon display": {
|
||||
"Map window class names to icon names for proper icon display": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "Margó"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "New York, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "Következő átmenet"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "Opciók"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "Egyéb"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "Jelszó"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "Szüneteltetés"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "Jelentés"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "Mód szinkronizálása a portállal"
|
||||
},
|
||||
"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": "Sötét mód szinkronizálása a beállítási portálokkal a rendszer egészére vonatkozó témajavaslatokhoz"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "Bővítmény eltávolítása"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "Világos téma használata a sötét helyett"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"Use sound theme from system settings": {
|
||||
"Use sound theme from system settings": "Hangtéma használata a rendszerbeállításokból"
|
||||
},
|
||||
"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": ""
|
||||
},
|
||||
@@ -4508,7 +4553,7 @@
|
||||
"No wallpaper selected": "Nincs háttérkép kiválasztva"
|
||||
},
|
||||
"notification center tab": {
|
||||
"Current": "",
|
||||
"Current": "Jelenlegi",
|
||||
"History": "Előzmények"
|
||||
},
|
||||
"notification history filter": {
|
||||
@@ -4546,7 +4591,7 @@
|
||||
"Save dismissed notifications to history": ""
|
||||
},
|
||||
"notification history toggle label": {
|
||||
"Enable History": ""
|
||||
"Enable History": "Előzmények engedélyezése"
|
||||
},
|
||||
"now": {
|
||||
"now": "most"
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "Tutti gli schermi"
|
||||
},
|
||||
"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: Indietro • F1/I: File Info • F10: Aiuto • Esc: Chiudi"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "Identità anonima (facoltativa)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "App Launcher"
|
||||
},
|
||||
@@ -303,7 +309,7 @@
|
||||
"Apps are ordered by usage frequency, then last used, then alphabetically.": "Le applicazioni sono ordinate per frequenza d'uso, poi per ultimo utilizzo, e infine in ordine alfabetico."
|
||||
},
|
||||
"Arrange displays and configure resolution, refresh rate, and VRR": {
|
||||
"Arrange displays and configure resolution, refresh rate, and VRR": "Disponi gli schermi e configurare risoluzione, frequenza di aggiornamento e VRR"
|
||||
"Arrange displays and configure resolution, refresh rate, and VRR": "Disponi gli schermi e configura risoluzione, frequenza di aggiornamento e VRR"
|
||||
},
|
||||
"Audio": {
|
||||
"Audio": "Audio"
|
||||
@@ -621,7 +627,7 @@
|
||||
"Caps Lock": "Blocco Maiuscole"
|
||||
},
|
||||
"Caps Lock Indicator": {
|
||||
"Caps Lock Indicator": "Indicatore Maiuscolo"
|
||||
"Caps Lock Indicator": "Indicatore Blocco Maiuscole"
|
||||
},
|
||||
"Center Section": {
|
||||
"Center Section": "Sezione Centrale"
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "Clicca su Importa per aggiungere un file .ovpn o .conf"
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"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"
|
||||
},
|
||||
@@ -993,7 +1002,7 @@
|
||||
"Custom Lock Command": "Comando Personalizzato per Blocco"
|
||||
},
|
||||
"Custom Logout Command": {
|
||||
"Custom Logout Command": "Comando Personalizzato per il Termina Sessione"
|
||||
"Custom Logout Command": "Comando Personalizzato di Termine Sessione"
|
||||
},
|
||||
"Custom Power Actions": {
|
||||
"Custom Power Actions": "Azioni Alimentazione Personalizzate"
|
||||
@@ -1317,7 +1326,7 @@
|
||||
"Edge Spacing": "Spaziatura del Bordo"
|
||||
},
|
||||
"Education": {
|
||||
"Education": "Educazione"
|
||||
"Education": "Istruzione"
|
||||
},
|
||||
"Empty": {
|
||||
"Empty": "Vuoto"
|
||||
@@ -1530,7 +1539,7 @@
|
||||
"Failed to import VPN": "Impossibile importare la VPN"
|
||||
},
|
||||
"Failed to load VPN config": {
|
||||
"Failed to load VPN config": "Impossibile importare la configurazione VPN"
|
||||
"Failed to load VPN config": "Impossibile caricare la configurazione VPN"
|
||||
},
|
||||
"Failed to load clipboard configuration.": {
|
||||
"Failed to load clipboard configuration.": "Impossibile caricare la configurazione degli appunti"
|
||||
@@ -1656,31 +1665,31 @@
|
||||
"Flags": "Flag"
|
||||
},
|
||||
"Flipped": {
|
||||
"Flipped": "Ruotato"
|
||||
"Flipped": "Specchiato"
|
||||
},
|
||||
"Flipped 180°": {
|
||||
"Flipped 180°": "Ruotato di 180°"
|
||||
"Flipped 180°": "Specchiato di 180°"
|
||||
},
|
||||
"Flipped 270°": {
|
||||
"Flipped 270°": "Ruotato di 270°"
|
||||
"Flipped 270°": "Specchiato di 270°"
|
||||
},
|
||||
"Flipped 90°": {
|
||||
"Flipped 90°": "Ruotato di 90°"
|
||||
"Flipped 90°": "Specchiato di 90°"
|
||||
},
|
||||
"Focus at Startup": {
|
||||
"Focus at Startup": "Attiva all'Avvio"
|
||||
},
|
||||
"Focused Border": {
|
||||
"Focused Border": ""
|
||||
"Focused Border": "Bordo Attivo"
|
||||
},
|
||||
"Focused Color": {
|
||||
"Focused Color": ""
|
||||
"Focused Color": "Colore Attivo"
|
||||
},
|
||||
"Focused Window": {
|
||||
"Focused Window": "Finestra Attiva"
|
||||
},
|
||||
"Follow Monitor Focus": {
|
||||
"Follow Monitor Focus": ""
|
||||
"Follow Monitor Focus": "Segui il Monitor Attivo"
|
||||
},
|
||||
"Follow focus": {
|
||||
"Follow focus": "Segui il focus"
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "Colonne Griglia"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": "Raggruppa App per Spazio di Lavoro"
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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": "Raggruppa molteplici finestre della stessa app con un indicatore del numero di finestre"
|
||||
},
|
||||
"Group removed": {
|
||||
"Group removed": ""
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR (EDID)"
|
||||
},
|
||||
@@ -1842,7 +1860,7 @@
|
||||
"Hide When Windows Open": "Nascondi Quando le Finestre Sono Aperte"
|
||||
},
|
||||
"Hide cursor after inactivity (0 = disabled)": {
|
||||
"Hide cursor after inactivity (0 = disabled)": "Nascondi il cursore dopo inattività (0 = disabilitato)"
|
||||
"Hide cursor after inactivity (0 = disabled)": "Nascondi il cursore dopo un periodo di inattività (0 = disabilitato)"
|
||||
},
|
||||
"Hide cursor when pressing keyboard keys": {
|
||||
"Hide cursor when pressing keyboard keys": "Nascondi il cursore quando si premono i tasti della tastiera"
|
||||
@@ -1917,7 +1935,7 @@
|
||||
"Icon Theme": "Tema Icona"
|
||||
},
|
||||
"Idle": {
|
||||
"Idle": "Inattività"
|
||||
"Idle": "In Attesa"
|
||||
},
|
||||
"Idle Inhibitor": {
|
||||
"Idle Inhibitor": "Blocco Sospensione"
|
||||
@@ -2043,19 +2061,19 @@
|
||||
"LED device": "Dispositivo LED"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "Ultimo avviato %1"
|
||||
"Last launched %1": "Ultimo avvio %1"
|
||||
},
|
||||
"Last launched %1 day%2 ago": {
|
||||
"Last launched %1 day%2 ago": "Ultimo avviato %1 giorno%2 fa"
|
||||
"Last launched %1 day%2 ago": "Ultimo avvio %1 giorno%2 fa"
|
||||
},
|
||||
"Last launched %1 hour%2 ago": {
|
||||
"Last launched %1 hour%2 ago": "Ultimo avviato %1 ora%2 fa"
|
||||
"Last launched %1 hour%2 ago": "Ultimo avvio %1 ora%2 fa"
|
||||
},
|
||||
"Last launched %1 minute%2 ago": {
|
||||
"Last launched %1 minute%2 ago": "Ultimo avviato %1 minuto%2 fa"
|
||||
"Last launched %1 minute%2 ago": "Ultimo avvio %1 minuto%2 fa"
|
||||
},
|
||||
"Last launched just now": {
|
||||
"Last launched just now": "Ultimo avviato ora"
|
||||
"Last launched just now": "Ultimo avvio ora"
|
||||
},
|
||||
"Latitude": {
|
||||
"Latitude": "Latitudine"
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"Manual Show/Hide": {
|
||||
"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": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "Margini"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "New York, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "Prossima Transizione"
|
||||
},
|
||||
@@ -2616,7 +2640,7 @@
|
||||
"On-screen Displays": "Indicatori a Schermo"
|
||||
},
|
||||
"Only adjust gamma based on time or location rules.": {
|
||||
"Only adjust gamma based on time or location rules.": "Regolare gamma solo in base alle regole di tempo o di posizione."
|
||||
"Only adjust gamma based on time or location rules.": "Regola la gamma solo in base alle regole di tempo o di posizione."
|
||||
},
|
||||
"Only show windows from the current monitor on each dock": {
|
||||
"Only show windows from the current monitor on each dock": "Mostra solo le finestre del monitor corrente su ogni dock"
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "Opzioni"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "Altro"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "Password"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "Pausa"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": "Ripetizione"
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "Riepilogo"
|
||||
},
|
||||
@@ -3396,7 +3429,7 @@
|
||||
"Show all 9 tags instead of only occupied tags (DWL only)": "Mostra tutti i 9 tag invece di quelli occupati (solo DWL)"
|
||||
},
|
||||
"Show an outline ring around the focused workspace indicator": {
|
||||
"Show an outline ring around the focused workspace indicator": ""
|
||||
"Show an outline ring around the focused workspace indicator": "Mostra un contorno attorno all’indicatore dello spazio di lavoro attivo"
|
||||
},
|
||||
"Show cava audio visualizer in media widget": {
|
||||
"Show cava audio visualizer in media widget": "Mostra il visualizzatore audio cava nel widget multimediale"
|
||||
@@ -3429,7 +3462,7 @@
|
||||
"Show on-screen display when brightness changes": "Visualizza un messaggio a schermo quando la luminosità cambia"
|
||||
},
|
||||
"Show on-screen display when caps lock state changes": {
|
||||
"Show on-screen display when caps lock state changes": "Visualizza un messaggio a schermo quando lo stato del maiuscolo cambia"
|
||||
"Show on-screen display when caps lock state changes": "Visualizza un messaggio a schermo quando lo stato del blocco maiuscole cambia"
|
||||
},
|
||||
"Show on-screen display when cycling audio output devices": {
|
||||
"Show on-screen display when cycling audio output devices": "Mostra un avviso sullo schermo quando si scorre tra i dispositivi di uscita audio"
|
||||
@@ -3468,7 +3501,7 @@
|
||||
"Show workspace name on horizontal bars, and first letter on vertical bars": "Mostra il nome dello spazio di lavoro nelle barre orizzontali e la prima lettera in quelle verticali"
|
||||
},
|
||||
"Show workspaces of the currently focused monitor": {
|
||||
"Show workspaces of the currently focused monitor": ""
|
||||
"Show workspaces of the currently focused monitor": "Mostra gli spazi di lavoro del monitor attualmente attivo"
|
||||
},
|
||||
"Shows all running applications with focus indication": {
|
||||
"Shows all running applications with focus indication": "Mostra tutte le applicazioni in esecuzione con indicazione focus"
|
||||
@@ -3477,7 +3510,7 @@
|
||||
"Shows current workspace and allows switching": "Visualizza lo spazio di lavoro attuale e consente di passare ad un altro"
|
||||
},
|
||||
"Shows when caps lock is active": {
|
||||
"Shows when caps lock is active": "Indica quando il maiuscolo è attivo"
|
||||
"Shows when caps lock is active": "Indica quando il blocco maiuscole è attivo"
|
||||
},
|
||||
"Shows when microphone, camera, or screen sharing is active": {
|
||||
"Shows when microphone, camera, or screen sharing is active": "Mostra quando microfono, videocamera, o condivisione schermo sono attivi"
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "Modalità Sync con Portale"
|
||||
},
|
||||
"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": "Sincronizza tema scuro con impostazioni di sistema"
|
||||
},
|
||||
@@ -3636,7 +3672,7 @@
|
||||
"System Update": "Aggiornamento Sistema"
|
||||
},
|
||||
"System Updater": {
|
||||
"System Updater": "Updater Sistema"
|
||||
"System Updater": "Aggiornamento Sistema"
|
||||
},
|
||||
"System Updates": {
|
||||
"System Updates": "Aggiornamenti Sistema"
|
||||
@@ -3705,10 +3741,10 @@
|
||||
"Thickness": "Spessore"
|
||||
},
|
||||
"Third-Party Plugin Warning": {
|
||||
"Third-Party Plugin Warning": "Avviso Plugin Terze-Parti"
|
||||
"Third-Party Plugin Warning": "Avviso Plugin di Terze Parti"
|
||||
},
|
||||
"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.": {
|
||||
"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.": "I plugin di terze parti sono creati dalla community e non sono ufficialmente supportati da DankMaterialShell.\\n\\nQuesti plugin possono comportare rischi per la sicurezza e la privacy - installa a proprio rischio."
|
||||
"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.": "I plugin di terze parti sono creati dalla community e non sono ufficialmente supportati da DankMaterialShell.\\n\\nQuesti plugin possono comportare rischi per la sicurezza e la privacy - l'installazione è a proprio rischio."
|
||||
},
|
||||
"This bind is overridden by config.kdl": {
|
||||
"This bind is overridden by config.kdl": "Questa associazione di tasti è stata sovrascritta da config.kdl"
|
||||
@@ -3837,7 +3873,10 @@
|
||||
"Unavailable": "Non disponibile"
|
||||
},
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
"Unfocused Color": "Colore Inattivo"
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "Disinstalla Plugin"
|
||||
@@ -3882,7 +3921,7 @@
|
||||
"Update Plugin": "Aggiorna Plugin"
|
||||
},
|
||||
"Urgent Color": {
|
||||
"Urgent Color": ""
|
||||
"Urgent Color": "Colore Urgente"
|
||||
},
|
||||
"Usage Tips": {
|
||||
"Usage Tips": "Suggerimenti d'Uso"
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "Usa tema chiaro invece del tema scuro"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"Use sound theme from system settings": {
|
||||
"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 trigger prefix to activate": {
|
||||
"Use trigger prefix to activate": "Usa il prefisso attivatore per attivare"
|
||||
},
|
||||
@@ -4178,7 +4223,7 @@
|
||||
"Workspace": "Spazio di Lavoro"
|
||||
},
|
||||
"Workspace Appearance": {
|
||||
"Workspace Appearance": ""
|
||||
"Workspace Appearance": "Aspetto degli Spazi di Lavoro"
|
||||
},
|
||||
"Workspace Index Numbers": {
|
||||
"Workspace Index Numbers": "Numeri Indice Spazi di Lavoro"
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "すべてのディスプレイ"
|
||||
},
|
||||
"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: 戻る • F1/I: ファイル情報 • F10: ヘルプ • Esc: 閉じる"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "匿名 ID (オプション)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "アプリランチャー"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": ""
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "グリッド列"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": ""
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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 repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": ""
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": ""
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"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": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "マージン"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "New York, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": ""
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": ""
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "他"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "パスワード"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "一時停止"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "報告"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "ポータルとの同期モード"
|
||||
},
|
||||
"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": "ダークモードをシステム全体のテーマヒントの設定ポータルと同期"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "プラグインをアンインストール"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "ダークテーマではなく、ライトテーマを使用"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"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 trigger prefix to activate": {
|
||||
"Use trigger prefix to activate": ""
|
||||
},
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "Wszystkie ekrany"
|
||||
},
|
||||
"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: Wstecz • F1/I: Informacje o pliku • F10: Pomoc • Esc: Zamknij"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "Tożsamość anonimowa (opcjonalnie)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "Program Uruchamiający"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "Kliknij Importuj, aby dodać plik .ovpn lub .conf"
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "Kolumny siatki"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": ""
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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": "Grupuj wiele okien tej samej aplikacji ze wskaźnikiem liczby okien"
|
||||
},
|
||||
"Group removed": {
|
||||
"Group removed": ""
|
||||
},
|
||||
"Group repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": ""
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR (EDID)"
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"Manual Show/Hide": {
|
||||
"Manual Show/Hide": "Ręczne pokazywanie/ukrywanie"
|
||||
},
|
||||
"Map window class names to icon names for proper icon display": {
|
||||
"Map window class names to icon names for proper icon display": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "Margines"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "Nowy Jork, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "Następne Przejście"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "Opcje"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "Inne"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "Hasło"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "Wstrzymaj"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "Raport"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "Tryb synchronizacji z portalem"
|
||||
},
|
||||
"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": "Synchronizuj ciemny motyw z systemem"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "Odinstaluj wtyczkę"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "Użyj jasnego motywu zamiast ciemnego"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"Use sound theme from system settings": {
|
||||
"Use sound theme from system settings": "Użyj motywu dźwiękowego z ustawień systemowych"
|
||||
},
|
||||
"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": ""
|
||||
},
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
"All": "Todos"
|
||||
},
|
||||
"All Monitors": {
|
||||
"All Monitors": ""
|
||||
"All Monitors": "Todos os Monitores"
|
||||
},
|
||||
"All day": {
|
||||
"All day": "O dia todo"
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "Todos as Telas"
|
||||
},
|
||||
"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: Voltar • F1/I: Informações de Arquivo • F10: Ajuda • Esc: Fechar"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "Identidade Anônima (opcional)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "Lançador de Apps"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "Clique em Importar para adicionar um arquivo .ovpn ou .conf"
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -819,7 +828,7 @@
|
||||
"Config Format": ""
|
||||
},
|
||||
"Config action: %1": {
|
||||
"Config action: %1": ""
|
||||
"Config action: %1": "Configurar ação: %1"
|
||||
},
|
||||
"Config validation failed": {
|
||||
"Config validation failed": ""
|
||||
@@ -981,10 +990,10 @@
|
||||
"Custom Color": ""
|
||||
},
|
||||
"Custom Duration": {
|
||||
"Custom Duration": ""
|
||||
"Custom Duration": "Duração Personalizada"
|
||||
},
|
||||
"Custom Hibernate Command": {
|
||||
"Custom Hibernate Command": ""
|
||||
"Custom Hibernate Command": "Comando Personalizado Para Hibernar"
|
||||
},
|
||||
"Custom Location": {
|
||||
"Custom Location": "Customizar Localização"
|
||||
@@ -993,19 +1002,19 @@
|
||||
"Custom Lock Command": ""
|
||||
},
|
||||
"Custom Logout Command": {
|
||||
"Custom Logout Command": ""
|
||||
"Custom Logout Command": "Comando Personalizado Para Sair"
|
||||
},
|
||||
"Custom Power Actions": {
|
||||
"Custom Power Actions": "Ações de Energia Customizadas"
|
||||
},
|
||||
"Custom Power Off Command": {
|
||||
"Custom Power Off Command": ""
|
||||
"Custom Power Off Command": "Comando Personalizado Para Desligar"
|
||||
},
|
||||
"Custom Reboot Command": {
|
||||
"Custom Reboot Command": ""
|
||||
"Custom Reboot Command": "Comando Personalizado Para Reiniciar"
|
||||
},
|
||||
"Custom Suspend Command": {
|
||||
"Custom Suspend Command": ""
|
||||
"Custom Suspend Command": "Comando Personalizado Para Suspender"
|
||||
},
|
||||
"Custom Transparency": {
|
||||
"Custom Transparency": "Transparência Customizada"
|
||||
@@ -1212,7 +1221,7 @@
|
||||
"Display Settings": ""
|
||||
},
|
||||
"Display a dock with pinned and running applications": {
|
||||
"Display a dock with pinned and running applications": ""
|
||||
"Display a dock with pinned and running applications": "Exibir um dock com aplicativos fixados e abertos"
|
||||
},
|
||||
"Display all priorities over fullscreen apps": {
|
||||
"Display all priorities over fullscreen apps": "Exibir todas as prioridades em aplicativos de tela cheia"
|
||||
@@ -1242,13 +1251,13 @@
|
||||
"Display power menu actions in a grid instead of a list": "Mostra as ações do menu de energia em uma grade ao invés de uma lista"
|
||||
},
|
||||
"Display seconds in the clock": {
|
||||
"Display seconds in the clock": ""
|
||||
"Display seconds in the clock": "Exibir segundos no relógio"
|
||||
},
|
||||
"Display the power system menu": {
|
||||
"Display the power system menu": "Mostra o menu de energia do sistema"
|
||||
},
|
||||
"Display volume and brightness percentage values in OSD popups": {
|
||||
"Display volume and brightness percentage values in OSD popups": ""
|
||||
"Display volume and brightness percentage values in OSD popups": "Exibir porcentagem de volume e brilho nos pop-ups OSD"
|
||||
},
|
||||
"Displays": {
|
||||
"Displays": "Telas"
|
||||
@@ -1266,7 +1275,7 @@
|
||||
"Dock": "Dock"
|
||||
},
|
||||
"Dock & Launcher": {
|
||||
"Dock & Launcher": ""
|
||||
"Dock & Launcher": "Dock & Lançador"
|
||||
},
|
||||
"Dock Position": {
|
||||
"Dock Position": "Posição da Dock"
|
||||
@@ -1275,7 +1284,7 @@
|
||||
"Dock Transparency": "Transparência da Dock"
|
||||
},
|
||||
"Dock Visibility": {
|
||||
"Dock Visibility": ""
|
||||
"Dock Visibility": "Visibilidade do Dock"
|
||||
},
|
||||
"Docs": {
|
||||
"Docs": ""
|
||||
@@ -1335,7 +1344,7 @@
|
||||
"Enable Desktop Clock": ""
|
||||
},
|
||||
"Enable Do Not Disturb": {
|
||||
"Enable Do Not Disturb": ""
|
||||
"Enable Do Not Disturb": "Habilitar Não Perturbe"
|
||||
},
|
||||
"Enable GPU Temperature": {
|
||||
"Enable GPU Temperature": "Habilitar Temperatura da GPU"
|
||||
@@ -1629,7 +1638,7 @@
|
||||
"File Information": "Informação do Arquivo"
|
||||
},
|
||||
"Files": {
|
||||
"Files": ""
|
||||
"Files": "Arquivos"
|
||||
},
|
||||
"Filesystem usage monitoring": {
|
||||
"Filesystem usage monitoring": ""
|
||||
@@ -1644,7 +1653,7 @@
|
||||
"Fine-tune animation timing in milliseconds": ""
|
||||
},
|
||||
"First Time Setup": {
|
||||
"First Time Setup": ""
|
||||
"First Time Setup": "Configuração Inicial"
|
||||
},
|
||||
"Fix Now": {
|
||||
"Fix Now": "Consertar Agora"
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "Colunas da Grade"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": ""
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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": "Agrupar múltiplas janelas do mesmo app com um indicador de número de janelas"
|
||||
},
|
||||
"Group removed": {
|
||||
"Group removed": ""
|
||||
},
|
||||
"Group repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": ""
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": ""
|
||||
},
|
||||
@@ -1836,7 +1854,7 @@
|
||||
"Hide Delay": ""
|
||||
},
|
||||
"Hide When Typing": {
|
||||
"Hide When Typing": ""
|
||||
"Hide When Typing": "Ocultar ao Digitar"
|
||||
},
|
||||
"Hide When Windows Open": {
|
||||
"Hide When Windows Open": ""
|
||||
@@ -1944,7 +1962,7 @@
|
||||
"Import VPN": "Importar VPN"
|
||||
},
|
||||
"Inactive Monitor Color": {
|
||||
"Inactive Monitor Color": ""
|
||||
"Inactive Monitor Color": "Cor do Monitor Inativo"
|
||||
},
|
||||
"Include Transitions": {
|
||||
"Include Transitions": "Incluir Transições"
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"Manual Show/Hide": {
|
||||
"Manual Show/Hide": "Mostrar/Esconder Manualmente"
|
||||
},
|
||||
"Map window class names to icon names for proper icon display": {
|
||||
"Map window class names to icon names for proper icon display": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "Margem"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "Nova York, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "Próxima Transição"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "Opções"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "Outro"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "Senha"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "Pausar"
|
||||
},
|
||||
@@ -2748,13 +2778,13 @@
|
||||
"Personalization": "Personalização"
|
||||
},
|
||||
"Pin": {
|
||||
"Pin": ""
|
||||
"Pin": "Fixar"
|
||||
},
|
||||
"Pin to Dock": {
|
||||
"Pin to Dock": "Fixar ao Dock"
|
||||
},
|
||||
"Pinned": {
|
||||
"Pinned": ""
|
||||
"Pinned": "Fixado"
|
||||
},
|
||||
"Place plugin directories here. Each plugin should have a plugin.json manifest file.": {
|
||||
"Place plugin directories here. Each plugin should have a plugin.json manifest file.": "Use este local para os diretórios de plugin. Cada plugin deve ter um arquivo de manifesto plugin.json."
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "Relatório"
|
||||
},
|
||||
@@ -3369,7 +3402,7 @@
|
||||
"Show Restart DMS": "Mostrar Reiniciar DMS"
|
||||
},
|
||||
"Show Seconds": {
|
||||
"Show Seconds": ""
|
||||
"Show Seconds": "Mostrar Segundos"
|
||||
},
|
||||
"Show Sunrise/Sunset": {
|
||||
"Show Sunrise/Sunset": ""
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "Sincronizar Modo Com Portal"
|
||||
},
|
||||
"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": "Sincronize o modo escuro com os portais de configurações para ter indicações de temas em todo o sistema"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "Desinstalar Plugin"
|
||||
},
|
||||
@@ -3858,7 +3897,7 @@
|
||||
"Unknown Network": ""
|
||||
},
|
||||
"Unpin": {
|
||||
"Unpin": ""
|
||||
"Unpin": "Desafixar"
|
||||
},
|
||||
"Unpin from Dock": {
|
||||
"Unpin from Dock": "Desafixar do Dock"
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "Usar tema claro em vez de escuro"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"Use sound theme from system settings": {
|
||||
"Use sound theme from system settings": "Usar tema de som das configurações do sistema"
|
||||
},
|
||||
"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": ""
|
||||
},
|
||||
@@ -4649,10 +4694,10 @@
|
||||
"Use an external wallpaper manager like swww, hyprpaper, or swaybg.": ""
|
||||
},
|
||||
"wallpaper settings disable toggle": {
|
||||
"Disable Built-in Wallpapers": ""
|
||||
"Disable Built-in Wallpapers": "Desabilitar Papéis de Parede Embutidos"
|
||||
},
|
||||
"wallpaper settings external management": {
|
||||
"External Wallpaper Management": ""
|
||||
"External Wallpaper Management": "Gerenciamento Externo de Papéis de Parede"
|
||||
},
|
||||
"wtype not available - install wtype for paste support": {
|
||||
"wtype not available - install wtype for paste support": ""
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "Tüm ekranlar"
|
||||
},
|
||||
"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: Geri • F1/I: Dosya bilgisi • F10: Yardım • Esc: Kapat"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "Anonim Kimlik (isteğe bağlı)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "Uygulama Başlatıcı"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": ".ovpn veya .conf dosyası eklemek için İçe Aktar'ı tıklayın."
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": ""
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "Izgara Sütunları"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": ""
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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": "Aynı uygulamanın birden fazla penceresini pencere sayısı göstergesi ile gruplayın"
|
||||
},
|
||||
"Group removed": {
|
||||
"Group removed": ""
|
||||
},
|
||||
"Group repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": ""
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR (EDID)"
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"Manual Show/Hide": {
|
||||
"Manual Show/Hide": "Manuel Göster/Gizle"
|
||||
},
|
||||
"Map window class names to icon names for proper icon display": {
|
||||
"Map window class names to icon names for proper icon display": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "Kenar Boşluğu"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "New York, NY"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "Sonraki Geçiş"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "Seçenekler"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "Diğer"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "Parola"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "Duraklat"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "Rapor"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "Modu Portal ile Eşitle"
|
||||
},
|
||||
"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": "Sistem genelindeki tema ipuçları için karanlık modu ayar portalları ile senkronize et"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "Eklentiyi Kaldır"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "Karanlık tema yerine aydınlık tema kullan"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"Use sound theme from system settings": {
|
||||
"Use sound theme from system settings": "Sistem ayarlarındaki ses temasını kullan"
|
||||
},
|
||||
"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": ""
|
||||
},
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
"%1 display(s)": "%1 显示"
|
||||
},
|
||||
"%1 exists but is not included in config. Custom keybinds will not work until this is fixed.": {
|
||||
"%1 exists but is not included in config. Custom keybinds will not work until this is fixed.": ""
|
||||
"%1 exists but is not included in config. Custom keybinds will not work until this is fixed.": "%1存在但并未被包含至配置文件。在此问题修复前,自定义快捷键绑定将不会生效。"
|
||||
},
|
||||
"%1 is now included in config": {
|
||||
"%1 is now included in config": ""
|
||||
"%1 is now included in config": "%1现在已被包含至配置文件"
|
||||
},
|
||||
"%1 job(s)": {
|
||||
"%1 job(s)": "%1 个任务"
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "所有显示器"
|
||||
},
|
||||
"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+←/退格: 返回 • F1/I: 文件信息 • F10: 帮助 • Esc: 关闭"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "匿名身份(可选)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "启动器"
|
||||
},
|
||||
@@ -708,7 +714,7 @@
|
||||
"Clear at Startup": "启动时清除"
|
||||
},
|
||||
"Click 'Setup' to create %1 and add include to config.": {
|
||||
"Click 'Setup' to create %1 and add include to config.": ""
|
||||
"Click 'Setup' to create %1 and add include to config.": "点击设置以创建%1并将其包含至配置文件。"
|
||||
},
|
||||
"Click 'Setup' to create cursor config and add include to your compositor config.": {
|
||||
"Click 'Setup' to create cursor config and add include to your compositor config.": "点击设置以创建光标配置,并导入至合成器配置文件。"
|
||||
@@ -722,8 +728,11 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "点击导入添加 .ovpn 或 .conf 文件"
|
||||
},
|
||||
"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 dms/binds.kdl": {
|
||||
"Click any shortcut to edit. Changes save to dms/binds.kdl": "点击任意快捷方式进行编辑。更改将保存到 dms/binds.kdl"
|
||||
@@ -1653,7 +1662,7 @@
|
||||
"Fixing...": "正在修复..."
|
||||
},
|
||||
"Flags": {
|
||||
"Flags": ""
|
||||
"Flags": "标签"
|
||||
},
|
||||
"Flipped": {
|
||||
"Flipped": "翻转"
|
||||
@@ -1671,16 +1680,16 @@
|
||||
"Focus at Startup": "启动时聚焦"
|
||||
},
|
||||
"Focused Border": {
|
||||
"Focused Border": ""
|
||||
"Focused Border": "聚焦边框"
|
||||
},
|
||||
"Focused Color": {
|
||||
"Focused Color": ""
|
||||
"Focused Color": "聚焦颜色"
|
||||
},
|
||||
"Focused Window": {
|
||||
"Focused Window": "当前窗口"
|
||||
},
|
||||
"Follow Monitor Focus": {
|
||||
"Follow Monitor Focus": ""
|
||||
"Follow Monitor Focus": "遵守显示器聚焦"
|
||||
},
|
||||
"Follow focus": {
|
||||
"Follow focus": "跟随焦点"
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "网格列"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": "分组工作区应用"
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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 repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": "在不聚焦的工作区中将重复应用图标分组"
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR(EDID)"
|
||||
},
|
||||
@@ -1827,7 +1845,7 @@
|
||||
"Hibernate": "休眠"
|
||||
},
|
||||
"Hidden": {
|
||||
"Hidden": ""
|
||||
"Hidden": "已隐藏"
|
||||
},
|
||||
"Hidden Network": {
|
||||
"Hidden Network": "隐藏的网络"
|
||||
@@ -2148,7 +2166,7 @@
|
||||
"Lock fade grace period": "锁定淡出时间"
|
||||
},
|
||||
"Locked": {
|
||||
"Locked": ""
|
||||
"Locked": "已锁定"
|
||||
},
|
||||
"Log Out": {
|
||||
"Log Out": "注销"
|
||||
@@ -2160,7 +2178,7 @@
|
||||
"Long Text": "长文本"
|
||||
},
|
||||
"Long press": {
|
||||
"Long press": ""
|
||||
"Long press": "长按"
|
||||
},
|
||||
"Longitude": {
|
||||
"Longitude": "经度"
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"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": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "边距"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "纽约,美国纽约州"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "下一过渡"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "选项"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "其他"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "密码"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "暂停"
|
||||
},
|
||||
@@ -2967,7 +2997,7 @@
|
||||
"Reject Jobs": "拒绝任务"
|
||||
},
|
||||
"Release": {
|
||||
"Release": ""
|
||||
"Release": "松开"
|
||||
},
|
||||
"Reload Plugin": {
|
||||
"Reload Plugin": "重载插件"
|
||||
@@ -2979,7 +3009,10 @@
|
||||
"Remove gaps and border when windows are maximized": "当窗口最大化时移除间距和边框"
|
||||
},
|
||||
"Repeat": {
|
||||
"Repeat": ""
|
||||
"Repeat": "重复"
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "报告"
|
||||
@@ -3396,7 +3429,7 @@
|
||||
"Show all 9 tags instead of only occupied tags (DWL only)": "显示所有 9 个标签,而非仅占用的标签(仅限 DWL)"
|
||||
},
|
||||
"Show an outline ring around the focused workspace indicator": {
|
||||
"Show an outline ring around the focused workspace indicator": ""
|
||||
"Show an outline ring around the focused workspace indicator": "在聚焦工作区指示器周围显示一个轮廓环"
|
||||
},
|
||||
"Show cava audio visualizer in media widget": {
|
||||
"Show cava audio visualizer in media widget": "在多媒体部件中显示cava音频可视化"
|
||||
@@ -3468,7 +3501,7 @@
|
||||
"Show workspace name on horizontal bars, and first letter on vertical bars": "在水平状态栏上显示工作区名称,而在垂直状态栏上显示首字母。"
|
||||
},
|
||||
"Show workspaces of the currently focused monitor": {
|
||||
"Show workspaces of the currently focused monitor": ""
|
||||
"Show workspaces of the currently focused monitor": "显示当前聚焦显示器的工作区"
|
||||
},
|
||||
"Shows all running applications with focus indication": {
|
||||
"Shows all running applications with focus indication": "显示所有正在运行应用程序,并标记焦点所在"
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "同步系统深色模式"
|
||||
},
|
||||
"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": "随系统设置开启深色模式,以适配全局主题"
|
||||
},
|
||||
@@ -3837,7 +3873,10 @@
|
||||
"Unavailable": "不可用"
|
||||
},
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
"Unfocused Color": "未聚焦颜色"
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "卸载插件"
|
||||
@@ -3882,7 +3921,7 @@
|
||||
"Update Plugin": "更新插件"
|
||||
},
|
||||
"Urgent Color": {
|
||||
"Urgent Color": ""
|
||||
"Urgent Color": "高亮颜色"
|
||||
},
|
||||
"Usage Tips": {
|
||||
"Usage Tips": "使用提示"
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "使用浅色主题替代深色主题"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"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 trigger prefix to activate": {
|
||||
"Use trigger prefix to activate": "使用触发前缀以激活"
|
||||
},
|
||||
@@ -4178,7 +4223,7 @@
|
||||
"Workspace": "工作区"
|
||||
},
|
||||
"Workspace Appearance": {
|
||||
"Workspace Appearance": ""
|
||||
"Workspace Appearance": "工作区外观"
|
||||
},
|
||||
"Workspace Index Numbers": {
|
||||
"Workspace Index Numbers": "工作区序号"
|
||||
@@ -4367,7 +4412,7 @@
|
||||
"Night mode & gamma": "夜间模式与伽玛",
|
||||
"Per-screen config": "按屏幕区分设置",
|
||||
"Quick system toggles": "快速系统切换",
|
||||
"Security & privacy": ""
|
||||
"Security & privacy": "安全与隐私"
|
||||
},
|
||||
"greeter feature card title": {
|
||||
"App Theming": "应用主题",
|
||||
@@ -4631,7 +4676,7 @@
|
||||
"update dms for NM integration.": "更新 DMS 以集成 NM"
|
||||
},
|
||||
"version requirement": {
|
||||
"Requires %1": ""
|
||||
"Requires %1": "需要%1"
|
||||
},
|
||||
"wallpaper directory file browser title": {
|
||||
"Select Wallpaper Directory": "选择壁纸位置"
|
||||
|
||||
@@ -239,6 +239,9 @@
|
||||
"All displays": {
|
||||
"All displays": "所有螢幕"
|
||||
},
|
||||
"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: 返回 • F1/I: 檔案資訊 • F10: 幫助 • Esc: 關閉"
|
||||
},
|
||||
@@ -275,6 +278,9 @@
|
||||
"Anonymous Identity (optional)": {
|
||||
"Anonymous Identity (optional)": "匿名身分 (可選)"
|
||||
},
|
||||
"App ID Substitutions": {
|
||||
"App ID Substitutions": ""
|
||||
},
|
||||
"App Launcher": {
|
||||
"App Launcher": "應用程式啟動器"
|
||||
},
|
||||
@@ -722,6 +728,9 @@
|
||||
"Click Import to add a .ovpn or .conf": {
|
||||
"Click Import to add a .ovpn or .conf": "點擊匯入以新增 .ovpn 或 .conf"
|
||||
},
|
||||
"Click Through": {
|
||||
"Click Through": ""
|
||||
},
|
||||
"Click any shortcut to edit. Changes save to %1": {
|
||||
"Click any shortcut to edit. Changes save to %1": "點擊任一快捷鍵進行編輯。變更會儲存到 %1"
|
||||
},
|
||||
@@ -1787,6 +1796,9 @@
|
||||
"Grid Columns": {
|
||||
"Grid Columns": "網格欄數"
|
||||
},
|
||||
"Group": {
|
||||
"Group": ""
|
||||
},
|
||||
"Group Workspace Apps": {
|
||||
"Group Workspace Apps": "群組工作區應用程式"
|
||||
},
|
||||
@@ -1796,9 +1808,15 @@
|
||||
"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 repeated application icons in unfocused workspaces": {
|
||||
"Group repeated application icons in unfocused workspaces": "群組非作用中工作區的重複應用程式圖示"
|
||||
},
|
||||
"Groups": {
|
||||
"Groups": ""
|
||||
},
|
||||
"HDR (EDID)": {
|
||||
"HDR (EDID)": "HDR (EDID)"
|
||||
},
|
||||
@@ -2195,6 +2213,9 @@
|
||||
"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": ""
|
||||
},
|
||||
"Margin": {
|
||||
"Margin": "邊距"
|
||||
},
|
||||
@@ -2417,6 +2438,9 @@
|
||||
"New York, NY": {
|
||||
"New York, NY": "紐約"
|
||||
},
|
||||
"New group name...": {
|
||||
"New group name...": ""
|
||||
},
|
||||
"Next Transition": {
|
||||
"Next Transition": "下一個轉場"
|
||||
},
|
||||
@@ -2648,6 +2672,9 @@
|
||||
"Options": {
|
||||
"Options": "選項"
|
||||
},
|
||||
"Organize widgets into collapsible groups": {
|
||||
"Organize widgets into collapsible groups": ""
|
||||
},
|
||||
"Other": {
|
||||
"Other": "其他"
|
||||
},
|
||||
@@ -2720,6 +2747,9 @@
|
||||
"Password": {
|
||||
"Password": "密碼"
|
||||
},
|
||||
"Pattern": {
|
||||
"Pattern": ""
|
||||
},
|
||||
"Pause": {
|
||||
"Pause": "暫停"
|
||||
},
|
||||
@@ -2981,6 +3011,9 @@
|
||||
"Repeat": {
|
||||
"Repeat": "重複"
|
||||
},
|
||||
"Replacement": {
|
||||
"Replacement": ""
|
||||
},
|
||||
"Report": {
|
||||
"Report": "報告"
|
||||
},
|
||||
@@ -3614,6 +3647,9 @@
|
||||
"Sync Mode with Portal": {
|
||||
"Sync Mode with Portal": "透過 Portal 同步主題模式"
|
||||
},
|
||||
"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": "將暗模式與設定入口網站同步以取得系統範圍的主題提示"
|
||||
},
|
||||
@@ -3839,6 +3875,9 @@
|
||||
"Unfocused Color": {
|
||||
"Unfocused Color": ""
|
||||
},
|
||||
"Ungrouped": {
|
||||
"Ungrouped": ""
|
||||
},
|
||||
"Uninstall Plugin": {
|
||||
"Uninstall Plugin": "解除安裝插件"
|
||||
},
|
||||
@@ -3938,9 +3977,15 @@
|
||||
"Use light theme instead of dark theme": {
|
||||
"Use light theme instead of dark theme": "使用淺色主題而不是深色主題"
|
||||
},
|
||||
"Use smaller notification cards": {
|
||||
"Use smaller notification cards": ""
|
||||
},
|
||||
"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 trigger prefix to activate": {
|
||||
"Use trigger prefix to activate": "使用觸發前綴啟用"
|
||||
},
|
||||
|
||||
@@ -295,6 +295,20 @@
|
||||
],
|
||||
"description": "Set different wallpapers for each connected monitor"
|
||||
},
|
||||
{
|
||||
"section": "_tab_0",
|
||||
"label": "Personalization",
|
||||
"tabIndex": 0,
|
||||
"category": "Personalization",
|
||||
"keywords": [
|
||||
"appearance",
|
||||
"custom",
|
||||
"customize",
|
||||
"personal",
|
||||
"personalization"
|
||||
],
|
||||
"icon": "palette"
|
||||
},
|
||||
{
|
||||
"section": "wallpaperTransition",
|
||||
"label": "Transition Effect",
|
||||
@@ -494,6 +508,22 @@
|
||||
],
|
||||
"description": "Display seconds in the clock"
|
||||
},
|
||||
{
|
||||
"section": "_tab_1",
|
||||
"label": "Time & Weather",
|
||||
"tabIndex": 1,
|
||||
"category": "Time & Weather",
|
||||
"keywords": [
|
||||
"climate",
|
||||
"clock",
|
||||
"date",
|
||||
"forecast",
|
||||
"temperature",
|
||||
"time",
|
||||
"weather"
|
||||
],
|
||||
"icon": "schedule"
|
||||
},
|
||||
{
|
||||
"section": "timeFormat",
|
||||
"label": "Time Format",
|
||||
@@ -576,6 +606,23 @@
|
||||
"icon": "cloud",
|
||||
"description": "Show weather information in top bar and control center"
|
||||
},
|
||||
{
|
||||
"section": "_tab_2",
|
||||
"label": "Keyboard Shortcuts",
|
||||
"tabIndex": 2,
|
||||
"category": "Keyboard Shortcuts",
|
||||
"keywords": [
|
||||
"bindings",
|
||||
"hotkey",
|
||||
"hotkeys",
|
||||
"keybinds",
|
||||
"keyboard",
|
||||
"keys",
|
||||
"shortcuts"
|
||||
],
|
||||
"icon": "keyboard",
|
||||
"conditionKey": "keybindsAvailable"
|
||||
},
|
||||
{
|
||||
"section": "barConfigurations",
|
||||
"label": "Bar Configurations",
|
||||
@@ -614,6 +661,21 @@
|
||||
],
|
||||
"icon": "rounded_corner"
|
||||
},
|
||||
{
|
||||
"section": "_tab_3",
|
||||
"label": "Dank Bar",
|
||||
"tabIndex": 3,
|
||||
"category": "Dank Bar",
|
||||
"keywords": [
|
||||
"bar",
|
||||
"dank",
|
||||
"panel",
|
||||
"statusbar",
|
||||
"taskbar",
|
||||
"topbar"
|
||||
],
|
||||
"icon": "toolbar"
|
||||
},
|
||||
{
|
||||
"section": "barDisplay",
|
||||
"label": "Display Assignment",
|
||||
@@ -1022,6 +1084,25 @@
|
||||
"description": "Show workspace index numbers in the top bar workspace switcher",
|
||||
"conditionKey": "isNiri"
|
||||
},
|
||||
{
|
||||
"section": "_tab_4",
|
||||
"label": "Workspaces & Widgets",
|
||||
"tabIndex": 4,
|
||||
"category": "Workspaces",
|
||||
"keywords": [
|
||||
"components",
|
||||
"desktop",
|
||||
"desktops",
|
||||
"modules",
|
||||
"spaces",
|
||||
"virtual",
|
||||
"virtual desktops",
|
||||
"widgets",
|
||||
"workspace",
|
||||
"workspaces"
|
||||
],
|
||||
"icon": "dashboard"
|
||||
},
|
||||
{
|
||||
"section": "dockAutoHide",
|
||||
"label": "Auto-hide Dock",
|
||||
@@ -1080,6 +1161,24 @@
|
||||
"icon": "border_style",
|
||||
"description": "Add a border around the dock"
|
||||
},
|
||||
{
|
||||
"section": "_tab_5",
|
||||
"label": "Dock & Launcher",
|
||||
"tabIndex": 5,
|
||||
"category": "Dock",
|
||||
"keywords": [
|
||||
"app drawer",
|
||||
"app menu",
|
||||
"applications",
|
||||
"dock",
|
||||
"launcher",
|
||||
"launcher bar",
|
||||
"panel",
|
||||
"start menu",
|
||||
"taskbar"
|
||||
],
|
||||
"icon": "apps"
|
||||
},
|
||||
{
|
||||
"section": "dockPosition",
|
||||
"label": "Dock Position",
|
||||
@@ -1297,6 +1396,38 @@
|
||||
],
|
||||
"icon": "opacity"
|
||||
},
|
||||
{
|
||||
"section": "_tab_7",
|
||||
"label": "Network",
|
||||
"tabIndex": 7,
|
||||
"category": "Network",
|
||||
"keywords": [
|
||||
"connection",
|
||||
"connectivity",
|
||||
"ethernet",
|
||||
"internet",
|
||||
"network",
|
||||
"online",
|
||||
"wi-fi",
|
||||
"wifi",
|
||||
"wireless"
|
||||
],
|
||||
"icon": "wifi",
|
||||
"conditionKey": "dmsConnected"
|
||||
},
|
||||
{
|
||||
"section": "_tab_8",
|
||||
"label": "System",
|
||||
"tabIndex": 8,
|
||||
"category": "System",
|
||||
"keywords": [
|
||||
"linux",
|
||||
"os",
|
||||
"system"
|
||||
],
|
||||
"icon": "computer",
|
||||
"conditionKey": "cupsAvailable"
|
||||
},
|
||||
{
|
||||
"section": "launcherLogoBrightness",
|
||||
"label": "Brightness",
|
||||
@@ -1421,6 +1552,23 @@
|
||||
],
|
||||
"icon": "terminal"
|
||||
},
|
||||
{
|
||||
"section": "_tab_9",
|
||||
"label": "Launcher",
|
||||
"tabIndex": 9,
|
||||
"category": "Launcher",
|
||||
"keywords": [
|
||||
"app drawer",
|
||||
"app menu",
|
||||
"applications",
|
||||
"drawer",
|
||||
"launcher",
|
||||
"menu",
|
||||
"start",
|
||||
"start menu"
|
||||
],
|
||||
"icon": "grid_view"
|
||||
},
|
||||
{
|
||||
"section": "launcherLogo",
|
||||
"label": "Launcher Button Logo",
|
||||
@@ -2531,6 +2679,26 @@
|
||||
],
|
||||
"description": "Force terminal applications to always use dark color schemes"
|
||||
},
|
||||
{
|
||||
"section": "_tab_10",
|
||||
"label": "Theme & Colors",
|
||||
"tabIndex": 10,
|
||||
"category": "Theme & Colors",
|
||||
"keywords": [
|
||||
"appearance",
|
||||
"colors",
|
||||
"colour",
|
||||
"colours",
|
||||
"hue",
|
||||
"look",
|
||||
"palette",
|
||||
"scheme",
|
||||
"style",
|
||||
"theme",
|
||||
"tint"
|
||||
],
|
||||
"icon": "format_paint"
|
||||
},
|
||||
{
|
||||
"section": "themeColor",
|
||||
"label": "Theme Color",
|
||||
@@ -3180,6 +3348,27 @@
|
||||
],
|
||||
"description": "Control what notification information is shown on the lock screen"
|
||||
},
|
||||
{
|
||||
"section": "_tab_11",
|
||||
"label": "Power & Security",
|
||||
"tabIndex": 11,
|
||||
"category": "Lock Screen",
|
||||
"keywords": [
|
||||
"hibernate",
|
||||
"lock",
|
||||
"login",
|
||||
"password",
|
||||
"power",
|
||||
"reboot",
|
||||
"restart",
|
||||
"screen",
|
||||
"security",
|
||||
"shutdown",
|
||||
"sleep",
|
||||
"suspend"
|
||||
],
|
||||
"icon": "security"
|
||||
},
|
||||
{
|
||||
"section": "lockScreenShowPasswordField",
|
||||
"label": "Show Password Field",
|
||||
@@ -3295,6 +3484,35 @@
|
||||
"time"
|
||||
]
|
||||
},
|
||||
{
|
||||
"section": "_tab_12",
|
||||
"label": "Plugins",
|
||||
"tabIndex": 12,
|
||||
"category": "Plugins",
|
||||
"keywords": [
|
||||
"addon",
|
||||
"addons",
|
||||
"extend",
|
||||
"extensions",
|
||||
"plugins",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "extension"
|
||||
},
|
||||
{
|
||||
"section": "_tab_13",
|
||||
"label": "About",
|
||||
"tabIndex": 13,
|
||||
"category": "About",
|
||||
"keywords": [
|
||||
"about",
|
||||
"credits",
|
||||
"help",
|
||||
"info",
|
||||
"version"
|
||||
],
|
||||
"icon": "info"
|
||||
},
|
||||
{
|
||||
"section": "animationSpeed",
|
||||
"label": "Animation Speed",
|
||||
@@ -3449,6 +3667,22 @@
|
||||
"icon": "text_fields",
|
||||
"description": "Select the font family for UI text"
|
||||
},
|
||||
{
|
||||
"section": "_tab_14",
|
||||
"label": "Typography & Motion",
|
||||
"tabIndex": 14,
|
||||
"category": "Typography & Motion",
|
||||
"keywords": [
|
||||
"animation",
|
||||
"font",
|
||||
"fonts",
|
||||
"motion",
|
||||
"text",
|
||||
"typeface",
|
||||
"typography"
|
||||
],
|
||||
"icon": "text_fields"
|
||||
},
|
||||
{
|
||||
"section": "soundsEnabled",
|
||||
"label": "Enable System Sounds",
|
||||
@@ -3534,6 +3768,20 @@
|
||||
],
|
||||
"description": "Select system sound theme"
|
||||
},
|
||||
{
|
||||
"section": "_tab_15",
|
||||
"label": "Sounds",
|
||||
"tabIndex": 15,
|
||||
"category": "Sounds",
|
||||
"keywords": [
|
||||
"audio",
|
||||
"effects",
|
||||
"sfx",
|
||||
"sounds"
|
||||
],
|
||||
"icon": "volume_up",
|
||||
"conditionKey": "soundsAvailable"
|
||||
},
|
||||
{
|
||||
"section": "systemSounds",
|
||||
"label": "System Sounds",
|
||||
@@ -3596,6 +3844,22 @@
|
||||
],
|
||||
"description": "Play sound when volume is adjusted"
|
||||
},
|
||||
{
|
||||
"section": "_tab_16",
|
||||
"label": "Media Player",
|
||||
"tabIndex": 16,
|
||||
"category": "Media Player",
|
||||
"keywords": [
|
||||
"audio",
|
||||
"media",
|
||||
"mpris",
|
||||
"music",
|
||||
"playback",
|
||||
"player",
|
||||
"spotify"
|
||||
],
|
||||
"icon": "music_note"
|
||||
},
|
||||
{
|
||||
"section": "mediaPlayer",
|
||||
"label": "Media Player Settings",
|
||||
@@ -3641,6 +3905,28 @@
|
||||
],
|
||||
"description": "Scroll wheel behavior on media widget"
|
||||
},
|
||||
{
|
||||
"section": "notificationCompactMode",
|
||||
"label": "Compact",
|
||||
"tabIndex": 17,
|
||||
"category": "Notifications",
|
||||
"keywords": [
|
||||
"alert",
|
||||
"alerts",
|
||||
"cards",
|
||||
"compact",
|
||||
"display",
|
||||
"messages",
|
||||
"mode",
|
||||
"notif",
|
||||
"notification",
|
||||
"notifications",
|
||||
"size",
|
||||
"smaller",
|
||||
"toast"
|
||||
],
|
||||
"description": "Use smaller notification cards"
|
||||
},
|
||||
{
|
||||
"section": "notificationHistorySaveCritical",
|
||||
"label": "Critical Priority",
|
||||
@@ -3989,6 +4275,22 @@
|
||||
"icon": "timer",
|
||||
"description": "Timeout for low priority notifications"
|
||||
},
|
||||
{
|
||||
"section": "_tab_17",
|
||||
"label": "Notifications",
|
||||
"tabIndex": 17,
|
||||
"category": "Notifications",
|
||||
"keywords": [
|
||||
"alert",
|
||||
"alerts",
|
||||
"messages",
|
||||
"notif",
|
||||
"notifications",
|
||||
"notifs",
|
||||
"toast"
|
||||
],
|
||||
"icon": "notifications"
|
||||
},
|
||||
{
|
||||
"section": "notificationPopupPosition",
|
||||
"label": "Popup Position",
|
||||
@@ -4013,6 +4315,25 @@
|
||||
],
|
||||
"description": "Choose where notification popups appear on screen"
|
||||
},
|
||||
{
|
||||
"section": "_tab_18",
|
||||
"label": "On-screen Displays",
|
||||
"tabIndex": 18,
|
||||
"category": "On-screen Displays",
|
||||
"keywords": [
|
||||
"displays",
|
||||
"indicator",
|
||||
"monitor",
|
||||
"monitors",
|
||||
"osd",
|
||||
"output",
|
||||
"outputs",
|
||||
"popup",
|
||||
"screen",
|
||||
"screens"
|
||||
],
|
||||
"icon": "tune"
|
||||
},
|
||||
{
|
||||
"section": "osd",
|
||||
"label": "On-screen Displays",
|
||||
@@ -4036,6 +4357,46 @@
|
||||
"icon": "tune",
|
||||
"description": "Choose where on-screen displays appear on screen"
|
||||
},
|
||||
{
|
||||
"section": "appIdSubstitutions",
|
||||
"label": "App ID Substitutions",
|
||||
"tabIndex": 19,
|
||||
"category": "Running Apps",
|
||||
"keywords": [
|
||||
"active",
|
||||
"app",
|
||||
"apps",
|
||||
"class",
|
||||
"icon",
|
||||
"pattern",
|
||||
"regex",
|
||||
"replacement",
|
||||
"running",
|
||||
"substitution",
|
||||
"substitutions",
|
||||
"tasks",
|
||||
"window",
|
||||
"windows"
|
||||
],
|
||||
"icon": "find_replace"
|
||||
},
|
||||
{
|
||||
"section": "_tab_19",
|
||||
"label": "Running Apps",
|
||||
"tabIndex": 19,
|
||||
"category": "Running Apps",
|
||||
"keywords": [
|
||||
"active",
|
||||
"apps",
|
||||
"open",
|
||||
"running",
|
||||
"taskbar",
|
||||
"tasks",
|
||||
"windows"
|
||||
],
|
||||
"icon": "apps",
|
||||
"conditionKey": "isHyprlandOrNiri"
|
||||
},
|
||||
{
|
||||
"section": "runningApps",
|
||||
"label": "Running Apps Settings",
|
||||
@@ -4059,6 +4420,20 @@
|
||||
"icon": "apps",
|
||||
"description": "Show only apps running in current workspace"
|
||||
},
|
||||
{
|
||||
"section": "_tab_20",
|
||||
"label": "System Updater",
|
||||
"tabIndex": 20,
|
||||
"category": "System Updater",
|
||||
"keywords": [
|
||||
"packages",
|
||||
"system",
|
||||
"updater",
|
||||
"updates",
|
||||
"upgrade"
|
||||
],
|
||||
"icon": "refresh"
|
||||
},
|
||||
{
|
||||
"section": "systemUpdater",
|
||||
"label": "System Updater",
|
||||
@@ -4369,6 +4744,23 @@
|
||||
"timeout"
|
||||
]
|
||||
},
|
||||
{
|
||||
"section": "_tab_21",
|
||||
"label": "Power & Sleep",
|
||||
"tabIndex": 21,
|
||||
"category": "Power & Sleep",
|
||||
"keywords": [
|
||||
"energy",
|
||||
"hibernate",
|
||||
"power",
|
||||
"reboot",
|
||||
"restart",
|
||||
"shutdown",
|
||||
"sleep",
|
||||
"suspend"
|
||||
],
|
||||
"icon": "power_settings_new"
|
||||
},
|
||||
{
|
||||
"section": "powerConfirmation",
|
||||
"label": "Power Action Confirmation",
|
||||
@@ -4511,6 +4903,23 @@
|
||||
],
|
||||
"description": "Display power menu actions in a grid instead of a list"
|
||||
},
|
||||
{
|
||||
"section": "_tab_22",
|
||||
"label": "Widgets",
|
||||
"tabIndex": 22,
|
||||
"category": "Dank Bar",
|
||||
"keywords": [
|
||||
"bar",
|
||||
"components",
|
||||
"dank",
|
||||
"modules",
|
||||
"panel",
|
||||
"statusbar",
|
||||
"topbar",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "widgets"
|
||||
},
|
||||
{
|
||||
"section": "disabled",
|
||||
"label": "Advanced",
|
||||
@@ -4575,6 +4984,24 @@
|
||||
"icon": "settings",
|
||||
"description": "Clear all history when server starts"
|
||||
},
|
||||
{
|
||||
"section": "_tab_23",
|
||||
"label": "Clipboard",
|
||||
"tabIndex": 23,
|
||||
"category": "System",
|
||||
"keywords": [
|
||||
"clipboard",
|
||||
"cliphist",
|
||||
"copy",
|
||||
"history",
|
||||
"linux",
|
||||
"os",
|
||||
"paste",
|
||||
"system"
|
||||
],
|
||||
"icon": "content_paste",
|
||||
"conditionKey": "dmsConnected"
|
||||
},
|
||||
{
|
||||
"section": "maxHistory",
|
||||
"label": "History Settings",
|
||||
@@ -4620,6 +5047,23 @@
|
||||
],
|
||||
"description": "Maximum size per clipboard entry"
|
||||
},
|
||||
{
|
||||
"section": "_tab_24",
|
||||
"label": "Displays",
|
||||
"tabIndex": 24,
|
||||
"category": "Displays",
|
||||
"keywords": [
|
||||
"displays",
|
||||
"monitor",
|
||||
"monitors",
|
||||
"output",
|
||||
"outputs",
|
||||
"resolution",
|
||||
"screen",
|
||||
"screens"
|
||||
],
|
||||
"icon": "monitor"
|
||||
},
|
||||
{
|
||||
"section": "nightModeHighTemperature",
|
||||
"label": "Day Temperature",
|
||||
@@ -4645,6 +5089,25 @@
|
||||
],
|
||||
"description": "Color temperature for day time"
|
||||
},
|
||||
{
|
||||
"section": "_tab_25",
|
||||
"label": "Gamma Control",
|
||||
"tabIndex": 25,
|
||||
"category": "Displays",
|
||||
"keywords": [
|
||||
"blue light",
|
||||
"color temperature",
|
||||
"control",
|
||||
"displays",
|
||||
"gamma",
|
||||
"monitor",
|
||||
"night light",
|
||||
"redshift",
|
||||
"resolution",
|
||||
"screen"
|
||||
],
|
||||
"icon": "brightness_6"
|
||||
},
|
||||
{
|
||||
"section": "nightModeTemperature",
|
||||
"label": "Night Temperature",
|
||||
@@ -4671,5 +5134,36 @@
|
||||
"warm"
|
||||
],
|
||||
"description": "Color temperature for night mode"
|
||||
},
|
||||
{
|
||||
"section": "_tab_26",
|
||||
"label": "Widgets",
|
||||
"tabIndex": 26,
|
||||
"category": "Displays",
|
||||
"keywords": [
|
||||
"components",
|
||||
"displays",
|
||||
"modules",
|
||||
"monitor",
|
||||
"resolution",
|
||||
"screen",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "widgets"
|
||||
},
|
||||
{
|
||||
"section": "_tab_27",
|
||||
"label": "Desktop Widgets",
|
||||
"tabIndex": 27,
|
||||
"category": "Desktop Widgets",
|
||||
"keywords": [
|
||||
"components",
|
||||
"conky",
|
||||
"desktop",
|
||||
"desktop clock",
|
||||
"modules",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "widgets"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -580,6 +580,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Allow clicks to pass through the widget",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close",
|
||||
"translation": "",
|
||||
@@ -678,6 +685,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "App ID Substitutions",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "App Launcher",
|
||||
"translation": "",
|
||||
@@ -1756,6 +1770,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Click Through",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Click any shortcut to edit. Changes save to %1",
|
||||
"translation": "",
|
||||
@@ -4381,6 +4402,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Group",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Group Workspace Apps",
|
||||
"translation": "",
|
||||
@@ -4402,6 +4430,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Group removed",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Group repeated application icons in unfocused workspaces",
|
||||
"translation": "",
|
||||
@@ -4409,6 +4444,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Groups",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "HDR (EDID)",
|
||||
"translation": "",
|
||||
@@ -5452,6 +5494,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Map window class names to icon names for proper icon display",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Margin",
|
||||
"translation": "",
|
||||
@@ -6012,6 +6061,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "New group name...",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Next",
|
||||
"translation": "",
|
||||
@@ -6642,6 +6698,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Organize widgets into collapsible groups",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Other",
|
||||
"translation": "",
|
||||
@@ -6810,6 +6873,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Pattern",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Pause",
|
||||
"translation": "",
|
||||
@@ -7440,6 +7510,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Replacement",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Report",
|
||||
"translation": "",
|
||||
@@ -8686,13 +8763,6 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show password",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show weather information in top bar and control center",
|
||||
"translation": "",
|
||||
@@ -9071,6 +9141,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Sync Position Across Screens",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Sync dark mode with settings portals for system-wide theme hints",
|
||||
"translation": "",
|
||||
@@ -9610,6 +9687,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Ungrouped",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Uninstall",
|
||||
"translation": "",
|
||||
@@ -9876,6 +9960,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Use smaller notification cards",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Use sound theme from system settings",
|
||||
"translation": "",
|
||||
@@ -9883,6 +9974,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Use the same position and size on all displays",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Use trigger prefix to activate",
|
||||
"translation": "",
|
||||
|
||||
Reference in New Issue
Block a user