mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6013c994a6 | ||
|
|
46c90628b9 | ||
|
|
d2d2dac5d1 | ||
|
|
fd3e7470f4 | ||
|
|
b79e9f72ce | ||
|
|
77eb5dd3bf | ||
|
|
b17c14a07b | ||
|
|
494d90be22 | ||
|
|
da7e599e65 | ||
|
|
e3b7360f39 | ||
|
|
367130882d | ||
|
|
d8563ba79d | ||
|
|
e527453964 | ||
|
|
88fe3c5fbd | ||
|
|
748faf92c1 | ||
|
|
0126aded78 | ||
|
|
695a75ea09 | ||
|
|
80e690f9fc | ||
|
|
e8770b90ef | ||
|
|
eec9da42bf | ||
|
|
1c8f0d6292 | ||
|
|
b753c8840b | ||
|
|
95589982a5 | ||
|
|
37a10bd453 | ||
|
|
7abc76e92c | ||
|
|
7aa4467bda | ||
|
|
471938adb6 | ||
|
|
201a7e3b34 | ||
|
|
11ec3723c3 | ||
|
|
75eb736856 | ||
|
|
8fea126c20 | ||
|
|
cc02d09c4d | ||
|
|
af95631a1d | ||
|
|
7b3d2ab85a | ||
|
|
c52df96af9 | ||
|
|
dee5fa60af | ||
|
|
5e99fdd9c9 | ||
|
|
eb01fe757b | ||
|
|
c52483da2c |
15
.github/workflows/copr-release.yml
vendored
15
.github/workflows/copr-release.yml
vendored
@@ -79,7 +79,7 @@ jobs:
|
||||
Release: 1%{?dist}
|
||||
Summary: %{pkg_summary}
|
||||
|
||||
License: GPL-3.0-only
|
||||
License: MIT
|
||||
URL: https://github.com/AvengeMedia/DankMaterialShell
|
||||
|
||||
Source0: dms-qml.tar.gz
|
||||
@@ -114,7 +114,7 @@ jobs:
|
||||
|
||||
%package -n dms-cli
|
||||
Summary: DankMaterialShell CLI tool
|
||||
License: GPL-3.0-only
|
||||
License: MIT
|
||||
URL: https://github.com/AvengeMedia/danklinux
|
||||
|
||||
%description -n dms-cli
|
||||
@@ -172,6 +172,14 @@ jobs:
|
||||
install -Dm755 %{_builddir}/dms-cli %{buildroot}%{_bindir}/dms
|
||||
install -Dm755 %{_builddir}/dgop %{buildroot}%{_bindir}/dgop
|
||||
|
||||
# Shell completions
|
||||
install -d %{buildroot}%{_datadir}/bash-completion/completions
|
||||
install -d %{buildroot}%{_datadir}/zsh/site-functions
|
||||
install -d %{buildroot}%{_datadir}/fish/vendor_completions.d
|
||||
%{_builddir}/dms-cli completion bash > %{buildroot}%{_datadir}/bash-completion/completions/dms || :
|
||||
%{_builddir}/dms-cli completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || :
|
||||
%{_builddir}/dms-cli completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || :
|
||||
|
||||
install -Dm644 %{_builddir}/dms-qml/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service
|
||||
|
||||
install -dm755 %{buildroot}%{_datadir}/quickshell/dms
|
||||
@@ -204,6 +212,9 @@ jobs:
|
||||
|
||||
%files -n dms-cli
|
||||
%{_bindir}/dms
|
||||
%{_datadir}/bash-completion/completions/dms
|
||||
%{_datadir}/zsh/site-functions/_dms
|
||||
%{_datadir}/fish/vendor_completions.d/dms.fish
|
||||
|
||||
%files -n dgop
|
||||
%{_bindir}/dgop
|
||||
|
||||
34
.github/workflows/release.yml
vendored
34
.github/workflows/release.yml
vendored
@@ -58,8 +58,8 @@ jobs:
|
||||
## Assets
|
||||
|
||||
### Complete Packages
|
||||
- **`dms-full-amd64.tar.gz`** - Complete package for x86_64 systems (CLI binaries + QML source + installation guide)
|
||||
- **`dms-full-arm64.tar.gz`** - Complete package for ARM64 systems (CLI binaries + QML source + installation guide)
|
||||
- **`dms-full-amd64.tar.gz`** - Complete package for x86_64 systems (CLI binaries + QML source + shell completions + installation guide)
|
||||
- **`dms-full-arm64.tar.gz`** - Complete package for ARM64 systems (CLI binaries + QML source + shell completions + installation guide)
|
||||
|
||||
### Individual Components
|
||||
- **`dms-cli-amd64.gz`** - DMS CLI binary for x86_64 systems
|
||||
@@ -135,27 +135,28 @@ jobs:
|
||||
# Generate checksum for QML package
|
||||
(cd _release_assets && sha256sum dms-qml.tar.gz > dms-qml.tar.gz.sha256)
|
||||
|
||||
# Create full packages for each architecture
|
||||
for arch in amd64 arm64; do
|
||||
mkdir -p _temp_full/dms
|
||||
mkdir -p _temp_full/bin
|
||||
mkdir -p _temp_full/completions
|
||||
|
||||
# Extract QML source to temp directory
|
||||
tar -xzf _release_assets/dms-qml.tar.gz -C _temp_full/dms
|
||||
|
||||
# Copy CLI binary if it exists
|
||||
if [ -f "_dms_assets/dms-${arch}.gz" ]; then
|
||||
gunzip -c "_dms_assets/dms-${arch}.gz" > _temp_full/bin/dms
|
||||
chmod +x _temp_full/bin/dms
|
||||
fi
|
||||
|
||||
# Copy distropkg binary if it exists
|
||||
if [ -f "_dms_assets/dms-distropkg-${arch}.gz" ]; then
|
||||
gunzip -c "_dms_assets/dms-distropkg-${arch}.gz" > _temp_full/bin/dms-distropkg
|
||||
chmod +x _temp_full/bin/dms-distropkg
|
||||
fi
|
||||
|
||||
# Create INSTALL.md
|
||||
for completion in _dms_assets/completion.*; do
|
||||
if [ -f "$completion" ]; then
|
||||
cp "$completion" _temp_full/completions/
|
||||
fi
|
||||
done
|
||||
cat > _temp_full/INSTALL.md << 'EOF'
|
||||
# DankMaterialShell Installation
|
||||
|
||||
@@ -176,16 +177,23 @@ jobs:
|
||||
2. **Install the DMS CLI binaries:**
|
||||
```bash
|
||||
sudo install -m 755 bin/dms /usr/local/bin/dms
|
||||
# or install to a local directory:
|
||||
mkdir -p ~/.local/bin
|
||||
install -m 755 bin/dms ~/.local/bin/dms
|
||||
```
|
||||
|
||||
3. **Start the shell:**
|
||||
3. **Install shell completions (optional):**
|
||||
```bash
|
||||
# Bash
|
||||
sudo install -m 644 completions/completion.bash /usr/share/bash-completion/completions/dms
|
||||
|
||||
# Fish
|
||||
sudo install -m 644 completions/completion.fish /usr/share/fish/vendor_completions.d/dms.fish
|
||||
|
||||
# Zsh
|
||||
sudo install -m 644 completions/completion.zsh /usr/share/zsh/site-functions/_dms
|
||||
```
|
||||
|
||||
4. **Start the shell:**
|
||||
```bash
|
||||
dms run
|
||||
# or directly with quickshell (will lack some dbus integrations & plugin management):
|
||||
quickshell -p ~/.config/quickshell/dms
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -53,7 +53,7 @@ Singleton {
|
||||
// ! Spotify and maybe some other apps report the wrong app id in toplevels, hardcode special case
|
||||
function moddedAppId(appId: string): string {
|
||||
if (appId === "Spotify")
|
||||
return "spotify-launcher"
|
||||
return "spotify"
|
||||
if (appId === "beepertexts")
|
||||
return "beeper"
|
||||
if (appId === "home assistant desktop")
|
||||
|
||||
@@ -56,6 +56,7 @@ Singleton {
|
||||
property string nightModeLocationProvider: ""
|
||||
|
||||
property var pinnedApps: []
|
||||
property var hiddenTrayIds: []
|
||||
property var recentColors: []
|
||||
property bool showThirdPartyPlugins: false
|
||||
property string launchPrefix: ""
|
||||
@@ -140,6 +141,7 @@ Singleton {
|
||||
nightModeUseIPLocation = settings.nightModeUseIPLocation !== undefined ? settings.nightModeUseIPLocation : false
|
||||
nightModeLocationProvider = settings.nightModeLocationProvider !== undefined ? settings.nightModeLocationProvider : ""
|
||||
pinnedApps = settings.pinnedApps !== undefined ? settings.pinnedApps : []
|
||||
hiddenTrayIds = settings.hiddenTrayIds !== undefined ? settings.hiddenTrayIds : []
|
||||
selectedGpuIndex = settings.selectedGpuIndex !== undefined ? settings.selectedGpuIndex : 0
|
||||
nvidiaGpuTempEnabled = settings.nvidiaGpuTempEnabled !== undefined ? settings.nvidiaGpuTempEnabled : false
|
||||
nonNvidiaGpuTempEnabled = settings.nonNvidiaGpuTempEnabled !== undefined ? settings.nonNvidiaGpuTempEnabled : false
|
||||
@@ -209,6 +211,7 @@ Singleton {
|
||||
"nightModeUseIPLocation": nightModeUseIPLocation,
|
||||
"nightModeLocationProvider": nightModeLocationProvider,
|
||||
"pinnedApps": pinnedApps,
|
||||
"hiddenTrayIds": hiddenTrayIds,
|
||||
"selectedGpuIndex": selectedGpuIndex,
|
||||
"nvidiaGpuTempEnabled": nvidiaGpuTempEnabled,
|
||||
"nonNvidiaGpuTempEnabled": nonNvidiaGpuTempEnabled,
|
||||
@@ -277,7 +280,7 @@ Singleton {
|
||||
}
|
||||
|
||||
function cleanupUnusedKeys() {
|
||||
const validKeys = ["isLightMode", "wallpaperPath", "perMonitorWallpaper", "monitorWallpapers", "perModeWallpaper", "wallpaperPathLight", "wallpaperPathDark", "monitorWallpapersLight", "monitorWallpapersDark", "doNotDisturb", "nightModeEnabled", "nightModeTemperature", "nightModeHighTemperature", "nightModeAutoEnabled", "nightModeAutoMode", "nightModeStartHour", "nightModeStartMinute", "nightModeEndHour", "nightModeEndMinute", "latitude", "longitude", "nightModeUseIPLocation", "nightModeLocationProvider", "pinnedApps", "selectedGpuIndex", "nvidiaGpuTempEnabled", "nonNvidiaGpuTempEnabled", "enabledGpuPciIds", "wallpaperCyclingEnabled", "wallpaperCyclingMode", "wallpaperCyclingInterval", "wallpaperCyclingTime", "monitorCyclingSettings", "lastBrightnessDevice", "brightnessExponentialDevices", "brightnessUserSetValues", "launchPrefix", "wallpaperTransition", "includedTransitions", "recentColors", "showThirdPartyPlugins", "configVersion"]
|
||||
const validKeys = ["isLightMode", "wallpaperPath", "perMonitorWallpaper", "monitorWallpapers", "perModeWallpaper", "wallpaperPathLight", "wallpaperPathDark", "monitorWallpapersLight", "monitorWallpapersDark", "doNotDisturb", "nightModeEnabled", "nightModeTemperature", "nightModeHighTemperature", "nightModeAutoEnabled", "nightModeAutoMode", "nightModeStartHour", "nightModeStartMinute", "nightModeEndHour", "nightModeEndMinute", "latitude", "longitude", "nightModeUseIPLocation", "nightModeLocationProvider", "pinnedApps", "hiddenTrayIds", "selectedGpuIndex", "nvidiaGpuTempEnabled", "nonNvidiaGpuTempEnabled", "enabledGpuPciIds", "wallpaperCyclingEnabled", "wallpaperCyclingMode", "wallpaperCyclingInterval", "wallpaperCyclingTime", "monitorCyclingSettings", "lastBrightnessDevice", "brightnessExponentialDevices", "brightnessUserSetValues", "brightnessExponentValues", "launchPrefix", "wallpaperTransition", "includedTransitions", "recentColors", "showThirdPartyPlugins", "configVersion"]
|
||||
|
||||
try {
|
||||
const content = settingsFile.text()
|
||||
@@ -639,6 +642,26 @@ Singleton {
|
||||
return appId && pinnedApps.indexOf(appId) !== -1
|
||||
}
|
||||
|
||||
function hideTrayId(trayId) {
|
||||
if (!trayId) return
|
||||
const current = [...hiddenTrayIds]
|
||||
if (current.indexOf(trayId) === -1) {
|
||||
current.push(trayId)
|
||||
hiddenTrayIds = current
|
||||
saveSettings()
|
||||
}
|
||||
}
|
||||
|
||||
function showTrayId(trayId) {
|
||||
if (!trayId) return
|
||||
hiddenTrayIds = hiddenTrayIds.filter(id => id !== trayId)
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function isHiddenTrayId(trayId) {
|
||||
return trayId && hiddenTrayIds.indexOf(trayId) !== -1
|
||||
}
|
||||
|
||||
function addRecentColor(color) {
|
||||
const colorStr = color.toString()
|
||||
let recent = recentColors.slice()
|
||||
|
||||
@@ -292,6 +292,8 @@ Singleton {
|
||||
property bool osdAlwaysShowValue: false
|
||||
|
||||
property bool powerActionConfirm: true
|
||||
property var powerMenuActions: ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]
|
||||
property string powerMenuDefaultAction: "logout"
|
||||
property string customPowerActionLock: ""
|
||||
property string customPowerActionLogout: ""
|
||||
property string customPowerActionSuspend: ""
|
||||
|
||||
@@ -203,6 +203,8 @@ var SPEC = {
|
||||
osdAlwaysShowValue: { def: false },
|
||||
|
||||
powerActionConfirm: { def: true },
|
||||
powerMenuActions: { def: ["reboot", "logout", "poweroff", "lock", "suspend", "restart"] },
|
||||
powerMenuDefaultAction: { def: "logout" },
|
||||
customPowerActionLock: { def: "" },
|
||||
customPowerActionLogout: { def: "" },
|
||||
customPowerActionSuspend: { def: "" },
|
||||
|
||||
@@ -482,6 +482,10 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
onLockRequested: {
|
||||
lock.activate()
|
||||
}
|
||||
|
||||
function actionApply(action) {
|
||||
switch (action) {
|
||||
case "logout":
|
||||
|
||||
694
LICENSE
694
LICENSE
@@ -1,674 +1,20 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Avenge Media LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR
|
||||
|
||||
23
LICENSE_CHANGE_12_11_2025.md
Normal file
23
LICENSE_CHANGE_12_11_2025.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# DankMaterialShell License Change
|
||||
|
||||
Relicensing from GPL-3.0 to MIT.
|
||||
|
||||
Consent and documentation is available in [pull request #686](https://github.com/AvengeMedia/DankMaterialShell/pull/686) and is summarized below.
|
||||
|
||||
## Contributors
|
||||
|
||||
The project has 21 contributors requiring consent:
|
||||
- 2 primary authors (10k+ lines each)
|
||||
- 7 major contributors (1k+ lines or 10+ commits)
|
||||
- 12 significant contributors (100+ lines)
|
||||
- 2 derivative works (code adapted from other projects)
|
||||
|
||||
Contributors with <50 lines are excluded as they don't meet copyright thresholds. Automated bots don't hold copyright.
|
||||
|
||||
## Consent Status
|
||||
|
||||
All 21 contributors have provided consent. Three contributions were sufficiently reverted or rewritten by maintainers, making them eligible without original author consent.
|
||||
|
||||
## Reasoning
|
||||
|
||||
GPL-3.0 may require plugins to also be GPL-3.0 licensed. MIT allows plugin authors to choose their own licenses.
|
||||
@@ -4,6 +4,7 @@ import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
@@ -52,11 +53,15 @@ PanelWindow {
|
||||
closeTimer.stop()
|
||||
shouldBeVisible = true
|
||||
visible = true
|
||||
focusScope.forceActiveFocus()
|
||||
shouldHaveFocus = false
|
||||
Qt.callLater(() => {
|
||||
shouldHaveFocus = Qt.binding(() => shouldBeVisible)
|
||||
})
|
||||
}
|
||||
|
||||
function close() {
|
||||
shouldBeVisible = false
|
||||
shouldHaveFocus = false
|
||||
closeTimer.restart()
|
||||
}
|
||||
|
||||
@@ -70,7 +75,18 @@ PanelWindow {
|
||||
|
||||
visible: shouldBeVisible
|
||||
color: "transparent"
|
||||
WlrLayershell.layer: WlrLayershell.Top // if set to overlay -> virtual keyboards can be stuck under modal
|
||||
WlrLayershell.layer: {
|
||||
switch (Quickshell.env("DMS_MODAL_LAYER")) {
|
||||
case "bottom":
|
||||
return WlrLayershell.Bottom
|
||||
case "overlay":
|
||||
return WlrLayershell.Overlay
|
||||
case "background":
|
||||
return WlrLayershell.Background
|
||||
default:
|
||||
return WlrLayershell.Top
|
||||
}
|
||||
}
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: shouldHaveFocus ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||
onVisibleChanged: {
|
||||
@@ -209,21 +225,16 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
id: contentContainer
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
color: root.backgroundColor
|
||||
radius: root.cornerRadius
|
||||
border.color: root.borderColor
|
||||
border.width: root.borderWidth
|
||||
clip: false
|
||||
layer.enabled: true
|
||||
layer.smooth: false
|
||||
layer.textureSize: Qt.size(width * root.dpr, height * root.dpr)
|
||||
layer.textureMirroring: ShaderEffectSource.NoMirroring
|
||||
opacity: root.shouldBeVisible ? 1 : 0
|
||||
scale: modalContainer.scaleValue
|
||||
x: Theme.snap(modalContainer.animX + (parent.width - width) * (1 - modalContainer.scaleValue) * 0.5, root.dpr)
|
||||
@@ -237,6 +248,14 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
DankRectangle {
|
||||
anchors.fill: parent
|
||||
color: root.backgroundColor
|
||||
borderColor: root.borderColor
|
||||
borderWidth: root.borderWidth
|
||||
radius: root.cornerRadius
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
anchors.fill: parent
|
||||
focus: root.shouldBeVisible
|
||||
@@ -304,20 +323,5 @@ PanelWindow {
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
onVisibleChanged: {
|
||||
if (visible && shouldHaveFocus) {
|
||||
Qt.callLater(() => focusScope.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onShouldHaveFocusChanged() {
|
||||
if (shouldHaveFocus && shouldBeVisible) {
|
||||
Qt.callLater(() => focusScope.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
target: root
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Modals.Common
|
||||
import qs.Services
|
||||
@@ -9,12 +10,17 @@ DankModal {
|
||||
|
||||
layerNamespace: "dms:power-menu"
|
||||
|
||||
property int selectedIndex: 0
|
||||
property int optionCount: SessionService.hibernateSupported ? 5 : 4
|
||||
property int selectedRow: 0
|
||||
property int selectedCol: 0
|
||||
property int selectedIndex: selectedRow * gridColumns + selectedCol
|
||||
property rect parentBounds: Qt.rect(0, 0, 0, 0)
|
||||
property var parentScreen: null
|
||||
property var visibleActions: []
|
||||
property int gridColumns: 3
|
||||
property int gridRows: 2
|
||||
|
||||
signal powerActionRequested(string action, string title, string message)
|
||||
signal lockRequested
|
||||
|
||||
function openCentered() {
|
||||
parentBounds = Qt.rect(0, 0, 0, 0)
|
||||
@@ -30,8 +36,114 @@ DankModal {
|
||||
open()
|
||||
}
|
||||
|
||||
function updateVisibleActions() {
|
||||
const allActions = SettingsData.powerMenuActions || ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]
|
||||
visibleActions = allActions.filter(action => {
|
||||
if (action === "hibernate" && !SessionService.hibernateSupported)
|
||||
return false
|
||||
return true
|
||||
})
|
||||
|
||||
const count = visibleActions.length
|
||||
switch (count) {
|
||||
case 0:
|
||||
gridColumns = 1
|
||||
gridRows = 1
|
||||
break
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
gridColumns = 1
|
||||
gridRows = count
|
||||
break
|
||||
case 4:
|
||||
gridColumns = 2
|
||||
gridRows = 2
|
||||
break
|
||||
default:
|
||||
gridColumns = 3
|
||||
gridRows = Math.ceil(count / 3)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultActionIndex() {
|
||||
const defaultAction = SettingsData.powerMenuDefaultAction || "logout"
|
||||
const index = visibleActions.indexOf(defaultAction)
|
||||
return index >= 0 ? index : 0
|
||||
}
|
||||
|
||||
function getActionAtIndex(index) {
|
||||
if (index < 0 || index >= visibleActions.length)
|
||||
return ""
|
||||
return visibleActions[index]
|
||||
}
|
||||
|
||||
function getActionData(action) {
|
||||
switch (action) {
|
||||
case "reboot":
|
||||
return {
|
||||
"icon": "restart_alt",
|
||||
"label": I18n.tr("Reboot"),
|
||||
"key": "R"
|
||||
}
|
||||
case "logout":
|
||||
return {
|
||||
"icon": "logout",
|
||||
"label": I18n.tr("Log Out"),
|
||||
"key": "X"
|
||||
}
|
||||
case "poweroff":
|
||||
return {
|
||||
"icon": "power_settings_new",
|
||||
"label": I18n.tr("Power Off"),
|
||||
"key": "P"
|
||||
}
|
||||
case "lock":
|
||||
return {
|
||||
"icon": "lock",
|
||||
"label": I18n.tr("Lock"),
|
||||
"key": "L"
|
||||
}
|
||||
case "suspend":
|
||||
return {
|
||||
"icon": "bedtime",
|
||||
"label": I18n.tr("Suspend"),
|
||||
"key": "S"
|
||||
}
|
||||
case "hibernate":
|
||||
return {
|
||||
"icon": "ac_unit",
|
||||
"label": I18n.tr("Hibernate"),
|
||||
"key": "H"
|
||||
}
|
||||
case "restart":
|
||||
return {
|
||||
"icon": "refresh",
|
||||
"label": I18n.tr("Restart DMS"),
|
||||
"key": "D"
|
||||
}
|
||||
default:
|
||||
return {
|
||||
"icon": "help",
|
||||
"label": action,
|
||||
"key": "?"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectOption(action) {
|
||||
close();
|
||||
if (action === "lock") {
|
||||
close()
|
||||
lockRequested()
|
||||
return
|
||||
}
|
||||
if (action === "restart") {
|
||||
close()
|
||||
Quickshell.execDetached(["dms", "restart"])
|
||||
return
|
||||
}
|
||||
close()
|
||||
const actions = {
|
||||
"logout": {
|
||||
"title": I18n.tr("Log Out"),
|
||||
@@ -56,13 +168,12 @@ DankModal {
|
||||
}
|
||||
const selected = actions[action]
|
||||
if (selected) {
|
||||
root.powerActionRequested(action, selected.title, selected.message);
|
||||
root.powerActionRequested(action, selected.title, selected.message)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
shouldBeVisible: false
|
||||
width: 320
|
||||
width: Math.min(550, gridColumns * 180 + Theme.spacingS * (gridColumns - 1) + Theme.spacingL * 2)
|
||||
height: contentLoader.item ? contentLoader.item.implicitHeight : 300
|
||||
enableShadow: true
|
||||
screen: parentScreen
|
||||
@@ -75,382 +186,190 @@ DankModal {
|
||||
}
|
||||
return Qt.point(0, 0)
|
||||
}
|
||||
onBackgroundClicked: () => {
|
||||
return close();
|
||||
}
|
||||
onBackgroundClicked: () => close()
|
||||
onOpened: () => {
|
||||
selectedIndex = 0;
|
||||
Qt.callLater(() => modalFocusScope.forceActiveFocus());
|
||||
}
|
||||
modalFocusScope.Keys.onPressed: (event) => {
|
||||
switch (event.key) {
|
||||
case Qt.Key_Up:
|
||||
case Qt.Key_Backtab:
|
||||
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount;
|
||||
event.accepted = true;
|
||||
break;
|
||||
case Qt.Key_Down:
|
||||
case Qt.Key_Tab:
|
||||
selectedIndex = (selectedIndex + 1) % optionCount;
|
||||
event.accepted = true;
|
||||
break;
|
||||
case Qt.Key_Return:
|
||||
case Qt.Key_Enter:
|
||||
const actions = ["logout", "suspend"];
|
||||
if (SessionService.hibernateSupported) actions.push("hibernate");
|
||||
actions.push("reboot", "poweroff");
|
||||
if (selectedIndex < actions.length) {
|
||||
selectOption(actions[selectedIndex]);
|
||||
}
|
||||
event.accepted = true;
|
||||
break;
|
||||
case Qt.Key_N:
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
selectedIndex = (selectedIndex + 1) % optionCount;
|
||||
event.accepted = true;
|
||||
}
|
||||
break;
|
||||
case Qt.Key_P:
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount;
|
||||
event.accepted = true;
|
||||
}
|
||||
break;
|
||||
case Qt.Key_J:
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
selectedIndex = (selectedIndex + 1) % optionCount;
|
||||
event.accepted = true;
|
||||
}
|
||||
break;
|
||||
case Qt.Key_K:
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount;
|
||||
event.accepted = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateVisibleActions()
|
||||
const defaultIndex = getDefaultActionIndex()
|
||||
selectedRow = Math.floor(defaultIndex / gridColumns)
|
||||
selectedCol = defaultIndex % gridColumns
|
||||
Qt.callLater(() => modalFocusScope.forceActiveFocus())
|
||||
}
|
||||
Component.onCompleted: updateVisibleActions()
|
||||
modalFocusScope.Keys.onPressed: event => {
|
||||
switch (event.key) {
|
||||
case Qt.Key_Left:
|
||||
selectedCol = (selectedCol - 1 + gridColumns) % gridColumns
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_Right:
|
||||
selectedCol = (selectedCol + 1) % gridColumns
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_Up:
|
||||
case Qt.Key_Backtab:
|
||||
selectedRow = (selectedRow - 1 + gridRows) % gridRows
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_Down:
|
||||
case Qt.Key_Tab:
|
||||
selectedRow = (selectedRow + 1) % gridRows
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_Return:
|
||||
case Qt.Key_Enter:
|
||||
selectOption(getActionAtIndex(selectedIndex))
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_N:
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
selectedCol = (selectedCol + 1) % gridColumns
|
||||
event.accepted = true
|
||||
}
|
||||
break
|
||||
case Qt.Key_P:
|
||||
if (!(event.modifiers & Qt.ControlModifier)) {
|
||||
selectOption("poweroff")
|
||||
event.accepted = true
|
||||
} else {
|
||||
selectedCol = (selectedCol - 1 + gridColumns) % gridColumns
|
||||
event.accepted = true
|
||||
}
|
||||
break
|
||||
case Qt.Key_J:
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
selectedRow = (selectedRow + 1) % gridRows
|
||||
event.accepted = true
|
||||
}
|
||||
break
|
||||
case Qt.Key_K:
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
selectedRow = (selectedRow - 1 + gridRows) % gridRows
|
||||
event.accepted = true
|
||||
}
|
||||
break
|
||||
case Qt.Key_R:
|
||||
selectOption("reboot")
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_X:
|
||||
selectOption("logout")
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_L:
|
||||
selectOption("lock")
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_S:
|
||||
selectOption("suspend")
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_H:
|
||||
selectOption("hibernate")
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_D:
|
||||
selectOption("restart")
|
||||
event.accepted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
content: Component {
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
implicitHeight: mainColumn.implicitHeight + Theme.spacingL * 2
|
||||
implicitHeight: buttonGrid.implicitHeight + Theme.spacingL * 2
|
||||
|
||||
Column {
|
||||
id: mainColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
Grid {
|
||||
id: buttonGrid
|
||||
anchors.centerIn: parent
|
||||
columns: root.gridColumns
|
||||
columnSpacing: Theme.spacingS
|
||||
rowSpacing: Theme.spacingS
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
Repeater {
|
||||
model: root.visibleActions
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Power Options")
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Rectangle {
|
||||
required property int index
|
||||
required property string modelData
|
||||
|
||||
Item {
|
||||
width: parent.width - 150
|
||||
height: 1
|
||||
}
|
||||
readonly property var actionData: root.getActionData(modelData)
|
||||
readonly property bool isSelected: root.selectedIndex === index
|
||||
readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff"
|
||||
|
||||
DankActionButton {
|
||||
iconName: "close"
|
||||
iconSize: Theme.iconSize - 4
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: () => {
|
||||
return close();
|
||||
width: (root.width - Theme.spacingL * 2 - Theme.spacingS * (root.gridColumns - 1)) / root.gridColumns
|
||||
height: 100
|
||||
radius: Theme.cornerRadius
|
||||
color: {
|
||||
if (isSelected)
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
||||
if (mouseArea.containsMouse)
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
|
||||
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
|
||||
}
|
||||
border.color: isSelected ? Theme.primary : "transparent"
|
||||
border.width: isSelected ? 2 : 0
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankIcon {
|
||||
name: parent.parent.actionData.icon
|
||||
size: Theme.iconSize + 8
|
||||
color: {
|
||||
if (parent.parent.showWarning && mouseArea.containsMouse) {
|
||||
return parent.parent.modelData === "poweroff" ? Theme.error : Theme.warning
|
||||
}
|
||||
return Theme.surfaceText
|
||||
}
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: parent.parent.actionData.label
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: {
|
||||
if (parent.parent.showWarning && mouseArea.containsMouse) {
|
||||
return parent.parent.modelData === "poweroff" ? Theme.error : Theme.warning
|
||||
}
|
||||
return Theme.surfaceText
|
||||
}
|
||||
font.weight: Font.Medium
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 20
|
||||
height: 16
|
||||
radius: 4
|
||||
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
StyledText {
|
||||
text: parent.parent.parent.actionData.key
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
|
||||
font.weight: Font.Medium
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.selectedRow = Math.floor(index / root.gridColumns)
|
||||
root.selectedCol = index % root.gridColumns
|
||||
root.selectOption(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 50
|
||||
radius: Theme.cornerRadius
|
||||
color: {
|
||||
if (selectedIndex === 0) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
|
||||
} else if (logoutArea.containsMouse) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
|
||||
} else {
|
||||
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||
}
|
||||
}
|
||||
border.color: selectedIndex === 0 ? Theme.primary : "transparent"
|
||||
border.width: selectedIndex === 0 ? 1 : 0
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "logout"
|
||||
size: Theme.iconSize
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Log Out")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: logoutArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: () => {
|
||||
selectedIndex = 0;
|
||||
selectOption("logout");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 50
|
||||
radius: Theme.cornerRadius
|
||||
color: {
|
||||
if (selectedIndex === 1) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
|
||||
} else if (suspendArea.containsMouse) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
|
||||
} else {
|
||||
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||
}
|
||||
}
|
||||
border.color: selectedIndex === 1 ? Theme.primary : "transparent"
|
||||
border.width: selectedIndex === 1 ? 1 : 0
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "bedtime"
|
||||
size: Theme.iconSize
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Suspend")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: suspendArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: () => {
|
||||
selectedIndex = 1;
|
||||
selectOption("suspend");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 50
|
||||
radius: Theme.cornerRadius
|
||||
color: {
|
||||
if (selectedIndex === 2) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
|
||||
} else if (hibernateArea.containsMouse) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
|
||||
} else {
|
||||
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||
}
|
||||
}
|
||||
border.color: selectedIndex === 2 ? Theme.primary : "transparent"
|
||||
border.width: selectedIndex === 2 ? 1 : 0
|
||||
visible: SessionService.hibernateSupported
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "ac_unit"
|
||||
size: Theme.iconSize
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Hibernate")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hibernateArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: () => {
|
||||
selectedIndex = 2;
|
||||
selectOption("hibernate");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 50
|
||||
radius: Theme.cornerRadius
|
||||
color: {
|
||||
const rebootIndex = SessionService.hibernateSupported ? 3 : 2;
|
||||
if (selectedIndex === rebootIndex) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
|
||||
} else if (rebootArea.containsMouse) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
|
||||
} else {
|
||||
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||
}
|
||||
}
|
||||
border.color: selectedIndex === (SessionService.hibernateSupported ? 3 : 2) ? Theme.primary : "transparent"
|
||||
border.width: selectedIndex === (SessionService.hibernateSupported ? 3 : 2) ? 1 : 0
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "restart_alt"
|
||||
size: Theme.iconSize
|
||||
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Reboot")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: rebootArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: () => {
|
||||
selectedIndex = SessionService.hibernateSupported ? 3 : 2;
|
||||
selectOption("reboot");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 50
|
||||
radius: Theme.cornerRadius
|
||||
color: {
|
||||
const powerOffIndex = SessionService.hibernateSupported ? 4 : 3;
|
||||
if (selectedIndex === powerOffIndex) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
|
||||
} else if (powerOffArea.containsMouse) {
|
||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
|
||||
} else {
|
||||
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||
}
|
||||
}
|
||||
border.color: selectedIndex === (SessionService.hibernateSupported ? 4 : 3) ? Theme.primary : "transparent"
|
||||
border.width: selectedIndex === (SessionService.hibernateSupported ? 4 : 3) ? 1 : 0
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "power_settings_new"
|
||||
size: Theme.iconSize
|
||||
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Power Off")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: powerOffArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: () => {
|
||||
selectedIndex = SessionService.hibernateSupported ? 4 : 3;
|
||||
selectOption("poweroff");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
height: Theme.spacingS
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,10 +76,10 @@ Item {
|
||||
checked: SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration
|
||||
enabled: SessionService.loginctlAvailable
|
||||
onToggled: checked => {
|
||||
if (SessionService.loginctlAvailable) {
|
||||
SettingsData.set("loginctlLockIntegration", checked)
|
||||
}
|
||||
}
|
||||
if (SessionService.loginctlAvailable) {
|
||||
SettingsData.set("loginctlLockIntegration", checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
@@ -185,16 +185,16 @@ Item {
|
||||
}
|
||||
|
||||
onValueChanged: value => {
|
||||
const index = timeoutOptions.indexOf(value)
|
||||
if (index >= 0) {
|
||||
const timeout = timeoutValues[index]
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acLockTimeout", timeout)
|
||||
} else {
|
||||
SettingsData.set("batteryLockTimeout", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
const index = timeoutOptions.indexOf(value)
|
||||
if (index >= 0) {
|
||||
const timeout = timeoutValues[index]
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acLockTimeout", timeout)
|
||||
} else {
|
||||
SettingsData.set("batteryLockTimeout", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
@@ -222,16 +222,16 @@ Item {
|
||||
}
|
||||
|
||||
onValueChanged: value => {
|
||||
const index = timeoutOptions.indexOf(value)
|
||||
if (index >= 0) {
|
||||
const timeout = timeoutValues[index]
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acMonitorTimeout", timeout)
|
||||
} else {
|
||||
SettingsData.set("batteryMonitorTimeout", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
const index = timeoutOptions.indexOf(value)
|
||||
if (index >= 0) {
|
||||
const timeout = timeoutValues[index]
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acMonitorTimeout", timeout)
|
||||
} else {
|
||||
SettingsData.set("batteryMonitorTimeout", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
@@ -259,16 +259,16 @@ Item {
|
||||
}
|
||||
|
||||
onValueChanged: value => {
|
||||
const index = timeoutOptions.indexOf(value)
|
||||
if (index >= 0) {
|
||||
const timeout = timeoutValues[index]
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acSuspendTimeout", timeout)
|
||||
} else {
|
||||
SettingsData.set("batterySuspendTimeout", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
const index = timeoutOptions.indexOf(value)
|
||||
if (index >= 0) {
|
||||
const timeout = timeoutValues[index]
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acSuspendTimeout", timeout)
|
||||
} else {
|
||||
SettingsData.set("batterySuspendTimeout", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
@@ -304,14 +304,14 @@ Item {
|
||||
}
|
||||
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (selected) {
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acSuspendBehavior", index)
|
||||
} else {
|
||||
SettingsData.set("batterySuspendBehavior", index)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
if (powerCategory.currentIndex === 0) {
|
||||
SettingsData.set("acSuspendBehavior", index)
|
||||
} else {
|
||||
SettingsData.set("batterySuspendBehavior", index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +325,185 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
width: parent.width
|
||||
height: powerMenuCustomSection.implicitHeight + Theme.spacingL * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
border.width: 0
|
||||
|
||||
Column {
|
||||
id: powerMenuCustomSection
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "tune"
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Power Menu Customization")
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Customize which actions appear in the power menu")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
width: parent.width
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
id: defaultActionDropdown
|
||||
width: parent.width
|
||||
addHorizontalPadding: true
|
||||
text: I18n.tr("Default selected action")
|
||||
options: ["Reboot", "Log Out", "Power Off", "Lock", "Suspend", "Restart DMS", "Hibernate"]
|
||||
property var actionValues: ["reboot", "logout", "poweroff", "lock", "suspend", "restart", "hibernate"]
|
||||
|
||||
Component.onCompleted: {
|
||||
const currentAction = SettingsData.powerMenuDefaultAction || "logout"
|
||||
const index = actionValues.indexOf(currentAction)
|
||||
currentValue = index >= 0 ? options[index] : "Log Out"
|
||||
}
|
||||
|
||||
onValueChanged: value => {
|
||||
const index = options.indexOf(value)
|
||||
if (index >= 0) {
|
||||
SettingsData.set("powerMenuDefaultAction", actionValues[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Show Reboot")
|
||||
checked: SettingsData.powerMenuActions.includes("reboot")
|
||||
onToggled: checked => {
|
||||
let actions = [...SettingsData.powerMenuActions]
|
||||
if (checked && !actions.includes("reboot")) {
|
||||
actions.push("reboot")
|
||||
} else if (!checked) {
|
||||
actions = actions.filter(a => a !== "reboot")
|
||||
}
|
||||
SettingsData.set("powerMenuActions", actions)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Show Log Out")
|
||||
checked: SettingsData.powerMenuActions.includes("logout")
|
||||
onToggled: checked => {
|
||||
let actions = [...SettingsData.powerMenuActions]
|
||||
if (checked && !actions.includes("logout")) {
|
||||
actions.push("logout")
|
||||
} else if (!checked) {
|
||||
actions = actions.filter(a => a !== "logout")
|
||||
}
|
||||
SettingsData.set("powerMenuActions", actions)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Show Power Off")
|
||||
checked: SettingsData.powerMenuActions.includes("poweroff")
|
||||
onToggled: checked => {
|
||||
let actions = [...SettingsData.powerMenuActions]
|
||||
if (checked && !actions.includes("poweroff")) {
|
||||
actions.push("poweroff")
|
||||
} else if (!checked) {
|
||||
actions = actions.filter(a => a !== "poweroff")
|
||||
}
|
||||
SettingsData.set("powerMenuActions", actions)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Show Lock")
|
||||
checked: SettingsData.powerMenuActions.includes("lock")
|
||||
onToggled: checked => {
|
||||
let actions = [...SettingsData.powerMenuActions]
|
||||
if (checked && !actions.includes("lock")) {
|
||||
actions.push("lock")
|
||||
} else if (!checked) {
|
||||
actions = actions.filter(a => a !== "lock")
|
||||
}
|
||||
SettingsData.set("powerMenuActions", actions)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Show Suspend")
|
||||
checked: SettingsData.powerMenuActions.includes("suspend")
|
||||
onToggled: checked => {
|
||||
let actions = [...SettingsData.powerMenuActions]
|
||||
if (checked && !actions.includes("suspend")) {
|
||||
actions.push("suspend")
|
||||
} else if (!checked) {
|
||||
actions = actions.filter(a => a !== "suspend")
|
||||
}
|
||||
SettingsData.set("powerMenuActions", actions)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Show Restart DMS")
|
||||
description: I18n.tr("Restart the DankMaterialShell")
|
||||
checked: SettingsData.powerMenuActions.includes("restart")
|
||||
onToggled: checked => {
|
||||
let actions = [...SettingsData.powerMenuActions]
|
||||
if (checked && !actions.includes("restart")) {
|
||||
actions.push("restart")
|
||||
} else if (!checked) {
|
||||
actions = actions.filter(a => a !== "restart")
|
||||
}
|
||||
SettingsData.set("powerMenuActions", actions)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Show Hibernate")
|
||||
description: I18n.tr("Only visible if hibernate is supported by your system")
|
||||
checked: SettingsData.powerMenuActions.includes("hibernate")
|
||||
visible: SessionService.hibernateSupported
|
||||
onToggled: checked => {
|
||||
let actions = [...SettingsData.powerMenuActions]
|
||||
if (checked && !actions.includes("hibernate")) {
|
||||
actions.push("hibernate")
|
||||
} else if (!checked) {
|
||||
actions = actions.filter(a => a !== "hibernate")
|
||||
}
|
||||
SettingsData.set("powerMenuActions", actions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
width: parent.width
|
||||
height: powerCommandConfirmSection.implicitHeight + Theme.spacingL * 2
|
||||
@@ -425,12 +604,12 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (SettingsData.customPowerActionLock) {
|
||||
text = SettingsData.customPowerActionLock;
|
||||
text = SettingsData.customPowerActionLock
|
||||
}
|
||||
}
|
||||
|
||||
onTextEdited: {
|
||||
SettingsData.set("customPowerActionLock", text.trim());
|
||||
SettingsData.set("customPowerActionLock", text.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -457,12 +636,12 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (SettingsData.customPowerActionLogout) {
|
||||
text = SettingsData.customPowerActionLogout;
|
||||
text = SettingsData.customPowerActionLogout
|
||||
}
|
||||
}
|
||||
|
||||
onTextEdited: {
|
||||
SettingsData.set("customPowerActionLogout", text.trim());
|
||||
SettingsData.set("customPowerActionLogout", text.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,12 +668,12 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (SettingsData.customPowerActionSuspend) {
|
||||
text = SettingsData.customPowerActionSuspend;
|
||||
text = SettingsData.customPowerActionSuspend
|
||||
}
|
||||
}
|
||||
|
||||
onTextEdited: {
|
||||
SettingsData.set("customPowerActionSuspend", text.trim());
|
||||
SettingsData.set("customPowerActionSuspend", text.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -521,12 +700,12 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (SettingsData.customPowerActionHibernate) {
|
||||
text = SettingsData.customPowerActionHibernate;
|
||||
text = SettingsData.customPowerActionHibernate
|
||||
}
|
||||
}
|
||||
|
||||
onTextEdited: {
|
||||
SettingsData.set("customPowerActionHibernate", text.trim());
|
||||
SettingsData.set("customPowerActionHibernate", text.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,12 +732,12 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (SettingsData.customPowerActionReboot) {
|
||||
text = SettingsData.customPowerActionReboot;
|
||||
text = SettingsData.customPowerActionReboot
|
||||
}
|
||||
}
|
||||
|
||||
onTextEdited: {
|
||||
SettingsData.set("customPowerActionReboot", text.trim());
|
||||
SettingsData.set("customPowerActionReboot", text.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,12 +764,12 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (SettingsData.customPowerActionPowerOff) {
|
||||
text = SettingsData.customPowerActionPowerOff;
|
||||
text = SettingsData.customPowerActionPowerOff
|
||||
}
|
||||
}
|
||||
|
||||
onTextEdited: {
|
||||
SettingsData.set("customPowerActionPowerOff", text.trim());
|
||||
SettingsData.set("customPowerActionPowerOff", text.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ import QtQuick
|
||||
import qs.Common
|
||||
import qs.Modules.Settings
|
||||
|
||||
Item {
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
property int currentIndex: 0
|
||||
property var parentModal: null
|
||||
|
||||
focus: true
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 0
|
||||
@@ -22,6 +24,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 0
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: Component {
|
||||
PersonalizationTab {
|
||||
@@ -30,6 +33,12 @@ Item {
|
||||
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -38,10 +47,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 1
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: TimeWeatherTab {
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -50,11 +66,18 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 2
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: DankBarTab {
|
||||
parentModal: root.parentModal
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -63,10 +86,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 3
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: WidgetTweaksTab {
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -75,6 +105,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 4
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: Component {
|
||||
DockTab {
|
||||
@@ -82,6 +113,12 @@ Item {
|
||||
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -90,10 +127,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 5
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: DisplaysTab {
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -102,10 +146,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 6
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: LauncherTab {
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -114,10 +165,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 7
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: ThemeColorsTab {
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -126,10 +184,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 8
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: PowerSettings {
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -138,11 +203,18 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 9
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: PluginsTab {
|
||||
parentModal: root.parentModal
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -151,10 +223,17 @@ Item {
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 10
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
sourceComponent: AboutTab {
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (active && item) {
|
||||
Qt.callLater(() => item.forceActiveFocus())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,23 @@ DankModal {
|
||||
}
|
||||
content: settingsContent
|
||||
onOpened: () => {
|
||||
Qt.callLater(() => modalFocusScope.forceActiveFocus())
|
||||
Qt.callLater(() => {
|
||||
modalFocusScope.forceActiveFocus()
|
||||
if (contentLoader.item) {
|
||||
contentLoader.item.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible && shouldBeVisible) {
|
||||
Qt.callLater(() => {
|
||||
modalFocusScope.forceActiveFocus()
|
||||
if (contentLoader.item) {
|
||||
contentLoader.item.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
modalFocusScope.Keys.onPressed: event => {
|
||||
const tabCount = 11
|
||||
@@ -113,6 +129,14 @@ DankModal {
|
||||
}
|
||||
onDialogClosed: () => {
|
||||
allowStacking = true;
|
||||
if (settingsModal.shouldBeVisible) {
|
||||
Qt.callLater(() => {
|
||||
settingsModal.modalFocusScope.forceActiveFocus()
|
||||
if (settingsModal.contentLoader.item) {
|
||||
settingsModal.contentLoader.item.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +156,14 @@ DankModal {
|
||||
}
|
||||
onDialogClosed: () => {
|
||||
allowStacking = true;
|
||||
if (settingsModal.shouldBeVisible) {
|
||||
Qt.callLater(() => {
|
||||
settingsModal.modalFocusScope.forceActiveFocus()
|
||||
if (settingsModal.contentLoader.item) {
|
||||
settingsModal.contentLoader.item.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +172,11 @@ DankModal {
|
||||
id: rootScope
|
||||
anchors.fill: parent
|
||||
|
||||
Keys.onEscapePressed: event => {
|
||||
settingsModal.hide()
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Theme.spacingL
|
||||
|
||||
@@ -183,6 +183,7 @@ Item {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
leftPadding: Theme.spacingS
|
||||
topPadding: Theme.spacingS
|
||||
|
||||
DankTextField {
|
||||
id: searchField
|
||||
|
||||
@@ -27,6 +27,7 @@ DankPopout {
|
||||
property bool editMode: false
|
||||
property int expandedWidgetIndex: -1
|
||||
property var expandedWidgetData: null
|
||||
property bool powerMenuOpen: powerMenuModalLoader?.item?.shouldBeVisible ?? false
|
||||
|
||||
signal lockRequested
|
||||
|
||||
@@ -115,6 +116,21 @@ DankPopout {
|
||||
antialiasing: true
|
||||
smooth: true
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(0, 0, 0, 0.6)
|
||||
radius: parent.radius
|
||||
visible: root.powerMenuOpen
|
||||
z: 5000
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: mainColumn
|
||||
width: parent.width - Theme.spacingL * 2
|
||||
|
||||
@@ -24,8 +24,7 @@ Item {
|
||||
property real totalSize: 0
|
||||
|
||||
function updateLayout() {
|
||||
const containerSize = isVertical ? height : width
|
||||
if (containerSize <= 0 || !visible) {
|
||||
if ((isVertical ? height : width) <= 0 || !visible) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -34,32 +33,58 @@ Item {
|
||||
totalSize = 0
|
||||
|
||||
let configuredWidgets = 0
|
||||
let configuredMiddleWidget = null
|
||||
let configuredLeftWidget = null
|
||||
let configuredRightWidget = null
|
||||
|
||||
for (var i = 0; i < centerRepeater.count; i++) {
|
||||
const item = centerRepeater.itemAt(i)
|
||||
if (item && getWidgetVisible(item.widgetId)) {
|
||||
configuredWidgets++
|
||||
}
|
||||
}
|
||||
|
||||
const isOddConfigured = configuredWidgets % 2 === 1
|
||||
const configuredMiddlePos = Math.floor(configuredWidgets / 2)
|
||||
const configuredLeftPos = isOddConfigured ? -1 : ((configuredWidgets / 2) - 1)
|
||||
const configuredRightPos = isOddConfigured ? -1 : (configuredWidgets / 2)
|
||||
let currentConfigIndex = 0
|
||||
|
||||
for (var i = 0; i < centerRepeater.count; i++) {
|
||||
const item = centerRepeater.itemAt(i)
|
||||
if (item && getWidgetVisible(item.widgetId)) {
|
||||
if (isOddConfigured && currentConfigIndex === configuredMiddlePos && item.active && item.item) {
|
||||
configuredMiddleWidget = item.item
|
||||
}
|
||||
if (!isOddConfigured && currentConfigIndex === configuredLeftPos && item.active && item.item) {
|
||||
configuredLeftWidget = item.item
|
||||
}
|
||||
if (!isOddConfigured && currentConfigIndex === configuredRightPos && item.active && item.item) {
|
||||
configuredRightWidget = item.item
|
||||
}
|
||||
if (item.active && item.item) {
|
||||
centerWidgets.push(item.item)
|
||||
totalWidgets++
|
||||
totalSize += isVertical ? item.item.height : item.item.width
|
||||
}
|
||||
currentConfigIndex++
|
||||
}
|
||||
}
|
||||
|
||||
if (totalWidgets === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (totalWidgets > 1) {
|
||||
totalSize += spacing * (totalWidgets - 1)
|
||||
}
|
||||
|
||||
positionWidgets(configuredWidgets)
|
||||
positionWidgets(configuredWidgets, configuredMiddleWidget, configuredLeftWidget, configuredRightWidget)
|
||||
}
|
||||
|
||||
function positionWidgets(configuredWidgets) {
|
||||
if (totalWidgets === 0 || (isVertical ? height : width) <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
function positionWidgets(configuredWidgets, configuredMiddleWidget, configuredLeftWidget, configuredRightWidget) {
|
||||
const parentCenter = (isVertical ? height : width) / 2
|
||||
const isOdd = configuredWidgets % 2 === 1
|
||||
const isOddConfigured = configuredWidgets % 2 === 1
|
||||
|
||||
centerWidgets.forEach(widget => {
|
||||
if (isVertical) {
|
||||
@@ -69,193 +94,169 @@ Item {
|
||||
}
|
||||
})
|
||||
|
||||
if (isOdd) {
|
||||
const middleIndex = Math.floor(configuredWidgets / 2)
|
||||
let currentActiveIndex = 0
|
||||
let middleWidget = null
|
||||
if (isOddConfigured && configuredMiddleWidget) {
|
||||
const middleWidget = configuredMiddleWidget
|
||||
const middleIndex = centerWidgets.indexOf(middleWidget)
|
||||
const middleSize = isVertical ? middleWidget.height : middleWidget.width
|
||||
|
||||
for (var i = 0; i < centerRepeater.count; i++) {
|
||||
const item = centerRepeater.itemAt(i)
|
||||
if (item && getWidgetVisible(item.widgetId)) {
|
||||
if (currentActiveIndex === middleIndex && item.active && item.item) {
|
||||
middleWidget = item.item
|
||||
break
|
||||
}
|
||||
currentActiveIndex++
|
||||
if (isVertical) {
|
||||
middleWidget.y = parentCenter - (middleSize / 2)
|
||||
} else {
|
||||
middleWidget.x = parentCenter - (middleSize / 2)
|
||||
}
|
||||
|
||||
let currentPos = isVertical ? middleWidget.y : middleWidget.x
|
||||
for (var i = middleIndex - 1; i >= 0; i--) {
|
||||
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
currentPos -= (spacing + size)
|
||||
if (isVertical) {
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
}
|
||||
|
||||
if (middleWidget) {
|
||||
const middleSize = isVertical ? middleWidget.height : middleWidget.width
|
||||
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize
|
||||
for (var i = middleIndex + 1; i < totalWidgets; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
middleWidget.y = parentCenter - (middleSize / 2)
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
middleWidget.x = parentCenter - (middleSize / 2)
|
||||
}
|
||||
|
||||
let leftWidgets = []
|
||||
let rightWidgets = []
|
||||
let foundMiddle = false
|
||||
|
||||
for (var i = 0; i < centerWidgets.length; i++) {
|
||||
if (centerWidgets[i] === middleWidget) {
|
||||
foundMiddle = true
|
||||
continue
|
||||
}
|
||||
if (!foundMiddle) {
|
||||
leftWidgets.push(centerWidgets[i])
|
||||
} else {
|
||||
rightWidgets.push(centerWidgets[i])
|
||||
}
|
||||
}
|
||||
|
||||
let currentPos = isVertical ? middleWidget.y : middleWidget.x
|
||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
||||
currentPos -= (spacing + size)
|
||||
if (isVertical) {
|
||||
leftWidgets[i].y = currentPos
|
||||
} else {
|
||||
leftWidgets[i].x = currentPos
|
||||
}
|
||||
}
|
||||
|
||||
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize
|
||||
for (var i = 0; i < rightWidgets.length; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
rightWidgets[i].y = currentPos
|
||||
} else {
|
||||
rightWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
}
|
||||
} else {
|
||||
let configuredLeftIndex = (configuredWidgets / 2) - 1
|
||||
let configuredRightIndex = configuredWidgets / 2
|
||||
const halfSpacing = spacing / 2
|
||||
if (totalWidgets === 1) {
|
||||
const widget = centerWidgets[0]
|
||||
const size = isVertical ? widget.height : widget.width
|
||||
if (isVertical) {
|
||||
widget.y = parentCenter - (size / 2)
|
||||
} else {
|
||||
widget.x = parentCenter - (size / 2)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let leftWidget = null
|
||||
let rightWidget = null
|
||||
let leftWidgets = []
|
||||
let rightWidgets = []
|
||||
if (!configuredLeftWidget || !configuredRightWidget) {
|
||||
if (totalWidgets % 2 === 1) {
|
||||
const middleIndex = Math.floor(totalWidgets / 2)
|
||||
const middleWidget = centerWidgets[middleIndex]
|
||||
|
||||
let currentConfigIndex = 0
|
||||
for (var i = 0; i < centerRepeater.count; i++) {
|
||||
const item = centerRepeater.itemAt(i)
|
||||
if (item && getWidgetVisible(item.widgetId)) {
|
||||
if (item.active && item.item) {
|
||||
if (currentConfigIndex < configuredLeftIndex) {
|
||||
leftWidgets.push(item.item)
|
||||
} else if (currentConfigIndex === configuredLeftIndex) {
|
||||
leftWidget = item.item
|
||||
} else if (currentConfigIndex === configuredRightIndex) {
|
||||
rightWidget = item.item
|
||||
if (!middleWidget) {
|
||||
return
|
||||
}
|
||||
|
||||
const middleSize = isVertical ? middleWidget.height : middleWidget.width
|
||||
|
||||
if (isVertical) {
|
||||
middleWidget.y = parentCenter - (middleSize / 2)
|
||||
} else {
|
||||
middleWidget.x = parentCenter - (middleSize / 2)
|
||||
}
|
||||
|
||||
let currentPos = isVertical ? middleWidget.y : middleWidget.x
|
||||
for (var i = middleIndex - 1; i >= 0; i--) {
|
||||
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
currentPos -= (spacing + size)
|
||||
if (isVertical) {
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
rightWidgets.push(item.item)
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
}
|
||||
currentConfigIndex++
|
||||
|
||||
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize
|
||||
for (var i = middleIndex + 1; i < totalWidgets; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
}
|
||||
} else {
|
||||
const leftIndex = (totalWidgets / 2) - 1
|
||||
const rightIndex = totalWidgets / 2
|
||||
const fallbackLeft = centerWidgets[leftIndex]
|
||||
const fallbackRight = centerWidgets[rightIndex]
|
||||
|
||||
if (!fallbackLeft || !fallbackRight) {
|
||||
return
|
||||
}
|
||||
|
||||
const halfSpacing = spacing / 2
|
||||
const leftSize = isVertical ? fallbackLeft.height : fallbackLeft.width
|
||||
|
||||
if (isVertical) {
|
||||
fallbackLeft.y = parentCenter - halfSpacing - leftSize
|
||||
fallbackRight.y = parentCenter + halfSpacing
|
||||
} else {
|
||||
fallbackLeft.x = parentCenter - halfSpacing - leftSize
|
||||
fallbackRight.x = parentCenter + halfSpacing
|
||||
}
|
||||
|
||||
let currentPos = isVertical ? fallbackLeft.y : fallbackLeft.x
|
||||
for (var i = leftIndex - 1; i >= 0; i--) {
|
||||
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
currentPos -= (spacing + size)
|
||||
if (isVertical) {
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
}
|
||||
|
||||
currentPos = (isVertical ? fallbackRight.y + fallbackRight.height : fallbackRight.x + fallbackRight.width)
|
||||
for (var i = rightIndex + 1; i < totalWidgets; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const leftWidget = configuredLeftWidget
|
||||
const rightWidget = configuredRightWidget
|
||||
const leftIndex = centerWidgets.indexOf(leftWidget)
|
||||
const rightIndex = centerWidgets.indexOf(rightWidget)
|
||||
const halfSpacing = spacing / 2
|
||||
const leftSize = isVertical ? leftWidget.height : leftWidget.width
|
||||
|
||||
if (isVertical) {
|
||||
leftWidget.y = parentCenter - halfSpacing - leftSize
|
||||
rightWidget.y = parentCenter + halfSpacing
|
||||
} else {
|
||||
leftWidget.x = parentCenter - halfSpacing - leftSize
|
||||
rightWidget.x = parentCenter + halfSpacing
|
||||
}
|
||||
|
||||
let currentPos = isVertical ? leftWidget.y : leftWidget.x
|
||||
for (var i = leftIndex - 1; i >= 0; i--) {
|
||||
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
currentPos -= (spacing + size)
|
||||
if (isVertical) {
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
}
|
||||
|
||||
if (leftWidget && rightWidget) {
|
||||
const leftSize = isVertical ? leftWidget.height : leftWidget.width
|
||||
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width)
|
||||
for (var i = rightIndex + 1; i < totalWidgets; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
leftWidget.y = parentCenter - halfSpacing - leftSize
|
||||
rightWidget.y = parentCenter + halfSpacing
|
||||
centerWidgets[i].y = currentPos
|
||||
} else {
|
||||
leftWidget.x = parentCenter - halfSpacing - leftSize
|
||||
rightWidget.x = parentCenter + halfSpacing
|
||||
}
|
||||
|
||||
let currentPos = isVertical ? leftWidget.y : leftWidget.x
|
||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
||||
currentPos -= (spacing + size)
|
||||
if (isVertical) {
|
||||
leftWidgets[i].y = currentPos
|
||||
} else {
|
||||
leftWidgets[i].x = currentPos
|
||||
}
|
||||
}
|
||||
|
||||
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width)
|
||||
for (var i = 0; i < rightWidgets.length; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
rightWidgets[i].y = currentPos
|
||||
} else {
|
||||
rightWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
||||
}
|
||||
} else if (leftWidget && !rightWidget) {
|
||||
const leftSize = isVertical ? leftWidget.height : leftWidget.width
|
||||
if (isVertical) {
|
||||
leftWidget.y = parentCenter - halfSpacing - leftSize
|
||||
} else {
|
||||
leftWidget.x = parentCenter - halfSpacing - leftSize
|
||||
}
|
||||
|
||||
let currentPos = isVertical ? leftWidget.y : leftWidget.x
|
||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
||||
currentPos -= (spacing + size)
|
||||
if (isVertical) {
|
||||
leftWidgets[i].y = currentPos
|
||||
} else {
|
||||
leftWidgets[i].x = currentPos
|
||||
}
|
||||
}
|
||||
|
||||
currentPos = (isVertical ? leftWidget.y + leftWidget.height : leftWidget.x + leftWidget.width) + spacing
|
||||
for (var i = 0; i < rightWidgets.length; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
rightWidgets[i].y = currentPos
|
||||
} else {
|
||||
rightWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
||||
}
|
||||
} else if (!leftWidget && rightWidget) {
|
||||
if (isVertical) {
|
||||
rightWidget.y = parentCenter + halfSpacing
|
||||
} else {
|
||||
rightWidget.x = parentCenter + halfSpacing
|
||||
}
|
||||
|
||||
let currentPos = (isVertical ? rightWidget.y : rightWidget.x) - spacing
|
||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
||||
currentPos -= size
|
||||
if (isVertical) {
|
||||
leftWidgets[i].y = currentPos
|
||||
} else {
|
||||
leftWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos -= spacing
|
||||
}
|
||||
|
||||
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width)
|
||||
for (var i = 0; i < rightWidgets.length; i++) {
|
||||
currentPos += spacing
|
||||
if (isVertical) {
|
||||
rightWidgets[i].y = currentPos
|
||||
} else {
|
||||
rightWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
||||
}
|
||||
} else if (totalWidgets === 1 && centerWidgets[0]) {
|
||||
const size = isVertical ? centerWidgets[0].height : centerWidgets[0].width
|
||||
if (isVertical) {
|
||||
centerWidgets[0].y = parentCenter - (size / 2)
|
||||
} else {
|
||||
centerWidgets[0].x = parentCenter - (size / 2)
|
||||
centerWidgets[i].x = currentPos
|
||||
}
|
||||
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ Item {
|
||||
|
||||
property alias barVariants: barVariants
|
||||
property var hyprlandOverviewLoader: null
|
||||
property bool systemTrayMenuOpen: false
|
||||
|
||||
function triggerControlCenterOnFocusedScreen() {
|
||||
let focusedScreenName = ""
|
||||
@@ -444,7 +445,7 @@ Item {
|
||||
return item.loader.item[item.prop]
|
||||
}
|
||||
return false
|
||||
})
|
||||
}) || root.systemTrayMenuOpen
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -470,7 +471,10 @@ Item {
|
||||
}
|
||||
|
||||
onHasActivePopoutChanged: {
|
||||
if (!hasActivePopout && autoHide && !topBarMouseArea.containsMouse) {
|
||||
if (hasActivePopout) {
|
||||
revealSticky = true
|
||||
revealHold.stop()
|
||||
} else if (autoHide && !topBarMouseArea.containsMouse) {
|
||||
revealSticky = true
|
||||
revealHold.restart()
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ BasePill {
|
||||
}
|
||||
|
||||
IconImage {
|
||||
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway)
|
||||
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway || CompositorService.isLabwc)
|
||||
anchors.centerIn: parent
|
||||
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||
@@ -71,6 +71,8 @@ BasePill {
|
||||
return "file://" + Theme.shellDir + "/assets/mango.png"
|
||||
} else if (CompositorService.isSway) {
|
||||
return "file://" + Theme.shellDir + "/assets/sway.svg"
|
||||
} else if (CompositorService.isLabwc) {
|
||||
return "file://" + Theme.shellDir + "/assets/labwc.png"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -421,7 +421,11 @@ Item {
|
||||
tooltipLoader.item.show(delegateItem.tooltipText, screenX + tooltipX, relativeY, root.parentScreen, isLeft, !isLeft)
|
||||
} else {
|
||||
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, delegateItem.height)
|
||||
const tooltipY = Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS
|
||||
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height
|
||||
const isBottom = root.axis?.edge === "bottom"
|
||||
const tooltipY = isBottom
|
||||
? (screenHeight - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS - 35)
|
||||
: (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS)
|
||||
tooltipLoader.item.show(delegateItem.tooltipText, globalPos.x, tooltipY, root.parentScreen, false, false)
|
||||
}
|
||||
}
|
||||
@@ -650,7 +654,11 @@ Item {
|
||||
tooltipLoader.item.show(delegateItem.tooltipText, screenX + tooltipX, relativeY, root.parentScreen, isLeft, !isLeft)
|
||||
} else {
|
||||
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, delegateItem.height)
|
||||
const tooltipY = Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS
|
||||
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height
|
||||
const isBottom = root.axis?.edge === "bottom"
|
||||
const tooltipY = isBottom
|
||||
? (screenHeight - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS - 35)
|
||||
: (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS)
|
||||
tooltipLoader.item.show(delegateItem.tooltipText, globalPos.x, tooltipY, root.parentScreen, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ Item {
|
||||
const envValue = Quickshell.env("DMS_HIDE_TRAYIDS") || ""
|
||||
return envValue ? envValue.split(",").map(id => id.trim().toLowerCase()) : []
|
||||
}
|
||||
readonly property var visibleTrayItems: {
|
||||
readonly property var allTrayItems: {
|
||||
if (!hiddenTrayIds.length) {
|
||||
return SystemTray.items.values
|
||||
}
|
||||
@@ -31,13 +31,20 @@ Item {
|
||||
return !hiddenTrayIds.includes(itemId.toLowerCase())
|
||||
})
|
||||
}
|
||||
readonly property int calculatedSize: visibleTrayItems.length > 0 ? visibleTrayItems.length * 24 + horizontalPadding * 2 : 0
|
||||
readonly property var mainBarItems: allTrayItems.filter(item => !SessionData.isHiddenTrayId(item?.id || ""))
|
||||
readonly property int calculatedSize: {
|
||||
if (allTrayItems.length === 0) return 0
|
||||
const itemCount = mainBarItems.length + 1
|
||||
return itemCount * 24 + horizontalPadding * 2
|
||||
}
|
||||
readonly property real visualWidth: isVertical ? widgetThickness : calculatedSize
|
||||
readonly property real visualHeight: isVertical ? calculatedSize : widgetThickness
|
||||
|
||||
width: isVertical ? barThickness : visualWidth
|
||||
height: isVertical ? visualHeight : barThickness
|
||||
visible: visibleTrayItems.length > 0
|
||||
visible: allTrayItems.length > 0
|
||||
|
||||
property bool menuOpen: false
|
||||
|
||||
Rectangle {
|
||||
id: visualBackground
|
||||
@@ -46,7 +53,7 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
||||
color: {
|
||||
if (visibleTrayItems.length === 0) {
|
||||
if (allTrayItems.length === 0) {
|
||||
return "transparent";
|
||||
}
|
||||
|
||||
@@ -71,7 +78,7 @@ Item {
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: root.visibleTrayItems
|
||||
model: root.mainBarItems
|
||||
|
||||
delegate: Item {
|
||||
id: delegateRoot
|
||||
@@ -165,6 +172,35 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 24
|
||||
height: root.barThickness
|
||||
|
||||
Rectangle {
|
||||
id: caretButton
|
||||
width: 24
|
||||
height: 24
|
||||
anchors.centerIn: parent
|
||||
radius: Theme.cornerRadius
|
||||
color: caretArea.containsMouse ? Theme.primaryHover : "transparent"
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: root.menuOpen ? "expand_less" : "expand_more"
|
||||
size: Theme.barIconSize(root.barThickness)
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: caretArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.menuOpen = !root.menuOpen
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +210,7 @@ Item {
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: root.visibleTrayItems
|
||||
model: root.mainBarItems
|
||||
|
||||
delegate: Item {
|
||||
id: delegateRoot
|
||||
@@ -268,6 +304,320 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: root.barThickness
|
||||
height: 24
|
||||
|
||||
Rectangle {
|
||||
id: caretButtonVert
|
||||
width: 24
|
||||
height: 24
|
||||
anchors.centerIn: parent
|
||||
radius: Theme.cornerRadius
|
||||
color: caretAreaVert.containsMouse ? Theme.primaryHover : "transparent"
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: {
|
||||
const edge = root.axis?.edge
|
||||
if (edge === "left") {
|
||||
return root.menuOpen ? "chevron_left" : "chevron_right"
|
||||
} else {
|
||||
return root.menuOpen ? "chevron_right" : "chevron_left"
|
||||
}
|
||||
}
|
||||
size: Theme.barIconSize(root.barThickness)
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: caretAreaVert
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.menuOpen = !root.menuOpen
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: overflowMenu
|
||||
visible: root.menuOpen
|
||||
screen: root.parentScreen
|
||||
WlrLayershell.layer: WlrLayershell.Top
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
WlrLayershell.namespace: "dms:tray-overflow-menu"
|
||||
color: "transparent"
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
bottom: true
|
||||
}
|
||||
|
||||
property point anchorPos: Qt.point(screen.width / 2, screen.height / 2)
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) updatePosition()
|
||||
}
|
||||
|
||||
function updatePosition() {
|
||||
if (!root.parentWindow) {
|
||||
anchorPos = Qt.point(screen.width / 2, screen.height / 2)
|
||||
return
|
||||
}
|
||||
|
||||
const globalPos = root.mapToGlobal(0, 0)
|
||||
const screenX = screen.x || 0
|
||||
const screenY = screen.y || 0
|
||||
const relativeX = globalPos.x - screenX
|
||||
const relativeY = globalPos.y - screenY
|
||||
|
||||
const widgetThickness = Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
|
||||
const effectiveBarThickness = Math.max(widgetThickness + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
|
||||
|
||||
if (root.isVertical) {
|
||||
const edge = root.axis?.edge
|
||||
let targetX = edge === "left"
|
||||
? effectiveBarThickness + SettingsData.dankBarSpacing + Theme.popupDistance
|
||||
: screen.width - (effectiveBarThickness + SettingsData.dankBarSpacing + Theme.popupDistance)
|
||||
anchorPos = Qt.point(targetX, relativeY + root.height / 2)
|
||||
} else {
|
||||
let targetY = root.isAtBottom
|
||||
? screen.height - (effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap + Theme.popupDistance)
|
||||
: effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap + Theme.popupDistance
|
||||
anchorPos = Qt.point(relativeX + root.width / 2, targetY)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: menuContainer
|
||||
width: 250
|
||||
height: Math.min(screen.height - 100, menuColumn.implicitHeight + Theme.spacingS * 2)
|
||||
|
||||
x: {
|
||||
if (root.isVertical) {
|
||||
const edge = root.axis?.edge
|
||||
if (edge === "left") {
|
||||
const targetX = overflowMenu.anchorPos.x
|
||||
return Math.min(overflowMenu.screen.width - width - 10, targetX)
|
||||
} else {
|
||||
const targetX = overflowMenu.anchorPos.x - width
|
||||
return Math.max(10, targetX)
|
||||
}
|
||||
} else {
|
||||
const left = 10
|
||||
const right = overflowMenu.width - width - 10
|
||||
const want = overflowMenu.anchorPos.x - width / 2
|
||||
return Math.max(left, Math.min(right, want))
|
||||
}
|
||||
}
|
||||
|
||||
y: {
|
||||
if (root.isVertical) {
|
||||
const top = 10
|
||||
const bottom = overflowMenu.height - height - 10
|
||||
const want = overflowMenu.anchorPos.y - height / 2
|
||||
return Math.max(top, Math.min(bottom, want))
|
||||
} else {
|
||||
if (root.isAtBottom) {
|
||||
const targetY = overflowMenu.anchorPos.y - height
|
||||
return Math.max(10, targetY)
|
||||
} else {
|
||||
const targetY = overflowMenu.anchorPos.y
|
||||
return Math.min(overflowMenu.screen.height - height - 10, targetY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||
radius: Theme.cornerRadius
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||
border.width: 1
|
||||
|
||||
opacity: root.menuOpen ? 1 : 0
|
||||
scale: root.menuOpen ? 1 : 0.85
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Theme.mediumDuration
|
||||
easing.type: Theme.emphasizedEasing
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Theme.mediumDuration
|
||||
easing.type: Theme.emphasizedEasing
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 4
|
||||
anchors.leftMargin: 2
|
||||
anchors.rightMargin: -2
|
||||
anchors.bottomMargin: -4
|
||||
radius: parent.radius
|
||||
color: Qt.rgba(0, 0, 0, 0.15)
|
||||
z: parent.z - 1
|
||||
}
|
||||
|
||||
DankFlickable {
|
||||
id: scrollView
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingS
|
||||
contentWidth: width
|
||||
contentHeight: menuColumn.implicitHeight
|
||||
clip: true
|
||||
|
||||
Column {
|
||||
id: menuColumn
|
||||
width: parent.width
|
||||
spacing: 2
|
||||
|
||||
Repeater {
|
||||
model: root.allTrayItems
|
||||
|
||||
delegate: Rectangle {
|
||||
property var trayItem: modelData
|
||||
property string iconSource: {
|
||||
let icon = trayItem?.icon
|
||||
if (typeof icon === 'string' || icon instanceof String) {
|
||||
if (icon === "") return ""
|
||||
if (icon.includes("?path=")) {
|
||||
const split = icon.split("?path=")
|
||||
if (split.length !== 2) return icon
|
||||
const name = split[0]
|
||||
const path = split[1]
|
||||
let fileName = name.substring(name.lastIndexOf("/") + 1)
|
||||
if (fileName.startsWith("dropboxstatus")) {
|
||||
fileName = `hicolor/16x16/status/${fileName}`
|
||||
}
|
||||
return `file://${path}/${fileName}`
|
||||
}
|
||||
if (icon.startsWith("/") && !icon.startsWith("file://")) {
|
||||
return `file://${icon}`
|
||||
}
|
||||
return icon
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
width: menuColumn.width
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: itemArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingS
|
||||
|
||||
IconImage {
|
||||
id: menuIconImg
|
||||
width: 20
|
||||
height: 20
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: parent.parent.iconSource
|
||||
asynchronous: true
|
||||
smooth: true
|
||||
mipmap: true
|
||||
visible: status === Image.Ready
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: !menuIconImg.visible
|
||||
text: {
|
||||
const itemId = trayItem?.id || ""
|
||||
if (!itemId) return "?"
|
||||
return itemId.charAt(0).toUpperCase()
|
||||
}
|
||||
font.pixelSize: 10
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: trayItem?.tooltip?.title || trayItem?.id || "Unknown"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
elide: Text.ElideRight
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Math.min(implicitWidth, menuColumn.width - 80)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 24
|
||||
height: 24
|
||||
radius: Theme.cornerRadius
|
||||
color: visibilityArea.containsMouse ? Theme.primaryHover : "transparent"
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: SessionData.isHiddenTrayId(trayItem?.id || "") ? "visibility_off" : "visibility"
|
||||
size: 16
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: visibilityArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const itemId = trayItem?.id || ""
|
||||
if (!itemId) return
|
||||
if (SessionData.isHiddenTrayId(itemId)) {
|
||||
SessionData.showTrayId(itemId)
|
||||
} else {
|
||||
SessionData.hideTrayId(itemId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: itemArea
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 32
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: (mouse) => {
|
||||
if (!trayItem) return
|
||||
|
||||
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
|
||||
trayItem.activate()
|
||||
root.menuOpen = false
|
||||
return
|
||||
}
|
||||
if (trayItem.hasMenu) {
|
||||
root.menuOpen = false
|
||||
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
onClicked: root.menuOpen = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,9 +690,12 @@ Item {
|
||||
color: "transparent"
|
||||
|
||||
PanelWindow {
|
||||
|
||||
WlrLayershell.namespace: "dms:tray-menu-window"
|
||||
|
||||
id: menuWindow
|
||||
visible: menuRoot.showMenu && (menuRoot.trayItem?.hasMenu ?? false)
|
||||
WlrLayershell.layer: WlrLayershell.Overlay
|
||||
WlrLayershell.layer: WlrLayershell.Top
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
color: "transparent"
|
||||
@@ -678,7 +1031,21 @@ Item {
|
||||
|
||||
property var currentTrayMenu: null
|
||||
|
||||
Connections {
|
||||
target: currentTrayMenu
|
||||
enabled: currentTrayMenu !== null
|
||||
function onShowMenuChanged() {
|
||||
if (parentWindow && typeof parentWindow.systemTrayMenuOpen !== "undefined") {
|
||||
parentWindow.systemTrayMenuOpen = currentTrayMenu.showMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showForTrayItem(item, anchor, screen, atBottom, vertical, axisObj) {
|
||||
if (parentWindow && typeof parentWindow.systemTrayMenuOpen !== "undefined") {
|
||||
parentWindow.systemTrayMenuOpen = true
|
||||
}
|
||||
|
||||
if (currentTrayMenu) {
|
||||
currentTrayMenu.destroy()
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ Item {
|
||||
return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, screenName);
|
||||
}
|
||||
|
||||
readonly property bool useExtWorkspace: DMSService.forceExtWorkspace || (!CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isDwl && !CompositorService.isSway && ExtWorkspaceService.extWorkspaceAvailable)
|
||||
|
||||
Connections {
|
||||
target: DesktopEntries
|
||||
function onApplicationsChanged() {
|
||||
@@ -30,18 +32,22 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
property int currentWorkspace: {
|
||||
if (CompositorService.isNiri) {
|
||||
property var currentWorkspace: {
|
||||
if (useExtWorkspace) return getExtWorkspaceActiveWorkspace()
|
||||
|
||||
switch (CompositorService.compositor) {
|
||||
case "niri":
|
||||
return getNiriActiveWorkspace()
|
||||
} else if (CompositorService.isHyprland) {
|
||||
case "hyprland":
|
||||
return getHyprlandActiveWorkspace()
|
||||
} else if (CompositorService.isDwl) {
|
||||
case "dwl":
|
||||
const activeTags = getDwlActiveTags()
|
||||
return activeTags.length > 0 ? activeTags[0] : -1
|
||||
} else if (CompositorService.isSway) {
|
||||
case "sway":
|
||||
return getSwayActiveWorkspace()
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
property var dwlActiveTags: {
|
||||
if (CompositorService.isDwl) {
|
||||
@@ -50,24 +56,29 @@ Item {
|
||||
return []
|
||||
}
|
||||
property var workspaceList: {
|
||||
if (CompositorService.isNiri) {
|
||||
const baseList = getNiriWorkspaces()
|
||||
if (useExtWorkspace) {
|
||||
const baseList = getExtWorkspaceWorkspaces()
|
||||
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
||||
}
|
||||
if (CompositorService.isHyprland) {
|
||||
const baseList = getHyprlandWorkspaces()
|
||||
const filteredList = baseList.filter(ws => ws.id > -1)
|
||||
return SettingsData.showWorkspacePadding ? padWorkspaces(filteredList) : filteredList
|
||||
|
||||
let baseList
|
||||
switch (CompositorService.compositor) {
|
||||
case "niri":
|
||||
baseList = getNiriWorkspaces()
|
||||
break
|
||||
case "hyprland":
|
||||
baseList = getHyprlandWorkspaces()
|
||||
break
|
||||
case "dwl":
|
||||
baseList = getDwlTags()
|
||||
break
|
||||
case "sway":
|
||||
baseList = getSwayWorkspaces()
|
||||
break
|
||||
default:
|
||||
return [1]
|
||||
}
|
||||
if (CompositorService.isDwl) {
|
||||
const baseList = getDwlTags()
|
||||
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
||||
}
|
||||
if (CompositorService.isSway) {
|
||||
const baseList = getSwayWorkspaces()
|
||||
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
||||
}
|
||||
return [1]
|
||||
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
||||
}
|
||||
|
||||
function getSwayWorkspaces() {
|
||||
@@ -92,6 +103,27 @@ Item {
|
||||
return focusedWs ? focusedWs.num : 1
|
||||
}
|
||||
|
||||
function getHyprlandWorkspaces() {
|
||||
const workspaces = Hyprland.workspaces?.values || []
|
||||
if (workspaces.length === 0) return [{id: 1}]
|
||||
|
||||
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||
return workspaces.slice().sort((a, b) => a.id - b.id)
|
||||
}
|
||||
|
||||
const monitorWorkspaces = workspaces.filter(ws => ws.monitor?.name === root.screenName)
|
||||
return monitorWorkspaces.length > 0 ? monitorWorkspaces.sort((a, b) => a.id - b.id) : [{id: 1}]
|
||||
}
|
||||
|
||||
function getHyprlandActiveWorkspace() {
|
||||
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||
return Hyprland.focusedWorkspace?.id || 1
|
||||
}
|
||||
|
||||
const monitor = Hyprland.monitors?.values?.find(m => m.name === root.screenName)
|
||||
return monitor?.activeWorkspace?.id || 1
|
||||
}
|
||||
|
||||
function getWorkspaceIcons(ws) {
|
||||
_desktopEntriesUpdateTrigger
|
||||
if (!SettingsData.showWorkspaceApps || !ws) {
|
||||
@@ -192,7 +224,9 @@ Item {
|
||||
function padWorkspaces(list) {
|
||||
const padded = list.slice()
|
||||
let placeholder
|
||||
if (CompositorService.isHyprland) {
|
||||
if (useExtWorkspace) {
|
||||
placeholder = {"id": "", "name": "", "active": false, "hidden": true}
|
||||
} else if (CompositorService.isHyprland) {
|
||||
placeholder = {"id": -1, "name": ""}
|
||||
} else if (CompositorService.isDwl) {
|
||||
placeholder = {"tag": -1}
|
||||
@@ -233,51 +267,6 @@ Item {
|
||||
return activeWs ? activeWs.idx + 1 : 1
|
||||
}
|
||||
|
||||
function getHyprlandWorkspaces() {
|
||||
const workspaces = Hyprland.workspaces?.values || []
|
||||
|
||||
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||
// Show all workspaces on all monitors if per-monitor filtering is disabled
|
||||
const sorted = workspaces.slice().sort((a, b) => a.id - b.id)
|
||||
return sorted.length > 0 ? sorted : [{
|
||||
"id": 1,
|
||||
"name": "1"
|
||||
}]
|
||||
}
|
||||
|
||||
// Filter workspaces for this specific monitor using lastIpcObject.monitor
|
||||
// This matches the approach from the original kyle-config
|
||||
const monitorWorkspaces = workspaces.filter(ws => {
|
||||
return ws.lastIpcObject && ws.lastIpcObject.monitor === root.screenName
|
||||
})
|
||||
|
||||
if (monitorWorkspaces.length === 0) {
|
||||
// Fallback if no workspaces exist for this monitor
|
||||
return [{
|
||||
"id": 1,
|
||||
"name": "1"
|
||||
}]
|
||||
}
|
||||
|
||||
// Return all workspaces for this monitor, sorted by ID
|
||||
return monitorWorkspaces.sort((a, b) => a.id - b.id)
|
||||
}
|
||||
|
||||
function getHyprlandActiveWorkspace() {
|
||||
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||
return Hyprland.focusedWorkspace ? Hyprland.focusedWorkspace.id : 1
|
||||
}
|
||||
|
||||
const monitors = Hyprland.monitors?.values || []
|
||||
const currentMonitor = monitors.find(monitor => monitor.name === root.screenName)
|
||||
|
||||
if (!currentMonitor) {
|
||||
return 1
|
||||
}
|
||||
|
||||
return currentMonitor.activeWorkspace?.id ?? 1
|
||||
}
|
||||
|
||||
function getDwlTags() {
|
||||
if (!DwlService.dwlAvailable) {
|
||||
return []
|
||||
@@ -313,25 +302,77 @@ Item {
|
||||
return activeTags
|
||||
}
|
||||
|
||||
function getExtWorkspaceWorkspaces() {
|
||||
const groups = ExtWorkspaceService.groups
|
||||
if (!ExtWorkspaceService.extWorkspaceAvailable || groups.length === 0) {
|
||||
return [{"id": "1", "name": "1", "active": false}]
|
||||
}
|
||||
|
||||
const group = groups.find(g => g.outputs && g.outputs.includes(root.screenName))
|
||||
if (!group || !group.workspaces) {
|
||||
return [{"id": "1", "name": "1", "active": false}]
|
||||
}
|
||||
|
||||
const visible = group.workspaces.filter(ws => !ws.hidden).sort((a, b) => {
|
||||
const coordsA = a.coordinates || [0, 0]
|
||||
const coordsB = b.coordinates || [0, 0]
|
||||
if (coordsA[0] !== coordsB[0]) return coordsA[0] - coordsB[0]
|
||||
return coordsA[1] - coordsB[1]
|
||||
}).map(ws => ({
|
||||
id: ws.id,
|
||||
name: ws.name,
|
||||
coordinates: ws.coordinates,
|
||||
state: ws.state,
|
||||
active: ws.active,
|
||||
urgent: ws.urgent,
|
||||
hidden: ws.hidden,
|
||||
groupID: group.id
|
||||
}))
|
||||
|
||||
return visible.length > 0 ? visible : [{"id": "1", "name": "1", "active": false}]
|
||||
}
|
||||
|
||||
function getExtWorkspaceActiveWorkspace() {
|
||||
if (!ExtWorkspaceService.extWorkspaceAvailable) {
|
||||
return 1
|
||||
}
|
||||
|
||||
const activeWs = ExtWorkspaceService.getActiveWorkspaceForOutput(root.screenName)
|
||||
return activeWs ? (activeWs.id || activeWs.name || "1") : "1"
|
||||
}
|
||||
|
||||
readonly property real padding: Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30))
|
||||
readonly property real visualWidth: isVertical ? widgetHeight : (workspaceRow.implicitWidth + padding * 2)
|
||||
readonly property real visualHeight: isVertical ? (workspaceRow.implicitHeight + padding * 2) : widgetHeight
|
||||
|
||||
function getRealWorkspaces() {
|
||||
return root.workspaceList.filter(ws => {
|
||||
if (CompositorService.isHyprland) {
|
||||
return ws && ws.id !== -1
|
||||
} else if (CompositorService.isDwl) {
|
||||
return ws && ws.tag !== -1
|
||||
} else if (CompositorService.isSway) {
|
||||
return ws && ws.num !== -1
|
||||
}
|
||||
if (useExtWorkspace) return ws && ws.id !== "" && !ws.hidden
|
||||
if (CompositorService.isHyprland) return ws && ws.id !== -1
|
||||
if (CompositorService.isDwl) return ws && ws.tag !== -1
|
||||
if (CompositorService.isSway) return ws && ws.num !== -1
|
||||
return ws !== -1
|
||||
})
|
||||
}
|
||||
|
||||
function switchWorkspace(direction) {
|
||||
if (CompositorService.isNiri) {
|
||||
if (useExtWorkspace) {
|
||||
const realWorkspaces = getRealWorkspaces()
|
||||
if (realWorkspaces.length < 2) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentIndex = realWorkspaces.findIndex(ws => (ws.id || ws.name) === root.currentWorkspace)
|
||||
const validIndex = currentIndex === -1 ? 0 : currentIndex
|
||||
const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0)
|
||||
|
||||
if (nextIndex === validIndex) {
|
||||
return
|
||||
}
|
||||
|
||||
const nextWorkspace = realWorkspaces[nextIndex]
|
||||
ExtWorkspaceService.activateWorkspace(nextWorkspace.id || nextWorkspace.name, nextWorkspace.groupID || "")
|
||||
} else if (CompositorService.isNiri) {
|
||||
const realWorkspaces = getRealWorkspaces()
|
||||
if (realWorkspaces.length < 2) {
|
||||
return
|
||||
@@ -396,7 +437,7 @@ Item {
|
||||
|
||||
width: isVertical ? barThickness : visualWidth
|
||||
height: isVertical ? visualHeight : barThickness
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway || useExtWorkspace
|
||||
|
||||
Rectangle {
|
||||
id: visualBackground
|
||||
@@ -443,23 +484,17 @@ Item {
|
||||
id: delegateRoot
|
||||
|
||||
property bool isActive: {
|
||||
if (CompositorService.isHyprland) {
|
||||
return modelData && modelData.id === root.currentWorkspace
|
||||
} else if (CompositorService.isDwl) {
|
||||
return modelData && root.dwlActiveTags.includes(modelData.tag)
|
||||
} else if (CompositorService.isSway) {
|
||||
return modelData && modelData.num === root.currentWorkspace
|
||||
}
|
||||
if (root.useExtWorkspace) return (modelData?.id || modelData?.name) === root.currentWorkspace
|
||||
if (CompositorService.isHyprland) return !!(modelData && modelData.id === root.currentWorkspace)
|
||||
if (CompositorService.isDwl) return !!(modelData && root.dwlActiveTags.includes(modelData.tag))
|
||||
if (CompositorService.isSway) return !!(modelData && modelData.num === root.currentWorkspace)
|
||||
return modelData === root.currentWorkspace
|
||||
}
|
||||
property bool isPlaceholder: {
|
||||
if (CompositorService.isHyprland) {
|
||||
return modelData && modelData.id === -1
|
||||
} else if (CompositorService.isDwl) {
|
||||
return modelData && modelData.tag === -1
|
||||
} else if (CompositorService.isSway) {
|
||||
return modelData && modelData.num === -1
|
||||
}
|
||||
if (root.useExtWorkspace) return !!(modelData && modelData.hidden)
|
||||
if (CompositorService.isHyprland) return !!(modelData && modelData.id === -1)
|
||||
if (CompositorService.isDwl) return !!(modelData && modelData.tag === -1)
|
||||
if (CompositorService.isSway) return !!(modelData && modelData.num === -1)
|
||||
return modelData === -1
|
||||
}
|
||||
property bool isHovered: mouseArea.containsMouse
|
||||
@@ -467,15 +502,11 @@ Item {
|
||||
property var loadedWorkspaceData: null
|
||||
property bool loadedIsUrgent: false
|
||||
property bool isUrgent: {
|
||||
if (CompositorService.isHyprland) {
|
||||
return modelData?.urgent ?? false
|
||||
} else if (CompositorService.isNiri) {
|
||||
return loadedIsUrgent
|
||||
} else if (CompositorService.isDwl) {
|
||||
return modelData?.state === 2
|
||||
} else if (CompositorService.isSway) {
|
||||
return loadedIsUrgent
|
||||
}
|
||||
if (root.useExtWorkspace) return modelData?.urgent ?? false
|
||||
if (CompositorService.isHyprland) return modelData?.urgent ?? false
|
||||
if (CompositorService.isNiri) return loadedIsUrgent
|
||||
if (CompositorService.isDwl) return modelData?.state === 2
|
||||
if (CompositorService.isSway) return loadedIsUrgent
|
||||
return false
|
||||
}
|
||||
property var loadedIconData: null
|
||||
@@ -511,13 +542,13 @@ Item {
|
||||
enabled: !isPlaceholder
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: mouse => {
|
||||
if (isPlaceholder) {
|
||||
return
|
||||
}
|
||||
if (isPlaceholder) return
|
||||
|
||||
const isRightClick = mouse.button === Qt.RightButton
|
||||
|
||||
if (CompositorService.isNiri) {
|
||||
if (root.useExtWorkspace && (modelData?.id || modelData?.name)) {
|
||||
ExtWorkspaceService.activateWorkspace(modelData.id || modelData.name, modelData.groupID || "")
|
||||
} else if (CompositorService.isNiri) {
|
||||
if (isRightClick) {
|
||||
NiriService.toggleOverview()
|
||||
} else {
|
||||
@@ -558,7 +589,9 @@ Item {
|
||||
}
|
||||
|
||||
var wsData = null;
|
||||
if (CompositorService.isNiri) {
|
||||
if (root.useExtWorkspace) {
|
||||
wsData = modelData;
|
||||
} else if (CompositorService.isNiri) {
|
||||
wsData = NiriService.allWorkspaces.find(ws => ws.idx + 1 === modelData && ws.output === root.screenName) || null;
|
||||
} else if (CompositorService.isHyprland) {
|
||||
wsData = modelData;
|
||||
@@ -839,7 +872,9 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
text: {
|
||||
let isPlaceholder
|
||||
if (CompositorService.isHyprland) {
|
||||
if (root.useExtWorkspace) {
|
||||
isPlaceholder = modelData?.hidden === true
|
||||
} else if (CompositorService.isHyprland) {
|
||||
isPlaceholder = modelData?.id === -1
|
||||
} else if (CompositorService.isDwl) {
|
||||
isPlaceholder = modelData?.tag === -1
|
||||
@@ -849,17 +884,12 @@ Item {
|
||||
isPlaceholder = modelData === -1
|
||||
}
|
||||
|
||||
if (isPlaceholder) {
|
||||
return index + 1
|
||||
}
|
||||
if (isPlaceholder) return index + 1
|
||||
|
||||
if (CompositorService.isHyprland) {
|
||||
return modelData?.id || ""
|
||||
} else if (CompositorService.isDwl) {
|
||||
return (modelData?.tag !== undefined) ? (modelData.tag + 1) : ""
|
||||
} else if (CompositorService.isSway) {
|
||||
return modelData?.num || ""
|
||||
}
|
||||
if (root.useExtWorkspace) return modelData?.name || modelData?.id || ""
|
||||
if (CompositorService.isHyprland) return modelData?.id || ""
|
||||
if (CompositorService.isDwl) return (modelData?.tag !== undefined) ? (modelData.tag + 1) : ""
|
||||
if (CompositorService.isSway) return modelData?.num || ""
|
||||
return modelData - 1
|
||||
}
|
||||
color: (isActive || isUrgent) ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : isPlaceholder ? Theme.surfaceTextAlpha : Theme.surfaceTextMedium
|
||||
@@ -893,12 +923,28 @@ Item {
|
||||
enabled: CompositorService.isDwl
|
||||
function onStateChanged() { delegateRoot.updateAllData() }
|
||||
}
|
||||
Connections {
|
||||
target: Hyprland.workspaces
|
||||
enabled: CompositorService.isHyprland
|
||||
function onValuesChanged() { delegateRoot.updateAllData() }
|
||||
}
|
||||
Connections {
|
||||
target: I3.workspaces
|
||||
enabled: CompositorService.isSway
|
||||
function onValuesChanged() { delegateRoot.updateAllData() }
|
||||
}
|
||||
Connections {
|
||||
target: ExtWorkspaceService
|
||||
enabled: root.useExtWorkspace
|
||||
function onStateChanged() { delegateRoot.updateAllData() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (useExtWorkspace && !DMSService.activeSubscriptions.includes("extworkspace")) {
|
||||
DMSService.addSubscription("extworkspace")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ Variants {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
id: dockBackground
|
||||
objectName: "dockBackground"
|
||||
anchors {
|
||||
@@ -360,16 +360,13 @@ Variants {
|
||||
width: implicitWidth
|
||||
height: implicitHeight
|
||||
|
||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, backgroundTransparency)
|
||||
radius: Theme.cornerRadius
|
||||
border.width: 1
|
||||
border.color: Theme.outlineMedium
|
||||
layer.enabled: true
|
||||
clip: false
|
||||
|
||||
Rectangle {
|
||||
DankRectangle {
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g, Theme.surfaceTint.b, 0.04)
|
||||
radius: parent.radius
|
||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, backgroundTransparency)
|
||||
overlayColor: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g, Theme.surfaceTint.b, 0.04)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Widgets
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
@@ -91,56 +92,11 @@ Item {
|
||||
}
|
||||
|
||||
function getToplevelObject() {
|
||||
if (!appData) {
|
||||
return null
|
||||
}
|
||||
|
||||
const sortedToplevels = CompositorService.sortedToplevels
|
||||
if (!sortedToplevels) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (appData.type === "window") {
|
||||
if (appData.uniqueId) {
|
||||
for (var i = 0; i < sortedToplevels.length; i++) {
|
||||
const toplevel = sortedToplevels[i]
|
||||
const checkId = toplevel.title + "|" + (toplevel.appId || "") + "|" + i
|
||||
if (checkId === appData.uniqueId) {
|
||||
return toplevel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (appData.windowId !== undefined && appData.windowId !== null && appData.windowId >= 0) {
|
||||
if (appData.windowId < sortedToplevels.length) {
|
||||
return sortedToplevels[appData.windowId]
|
||||
}
|
||||
}
|
||||
} else if (appData.type === "grouped") {
|
||||
if (appData.windowId !== undefined && appData.windowId !== null && appData.windowId >= 0) {
|
||||
if (appData.windowId < sortedToplevels.length) {
|
||||
return sortedToplevels[appData.windowId]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return appData?.toplevel || null
|
||||
}
|
||||
|
||||
function getGroupedToplevels() {
|
||||
if (!appData || appData.type !== "grouped") {
|
||||
return []
|
||||
}
|
||||
|
||||
const toplevels = []
|
||||
const allToplevels = ToplevelManager.toplevels.values
|
||||
for (let i = 0; i < allToplevels.length; i++) {
|
||||
const toplevel = allToplevels[i]
|
||||
if (toplevel.appId === appData.appId) {
|
||||
toplevels.push(toplevel)
|
||||
}
|
||||
}
|
||||
return toplevels
|
||||
return appData?.allWindows?.map(w => w.toplevel).filter(t => t !== null) || []
|
||||
}
|
||||
onIsHoveredChanged: {
|
||||
if (mouseArea.pressed) return
|
||||
@@ -325,17 +281,9 @@ Item {
|
||||
}
|
||||
}
|
||||
} else if (mouse.button === Qt.MiddleButton) {
|
||||
if (appData && appData.type === "window") {
|
||||
const sortedToplevels = CompositorService.sortedToplevels
|
||||
for (var i = 0; i < sortedToplevels.length; i++) {
|
||||
const toplevel = sortedToplevels[i]
|
||||
const checkId = toplevel.title + "|" + (toplevel.appId || "") + "|" + i
|
||||
if (checkId === appData.uniqueId) {
|
||||
toplevel.close()
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (appData && appData.type === "grouped") {
|
||||
if (appData?.type === "window") {
|
||||
appData?.toplevel?.close()
|
||||
} else if (appData?.type === "grouped") {
|
||||
if (contextMenu) {
|
||||
contextMenu.showForButton(root, appData, root.height, false, cachedDesktopEntry, parentDockScreen)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
@@ -54,158 +55,149 @@ Item {
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: ListModel {
|
||||
id: dockModel
|
||||
|
||||
Component.onCompleted: updateModel()
|
||||
property var dockItems: []
|
||||
|
||||
function updateModel() {
|
||||
clear()
|
||||
model: ScriptModel {
|
||||
values: repeater.dockItems
|
||||
objectProp: "uniqueKey"
|
||||
}
|
||||
|
||||
const items = []
|
||||
const pinnedApps = [...(SessionData.pinnedApps || [])]
|
||||
const sortedToplevels = CompositorService.sortedToplevels
|
||||
Component.onCompleted: updateModel()
|
||||
|
||||
if (root.groupByApp) {
|
||||
// Group windows by appId
|
||||
const appGroups = new Map()
|
||||
function updateModel() {
|
||||
const items = []
|
||||
const pinnedApps = [...(SessionData.pinnedApps || [])]
|
||||
const sortedToplevels = CompositorService.sortedToplevels
|
||||
|
||||
// Add pinned apps first (even if they have no windows)
|
||||
pinnedApps.forEach(appId => {
|
||||
if (root.groupByApp) {
|
||||
const appGroups = new Map()
|
||||
|
||||
pinnedApps.forEach(appId => {
|
||||
appGroups.set(appId, {
|
||||
appId: appId,
|
||||
isPinned: true,
|
||||
windows: []
|
||||
})
|
||||
})
|
||||
|
||||
sortedToplevels.forEach((toplevel, index) => {
|
||||
const appId = toplevel.appId || "unknown"
|
||||
if (!appGroups.has(appId)) {
|
||||
appGroups.set(appId, {
|
||||
appId: appId,
|
||||
isPinned: true,
|
||||
isPinned: false,
|
||||
windows: []
|
||||
})
|
||||
})
|
||||
|
||||
// Group all running windows by appId
|
||||
sortedToplevels.forEach((toplevel, index) => {
|
||||
const appId = toplevel.appId || "unknown"
|
||||
if (!appGroups.has(appId)) {
|
||||
appGroups.set(appId, {
|
||||
appId: appId,
|
||||
isPinned: false,
|
||||
windows: []
|
||||
})
|
||||
}
|
||||
const title = toplevel.title || "(Unnamed)"
|
||||
const truncatedTitle = title.length > 50 ? title.substring(0, 47) + "..." : title
|
||||
const uniqueId = toplevel.title + "|" + (toplevel.appId || "") + "|" + index
|
||||
|
||||
appGroups.get(appId).windows.push({
|
||||
windowId: index,
|
||||
windowTitle: truncatedTitle,
|
||||
uniqueId: uniqueId
|
||||
})
|
||||
})
|
||||
|
||||
// Sort groups: pinned first, then unpinned
|
||||
const pinnedGroups = []
|
||||
const unpinnedGroups = []
|
||||
|
||||
Array.from(appGroups.entries()).forEach(([appId, group]) => {
|
||||
// For grouped apps, just show the first window info but track all windows
|
||||
const firstWindow = group.windows.length > 0 ? group.windows[0] : null
|
||||
|
||||
const item = {
|
||||
"type": "grouped",
|
||||
"appId": appId,
|
||||
"windowId": firstWindow ? firstWindow.windowId : -1,
|
||||
"windowTitle": firstWindow ? firstWindow.windowTitle : "",
|
||||
"workspaceId": -1,
|
||||
"isPinned": group.isPinned,
|
||||
"isRunning": group.windows.length > 0,
|
||||
"windowCount": group.windows.length,
|
||||
"uniqueId": firstWindow ? firstWindow.uniqueId : "",
|
||||
"allWindows": group.windows
|
||||
}
|
||||
|
||||
if (group.isPinned) {
|
||||
pinnedGroups.push(item)
|
||||
} else {
|
||||
unpinnedGroups.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
// Add items in order
|
||||
pinnedGroups.forEach(item => items.push(item))
|
||||
|
||||
// Add separator if needed
|
||||
if (pinnedGroups.length > 0 && unpinnedGroups.length > 0) {
|
||||
items.push({
|
||||
"type": "separator",
|
||||
"appId": "__SEPARATOR__",
|
||||
"windowId": -1,
|
||||
"windowTitle": "",
|
||||
"workspaceId": -1,
|
||||
"isPinned": false,
|
||||
"isRunning": false
|
||||
})
|
||||
}
|
||||
|
||||
unpinnedGroups.forEach(item => items.push(item))
|
||||
root.pinnedAppCount = pinnedGroups.length
|
||||
} else {
|
||||
pinnedApps.forEach(appId => {
|
||||
items.push({
|
||||
"type": "pinned",
|
||||
"appId": appId,
|
||||
"windowId": -1,
|
||||
"windowTitle": "",
|
||||
"workspaceId": -1,
|
||||
"isPinned": true,
|
||||
"isRunning": false
|
||||
})
|
||||
appGroups.get(appId).windows.push({
|
||||
toplevel: toplevel,
|
||||
index: index
|
||||
})
|
||||
})
|
||||
|
||||
root.pinnedAppCount = pinnedApps.length
|
||||
const pinnedGroups = []
|
||||
const unpinnedGroups = []
|
||||
|
||||
if (pinnedApps.length > 0 && sortedToplevels.length > 0) {
|
||||
items.push({
|
||||
"type": "separator",
|
||||
"appId": "__SEPARATOR__",
|
||||
"windowId": -1,
|
||||
"windowTitle": "",
|
||||
"workspaceId": -1,
|
||||
"isPinned": false,
|
||||
"isRunning": false,
|
||||
"isFocused": false
|
||||
})
|
||||
Array.from(appGroups.entries()).forEach(([appId, group]) => {
|
||||
const firstWindow = group.windows.length > 0 ? group.windows[0] : null
|
||||
|
||||
const item = {
|
||||
uniqueKey: "grouped_" + appId,
|
||||
type: "grouped",
|
||||
appId: appId,
|
||||
toplevel: firstWindow ? firstWindow.toplevel : null,
|
||||
isPinned: group.isPinned,
|
||||
isRunning: group.windows.length > 0,
|
||||
windowCount: group.windows.length,
|
||||
allWindows: group.windows
|
||||
}
|
||||
|
||||
sortedToplevels.forEach((toplevel, index) => {
|
||||
const title = toplevel.title || "(Unnamed)"
|
||||
const truncatedTitle = title.length > 50 ? title.substring(0, 47) + "..." : title
|
||||
const uniqueId = toplevel.title + "|" + (toplevel.appId || "") + "|" + index
|
||||
if (group.isPinned) {
|
||||
pinnedGroups.push(item)
|
||||
} else {
|
||||
unpinnedGroups.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
items.push({
|
||||
"type": "window",
|
||||
"appId": toplevel.appId,
|
||||
"windowId": index,
|
||||
"windowTitle": truncatedTitle,
|
||||
"workspaceId": -1,
|
||||
"isPinned": false,
|
||||
"isRunning": true,
|
||||
"uniqueId": uniqueId
|
||||
})
|
||||
pinnedGroups.forEach(item => items.push(item))
|
||||
|
||||
if (pinnedGroups.length > 0 && unpinnedGroups.length > 0) {
|
||||
items.push({
|
||||
uniqueKey: "separator_grouped",
|
||||
type: "separator",
|
||||
appId: "__SEPARATOR__",
|
||||
toplevel: null,
|
||||
isPinned: false,
|
||||
isRunning: false
|
||||
})
|
||||
}
|
||||
|
||||
items.forEach(item => append(item))
|
||||
unpinnedGroups.forEach(item => items.push(item))
|
||||
root.pinnedAppCount = pinnedGroups.length
|
||||
} else {
|
||||
pinnedApps.forEach(appId => {
|
||||
items.push({
|
||||
uniqueKey: "pinned_" + appId,
|
||||
type: "pinned",
|
||||
appId: appId,
|
||||
toplevel: null,
|
||||
isPinned: true,
|
||||
isRunning: false
|
||||
})
|
||||
})
|
||||
|
||||
root.pinnedAppCount = pinnedApps.length
|
||||
|
||||
if (pinnedApps.length > 0 && sortedToplevels.length > 0) {
|
||||
items.push({
|
||||
uniqueKey: "separator_ungrouped",
|
||||
type: "separator",
|
||||
appId: "__SEPARATOR__",
|
||||
toplevel: null,
|
||||
isPinned: false,
|
||||
isRunning: false
|
||||
})
|
||||
}
|
||||
|
||||
sortedToplevels.forEach((toplevel, index) => {
|
||||
let uniqueKey = "window_" + index
|
||||
if (CompositorService.isHyprland && Hyprland.toplevels) {
|
||||
const hyprlandToplevels = Array.from(Hyprland.toplevels.values)
|
||||
for (let i = 0; i < hyprlandToplevels.length; i++) {
|
||||
if (hyprlandToplevels[i].wayland === toplevel) {
|
||||
uniqueKey = "window_" + hyprlandToplevels[i].address
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items.push({
|
||||
uniqueKey: uniqueKey,
|
||||
type: "window",
|
||||
appId: toplevel.appId,
|
||||
toplevel: toplevel,
|
||||
isPinned: false,
|
||||
isRunning: true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
dockItems = items
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
id: delegateItem
|
||||
property alias dockButton: button
|
||||
property var itemData: modelData
|
||||
clip: false
|
||||
|
||||
width: model.type === "separator" ? (root.isVertical ? root.iconSize : 8) : (root.isVertical ? root.iconSize : root.iconSize * 1.2)
|
||||
height: model.type === "separator" ? (root.isVertical ? 8 : root.iconSize) : (root.isVertical ? root.iconSize * 1.2 : root.iconSize)
|
||||
width: itemData.type === "separator" ? (root.isVertical ? root.iconSize : 8) : (root.isVertical ? root.iconSize : root.iconSize * 1.2)
|
||||
height: itemData.type === "separator" ? (root.isVertical ? 8 : root.iconSize) : (root.isVertical ? root.iconSize * 1.2 : root.iconSize)
|
||||
|
||||
Rectangle {
|
||||
visible: model.type === "separator"
|
||||
visible: itemData.type === "separator"
|
||||
width: root.isVertical ? root.iconSize * 0.5 : 2
|
||||
height: root.isVertical ? 2 : root.iconSize * 0.5
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
||||
@@ -215,21 +207,24 @@ Item {
|
||||
|
||||
DockAppButton {
|
||||
id: button
|
||||
visible: model.type !== "separator"
|
||||
visible: itemData.type !== "separator"
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: delegateItem.width
|
||||
height: delegateItem.height
|
||||
actualIconSize: root.iconSize
|
||||
|
||||
appData: model
|
||||
appData: itemData
|
||||
contextMenu: root.contextMenu
|
||||
dockApps: root
|
||||
index: model.index
|
||||
parentDockScreen: root.dockScreen
|
||||
|
||||
showWindowTitle: model.type === "window" || model.type === "grouped"
|
||||
windowTitle: model.windowTitle || ""
|
||||
showWindowTitle: itemData?.type === "window" || itemData?.type === "grouped"
|
||||
windowTitle: {
|
||||
const title = itemData?.toplevel?.title || "(Unnamed)"
|
||||
return title.length > 50 ? title.substring(0, 47) + "..." : title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,18 +234,18 @@ Item {
|
||||
Connections {
|
||||
target: CompositorService
|
||||
function onToplevelsChanged() {
|
||||
dockModel.updateModel()
|
||||
repeater.updateModel()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SessionData
|
||||
function onPinnedAppsChanged() {
|
||||
dockModel.updateModel()
|
||||
repeater.updateModel()
|
||||
}
|
||||
}
|
||||
|
||||
onGroupByAppChanged: {
|
||||
dockModel.updateModel()
|
||||
repeater.updateModel()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Widgets
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
@@ -9,6 +10,8 @@ import qs.Widgets
|
||||
PanelWindow {
|
||||
id: root
|
||||
|
||||
WlrLayershell.namespace: "dms:dock-context-menu"
|
||||
|
||||
property var appData: null
|
||||
property var anchorItem: null
|
||||
property real dockVisibleHeight: 40
|
||||
@@ -475,24 +478,10 @@ PanelWindow {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const sortedToplevels = CompositorService.sortedToplevels
|
||||
if (root.appData && root.appData.type === "window") {
|
||||
for (var i = 0; i < sortedToplevels.length; i++) {
|
||||
const toplevel = sortedToplevels[i]
|
||||
const checkId = toplevel.title + "|" + (toplevel.appId || "") + "|" + i
|
||||
if (checkId === root.appData.uniqueId) {
|
||||
toplevel.close()
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (root.appData && root.appData.type === "grouped") {
|
||||
const allToplevels = ToplevelManager.toplevels.values
|
||||
for (let i = 0; i < allToplevels.length; i++) {
|
||||
const toplevel = allToplevels[i]
|
||||
if (toplevel.appId === root.appData.appId) {
|
||||
toplevel.close()
|
||||
}
|
||||
}
|
||||
if (root.appData?.type === "window") {
|
||||
root.appData?.toplevel?.close()
|
||||
} else if (root.appData?.type === "grouped") {
|
||||
root.appData?.allWindows?.forEach(window => window.toplevel?.close())
|
||||
}
|
||||
root.close()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ Rectangle {
|
||||
}
|
||||
radius: Theme.cornerRadius
|
||||
|
||||
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Theme.shortDuration
|
||||
@@ -266,6 +265,7 @@ Rectangle {
|
||||
|
||||
Column {
|
||||
id: expandedContent
|
||||
objectName: "expandedContent"
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
@@ -321,6 +321,8 @@ Rectangle {
|
||||
spacing: 16
|
||||
|
||||
Repeater {
|
||||
id: notificationRepeater
|
||||
objectName: "notificationRepeater"
|
||||
model: ScriptModel {
|
||||
values: notificationGroup?.notifications?.slice(0, 10) || []
|
||||
}
|
||||
@@ -348,7 +350,6 @@ Rectangle {
|
||||
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
|
||||
|
||||
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Theme.shortDuration
|
||||
|
||||
@@ -28,7 +28,7 @@ QtObject {
|
||||
const nav = []
|
||||
const groups = NotificationService.groupedNotifications
|
||||
|
||||
for (let i = 0; i < groups.length; i++) {
|
||||
for (var i = 0; i < groups.length; i++) {
|
||||
const group = groups[i]
|
||||
const isExpanded = NotificationService.expandedGroups[group.key] || false
|
||||
|
||||
@@ -42,7 +42,8 @@ QtObject {
|
||||
|
||||
if (isExpanded) {
|
||||
const notifications = group.notifications || []
|
||||
for (let j = 0; j < notifications.length; j++) {
|
||||
const maxNotifications = Math.min(notifications.length, 10)
|
||||
for (var j = 0; j < maxNotifications; j++) {
|
||||
const notifId = String(notifications[j] && notifications[j].notification && notifications[j].notification.id ? notifications[j].notification.id : "")
|
||||
nav.push({
|
||||
"type": "notification",
|
||||
@@ -65,7 +66,7 @@ QtObject {
|
||||
return
|
||||
}
|
||||
|
||||
for (let i = 0; i < flatNavigation.length; i++) {
|
||||
for (var i = 0; i < flatNavigation.length; i++) {
|
||||
const item = flatNavigation[i]
|
||||
|
||||
if (selectedItemType === "group" && item.type === "group" && item.groupKey === selectedGroupKey) {
|
||||
@@ -81,7 +82,7 @@ QtObject {
|
||||
|
||||
// If not found, try to find the same group but select the group header instead
|
||||
if (selectedItemType === "notification") {
|
||||
for (let j = 0; j < flatNavigation.length; j++) {
|
||||
for (var j = 0; j < flatNavigation.length; j++) {
|
||||
const groupItem = flatNavigation[j]
|
||||
if (groupItem.type === "group" && groupItem.groupKey === selectedGroupKey) {
|
||||
selectedFlatIndex = j
|
||||
@@ -195,7 +196,7 @@ QtObject {
|
||||
// Smart selection after toggle
|
||||
if (!wasExpanded) {
|
||||
// Just expanded - move to first notification in the group
|
||||
for (let i = 0; i < flatNavigation.length; i++) {
|
||||
for (var i = 0; i < flatNavigation.length; i++) {
|
||||
if (flatNavigation[i].type === "notification" && flatNavigation[i].groupIndex === groupIndex) {
|
||||
selectedFlatIndex = i
|
||||
break
|
||||
@@ -203,7 +204,7 @@ QtObject {
|
||||
}
|
||||
} else {
|
||||
// Just collapsed - stay on the group header
|
||||
for (let i = 0; i < flatNavigation.length; i++) {
|
||||
for (var i = 0; i < flatNavigation.length; i++) {
|
||||
if (flatNavigation[i].type === "group" && flatNavigation[i].groupIndex === groupIndex) {
|
||||
selectedFlatIndex = i
|
||||
break
|
||||
@@ -319,6 +320,23 @@ QtObject {
|
||||
}
|
||||
}
|
||||
|
||||
function findRepeater(parent) {
|
||||
if (!parent || !parent.children) {
|
||||
return null
|
||||
}
|
||||
for (var i = 0; i < parent.children.length; i++) {
|
||||
const child = parent.children[i]
|
||||
if (child.objectName === "notificationRepeater") {
|
||||
return child
|
||||
}
|
||||
const found = findRepeater(child)
|
||||
if (found) {
|
||||
return found
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function ensureVisible() {
|
||||
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length || !listView)
|
||||
return
|
||||
@@ -326,17 +344,34 @@ QtObject {
|
||||
const currentItem = flatNavigation[selectedFlatIndex]
|
||||
|
||||
if (keyboardNavigationActive && currentItem && currentItem.groupIndex >= 0) {
|
||||
// Always center the selected item for better visibility
|
||||
// This ensures the selected item stays in view even when new notifications arrive
|
||||
if (currentItem.type === "notification") {
|
||||
// For individual notifications, center on the group but bias towards the notification
|
||||
listView.positionViewAtIndex(currentItem.groupIndex, ListView.Center)
|
||||
const groupDelegate = listView.itemAtIndex(currentItem.groupIndex)
|
||||
if (groupDelegate && groupDelegate.children && groupDelegate.children.length > 0) {
|
||||
const notificationCard = groupDelegate.children[0]
|
||||
const repeater = findRepeater(notificationCard)
|
||||
|
||||
if (repeater && currentItem.notificationIndex < repeater.count) {
|
||||
const notificationItem = repeater.itemAt(currentItem.notificationIndex)
|
||||
if (notificationItem) {
|
||||
const itemPos = notificationItem.mapToItem(listView.contentItem, 0, 0)
|
||||
const itemY = itemPos.y
|
||||
const itemHeight = notificationItem.height
|
||||
|
||||
const viewportTop = listView.contentY
|
||||
const viewportBottom = listView.contentY + listView.height
|
||||
|
||||
if (itemY < viewportTop) {
|
||||
listView.contentY = itemY - 20
|
||||
} else if (itemY + itemHeight > viewportBottom) {
|
||||
listView.contentY = itemY + itemHeight - listView.height + 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For group headers, center on the group
|
||||
listView.positionViewAtIndex(currentItem.groupIndex, ListView.Center)
|
||||
listView.positionViewAtIndex(currentItem.groupIndex, ListView.Contain)
|
||||
}
|
||||
|
||||
// Force immediate update
|
||||
listView.forceLayout()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Shapes
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Widgets
|
||||
@@ -63,6 +64,20 @@ PanelWindow {
|
||||
|
||||
visible: hasValidData
|
||||
WlrLayershell.layer: {
|
||||
const envLayer = Quickshell.env("DMS_NOTIFICATION_LAYER")
|
||||
if (envLayer) {
|
||||
switch (envLayer) {
|
||||
case "bottom":
|
||||
return WlrLayershell.Bottom
|
||||
case "overlay":
|
||||
return WlrLayershell.Overlay
|
||||
case "background":
|
||||
return WlrLayershell.Background
|
||||
case "top":
|
||||
return WlrLayershell.Top
|
||||
}
|
||||
}
|
||||
|
||||
if (!notificationData)
|
||||
return WlrLayershell.Top
|
||||
|
||||
@@ -198,65 +213,81 @@ PanelWindow {
|
||||
return Theme.popupDistance
|
||||
}
|
||||
|
||||
readonly property real dpr: CompositorService.getScreenScale(win.screen)
|
||||
readonly property real alignedWidth: Theme.px(implicitWidth, dpr)
|
||||
readonly property real alignedHeight: Theme.px(implicitHeight, dpr)
|
||||
|
||||
Item {
|
||||
id: content
|
||||
|
||||
anchors.fill: parent
|
||||
x: Theme.snap((win.width - alignedWidth) / 2, dpr)
|
||||
y: Theme.snap((win.height - alignedHeight) / 2, dpr)
|
||||
width: alignedWidth
|
||||
height: alignedHeight
|
||||
visible: win.hasValidData
|
||||
layer.enabled: true
|
||||
layer.smooth: true
|
||||
|
||||
Rectangle {
|
||||
property var shadowLayers: [shadowLayer1, shadowLayer2, shadowLayer3]
|
||||
property real shadowBlurPx: 10
|
||||
property real shadowSpreadPx: 0
|
||||
property real shadowBaseAlpha: 0.60
|
||||
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
||||
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
||||
|
||||
Item {
|
||||
id: bgShadowLayer
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||
border.color: notificationData && notificationData.urgency === NotificationUrgency.Critical ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||
border.width: notificationData && notificationData.urgency === NotificationUrgency.Critical ? 2 : 0
|
||||
clip: true
|
||||
anchors.margins: Theme.snap(4, win.dpr)
|
||||
layer.enabled: true
|
||||
layer.smooth: false
|
||||
layer.textureSize: Qt.size(Math.round(width * win.dpr), Math.round(height * win.dpr))
|
||||
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
||||
|
||||
Rectangle {
|
||||
id: shadowLayer1
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: -3
|
||||
color: "transparent"
|
||||
radius: parent.radius + 3
|
||||
border.color: Qt.rgba(0, 0, 0, 0.05)
|
||||
border.width: 1
|
||||
z: -3
|
||||
layer.effect: MultiEffect {
|
||||
id: shadowFx
|
||||
autoPaddingEnabled: true
|
||||
shadowEnabled: true
|
||||
blurEnabled: false
|
||||
maskEnabled: false
|
||||
property int blurMax: 64
|
||||
shadowBlur: Math.max(0, Math.min(1, content.shadowBlurPx / blurMax))
|
||||
shadowScale: 1 + (2 * content.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
|
||||
shadowColor: Qt.rgba(0, 0, 0, content.effectiveShadowAlpha)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: shadowLayer2
|
||||
|
||||
Shape {
|
||||
id: backgroundShape
|
||||
anchors.fill: parent
|
||||
anchors.margins: -2
|
||||
color: "transparent"
|
||||
radius: parent.radius + 2
|
||||
border.color: Qt.rgba(0, 0, 0, 0.08)
|
||||
border.width: 1
|
||||
z: -2
|
||||
}
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
|
||||
Rectangle {
|
||||
id: shadowLayer3
|
||||
readonly property real radius: Theme.cornerRadius
|
||||
readonly property color fillColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||
readonly property color strokeColor: notificationData && notificationData.urgency === NotificationUrgency.Critical ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.outline, 0.08)
|
||||
readonly property real strokeWidth: notificationData && notificationData.urgency === NotificationUrgency.Critical ? 2 : 0
|
||||
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||
border.width: 1
|
||||
radius: parent.radius
|
||||
z: -1
|
||||
ShapePath {
|
||||
fillColor: backgroundShape.fillColor
|
||||
strokeColor: backgroundShape.strokeColor
|
||||
strokeWidth: backgroundShape.strokeWidth
|
||||
|
||||
startX: backgroundShape.radius
|
||||
startY: 0
|
||||
|
||||
PathLine { x: backgroundShape.width - backgroundShape.radius; y: 0 }
|
||||
PathQuad { x: backgroundShape.width; y: backgroundShape.radius; controlX: backgroundShape.width; controlY: 0 }
|
||||
PathLine { x: backgroundShape.width; y: backgroundShape.height - backgroundShape.radius }
|
||||
PathQuad { x: backgroundShape.width - backgroundShape.radius; y: backgroundShape.height; controlX: backgroundShape.width; controlY: backgroundShape.height }
|
||||
PathLine { x: backgroundShape.radius; y: backgroundShape.height }
|
||||
PathQuad { x: 0; y: backgroundShape.height - backgroundShape.radius; controlX: 0; controlY: backgroundShape.height }
|
||||
PathLine { x: 0; y: backgroundShape.radius }
|
||||
PathQuad { x: backgroundShape.radius; y: 0; controlX: 0; controlY: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
radius: backgroundShape.radius
|
||||
visible: notificationData && notificationData.urgency === NotificationUrgency.Critical
|
||||
opacity: 1
|
||||
clip: true
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
@@ -277,6 +308,13 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: backgroundContainer
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.snap(4, win.dpr)
|
||||
clip: true
|
||||
|
||||
Item {
|
||||
id: notificationContent
|
||||
|
||||
@@ -13,11 +13,13 @@ Item {
|
||||
property bool isNiri: CompositorService.isNiri
|
||||
property bool isSway: CompositorService.isSway
|
||||
property bool isDwl: CompositorService.isDwl
|
||||
property bool isLabwc: CompositorService.isLabwc
|
||||
|
||||
property string compositorName: {
|
||||
if (isHyprland) return "hyprland"
|
||||
if (isSway) return "sway"
|
||||
if (isDwl) return "mangowc"
|
||||
if (isLabwc) return "labwc"
|
||||
return "niri"
|
||||
}
|
||||
|
||||
@@ -25,6 +27,7 @@ Item {
|
||||
if (isHyprland) return "/assets/hyprland.svg"
|
||||
if (isSway) return "/assets/sway.svg"
|
||||
if (isDwl) return "/assets/mango.png"
|
||||
if (isLabwc) return "/assets/labwc.png"
|
||||
return "/assets/niri.svg"
|
||||
}
|
||||
|
||||
@@ -32,6 +35,7 @@ Item {
|
||||
if (isHyprland) return "https://hypr.land"
|
||||
if (isSway) return "https://swaywm.org"
|
||||
if (isDwl) return "https://github.com/DreamMaoMao/mangowc"
|
||||
if (isLabwc) return "https://labwc.github.io/"
|
||||
return "https://github.com/YaLTeR/niri"
|
||||
}
|
||||
|
||||
@@ -39,6 +43,7 @@ Item {
|
||||
if (isHyprland) return "Hyprland Website"
|
||||
if (isSway) return "Sway Website"
|
||||
if (isDwl) return "mangowc GitHub"
|
||||
if (isLabwc) return "LabWC Website"
|
||||
return "niri GitHub"
|
||||
}
|
||||
|
||||
@@ -60,9 +65,13 @@ Item {
|
||||
property string redditUrl: "https://reddit.com/r/niri"
|
||||
property string redditTooltip: "r/niri Subreddit"
|
||||
|
||||
property bool showMatrix: isNiri && !isHyprland && !isSway && !isDwl
|
||||
property string ircUrl: "https://web.libera.chat/gamja/?channels=#labwc"
|
||||
property string ircTooltip: "LabWC IRC Channel"
|
||||
|
||||
property bool showMatrix: isNiri && !isHyprland && !isSway && !isDwl && !isLabwc
|
||||
property bool showCompositorDiscord: isHyprland || isDwl
|
||||
property bool showReddit: isNiri && !isHyprland && !isSway && !isDwl
|
||||
property bool showReddit: isNiri && !isHyprland && !isSway && !isDwl && !isLabwc
|
||||
property bool showIrc: isLabwc
|
||||
|
||||
DankFlickable {
|
||||
anchors.fill: parent
|
||||
@@ -153,6 +162,9 @@ Item {
|
||||
if (showMatrix) {
|
||||
baseWidth += matrixButton.width + 4
|
||||
}
|
||||
if (showIrc) {
|
||||
baseWidth += ircButton.width + Theme.spacingM
|
||||
}
|
||||
if (showCompositorDiscord) {
|
||||
baseWidth += compositorDiscordButton.width + Theme.spacingM
|
||||
}
|
||||
@@ -232,11 +244,43 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: ircButton
|
||||
width: 24
|
||||
height: 24
|
||||
x: compositorButton.x + compositorButton.width + Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: showIrc
|
||||
|
||||
property bool hovered: false
|
||||
property string tooltipText: ircTooltip
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: "forum"
|
||||
size: 20
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: parent.hovered = true
|
||||
onExited: parent.hovered = false
|
||||
onClicked: Qt.openUrlExternally(ircUrl)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: dmsDiscordButton
|
||||
width: 20
|
||||
height: 20
|
||||
x: showMatrix ? matrixButton.x + matrixButton.width + Theme.spacingM : compositorButton.x + compositorButton.width + Theme.spacingM
|
||||
x: {
|
||||
if (showMatrix) return matrixButton.x + matrixButton.width + Theme.spacingM
|
||||
if (showIrc) return ircButton.x + ircButton.width + Theme.spacingM
|
||||
return compositorButton.x + compositorButton.width + Theme.spacingM
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
property bool hovered: false
|
||||
@@ -618,6 +662,7 @@ Item {
|
||||
property var hoveredButton: {
|
||||
if (compositorButton.hovered) return compositorButton
|
||||
if (matrixButton.visible && matrixButton.hovered) return matrixButton
|
||||
if (ircButton.visible && ircButton.hovered) return ircButton
|
||||
if (dmsDiscordButton.hovered) return dmsDiscordButton
|
||||
if (compositorDiscordButton.visible && compositorDiscordButton.hovered) return compositorDiscordButton
|
||||
if (redditButton.visible && redditButton.hovered) return redditButton
|
||||
|
||||
@@ -110,6 +110,11 @@ DankModal {
|
||||
parentModal.shouldHaveFocus = Qt.binding(() => {
|
||||
return parentModal.shouldBeVisible
|
||||
})
|
||||
Qt.callLater(() => {
|
||||
if (parentModal.modalFocusScope) {
|
||||
parentModal.modalFocusScope.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +122,17 @@ DankModal {
|
||||
refreshPlugins()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: contentLoader
|
||||
function onLoaded() {
|
||||
Qt.callLater(() => {
|
||||
if (contentLoader.item && contentLoader.item.searchField) {
|
||||
contentLoader.item.searchField.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onDialogClosed: () => {
|
||||
allPlugins = []
|
||||
searchQuery = ""
|
||||
@@ -138,6 +154,10 @@ DankModal {
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
|
||||
Component.onCompleted: {
|
||||
browserSearchField.forceActiveFocus()
|
||||
}
|
||||
|
||||
Keys.onPressed: event => {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
root.close()
|
||||
|
||||
@@ -81,8 +81,9 @@ Item {
|
||||
text: I18n.tr("Show Workspace Apps")
|
||||
description: I18n.tr("Display application icons in workspace indicators")
|
||||
checked: SettingsData.showWorkspaceApps
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland
|
||||
onToggled: checked => {
|
||||
return SettingsData.set("showWorkspaceApps",
|
||||
return SettingsData.set("showWorkspaceApps",
|
||||
checked)
|
||||
}
|
||||
}
|
||||
@@ -355,6 +356,7 @@ Item {
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||
Theme.outline.b, 0.2)
|
||||
border.width: 0
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland
|
||||
|
||||
Column {
|
||||
id: runningAppsSection
|
||||
|
||||
@@ -11,6 +11,8 @@ import qs.Widgets
|
||||
PanelWindow {
|
||||
id: root
|
||||
|
||||
WlrLayershell.namespace: "dms:toast"
|
||||
|
||||
property var modelData
|
||||
property bool shouldBeVisible: false
|
||||
property real frozenWidth: 0
|
||||
|
||||
@@ -100,7 +100,7 @@ Endless customization with the [plugin registry](https://plugins.danklinux.com).
|
||||
|
||||
## Supported Compositors
|
||||
|
||||
DankMaterialShell works best with **[niri](https://github.com/YaLTeR/niri)**, **[Hyprland](https://hyprland.org/)**, **[sway](https://swaywm.org/)**, and **[dwl/MangoWC](https://github.com/DreamMaoMao/mangowc)** - with full workspace switching, overview integration, and monitor management.
|
||||
DankMaterialShell works best with **[niri](https://github.com/YaLTeR/niri)**, **[Hyprland](https://hyprland.org/)**, **[sway](https://swaywm.org/)**, and **[dwl/MangoWC](https://github.com/DreamMaoMao/mangowc)**. - with full workspace switching, overview integration, and monitor management.
|
||||
|
||||
Other Wayland compositors work too, just with a reduced feature set.
|
||||
|
||||
|
||||
@@ -14,11 +14,13 @@ Singleton {
|
||||
property bool isNiri: false
|
||||
property bool isDwl: false
|
||||
property bool isSway: false
|
||||
property bool isLabwc: false
|
||||
property string compositor: "unknown"
|
||||
|
||||
readonly property string hyprlandSignature: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")
|
||||
readonly property string niriSocket: Quickshell.env("NIRI_SOCKET")
|
||||
readonly property string swaySocket: Quickshell.env("SWAYSOCK")
|
||||
readonly property string labwcPid: Quickshell.env("LABWC_PID")
|
||||
property bool useNiriSorting: isNiri && NiriService
|
||||
|
||||
property var sortedToplevels: []
|
||||
@@ -29,10 +31,17 @@ Singleton {
|
||||
function getScreenScale(screen) {
|
||||
if (!screen) return 1
|
||||
|
||||
if (Quickshell.env("QT_WAYLAND_FORCE_DPI")) {
|
||||
if (Quickshell.env("QT_WAYLAND_FORCE_DPI") || Quickshell.env("QT_SCALE_FACTOR")) {
|
||||
return screen.devicePixelRatio || 1
|
||||
}
|
||||
|
||||
if (WlrOutputService.wlrOutputAvailable && screen) {
|
||||
const wlrOutput = WlrOutputService.getOutput(screen.name)
|
||||
if (wlrOutput?.enabled && wlrOutput.scale !== undefined && wlrOutput.scale > 0) {
|
||||
return wlrOutput.scale
|
||||
}
|
||||
}
|
||||
|
||||
if (isNiri && screen) {
|
||||
const niriScale = NiriService.displayScales[screen.name]
|
||||
if (niriScale !== undefined) return niriScale
|
||||
@@ -338,11 +347,13 @@ Singleton {
|
||||
}
|
||||
|
||||
function detectCompositor() {
|
||||
if (hyprlandSignature && hyprlandSignature.length > 0) {
|
||||
if (hyprlandSignature && hyprlandSignature.length > 0 &&
|
||||
!niriSocket && !swaySocket && !labwcPid) {
|
||||
isHyprland = true
|
||||
isNiri = false
|
||||
isDwl = false
|
||||
isSway = false
|
||||
isLabwc = false
|
||||
compositor = "hyprland"
|
||||
console.info("CompositorService: Detected Hyprland")
|
||||
return
|
||||
@@ -355,6 +366,7 @@ Singleton {
|
||||
isHyprland = false
|
||||
isDwl = false
|
||||
isSway = false
|
||||
isLabwc = false
|
||||
compositor = "niri"
|
||||
console.info("CompositorService: Detected Niri with socket:", niriSocket)
|
||||
NiriService.generateNiriBinds()
|
||||
@@ -371,13 +383,25 @@ Singleton {
|
||||
isHyprland = false
|
||||
isDwl = false
|
||||
isSway = true
|
||||
isLabwc = false
|
||||
compositor = "sway"
|
||||
console.info("CompositorService: Detected Sway with socket:", swaySocket)
|
||||
}
|
||||
}, 0)
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (labwcPid && labwcPid.length > 0) {
|
||||
isHyprland = false
|
||||
isNiri = false
|
||||
isDwl = false
|
||||
isSway = false
|
||||
isLabwc = true
|
||||
compositor = "labwc"
|
||||
console.info("CompositorService: Detected LabWC with PID:", labwcPid)
|
||||
return
|
||||
}
|
||||
|
||||
if (DMSService.dmsAvailable) {
|
||||
Qt.callLater(checkForDwl)
|
||||
} else {
|
||||
@@ -385,6 +409,7 @@ Singleton {
|
||||
isNiri = false
|
||||
isDwl = false
|
||||
isSway = false
|
||||
isLabwc = false
|
||||
compositor = "unknown"
|
||||
console.warn("CompositorService: No compositor detected")
|
||||
}
|
||||
@@ -393,7 +418,7 @@ Singleton {
|
||||
Connections {
|
||||
target: DMSService
|
||||
function onCapabilitiesReceived() {
|
||||
if (!isHyprland && !isNiri && !isDwl) {
|
||||
if (!isHyprland && !isNiri && !isDwl && !isLabwc) {
|
||||
checkForDwl()
|
||||
}
|
||||
}
|
||||
@@ -404,6 +429,8 @@ Singleton {
|
||||
isHyprland = false
|
||||
isNiri = false
|
||||
isDwl = true
|
||||
isSway = false
|
||||
isLabwc = false
|
||||
compositor = "dwl"
|
||||
console.info("CompositorService: Detected DWL via DMS capability")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
import QtQuick
|
||||
@@ -20,6 +20,7 @@ Singleton {
|
||||
property bool isConnected: false
|
||||
property bool isConnecting: false
|
||||
property bool subscribeConnected: false
|
||||
readonly property bool forceExtWorkspace: false
|
||||
|
||||
readonly property string socketPath: Quickshell.env("DMS_SOCKET")
|
||||
|
||||
@@ -46,8 +47,10 @@ Singleton {
|
||||
signal dwlStateUpdate(var data)
|
||||
signal brightnessStateUpdate(var data)
|
||||
signal brightnessDeviceUpdate(var device)
|
||||
signal extWorkspaceStateUpdate(var data)
|
||||
signal wlrOutputStateUpdate(var data)
|
||||
|
||||
property var activeSubscriptions: ["network", "network.credentials", "loginctl", "freedesktop", "gamma", "bluetooth", "bluetooth.pairing", "dwl", "brightness"]
|
||||
property var activeSubscriptions: ["network", "network.credentials", "loginctl", "freedesktop", "gamma", "bluetooth", "bluetooth.pairing", "dwl", "brightness", "wlroutput"]
|
||||
|
||||
Component.onCompleted: {
|
||||
if (socketPath && socketPath.length > 0) {
|
||||
@@ -263,7 +266,7 @@ Singleton {
|
||||
|
||||
function removeSubscription(service) {
|
||||
if (activeSubscriptions.includes("all")) {
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness"]
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "extworkspace"]
|
||||
const filtered = allServices.filter(s => s !== service)
|
||||
subscribe(filtered)
|
||||
} else {
|
||||
@@ -285,7 +288,7 @@ Singleton {
|
||||
excludeServices = [excludeServices]
|
||||
}
|
||||
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness"]
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness", "extworkspace"]
|
||||
const filtered = allServices.filter(s => !excludeServices.includes(s))
|
||||
subscribe(filtered)
|
||||
}
|
||||
@@ -342,6 +345,10 @@ Singleton {
|
||||
if (data.device) {
|
||||
brightnessDeviceUpdate(data.device)
|
||||
}
|
||||
} else if (service === "extworkspace") {
|
||||
extWorkspaceStateUpdate(data)
|
||||
} else if (service === "wlroutput") {
|
||||
wlrOutputStateUpdate(data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
import QtQuick
|
||||
|
||||
259
Services/ExtWorkspaceService.qml
Normal file
259
Services/ExtWorkspaceService.qml
Normal file
@@ -0,0 +1,259 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property bool extWorkspaceAvailable: false
|
||||
property var groups: []
|
||||
property var _cachedWorkspaces: ({})
|
||||
|
||||
signal stateChanged()
|
||||
|
||||
Connections {
|
||||
target: DMSService
|
||||
function onCapabilitiesReceived() {
|
||||
checkCapabilities()
|
||||
}
|
||||
function onConnectionStateChanged() {
|
||||
if (DMSService.isConnected) {
|
||||
checkCapabilities()
|
||||
} else {
|
||||
extWorkspaceAvailable = false
|
||||
}
|
||||
}
|
||||
function onExtWorkspaceStateUpdate(data) {
|
||||
if (extWorkspaceAvailable) {
|
||||
handleStateUpdate(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (DMSService.dmsAvailable) {
|
||||
checkCapabilities()
|
||||
}
|
||||
}
|
||||
|
||||
function checkCapabilities() {
|
||||
if (!DMSService.capabilities || !Array.isArray(DMSService.capabilities)) {
|
||||
extWorkspaceAvailable = false
|
||||
return
|
||||
}
|
||||
|
||||
const hasExtWorkspace = DMSService.capabilities.includes("extworkspace")
|
||||
if (hasExtWorkspace && !extWorkspaceAvailable) {
|
||||
extWorkspaceAvailable = true
|
||||
console.info("ExtWorkspaceService: ext-workspace capability detected")
|
||||
requestState()
|
||||
} else if (!hasExtWorkspace) {
|
||||
extWorkspaceAvailable = false
|
||||
}
|
||||
}
|
||||
|
||||
function requestState() {
|
||||
if (!DMSService.isConnected || !extWorkspaceAvailable) {
|
||||
return
|
||||
}
|
||||
|
||||
DMSService.sendRequest("extworkspace.getState", null, response => {
|
||||
if (response.result) {
|
||||
handleStateUpdate(response.result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleStateUpdate(state) {
|
||||
groups = state.groups || []
|
||||
if (groups.length === 0) {
|
||||
console.warn("ExtWorkspaceService: Received empty workspace groups from backend")
|
||||
} else {
|
||||
console.log("ExtWorkspaceService: Updated with", groups.length, "workspace groups")
|
||||
}
|
||||
stateChanged()
|
||||
}
|
||||
|
||||
function activateWorkspace(workspaceID, groupID = "") {
|
||||
if (!DMSService.isConnected || !extWorkspaceAvailable) {
|
||||
return
|
||||
}
|
||||
|
||||
DMSService.sendRequest("extworkspace.activateWorkspace", {
|
||||
"workspaceID": workspaceID,
|
||||
"groupID": groupID
|
||||
}, response => {
|
||||
if (response.error) {
|
||||
console.warn("ExtWorkspaceService: activateWorkspace error:", response.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function deactivateWorkspace(workspaceID, groupID = "") {
|
||||
if (!DMSService.isConnected || !extWorkspaceAvailable) {
|
||||
return
|
||||
}
|
||||
|
||||
DMSService.sendRequest("extworkspace.deactivateWorkspace", {
|
||||
"workspaceID": workspaceID,
|
||||
"groupID": groupID
|
||||
}, response => {
|
||||
if (response.error) {
|
||||
console.warn("ExtWorkspaceService: deactivateWorkspace error:", response.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function removeWorkspace(workspaceID, groupID = "") {
|
||||
if (!DMSService.isConnected || !extWorkspaceAvailable) {
|
||||
return
|
||||
}
|
||||
|
||||
DMSService.sendRequest("extworkspace.removeWorkspace", {
|
||||
"workspaceID": workspaceID,
|
||||
"groupID": groupID
|
||||
}, response => {
|
||||
if (response.error) {
|
||||
console.warn("ExtWorkspaceService: removeWorkspace error:", response.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function createWorkspace(groupID, name) {
|
||||
if (!DMSService.isConnected || !extWorkspaceAvailable) {
|
||||
return
|
||||
}
|
||||
|
||||
DMSService.sendRequest("extworkspace.createWorkspace", {
|
||||
"groupID": groupID,
|
||||
"name": name
|
||||
}, response => {
|
||||
if (response.error) {
|
||||
console.warn("ExtWorkspaceService: createWorkspace error:", response.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getGroupForOutput(outputName) {
|
||||
for (const group of groups) {
|
||||
if (group.outputs && group.outputs.includes(outputName)) {
|
||||
return group
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getWorkspacesForOutput(outputName) {
|
||||
const group = getGroupForOutput(outputName)
|
||||
return group ? (group.workspaces || []) : []
|
||||
}
|
||||
|
||||
function getActiveWorkspaces() {
|
||||
const active = []
|
||||
for (const group of groups) {
|
||||
if (!group.workspaces) continue
|
||||
for (const ws of group.workspaces) {
|
||||
if (ws.active) {
|
||||
active.push({
|
||||
workspace: ws,
|
||||
group: group,
|
||||
outputs: group.outputs || []
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return active
|
||||
}
|
||||
|
||||
function getActiveWorkspaceForOutput(outputName) {
|
||||
const group = getGroupForOutput(outputName)
|
||||
if (!group || !group.workspaces) return null
|
||||
|
||||
for (const ws of group.workspaces) {
|
||||
if (ws.active) {
|
||||
return ws
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getVisibleWorkspaces(outputName) {
|
||||
const workspaces = getWorkspacesForOutput(outputName)
|
||||
const visible = workspaces.filter(ws => !ws.hidden).sort((a, b) => {
|
||||
const coordsA = a.coordinates || [0, 0]
|
||||
const coordsB = b.coordinates || [0, 0]
|
||||
if (coordsA[0] !== coordsB[0]) return coordsA[0] - coordsB[0]
|
||||
return coordsA[1] - coordsB[1]
|
||||
})
|
||||
|
||||
const cacheKey = outputName
|
||||
if (!_cachedWorkspaces[cacheKey]) {
|
||||
_cachedWorkspaces[cacheKey] = {
|
||||
workspaces: [],
|
||||
lastNames: []
|
||||
}
|
||||
}
|
||||
|
||||
const cache = _cachedWorkspaces[cacheKey]
|
||||
const currentNames = visible.map(ws => ws.name || ws.id)
|
||||
const namesChanged = JSON.stringify(cache.lastNames) !== JSON.stringify(currentNames)
|
||||
|
||||
if (namesChanged || cache.workspaces.length !== visible.length) {
|
||||
cache.workspaces = visible.map(ws => ({
|
||||
id: ws.id,
|
||||
name: ws.name,
|
||||
coordinates: ws.coordinates,
|
||||
state: ws.state,
|
||||
active: ws.active,
|
||||
urgent: ws.urgent,
|
||||
hidden: ws.hidden
|
||||
}))
|
||||
cache.lastNames = currentNames
|
||||
return cache.workspaces
|
||||
}
|
||||
|
||||
for (let i = 0; i < visible.length; i++) {
|
||||
const src = visible[i]
|
||||
const dst = cache.workspaces[i]
|
||||
dst.id = src.id
|
||||
dst.name = src.name
|
||||
dst.coordinates = src.coordinates
|
||||
dst.state = src.state
|
||||
dst.active = src.active
|
||||
dst.urgent = src.urgent
|
||||
dst.hidden = src.hidden
|
||||
}
|
||||
|
||||
return cache.workspaces
|
||||
}
|
||||
|
||||
function getUrgentWorkspaces() {
|
||||
const urgent = []
|
||||
for (const group of groups) {
|
||||
if (!group.workspaces) continue
|
||||
for (const ws of group.workspaces) {
|
||||
if (ws.urgent) {
|
||||
urgent.push({
|
||||
workspace: ws,
|
||||
group: group,
|
||||
outputs: group.outputs || []
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return urgent
|
||||
}
|
||||
|
||||
function switchToWorkspace(outputName, workspaceName) {
|
||||
const workspaces = getWorkspacesForOutput(outputName)
|
||||
for (const ws of workspaces) {
|
||||
if (ws.name === workspaceName || ws.id === workspaceName) {
|
||||
activateWorkspace(ws.name || ws.id)
|
||||
return
|
||||
}
|
||||
}
|
||||
console.warn("ExtWorkspaceService: workspace not found:", workspaceName)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
import QtQuick
|
||||
|
||||
275
Services/WlrOutputService.qml
Normal file
275
Services/WlrOutputService.qml
Normal file
@@ -0,0 +1,275 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property bool wlrOutputAvailable: false
|
||||
property var outputs: []
|
||||
property int serial: 0
|
||||
|
||||
signal stateChanged
|
||||
signal configurationApplied(bool success, string message)
|
||||
|
||||
Connections {
|
||||
target: DMSService
|
||||
|
||||
function onCapabilitiesReceived() {
|
||||
checkCapabilities()
|
||||
}
|
||||
|
||||
function onConnectionStateChanged() {
|
||||
if (DMSService.isConnected) {
|
||||
checkCapabilities()
|
||||
return
|
||||
}
|
||||
wlrOutputAvailable = false
|
||||
}
|
||||
|
||||
function onWlrOutputStateUpdate(data) {
|
||||
if (!wlrOutputAvailable) {
|
||||
return
|
||||
}
|
||||
handleStateUpdate(data)
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!DMSService.dmsAvailable) {
|
||||
return
|
||||
}
|
||||
checkCapabilities()
|
||||
}
|
||||
|
||||
function checkCapabilities() {
|
||||
if (!DMSService.capabilities || !Array.isArray(DMSService.capabilities)) {
|
||||
wlrOutputAvailable = false
|
||||
return
|
||||
}
|
||||
|
||||
const hasWlrOutput = DMSService.capabilities.includes("wlroutput")
|
||||
if (hasWlrOutput && !wlrOutputAvailable) {
|
||||
wlrOutputAvailable = true
|
||||
console.info("WlrOutputService: wlr-output-management capability detected")
|
||||
requestState()
|
||||
return
|
||||
}
|
||||
|
||||
if (!hasWlrOutput) {
|
||||
wlrOutputAvailable = false
|
||||
}
|
||||
}
|
||||
|
||||
function requestState() {
|
||||
if (!DMSService.isConnected || !wlrOutputAvailable) {
|
||||
return
|
||||
}
|
||||
|
||||
DMSService.sendRequest("wlroutput.getState", null, response => {
|
||||
if (!response.result) {
|
||||
return
|
||||
}
|
||||
handleStateUpdate(response.result)
|
||||
})
|
||||
}
|
||||
|
||||
function handleStateUpdate(state) {
|
||||
outputs = state.outputs || []
|
||||
serial = state.serial || 0
|
||||
|
||||
if (outputs.length === 0) {
|
||||
console.warn("WlrOutputService: Received empty outputs list")
|
||||
} else {
|
||||
console.log("WlrOutputService: Updated with", outputs.length, "outputs, serial:", serial)
|
||||
outputs.forEach((output, index) => {
|
||||
console.log("WlrOutputService: Output", index, "-", output.name,
|
||||
"enabled:", output.enabled,
|
||||
"mode:", output.currentMode ?
|
||||
output.currentMode.width + "x" + output.currentMode.height + "@" +
|
||||
(output.currentMode.refresh / 1000) + "Hz" : "none")
|
||||
})
|
||||
}
|
||||
stateChanged()
|
||||
}
|
||||
|
||||
function getOutput(name) {
|
||||
for (const output of outputs) {
|
||||
if (output.name === name) {
|
||||
return output
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getEnabledOutputs() {
|
||||
return outputs.filter(output => output.enabled)
|
||||
}
|
||||
|
||||
function applyConfiguration(heads, callback) {
|
||||
if (!DMSService.isConnected || !wlrOutputAvailable) {
|
||||
if (callback) {
|
||||
callback(false, "Not connected")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
console.log("WlrOutputService: Applying configuration for", heads.length, "outputs")
|
||||
heads.forEach((head, index) => {
|
||||
console.log("WlrOutputService: Head", index, "- name:", head.name,
|
||||
"enabled:", head.enabled,
|
||||
"modeId:", head.modeId,
|
||||
"customMode:", JSON.stringify(head.customMode),
|
||||
"position:", JSON.stringify(head.position),
|
||||
"scale:", head.scale,
|
||||
"transform:", head.transform,
|
||||
"adaptiveSync:", head.adaptiveSync)
|
||||
})
|
||||
|
||||
DMSService.sendRequest("wlroutput.applyConfiguration", {
|
||||
"heads": heads
|
||||
}, response => {
|
||||
const success = !response.error
|
||||
const message = response.error || response.result?.message || ""
|
||||
|
||||
if (response.error) {
|
||||
console.warn("WlrOutputService: applyConfiguration error:", response.error)
|
||||
} else {
|
||||
console.log("WlrOutputService: Configuration applied successfully")
|
||||
}
|
||||
|
||||
configurationApplied(success, message)
|
||||
if (callback) {
|
||||
callback(success, message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function testConfiguration(heads, callback) {
|
||||
if (!DMSService.isConnected || !wlrOutputAvailable) {
|
||||
if (callback) {
|
||||
callback(false, "Not connected")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
console.log("WlrOutputService: Testing configuration for", heads.length, "outputs")
|
||||
|
||||
DMSService.sendRequest("wlroutput.testConfiguration", {
|
||||
"heads": heads
|
||||
}, response => {
|
||||
const success = !response.error
|
||||
const message = response.error || response.result?.message || ""
|
||||
|
||||
if (response.error) {
|
||||
console.warn("WlrOutputService: testConfiguration error:", response.error)
|
||||
} else {
|
||||
console.log("WlrOutputService: Configuration test passed")
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(success, message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function setOutputEnabled(outputName, enabled, callback) {
|
||||
const output = getOutput(outputName)
|
||||
if (!output) {
|
||||
console.warn("WlrOutputService: Output not found:", outputName)
|
||||
if (callback) {
|
||||
callback(false, "Output not found")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const heads = [{
|
||||
"name": outputName,
|
||||
"enabled": enabled
|
||||
}]
|
||||
|
||||
if (enabled && output.currentMode) {
|
||||
heads[0].modeId = output.currentMode.id
|
||||
}
|
||||
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function setOutputMode(outputName, modeId, callback) {
|
||||
const heads = [{
|
||||
"name": outputName,
|
||||
"enabled": true,
|
||||
"modeId": modeId
|
||||
}]
|
||||
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function setOutputCustomMode(outputName, width, height, refresh, callback) {
|
||||
const heads = [{
|
||||
"name": outputName,
|
||||
"enabled": true,
|
||||
"customMode": {
|
||||
"width": width,
|
||||
"height": height,
|
||||
"refresh": refresh
|
||||
}
|
||||
}]
|
||||
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function setOutputPosition(outputName, x, y, callback) {
|
||||
const heads = [{
|
||||
"name": outputName,
|
||||
"enabled": true,
|
||||
"position": {
|
||||
"x": x,
|
||||
"y": y
|
||||
}
|
||||
}]
|
||||
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function setOutputScale(outputName, scale, callback) {
|
||||
const heads = [{
|
||||
"name": outputName,
|
||||
"enabled": true,
|
||||
"scale": scale
|
||||
}]
|
||||
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function setOutputTransform(outputName, transform, callback) {
|
||||
const heads = [{
|
||||
"name": outputName,
|
||||
"enabled": true,
|
||||
"transform": transform
|
||||
}]
|
||||
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function setOutputAdaptiveSync(outputName, state, callback) {
|
||||
const heads = [{
|
||||
"name": outputName,
|
||||
"enabled": true,
|
||||
"adaptiveSync": state
|
||||
}]
|
||||
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function configureOutput(config, callback) {
|
||||
const heads = [config]
|
||||
applyConfiguration(heads, callback)
|
||||
}
|
||||
|
||||
function configureMultipleOutputs(configs, callback) {
|
||||
applyConfiguration(configs, callback)
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ Flickable {
|
||||
property real lastWheelTime: 0
|
||||
property real momentum: 0
|
||||
property var velocitySamples: []
|
||||
property bool sessionUsedMouseWheel: false
|
||||
|
||||
function startMomentum() {
|
||||
flickable.isMomentumActive = true
|
||||
@@ -49,10 +50,12 @@ Flickable {
|
||||
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0
|
||||
|
||||
if (isMouseWheel) {
|
||||
sessionUsedMouseWheel = true
|
||||
momentumTimer.stop()
|
||||
flickable.isMomentumActive = false
|
||||
velocitySamples = []
|
||||
momentum = 0
|
||||
flickable.momentumVelocity = 0
|
||||
|
||||
const lines = Math.floor(Math.abs(deltaY) / 120)
|
||||
const scrollAmount = (deltaY > 0 ? -lines : lines) * flickable.mouseWheelSpeed
|
||||
@@ -65,6 +68,7 @@ Flickable {
|
||||
|
||||
flickable.contentY = newY
|
||||
} else {
|
||||
sessionUsedMouseWheel = false
|
||||
momentumTimer.stop()
|
||||
flickable.isMomentumActive = false
|
||||
|
||||
@@ -111,7 +115,7 @@ Flickable {
|
||||
|
||||
onActiveChanged: {
|
||||
if (!active) {
|
||||
if (Math.abs(flickable.momentumVelocity) >= flickable.minMomentumVelocity) {
|
||||
if (!sessionUsedMouseWheel && Math.abs(flickable.momentumVelocity) >= flickable.minMomentumVelocity) {
|
||||
startMomentum()
|
||||
} else {
|
||||
velocitySamples = []
|
||||
|
||||
@@ -33,6 +33,7 @@ GridView {
|
||||
property real lastWheelTime: 0
|
||||
property real momentum: 0
|
||||
property var velocitySamples: []
|
||||
property bool sessionUsedMouseWheel: false
|
||||
|
||||
function startMomentum() {
|
||||
isMomentumActive = true
|
||||
@@ -52,10 +53,12 @@ GridView {
|
||||
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0
|
||||
|
||||
if (isMouseWheel) {
|
||||
sessionUsedMouseWheel = true
|
||||
momentumTimer.stop()
|
||||
isMomentumActive = false
|
||||
velocitySamples = []
|
||||
momentum = 0
|
||||
momentumVelocity = 0
|
||||
|
||||
const lines = Math.floor(Math.abs(deltaY) / 120)
|
||||
const scrollAmount = (deltaY > 0 ? -lines : lines) * cellHeight * 0.35
|
||||
@@ -68,6 +71,7 @@ GridView {
|
||||
|
||||
contentY = newY
|
||||
} else {
|
||||
sessionUsedMouseWheel = false
|
||||
momentumTimer.stop()
|
||||
isMomentumActive = false
|
||||
|
||||
@@ -108,7 +112,7 @@ GridView {
|
||||
}
|
||||
onActiveChanged: {
|
||||
if (!active) {
|
||||
if (Math.abs(momentumVelocity) >= minMomentumVelocity) {
|
||||
if (!sessionUsedMouseWheel && Math.abs(momentumVelocity) >= minMomentumVelocity) {
|
||||
startMomentum()
|
||||
} else {
|
||||
velocitySamples = []
|
||||
|
||||
@@ -50,6 +50,7 @@ ListView {
|
||||
property real lastWheelTime: 0
|
||||
property real momentum: 0
|
||||
property var velocitySamples: []
|
||||
property bool sessionUsedMouseWheel: false
|
||||
|
||||
function startMomentum() {
|
||||
isMomentumActive = true
|
||||
@@ -71,10 +72,12 @@ ListView {
|
||||
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0
|
||||
|
||||
if (isMouseWheel) {
|
||||
sessionUsedMouseWheel = true
|
||||
momentumTimer.stop()
|
||||
isMomentumActive = false
|
||||
velocitySamples = []
|
||||
momentum = 0
|
||||
momentumVelocity = 0
|
||||
|
||||
const lines = Math.floor(Math.abs(deltaY) / 120)
|
||||
const scrollAmount = (deltaY > 0 ? -lines : lines) * mouseWheelSpeed
|
||||
@@ -89,6 +92,7 @@ ListView {
|
||||
listView.contentY = newY
|
||||
savedY = newY
|
||||
} else {
|
||||
sessionUsedMouseWheel = false
|
||||
momentumTimer.stop()
|
||||
isMomentumActive = false
|
||||
|
||||
@@ -138,7 +142,7 @@ ListView {
|
||||
onActiveChanged: {
|
||||
if (!active) {
|
||||
isUserScrolling = false
|
||||
if (Math.abs(momentumVelocity) >= minMomentumVelocity) {
|
||||
if (!sessionUsedMouseWheel && Math.abs(momentumVelocity) >= minMomentumVelocity) {
|
||||
startMomentum()
|
||||
} else {
|
||||
velocitySamples = []
|
||||
|
||||
@@ -4,6 +4,7 @@ import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
@@ -117,14 +118,37 @@ PanelWindow {
|
||||
scale: shouldBeVisible ? 1 : 0.9
|
||||
|
||||
property bool childHovered: false
|
||||
property real shadowBlurPx: 10
|
||||
property real shadowSpreadPx: 0
|
||||
property real shadowBaseAlpha: 0.60
|
||||
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
||||
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha * osdContainer.opacity))
|
||||
|
||||
Rectangle {
|
||||
id: osdBackground
|
||||
Item {
|
||||
id: bgShadowLayer
|
||||
anchors.fill: parent
|
||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||
radius: Theme.cornerRadius
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||
border.width: 1
|
||||
visible: osdContainer.popupSurfaceAlpha >= 0.95
|
||||
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||
layer.smooth: false
|
||||
layer.textureSize: Qt.size(Math.round(width * root.dpr), Math.round(height * root.dpr))
|
||||
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
||||
|
||||
layer.effect: MultiEffect {
|
||||
id: shadowFx
|
||||
autoPaddingEnabled: true
|
||||
shadowEnabled: true
|
||||
blurEnabled: false
|
||||
maskEnabled: false
|
||||
property int blurMax: 64
|
||||
shadowBlur: Math.max(0, Math.min(1, osdContainer.shadowBlurPx / blurMax))
|
||||
shadowScale: 1 + (2 * osdContainer.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
|
||||
shadowColor: Qt.rgba(0, 0, 0, osdContainer.effectiveShadowAlpha)
|
||||
}
|
||||
|
||||
DankRectangle {
|
||||
anchors.fill: parent
|
||||
radius: Theme.cornerRadius
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -162,6 +186,6 @@ PanelWindow {
|
||||
}
|
||||
|
||||
mask: Region {
|
||||
item: osdBackground
|
||||
item: bgShadowLayer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
@@ -63,7 +65,18 @@ PanelWindow {
|
||||
}
|
||||
|
||||
color: "transparent"
|
||||
WlrLayershell.layer: WlrLayershell.Top
|
||||
WlrLayershell.layer: {
|
||||
switch (Quickshell.env("DMS_DANKBAR_LAYER")) {
|
||||
case "bottom":
|
||||
return WlrLayershell.Bottom
|
||||
case "overlay":
|
||||
return WlrLayershell.Overlay
|
||||
case "background":
|
||||
return WlrLayershell.Background
|
||||
default:
|
||||
return WlrLayershell.Top
|
||||
}
|
||||
}
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: shouldBeVisible ? keyboardFocusMode : WlrKeyboardFocus.None
|
||||
|
||||
@@ -168,23 +181,23 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: contentLoader
|
||||
Item {
|
||||
id: contentWrapper
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
active: root.visible
|
||||
asynchronous: false
|
||||
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||
layer.smooth: false
|
||||
layer.textureSize: Qt.size(width * root.dpr, height * root.dpr)
|
||||
layer.textureMirroring: ShaderEffectSource.NoMirroring
|
||||
opacity: shouldBeVisible ? 1 : 0
|
||||
visible: opacity > 0
|
||||
scale: contentContainer.scaleValue
|
||||
x: Theme.snap(contentContainer.animX + (parent.width - width) * (1 - contentContainer.scaleValue) * 0.5, root.dpr)
|
||||
y: Theme.snap(contentContainer.animY + (parent.height - height) * (1 - contentContainer.scaleValue) * 0.5, root.dpr)
|
||||
|
||||
property real shadowBlurPx: 10
|
||||
property real shadowSpreadPx: 0
|
||||
property real shadowBaseAlpha: 0.60
|
||||
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
||||
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha * contentWrapper.opacity))
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: animationDuration
|
||||
@@ -192,6 +205,47 @@ PanelWindow {
|
||||
easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: bgShadowLayer
|
||||
anchors.fill: parent
|
||||
visible: contentWrapper.popupSurfaceAlpha >= 0.95
|
||||
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||
layer.smooth: false
|
||||
layer.textureSize: Qt.size(Math.round(width * root.dpr), Math.round(height * root.dpr))
|
||||
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
||||
|
||||
layer.effect: MultiEffect {
|
||||
id: shadowFx
|
||||
autoPaddingEnabled: true
|
||||
shadowEnabled: true
|
||||
blurEnabled: false
|
||||
maskEnabled: false
|
||||
property int blurMax: 64
|
||||
shadowBlur: Math.max(0, Math.min(1, contentWrapper.shadowBlurPx / blurMax))
|
||||
shadowScale: 1 + (2 * contentWrapper.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
|
||||
shadowColor: Qt.rgba(0, 0, 0, contentWrapper.effectiveShadowAlpha)
|
||||
}
|
||||
|
||||
DankRectangle {
|
||||
anchors.fill: parent
|
||||
radius: Theme.cornerRadius
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentLoaderWrapper
|
||||
anchors.fill: parent
|
||||
x: Theme.snap(x, root.dpr)
|
||||
y: Theme.snap(y, root.dpr)
|
||||
|
||||
Loader {
|
||||
id: contentLoader
|
||||
anchors.fill: parent
|
||||
active: root.visible
|
||||
asynchronous: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
54
Widgets/DankRectangle.qml
Normal file
54
Widgets/DankRectangle.qml
Normal file
@@ -0,0 +1,54 @@
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import qs.Common
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property color color: Theme.surfaceContainer
|
||||
property color borderColor: Theme.outlineMedium
|
||||
property real borderWidth: 1
|
||||
property real radius: Theme.cornerRadius
|
||||
property color overlayColor: "transparent"
|
||||
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
|
||||
ShapePath {
|
||||
fillColor: root.color
|
||||
strokeColor: root.borderColor
|
||||
strokeWidth: root.borderWidth
|
||||
|
||||
startX: root.radius
|
||||
startY: 0
|
||||
|
||||
PathLine { x: root.width - root.radius; y: 0 }
|
||||
PathQuad { x: root.width; y: root.radius; controlX: root.width; controlY: 0 }
|
||||
PathLine { x: root.width; y: root.height - root.radius }
|
||||
PathQuad { x: root.width - root.radius; y: root.height; controlX: root.width; controlY: root.height }
|
||||
PathLine { x: root.radius; y: root.height }
|
||||
PathQuad { x: 0; y: root.height - root.radius; controlX: 0; controlY: root.height }
|
||||
PathLine { x: 0; y: root.radius }
|
||||
PathQuad { x: root.radius; y: 0; controlX: 0; controlY: 0 }
|
||||
}
|
||||
|
||||
ShapePath {
|
||||
fillColor: root.overlayColor
|
||||
strokeColor: "transparent"
|
||||
strokeWidth: 0
|
||||
|
||||
startX: root.radius
|
||||
startY: 0
|
||||
|
||||
PathLine { x: root.width - root.radius; y: 0 }
|
||||
PathQuad { x: root.width; y: root.radius; controlX: root.width; controlY: 0 }
|
||||
PathLine { x: root.width; y: root.height - root.radius }
|
||||
PathQuad { x: root.width - root.radius; y: root.height; controlX: root.width; controlY: root.height }
|
||||
PathLine { x: root.radius; y: root.height }
|
||||
PathQuad { x: 0; y: root.height - root.radius; controlX: 0; controlY: root.height }
|
||||
PathLine { x: 0; y: root.radius }
|
||||
PathQuad { x: root.radius; y: 0; controlX: 0; controlY: 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,22 +110,22 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
Item {
|
||||
id: contentRect
|
||||
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||
layer.smooth: false
|
||||
layer.textureSize: Qt.size(width * root.dpr, height * root.dpr)
|
||||
layer.textureMirroring: ShaderEffectSource.NoMirroring
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
x: Theme.snap(slideContainer.slideOffset, root.dpr)
|
||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b,
|
||||
customTransparency >= 0 ? customTransparency : SettingsData.popupTransparency)
|
||||
border.color: Theme.outlineMedium
|
||||
border.width: 1
|
||||
radius: Theme.cornerRadius
|
||||
|
||||
DankRectangle {
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b,
|
||||
customTransparency >= 0 ? customTransparency : SettingsData.popupTransparency)
|
||||
}
|
||||
|
||||
Column {
|
||||
id: headerColumn
|
||||
|
||||
@@ -214,7 +214,7 @@ FocusScope {
|
||||
color: Theme.outlineStrong
|
||||
}
|
||||
|
||||
function updateIndicator(enableAnimation = true) {
|
||||
function updateIndicator() {
|
||||
if (tabRepeater.count === 0 || currentIndex < 0 || currentIndex >= tabRepeater.count) {
|
||||
return
|
||||
}
|
||||
@@ -229,25 +229,26 @@ FocusScope {
|
||||
const indicatorWidth = 60
|
||||
|
||||
if (tabPos.x < 10 && currentIndex > 0) {
|
||||
Qt.callLater(() => updateIndicator(enableAnimation))
|
||||
Qt.callLater(updateIndicator)
|
||||
return
|
||||
}
|
||||
|
||||
indicator.animationEnabled = enableAnimation
|
||||
indicator.width = indicatorWidth
|
||||
indicator.x = tabCenterX - indicatorWidth / 2
|
||||
indicator.visible = true
|
||||
if (!indicator.initialSetupComplete) {
|
||||
indicator.animationEnabled = false
|
||||
indicator.width = indicatorWidth
|
||||
indicator.x = tabCenterX - indicatorWidth / 2
|
||||
indicator.visible = true
|
||||
indicator.initialSetupComplete = true
|
||||
indicator.animationEnabled = true
|
||||
} else {
|
||||
indicator.width = indicatorWidth
|
||||
indicator.x = tabCenterX - indicatorWidth / 2
|
||||
indicator.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (indicator.initialSetupComplete) {
|
||||
Qt.callLater(() => updateIndicator(true))
|
||||
} else {
|
||||
Qt.callLater(() => {
|
||||
updateIndicator(false)
|
||||
indicator.initialSetupComplete = true
|
||||
})
|
||||
}
|
||||
Qt.callLater(updateIndicator)
|
||||
}
|
||||
onWidthChanged: Qt.callLater(() => updateIndicator(indicator.initialSetupComplete))
|
||||
onWidthChanged: Qt.callLater(updateIndicator)
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import qs.Common
|
||||
PanelWindow {
|
||||
id: root
|
||||
|
||||
WlrLayershell.namespace: "dms:tooltip"
|
||||
|
||||
property string text: ""
|
||||
property real targetX: 0
|
||||
property real targetY: 0
|
||||
|
||||
BIN
assets/labwc.png
Normal file
BIN
assets/labwc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
@@ -9,7 +9,7 @@ Version: %{version}
|
||||
Release: 0.git%{?dist}
|
||||
Summary: %{pkg_summary}
|
||||
|
||||
License: GPL-3.0-only
|
||||
License: MIT
|
||||
URL: https://github.com/AvengeMedia/DankMaterialShell
|
||||
VCS: {{{ git_repo_vcs }}}
|
||||
Source0: {{{ git_repo_pack }}}
|
||||
|
||||
@@ -10,7 +10,7 @@ Version: %{version}
|
||||
Release: 1%{?dist}
|
||||
Summary: %{pkg_summary}
|
||||
|
||||
License: GPL-3.0-only
|
||||
License: MIT
|
||||
URL: https://github.com/AvengeMedia/DankMaterialShell
|
||||
VCS: {{{ git_repo_vcs }}}
|
||||
Source0: {{{ git_repo_pack }}}
|
||||
@@ -57,7 +57,7 @@ lock screen, and comprehensive plugin system.
|
||||
|
||||
%package -n dms-cli
|
||||
Summary: DankMaterialShell CLI tool
|
||||
License: GPL-3.0-only
|
||||
License: MIT
|
||||
URL: https://github.com/AvengeMedia/danklinux
|
||||
|
||||
%description -n dms-cli
|
||||
@@ -124,6 +124,14 @@ esac
|
||||
|
||||
install -Dm755 %{_builddir}/danklinux-master/bin/${DMS_BINARY} %{buildroot}%{_bindir}/dms
|
||||
|
||||
# Shell completions
|
||||
install -d %{buildroot}%{_datadir}/bash-completion/completions
|
||||
install -d %{buildroot}%{_datadir}/zsh/site-functions
|
||||
install -d %{buildroot}%{_datadir}/fish/vendor_completions.d
|
||||
%{_builddir}/danklinux-master/bin/${DMS_BINARY} completion bash > %{buildroot}%{_datadir}/bash-completion/completions/dms || :
|
||||
%{_builddir}/danklinux-master/bin/${DMS_BINARY} completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || :
|
||||
%{_builddir}/danklinux-master/bin/${DMS_BINARY} completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || :
|
||||
|
||||
# Install dgop binary
|
||||
install -Dm755 %{_builddir}/dgop %{buildroot}%{_bindir}/dgop
|
||||
|
||||
@@ -162,6 +170,9 @@ fi
|
||||
|
||||
%files -n dms-cli
|
||||
%{_bindir}/dms
|
||||
%{_datadir}/bash-completion/completions/dms
|
||||
%{_datadir}/zsh/site-functions/_dms
|
||||
%{_datadir}/fish/vendor_completions.d/dms.fish
|
||||
|
||||
%files -n dgop
|
||||
%{_bindir}/dgop
|
||||
|
||||
@@ -8,19 +8,19 @@
|
||||
{
|
||||
"term": "(Unnamed)",
|
||||
"context": "(Unnamed)",
|
||||
"reference": "Modules/Dock/DockContextMenu.qml:226",
|
||||
"reference": "Modules/Dock/DockContextMenu.qml:229",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "- Stateless System Monitoring",
|
||||
"context": "- Stateless System Monitoring",
|
||||
"reference": "Modules/Settings/AboutTab.qml:544",
|
||||
"reference": "Modules/Settings/AboutTab.qml:588",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "- Support Us With a Star ⭐",
|
||||
"context": "- Support Us With a Star ⭐",
|
||||
"reference": "Modules/Settings/AboutTab.qml:509",
|
||||
"reference": "Modules/Settings/AboutTab.qml:553",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -44,7 +44,7 @@
|
||||
{
|
||||
"term": "3rd party",
|
||||
"context": "3rd party",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:408",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:428",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -62,7 +62,7 @@
|
||||
{
|
||||
"term": "About",
|
||||
"context": "About",
|
||||
"reference": "Modals/Settings/SettingsSidebar.qml:44, Modules/Settings/AboutTab.qml:363",
|
||||
"reference": "Modals/Settings/SettingsSidebar.qml:44, Modules/Settings/AboutTab.qml:407",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -140,7 +140,7 @@
|
||||
{
|
||||
"term": "Always Show OSD Percentage",
|
||||
"context": "Always Show OSD Percentage",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:675",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:677",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -212,31 +212,31 @@
|
||||
{
|
||||
"term": "Are you sure you want to hibernate the system?",
|
||||
"context": "Are you sure you want to hibernate the system?",
|
||||
"reference": "Modals/PowerMenuModal.qml:46",
|
||||
"reference": "Modals/PowerMenuModal.qml:158",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Are you sure you want to log out?",
|
||||
"context": "Are you sure you want to log out?",
|
||||
"reference": "Modals/PowerMenuModal.qml:38",
|
||||
"reference": "Modals/PowerMenuModal.qml:150",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Are you sure you want to power off the system?",
|
||||
"context": "Are you sure you want to power off the system?",
|
||||
"reference": "Modals/PowerMenuModal.qml:54",
|
||||
"reference": "Modals/PowerMenuModal.qml:166",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Are you sure you want to reboot the system?",
|
||||
"context": "Are you sure you want to reboot the system?",
|
||||
"reference": "Modals/PowerMenuModal.qml:50",
|
||||
"reference": "Modals/PowerMenuModal.qml:162",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Are you sure you want to suspend the system?",
|
||||
"context": "Are you sure you want to suspend the system?",
|
||||
"reference": "Modals/PowerMenuModal.qml:42",
|
||||
"reference": "Modals/PowerMenuModal.qml:154",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -428,7 +428,7 @@
|
||||
{
|
||||
"term": "Back",
|
||||
"context": "Back",
|
||||
"reference": "Modules/DankBar/Widgets/SystemTrayBar.qml:511",
|
||||
"reference": "Modules/DankBar/Widgets/SystemTrayBar.qml:863",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -542,7 +542,7 @@
|
||||
{
|
||||
"term": "Browse Plugins",
|
||||
"context": "Browse Plugins",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:177",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:197",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -590,7 +590,7 @@
|
||||
{
|
||||
"term": "Cancel",
|
||||
"context": "Cancel",
|
||||
"reference": "Modals/BluetoothPairingModal.qml:251, Modals/PolkitAuthModal.qml:291, Modals/WifiPasswordModal.qml:494, Modals/FileBrowser/FileBrowserOverwriteDialog.qml:83, Modules/Settings/PluginBrowser.qml:630",
|
||||
"reference": "Modals/BluetoothPairingModal.qml:251, Modals/PolkitAuthModal.qml:291, Modals/WifiPasswordModal.qml:494, Modals/FileBrowser/FileBrowserOverwriteDialog.qml:83, Modules/Settings/PluginBrowser.qml:650",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -644,7 +644,7 @@
|
||||
{
|
||||
"term": "Choose where notification popups appear on screen",
|
||||
"context": "Choose where notification popups appear on screen",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:602",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:604",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -692,7 +692,7 @@
|
||||
{
|
||||
"term": "Close",
|
||||
"context": "Close",
|
||||
"reference": "Modules/SystemUpdatePopout.qml:335, Modals/NetworkWiredInfoModal.qml:131, Modals/NetworkInfoModal.qml:131, Modules/DankBar/Widgets/RunningApps.qml:770",
|
||||
"reference": "Modules/SystemUpdatePopout.qml:335, Modals/NetworkWiredInfoModal.qml:131, Modals/NetworkInfoModal.qml:131, Modules/DankBar/Widgets/RunningApps.qml:778",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -728,37 +728,37 @@
|
||||
{
|
||||
"term": "Command or script to run instead of the standard hibernate procedure",
|
||||
"context": "Command or script to run instead of the standard hibernate procedure",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:508",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:687",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Command or script to run instead of the standard lock procedure",
|
||||
"context": "Command or script to run instead of the standard lock procedure",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:412",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:591",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Command or script to run instead of the standard logout procedure",
|
||||
"context": "Command or script to run instead of the standard logout procedure",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:444",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:623",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Command or script to run instead of the standard power off procedure",
|
||||
"context": "Command or script to run instead of the standard power off procedure",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:572",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:751",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Command or script to run instead of the standard reboot procedure",
|
||||
"context": "Command or script to run instead of the standard reboot procedure",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:540",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:719",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Command or script to run instead of the standard suspend procedure",
|
||||
"context": "Command or script to run instead of the standard suspend procedure",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:476",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:655",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -788,7 +788,7 @@
|
||||
{
|
||||
"term": "Configure icons for named workspaces. Icons take priority over numbers when both are enabled.",
|
||||
"context": "Configure icons for named workspaces. Icons take priority over numbers when both are enabled.",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:438",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:440",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -890,7 +890,7 @@
|
||||
{
|
||||
"term": "Copied!",
|
||||
"context": "Copied!",
|
||||
"reference": "Modules/Toast.qml:17",
|
||||
"reference": "Modules/Toast.qml:19",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -974,7 +974,7 @@
|
||||
{
|
||||
"term": "Custom Power Actions",
|
||||
"context": "Custom Power Actions",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:398",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:577",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -995,6 +995,12 @@
|
||||
"reference": "Modules/Settings/DankBarTab.qml:151",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Customize which actions appear in the power menu",
|
||||
"context": "Customize which actions appear in the power menu",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:363",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "DEMO MODE - Click anywhere to exit",
|
||||
"context": "DEMO MODE - Click anywhere to exit",
|
||||
@@ -1010,7 +1016,7 @@
|
||||
{
|
||||
"term": "DMS out of date",
|
||||
"context": "DMS out of date",
|
||||
"reference": "Services/DMSService.qml:298",
|
||||
"reference": "Services/DMSService.qml:301",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1091,6 +1097,12 @@
|
||||
"reference": "Modules/Settings/LauncherTab.qml:202",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Default selected action",
|
||||
"context": "Default selected action",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:374",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Defaults",
|
||||
"context": "Defaults",
|
||||
@@ -1172,7 +1184,7 @@
|
||||
{
|
||||
"term": "Dismiss",
|
||||
"context": "Dismiss",
|
||||
"reference": "Modules/Notifications/Popup/NotificationPopup.qml:24, Modules/Notifications/Center/NotificationCard.qml:542, Modules/Notifications/Center/NotificationCard.qml:635",
|
||||
"reference": "Modules/Notifications/Popup/NotificationPopup.qml:25, Modules/Notifications/Center/NotificationCard.qml:543, Modules/Notifications/Center/NotificationCard.qml:636",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1208,7 +1220,7 @@
|
||||
{
|
||||
"term": "Display volume and brightness percentage values by default in OSD popups",
|
||||
"context": "Display volume and brightness percentage values by default in OSD popups",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:682",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:684",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1262,7 +1274,7 @@
|
||||
{
|
||||
"term": "Donate on Ko-fi",
|
||||
"context": "Donate on Ko-fi",
|
||||
"reference": "Modules/Settings/AboutTab.qml:598",
|
||||
"reference": "Modules/Settings/AboutTab.qml:642",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1688,7 +1700,7 @@
|
||||
{
|
||||
"term": "Github:",
|
||||
"context": "Github:",
|
||||
"reference": "Modules/Settings/AboutTab.qml:482",
|
||||
"reference": "Modules/Settings/AboutTab.qml:526",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1754,7 +1766,7 @@
|
||||
{
|
||||
"term": "Hibernate",
|
||||
"context": "Hibernate",
|
||||
"reference": "Modals/PowerMenuModal.qml:45, Modals/PowerMenuModal.qml:313, Modules/Lock/LockPowerMenu.qml:312",
|
||||
"reference": "Modals/PowerMenuModal.qml:117, Modals/PowerMenuModal.qml:157, Modules/Lock/LockPowerMenu.qml:312",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1796,7 +1808,7 @@
|
||||
{
|
||||
"term": "I Understand",
|
||||
"context": "I Understand",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:636",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:656",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1880,7 +1892,7 @@
|
||||
{
|
||||
"term": "Install plugins from the DMS plugin registry",
|
||||
"context": "Install plugins from the DMS plugin registry",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:231",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:251",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -1988,7 +2000,7 @@
|
||||
{
|
||||
"term": "Launch on dGPU",
|
||||
"context": "Launch on dGPU",
|
||||
"reference": "Modals/Spotlight/SpotlightContextMenu.qml:312, Modules/AppDrawer/AppDrawerPopout.qml:806, Modules/Dock/DockContextMenu.qml:417",
|
||||
"reference": "Modals/Spotlight/SpotlightContextMenu.qml:312, Modules/AppDrawer/AppDrawerPopout.qml:806, Modules/Dock/DockContextMenu.qml:420",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2036,7 +2048,7 @@
|
||||
{
|
||||
"term": "Loading plugins...",
|
||||
"context": "Loading plugins...",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:299",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:319",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2045,6 +2057,12 @@
|
||||
"reference": "Modules/Settings/TimeWeatherTab.qml:769",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Lock",
|
||||
"context": "Lock",
|
||||
"reference": "Modals/PowerMenuModal.qml:105",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Lock Screen",
|
||||
"context": "Lock Screen",
|
||||
@@ -2066,7 +2084,7 @@
|
||||
{
|
||||
"term": "Log Out",
|
||||
"context": "Log Out",
|
||||
"reference": "Modals/PowerMenuModal.qml:37, Modals/PowerMenuModal.qml:206, Modules/Lock/LockPowerMenu.qml:209, Modules/ControlCenter/PowerMenu.qml:14",
|
||||
"reference": "Modals/PowerMenuModal.qml:93, Modals/PowerMenuModal.qml:149, Modules/Lock/LockPowerMenu.qml:209, Modules/ControlCenter/PowerMenu.qml:14",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2168,7 +2186,7 @@
|
||||
{
|
||||
"term": "Max apps to show",
|
||||
"context": "Max apps to show",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:103",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:104",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2210,7 +2228,7 @@
|
||||
{
|
||||
"term": "Media Player Settings",
|
||||
"context": "Media Player Settings",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:183",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:184",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2306,7 +2324,7 @@
|
||||
{
|
||||
"term": "Named Workspace Icons",
|
||||
"context": "Named Workspace Icons",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:428",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:430",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2450,7 +2468,7 @@
|
||||
{
|
||||
"term": "No plugins found",
|
||||
"context": "No plugins found",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:533",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:553",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2516,7 +2534,7 @@
|
||||
{
|
||||
"term": "Notification Popups",
|
||||
"context": "Notification Popups",
|
||||
"reference": "Modules/Settings/DisplaysTab.qml:24, Modules/Settings/WidgetTweaksTab.qml:585",
|
||||
"reference": "Modules/Settings/DisplaysTab.qml:24, Modules/Settings/WidgetTweaksTab.qml:587",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2579,6 +2597,12 @@
|
||||
"reference": "Modules/Settings/DisplaysTab.qml:200",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Only visible if hibernate is supported by your system",
|
||||
"context": "Only visible if hibernate is supported by your system",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:490",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Opacity",
|
||||
"context": "Opacity",
|
||||
@@ -2702,7 +2726,7 @@
|
||||
{
|
||||
"term": "Per-Monitor Workspaces",
|
||||
"context": "Per-Monitor Workspaces",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:134",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:135",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2726,7 +2750,7 @@
|
||||
{
|
||||
"term": "Pin to Dock",
|
||||
"context": "Pin to Dock",
|
||||
"reference": "Modals/Spotlight/SpotlightContextMenu.qml:110, Modals/Spotlight/SpotlightContextMenu.qml:113, Modules/AppDrawer/AppDrawerPopout.qml:609, Modules/Dock/DockContextMenu.qml:370",
|
||||
"reference": "Modals/Spotlight/SpotlightContextMenu.qml:110, Modals/Spotlight/SpotlightContextMenu.qml:113, Modules/AppDrawer/AppDrawerPopout.qml:609, Modules/Dock/DockContextMenu.qml:373",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2798,13 +2822,13 @@
|
||||
{
|
||||
"term": "Plugins:",
|
||||
"context": "Plugins:",
|
||||
"reference": "Modules/Settings/AboutTab.qml:459",
|
||||
"reference": "Modules/Settings/AboutTab.qml:503",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Popup Position",
|
||||
"context": "Popup Position",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:601",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:603",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2834,19 +2858,25 @@
|
||||
{
|
||||
"term": "Power Action Confirmation",
|
||||
"context": "Power Action Confirmation",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:533",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Power Menu Customization",
|
||||
"context": "Power Menu Customization",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:354",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Power Off",
|
||||
"context": "Power Off",
|
||||
"reference": "Modals/PowerMenuModal.qml:53, Modals/PowerMenuModal.qml:421, Modules/Lock/LockPowerMenu.qml:432, Modules/ControlCenter/PowerMenu.qml:17",
|
||||
"reference": "Modals/PowerMenuModal.qml:99, Modals/PowerMenuModal.qml:165, Modules/Lock/LockPowerMenu.qml:432, Modules/ControlCenter/PowerMenu.qml:17",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Power Options",
|
||||
"context": "Power Options",
|
||||
"reference": "Modals/PowerMenuModal.qml:149, Modules/Lock/LockPowerMenu.qml:154, Modules/ControlCenter/PowerMenu.qml:13",
|
||||
"reference": "Modules/Lock/LockPowerMenu.qml:154, Modules/ControlCenter/PowerMenu.qml:13",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -2972,7 +3002,7 @@
|
||||
{
|
||||
"term": "Reboot",
|
||||
"context": "Reboot",
|
||||
"reference": "Modals/PowerMenuModal.qml:49, Modals/PowerMenuModal.qml:367, Modules/Lock/LockPowerMenu.qml:372, Modules/ControlCenter/PowerMenu.qml:16",
|
||||
"reference": "Modals/PowerMenuModal.qml:87, Modals/PowerMenuModal.qml:161, Modules/Lock/LockPowerMenu.qml:372, Modules/ControlCenter/PowerMenu.qml:16",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3014,7 +3044,7 @@
|
||||
{
|
||||
"term": "Request confirmation on power off, restart, suspend, hibernate and logout actions",
|
||||
"context": "Request confirmation on power off, restart, suspend, hibernate and logout actions",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:365",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:544",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3026,7 +3056,19 @@
|
||||
{
|
||||
"term": "Resources",
|
||||
"context": "Resources",
|
||||
"reference": "Modules/Settings/AboutTab.qml:421",
|
||||
"reference": "Modules/Settings/AboutTab.qml:465",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Restart DMS",
|
||||
"context": "Restart DMS",
|
||||
"reference": "Modals/PowerMenuModal.qml:123",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Restart the DankMaterialShell",
|
||||
"context": "Restart the DankMaterialShell",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:474",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3074,13 +3116,13 @@
|
||||
{
|
||||
"term": "Running Apps Only In Current Workspace",
|
||||
"context": "Running Apps Only In Current Workspace",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:388",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:390",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Running Apps Settings",
|
||||
"context": "Running Apps Settings",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:378",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:380",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3128,13 +3170,13 @@
|
||||
{
|
||||
"term": "Search file contents",
|
||||
"context": "Search file contents",
|
||||
"reference": "Modals/Spotlight/SpotlightContent.qml:372",
|
||||
"reference": "Modals/Spotlight/SpotlightContent.qml:373",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Search filenames",
|
||||
"context": "Search filenames",
|
||||
"reference": "Modals/Spotlight/SpotlightContent.qml:330",
|
||||
"reference": "Modals/Spotlight/SpotlightContent.qml:331",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3146,7 +3188,7 @@
|
||||
{
|
||||
"term": "Search plugins...",
|
||||
"context": "Search plugins...",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:255",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:275",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3260,7 +3302,7 @@
|
||||
{
|
||||
"term": "Settings",
|
||||
"context": "Settings",
|
||||
"reference": "Services/AppSearchService.qml:176, Modals/Settings/SettingsModal.qml:168, Modules/DankDash/DankDashPopout.qml:249",
|
||||
"reference": "Services/AppSearchService.qml:176, Modals/Settings/SettingsModal.qml:205, Modules/DankDash/DankDashPopout.qml:249",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3272,13 +3314,13 @@
|
||||
{
|
||||
"term": "Show All Tags",
|
||||
"context": "Show All Tags",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:144",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:145",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Confirmation on Power Actions",
|
||||
"context": "Show Confirmation on Power Actions",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:364",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:543",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3287,18 +3329,60 @@
|
||||
"reference": "Modules/Settings/DockTab.qml:128",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Hibernate",
|
||||
"context": "Show Hibernate",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:489",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Line Numbers",
|
||||
"context": "Show Line Numbers",
|
||||
"reference": "Modules/Notepad/NotepadSettings.qml:151",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Lock",
|
||||
"context": "Show Lock",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:443",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Log Out",
|
||||
"context": "Show Log Out",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:413",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Power Actions",
|
||||
"context": "Show Power Actions",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:57",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Power Off",
|
||||
"context": "Show Power Off",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:428",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Reboot",
|
||||
"context": "Show Reboot",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:398",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Restart DMS",
|
||||
"context": "Show Restart DMS",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:473",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Suspend",
|
||||
"context": "Show Suspend",
|
||||
"reference": "Modals/Settings/PowerSettings.qml:458",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Workspace Apps",
|
||||
"context": "Show Workspace Apps",
|
||||
@@ -3308,7 +3392,7 @@
|
||||
{
|
||||
"term": "Show all 9 tags instead of only occupied tags (DWL only)",
|
||||
"context": "Show all 9 tags instead of only occupied tags (DWL only)",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:145",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:146",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3344,13 +3428,13 @@
|
||||
{
|
||||
"term": "Show only apps running in current workspace",
|
||||
"context": "Show only apps running in current workspace",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:389",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:391",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show only workspaces belonging to each specific monitor.",
|
||||
"context": "Show only workspaces belonging to each specific monitor.",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:135",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:136",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3500,7 +3584,7 @@
|
||||
{
|
||||
"term": "Support Development",
|
||||
"context": "Support Development",
|
||||
"reference": "Modules/Settings/AboutTab.qml:583",
|
||||
"reference": "Modules/Settings/AboutTab.qml:627",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3512,7 +3596,7 @@
|
||||
{
|
||||
"term": "Suspend",
|
||||
"context": "Suspend",
|
||||
"reference": "Modals/PowerMenuModal.qml:41, Modals/PowerMenuModal.qml:259, Modules/Lock/LockPowerMenu.qml:260, Modules/ControlCenter/PowerMenu.qml:15",
|
||||
"reference": "Modals/PowerMenuModal.qml:111, Modals/PowerMenuModal.qml:153, Modules/Lock/LockPowerMenu.qml:260, Modules/ControlCenter/PowerMenu.qml:15",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3578,7 +3662,7 @@
|
||||
{
|
||||
"term": "System Monitoring:",
|
||||
"context": "System Monitoring:",
|
||||
"reference": "Modules/Settings/AboutTab.qml:517",
|
||||
"reference": "Modules/Settings/AboutTab.qml:561",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3596,7 +3680,7 @@
|
||||
{
|
||||
"term": "System Updater",
|
||||
"context": "System Updater",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:230",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:231",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3632,7 +3716,7 @@
|
||||
{
|
||||
"term": "System update custom command",
|
||||
"context": "System update custom command",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:266",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:267",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3644,7 +3728,7 @@
|
||||
{
|
||||
"term": "Terminal custom additional parameters",
|
||||
"context": "Terminal custom additional parameters",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:313",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:314",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3686,13 +3770,13 @@
|
||||
{
|
||||
"term": "Third-Party Plugin Warning",
|
||||
"context": "Third-Party Plugin Warning",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:581",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:601",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "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.",
|
||||
"context": "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.",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:591",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:611",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3728,7 +3812,7 @@
|
||||
{
|
||||
"term": "To update, run the following command:",
|
||||
"context": "To update, run the following command:",
|
||||
"reference": "Services/DMSService.qml:298",
|
||||
"reference": "Services/DMSService.qml:301",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3806,7 +3890,7 @@
|
||||
{
|
||||
"term": "Unpin from Dock",
|
||||
"context": "Unpin from Dock",
|
||||
"reference": "Modals/Spotlight/SpotlightContextMenu.qml:113, Modules/AppDrawer/AppDrawerPopout.qml:609, Modules/Dock/DockContextMenu.qml:370",
|
||||
"reference": "Modals/Spotlight/SpotlightContextMenu.qml:113, Modules/AppDrawer/AppDrawerPopout.qml:609, Modules/Dock/DockContextMenu.qml:373",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3854,7 +3938,7 @@
|
||||
{
|
||||
"term": "Use Custom Command",
|
||||
"context": "Use Custom Command",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:240",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:241",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -3890,13 +3974,13 @@
|
||||
{
|
||||
"term": "Use animated wave progress bars for media playback",
|
||||
"context": "Use animated wave progress bars for media playback",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:194",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:195",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Use custom command for update your system",
|
||||
"context": "Use custom command for update your system",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:241",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:242",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -4034,7 +4118,7 @@
|
||||
{
|
||||
"term": "Wave Progress Bars",
|
||||
"context": "Wave Progress Bars",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:193",
|
||||
"reference": "Modules/Settings/WidgetTweaksTab.qml:194",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -4052,7 +4136,7 @@
|
||||
{
|
||||
"term": "Website:",
|
||||
"context": "Website:",
|
||||
"reference": "Modules/Settings/AboutTab.qml:436",
|
||||
"reference": "Modules/Settings/AboutTab.qml:480",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -4178,7 +4262,7 @@
|
||||
{
|
||||
"term": "official",
|
||||
"context": "official",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:388",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:408",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -4190,7 +4274,7 @@
|
||||
{
|
||||
"term": "• Install only from trusted sources",
|
||||
"context": "• Install only from trusted sources",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:614",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:634",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
@@ -4220,13 +4304,13 @@
|
||||
{
|
||||
"term": "• Plugins may contain bugs or security issues",
|
||||
"context": "• Plugins may contain bugs or security issues",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:602",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:622",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "• Review code before installation when possible",
|
||||
"context": "• Review code before installation when possible",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:608",
|
||||
"reference": "Modules/Settings/PluginBrowser.qml:628",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"Applications": {
|
||||
"Applications": "Applicazioni"
|
||||
},
|
||||
"Apply": {
|
||||
"Apply": "Applica"
|
||||
},
|
||||
"Apply GTK Colors": {
|
||||
"Apply GTK Colors": "Applica Colori GTK"
|
||||
},
|
||||
@@ -167,9 +164,6 @@
|
||||
"Auto-hide Dock": {
|
||||
"Auto-hide Dock": "Nascondi automaticamente Dock"
|
||||
},
|
||||
"Auto-location": {
|
||||
"Auto-location": "Localizzazione automatica"
|
||||
},
|
||||
"Auto-saving...": {
|
||||
"Auto-saving...": "Salvataggio automatico..."
|
||||
},
|
||||
@@ -230,9 +224,6 @@
|
||||
"Battery level and power management": {
|
||||
"Battery level and power management": "Livello batteria e gestione energetica"
|
||||
},
|
||||
"Battery not detected - only AC power settings available": {
|
||||
"Battery not detected - only AC power settings available": "Batteria non rilevata - disponibili solo impostazioni di alimentazione di rete"
|
||||
},
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "Collega il blocca schermo ai segnali dbus da loginctl.\nDisabilità se stai usando un blocca schermo esterno"
|
||||
},
|
||||
@@ -398,9 +389,6 @@
|
||||
"Compositor": {
|
||||
"Compositor": "Compositor\n"
|
||||
},
|
||||
"Compositor:": {
|
||||
"Compositor:": "Compositor:"
|
||||
},
|
||||
"Configuration activated": {
|
||||
"Configuration activated": "Configurazione attivata"
|
||||
},
|
||||
@@ -434,9 +422,6 @@
|
||||
"Connecting to Device": {
|
||||
"Connecting to Device": "Connessione al Dispositivo"
|
||||
},
|
||||
"Connection failed. Check password and try again.": {
|
||||
"Connection failed. Check password and try again.": "Connessione fallita. Controlla la password e riprova"
|
||||
},
|
||||
"Contrast": {
|
||||
"Contrast": "Contrasto"
|
||||
},
|
||||
@@ -461,9 +446,6 @@
|
||||
"Copied!": {
|
||||
"Copied!": "Copiato!"
|
||||
},
|
||||
"Copy": {
|
||||
"Copy": "Copia"
|
||||
},
|
||||
"Copy PID": {
|
||||
"Copy PID": "Copia PID"
|
||||
},
|
||||
@@ -515,6 +497,9 @@
|
||||
"Customizable empty space": {
|
||||
"Customizable empty space": "Spazio vuoto personalizzabile"
|
||||
},
|
||||
"Customize which actions appear in the power menu": {
|
||||
"Customize which actions appear in the power menu": ""
|
||||
},
|
||||
"DEMO MODE - Click anywhere to exit": {
|
||||
"DEMO MODE - Click anywhere to exit": "DEMO MODE - Clicca ovunque per uscire"
|
||||
},
|
||||
@@ -542,9 +527,6 @@
|
||||
"Dank Bar Widget Transparency": {
|
||||
"Dank Bar Widget Transparency": "Trasparenza Widget Dank Bar"
|
||||
},
|
||||
"Dank Suite:": {
|
||||
"Dank Suite:": "Dank Suite:"
|
||||
},
|
||||
"DankBar Font Scale": {
|
||||
"DankBar Font Scale": "Scala Font DankBar"
|
||||
},
|
||||
@@ -566,6 +548,9 @@
|
||||
"Default": {
|
||||
"Default": "Predefinito"
|
||||
},
|
||||
"Default selected action": {
|
||||
"Default selected action": ""
|
||||
},
|
||||
"Defaults": {
|
||||
"Defaults": "Predefiniti"
|
||||
},
|
||||
@@ -842,9 +827,6 @@
|
||||
"Format Legend": {
|
||||
"Format Legend": "Legenda Formato"
|
||||
},
|
||||
"Framework:": {
|
||||
"Framework:": "Framework:"
|
||||
},
|
||||
"Fun": {
|
||||
"Fun": "Svago"
|
||||
},
|
||||
@@ -866,9 +848,6 @@
|
||||
"Gamma control not available. Requires DMS API v6+.": {
|
||||
"Gamma control not available. Requires DMS API v6+.": "Gamma control non disponibile. Richiede API DMS v6+."
|
||||
},
|
||||
"Geoclue service not running - cannot auto-detect location": {
|
||||
"Geoclue service not running - cannot auto-detect location": "Il servizio Geoclue non è in esecuzione - non può determinare la posizione automaticamente"
|
||||
},
|
||||
"Github:": {
|
||||
"Github:": "Github:"
|
||||
},
|
||||
@@ -902,15 +881,9 @@
|
||||
"Hex": {
|
||||
"Hex": "Hex"
|
||||
},
|
||||
"Hex:": {
|
||||
"Hex:": "Hex:"
|
||||
},
|
||||
"Hibernate": {
|
||||
"Hibernate": "Iberna"
|
||||
},
|
||||
"Hibernate system after": {
|
||||
"Hibernate system after": "Iberna sistema dopo"
|
||||
},
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": {
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": "Nascondi la dock quando "
|
||||
},
|
||||
@@ -1001,9 +974,6 @@
|
||||
"Kill Process": {
|
||||
"Kill Process": "Chiusura Processo"
|
||||
},
|
||||
"Language:": {
|
||||
"Language:": "Lingua:"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "Ultimo avviato %1"
|
||||
},
|
||||
@@ -1058,6 +1028,9 @@
|
||||
"Location Search": {
|
||||
"Location Search": "Ricerca Posizione"
|
||||
},
|
||||
"Lock": {
|
||||
"Lock": ""
|
||||
},
|
||||
"Lock Screen": {
|
||||
"Lock Screen": "Blocca Schermo"
|
||||
},
|
||||
@@ -1166,9 +1139,6 @@
|
||||
"Mode: ": {
|
||||
"Mode: ": ""
|
||||
},
|
||||
"Monitor": {
|
||||
"Monitor": "Monitor"
|
||||
},
|
||||
"Monitor Selection:": {
|
||||
"Monitor Selection:": "Selezione Monitor:"
|
||||
},
|
||||
@@ -1328,6 +1298,9 @@
|
||||
"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 visible if hibernate is supported by your system": {
|
||||
"Only visible if hibernate is supported by your system": ""
|
||||
},
|
||||
"Opacity": {
|
||||
"Opacity": "Opacità"
|
||||
},
|
||||
@@ -1457,6 +1430,9 @@
|
||||
"Power Action Confirmation": {
|
||||
"Power Action Confirmation": "Conferma Azioni Alimentazione"
|
||||
},
|
||||
"Power Menu Customization": {
|
||||
"Power Menu Customization": ""
|
||||
},
|
||||
"Power Off": {
|
||||
"Power Off": "Spegni"
|
||||
},
|
||||
@@ -1502,9 +1478,6 @@
|
||||
"Profile image is too large. Please use a smaller image.": {
|
||||
"Profile image is too large. Please use a smaller image.": "Immagine profilo troppo grande. Per favore usa un'immagine più piccola"
|
||||
},
|
||||
"QML, JavaScript, Go": {
|
||||
"QML, JavaScript, Go": "\nQML, JavaScript, Go"
|
||||
},
|
||||
"Quick access to application launcher": {
|
||||
"Quick access to application launcher": "Accesso veloce al launcher applicazioni"
|
||||
},
|
||||
@@ -1556,6 +1529,15 @@
|
||||
"Resources": {
|
||||
"Resources": "Risorse"
|
||||
},
|
||||
"Restart": {
|
||||
"Restart": ""
|
||||
},
|
||||
"Restart DMS": {
|
||||
"Restart DMS": ""
|
||||
},
|
||||
"Restart the DankMaterialShell": {
|
||||
"Restart the DankMaterialShell": ""
|
||||
},
|
||||
"Resume": {
|
||||
"Resume": "Riprendi"
|
||||
},
|
||||
@@ -1604,9 +1586,6 @@
|
||||
"Science": {
|
||||
"Science": "Scienza"
|
||||
},
|
||||
"Scroll through windows, rather than workspaces": {
|
||||
"Scroll through windows, rather than workspaces": "Scorri tra le finestre, piuttosto che i workspaces"
|
||||
},
|
||||
"Search file contents": {
|
||||
"Search file contents": "Cerca il contenuto dei files"
|
||||
},
|
||||
@@ -1688,12 +1667,33 @@
|
||||
"Show Dock": {
|
||||
"Show Dock": "Mostra Dock"
|
||||
},
|
||||
"Show Hibernate": {
|
||||
"Show Hibernate": ""
|
||||
},
|
||||
"Show Line Numbers": {
|
||||
"Show Line Numbers": "Mostra Numero Righe"
|
||||
},
|
||||
"Show Lock": {
|
||||
"Show Lock": ""
|
||||
},
|
||||
"Show Log Out": {
|
||||
"Show Log Out": ""
|
||||
},
|
||||
"Show Power Actions": {
|
||||
"Show Power Actions": "Mostra Azioni Alimentazione"
|
||||
},
|
||||
"Show Power Off": {
|
||||
"Show Power Off": ""
|
||||
},
|
||||
"Show Reboot": {
|
||||
"Show Reboot": ""
|
||||
},
|
||||
"Show Restart DMS": {
|
||||
"Show Restart DMS": ""
|
||||
},
|
||||
"Show Suspend": {
|
||||
"Show Suspend": ""
|
||||
},
|
||||
"Show Workspace Apps": {
|
||||
"Show Workspace Apps": "Mostra Apps Workspace"
|
||||
},
|
||||
@@ -1865,12 +1865,6 @@
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Nav • ←→↑↓: Griglia Nav • Enter/Spazio: Seleziona"
|
||||
},
|
||||
"Technical Details": {
|
||||
"Technical Details": "Dettagli Tecnici"
|
||||
},
|
||||
"Temperature": {
|
||||
"Temperature": "Temperatura"
|
||||
},
|
||||
"Terminal custom additional parameters": {
|
||||
"Terminal custom additional parameters": "Parametri aggiuntivi personalizzati terminale"
|
||||
},
|
||||
@@ -1997,9 +1991,6 @@
|
||||
"Use animated wave progress bars for media playback": {
|
||||
"Use animated wave progress bars for media playback": "Usa barre ad onde animate per la riproduzione media"
|
||||
},
|
||||
"Use automatic location detection (geoclue2)": {
|
||||
"Use automatic location detection (geoclue2)": "Usa il rilevamento automatico della posizione (geoclue2)"
|
||||
},
|
||||
"Use custom command for update your system": {
|
||||
"Use custom command for update your system": "Usa comando personalizzato per aggiornare il sistema"
|
||||
},
|
||||
@@ -2105,9 +2096,6 @@
|
||||
"Wind": {
|
||||
"Wind": "Vento"
|
||||
},
|
||||
"Window Scrolling": {
|
||||
"Window Scrolling": "Scorrimento Finestra"
|
||||
},
|
||||
"Workspace": {
|
||||
"Workspace": "Workspace"
|
||||
},
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"Applications": {
|
||||
"Applications": "アプリ"
|
||||
},
|
||||
"Apply": {
|
||||
"Apply": "適用"
|
||||
},
|
||||
"Apply GTK Colors": {
|
||||
"Apply GTK Colors": "GTKカラーを適用"
|
||||
},
|
||||
@@ -167,9 +164,6 @@
|
||||
"Auto-hide Dock": {
|
||||
"Auto-hide Dock": "ドックを自動的に隠す"
|
||||
},
|
||||
"Auto-location": {
|
||||
"Auto-location": "自動位置特定"
|
||||
},
|
||||
"Auto-saving...": {
|
||||
"Auto-saving...": "自動保存中..."
|
||||
},
|
||||
@@ -230,9 +224,6 @@
|
||||
"Battery level and power management": {
|
||||
"Battery level and power management": "バッテリーレベルおよび電源管理"
|
||||
},
|
||||
"Battery not detected - only AC power settings available": {
|
||||
"Battery not detected - only AC power settings available": "バッテリーが検出されません - AC電源設定のみ利用可能です"
|
||||
},
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "ロック画面をloginctlからのdbus信号にバインド。外部ロック画面を使用している場合は無効に"
|
||||
},
|
||||
@@ -312,7 +303,7 @@
|
||||
"Center Section": "センターセクション"
|
||||
},
|
||||
"Changes:": {
|
||||
"Changes:": ""
|
||||
"Changes:": "変更:"
|
||||
},
|
||||
"Check for system updates": {
|
||||
"Check for system updates": "システムアップデートを検査"
|
||||
@@ -398,9 +389,6 @@
|
||||
"Compositor": {
|
||||
"Compositor": "コンポジター"
|
||||
},
|
||||
"Compositor:": {
|
||||
"Compositor:": "コンポジター:"
|
||||
},
|
||||
"Configuration activated": {
|
||||
"Configuration activated": "設定が適用されました"
|
||||
},
|
||||
@@ -414,7 +402,7 @@
|
||||
"Confirm": "確認"
|
||||
},
|
||||
"Confirm Display Changes": {
|
||||
"Confirm Display Changes": ""
|
||||
"Confirm Display Changes": "表示変更を確認"
|
||||
},
|
||||
"Confirm passkey for ": {
|
||||
"Confirm passkey for ": "パスキーを確認 "
|
||||
@@ -434,9 +422,6 @@
|
||||
"Connecting to Device": {
|
||||
"Connecting to Device": "デバイスに接続中"
|
||||
},
|
||||
"Connection failed. Check password and try again.": {
|
||||
"Connection failed. Check password and try again.": "接続に失敗しました。パスワードを確認して、もう一度やり直してください。"
|
||||
},
|
||||
"Contrast": {
|
||||
"Contrast": "コントラスト"
|
||||
},
|
||||
@@ -461,9 +446,6 @@
|
||||
"Copied!": {
|
||||
"Copied!": "コピーしました!"
|
||||
},
|
||||
"Copy": {
|
||||
"Copy": "コピー"
|
||||
},
|
||||
"Copy PID": {
|
||||
"Copy PID": "PIDをコピー"
|
||||
},
|
||||
@@ -515,6 +497,9 @@
|
||||
"Customizable empty space": {
|
||||
"Customizable empty space": "カスタマイズ可能な空きスペース"
|
||||
},
|
||||
"Customize which actions appear in the power menu": {
|
||||
"Customize which actions appear in the power menu": ""
|
||||
},
|
||||
"DEMO MODE - Click anywhere to exit": {
|
||||
"DEMO MODE - Click anywhere to exit": "デモモード -任意の場所をクリックして 終了"
|
||||
},
|
||||
@@ -542,9 +527,6 @@
|
||||
"Dank Bar Widget Transparency": {
|
||||
"Dank Bar Widget Transparency": "Dank Barウィジェットの透明度"
|
||||
},
|
||||
"Dank Suite:": {
|
||||
"Dank Suite:": "Dankスイート:"
|
||||
},
|
||||
"DankBar Font Scale": {
|
||||
"DankBar Font Scale": "Dank Bar フォントスケール"
|
||||
},
|
||||
@@ -566,6 +548,9 @@
|
||||
"Default": {
|
||||
"Default": "デフォルト"
|
||||
},
|
||||
"Default selected action": {
|
||||
"Default selected action": ""
|
||||
},
|
||||
"Defaults": {
|
||||
"Defaults": "デフォルト"
|
||||
},
|
||||
@@ -591,7 +576,7 @@
|
||||
"Disable Autoconnect": "自動接続を無効"
|
||||
},
|
||||
"Disabled": {
|
||||
"Disabled": ""
|
||||
"Disabled": "無効化されました"
|
||||
},
|
||||
"Disconnect": {
|
||||
"Disconnect": "切断"
|
||||
@@ -621,7 +606,7 @@
|
||||
"Display currently focused application title": "現在フォーカスされているアプリケーションのタイトルを表示"
|
||||
},
|
||||
"Display settings for ": {
|
||||
"Display settings for ": ""
|
||||
"Display settings for ": "以下の設定を表示 "
|
||||
},
|
||||
"Display volume and brightness percentage values by default in OSD popups": {
|
||||
"Display volume and brightness percentage values by default in OSD popups": "OSDポップアップに音量と輝度のパーセンテージ値をデフォルトで表示"
|
||||
@@ -699,7 +684,7 @@
|
||||
"Enable loginctl lock integration": "ログインロックの統合を有効に"
|
||||
},
|
||||
"Enabled": {
|
||||
"Enabled": ""
|
||||
"Enabled": "有効化されました"
|
||||
},
|
||||
"End": {
|
||||
"End": "終わり"
|
||||
@@ -842,9 +827,6 @@
|
||||
"Format Legend": {
|
||||
"Format Legend": "フォーマット凡例"
|
||||
},
|
||||
"Framework:": {
|
||||
"Framework:": "フレームワーク:"
|
||||
},
|
||||
"Fun": {
|
||||
"Fun": "娯楽"
|
||||
},
|
||||
@@ -866,9 +848,6 @@
|
||||
"Gamma control not available. Requires DMS API v6+.": {
|
||||
"Gamma control not available. Requires DMS API v6+.": "ガンマ制御は使用できません。DMS API v6+ が必要です。"
|
||||
},
|
||||
"Geoclue service not running - cannot auto-detect location": {
|
||||
"Geoclue service not running - cannot auto-detect location": "ジオクルー サービスが実行されていない - 位置を自動検出できません"
|
||||
},
|
||||
"Github:": {
|
||||
"Github:": "GitHub:"
|
||||
},
|
||||
@@ -902,15 +881,9 @@
|
||||
"Hex": {
|
||||
"Hex": "16進数"
|
||||
},
|
||||
"Hex:": {
|
||||
"Hex:": "16進数:"
|
||||
},
|
||||
"Hibernate": {
|
||||
"Hibernate": "休止状態"
|
||||
},
|
||||
"Hibernate system after": {
|
||||
"Hibernate system after": "後にシステムを休止状態"
|
||||
},
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": {
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": "使用していないときはドックを非表示にし、ドックエリアの近くにホバーすると表示されます"
|
||||
},
|
||||
@@ -966,7 +939,7 @@
|
||||
"Individual Batteries": "バッテリーごと"
|
||||
},
|
||||
"Inhibit idle timeout when audio or video is playing": {
|
||||
"Inhibit idle timeout when audio or video is playing": ""
|
||||
"Inhibit idle timeout when audio or video is playing": "オーディオまたはビデオの再生中のアイドルタイムアウトを禁止"
|
||||
},
|
||||
"Input Devices": {
|
||||
"Input Devices": "入力デバイス"
|
||||
@@ -993,7 +966,7 @@
|
||||
"Jobs: ": "ジョブ: "
|
||||
},
|
||||
"Keep Changes": {
|
||||
"Keep Changes": ""
|
||||
"Keep Changes": "変更を保持"
|
||||
},
|
||||
"Keyboard Layout Name": {
|
||||
"Keyboard Layout Name": "キーボードレイアウト名"
|
||||
@@ -1001,9 +974,6 @@
|
||||
"Kill Process": {
|
||||
"Kill Process": "プロセスを強制終了"
|
||||
},
|
||||
"Language:": {
|
||||
"Language:": "言語:"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "最終起動日 %1"
|
||||
},
|
||||
@@ -1058,6 +1028,9 @@
|
||||
"Location Search": {
|
||||
"Location Search": "ロケーション検索"
|
||||
},
|
||||
"Lock": {
|
||||
"Lock": "ロック"
|
||||
},
|
||||
"Lock Screen": {
|
||||
"Lock Screen": "ロック画面"
|
||||
},
|
||||
@@ -1164,10 +1137,7 @@
|
||||
"Mode:": "モード:"
|
||||
},
|
||||
"Mode: ": {
|
||||
"Mode: ": ""
|
||||
},
|
||||
"Monitor": {
|
||||
"Monitor": "モニター"
|
||||
"Mode: ": "モード: "
|
||||
},
|
||||
"Monitor Selection:": {
|
||||
"Monitor Selection:": "モニターの選択:"
|
||||
@@ -1328,6 +1298,9 @@
|
||||
"Only adjust gamma based on time or location rules.": {
|
||||
"Only adjust gamma based on time or location rules.": "ガンマは、時間または場所のルールに基づいてのみ調整します。"
|
||||
},
|
||||
"Only visible if hibernate is supported by your system": {
|
||||
"Only visible if hibernate is supported by your system": ""
|
||||
},
|
||||
"Opacity": {
|
||||
"Opacity": "不透明度"
|
||||
},
|
||||
@@ -1449,7 +1422,7 @@
|
||||
"Position": "位置"
|
||||
},
|
||||
"Position: ": {
|
||||
"Position: ": ""
|
||||
"Position: ": "位置: "
|
||||
},
|
||||
"Power & Security": {
|
||||
"Power & Security": "電源とセキュリティ"
|
||||
@@ -1457,6 +1430,9 @@
|
||||
"Power Action Confirmation": {
|
||||
"Power Action Confirmation": "電源アクションの確認"
|
||||
},
|
||||
"Power Menu Customization": {
|
||||
"Power Menu Customization": ""
|
||||
},
|
||||
"Power Off": {
|
||||
"Power Off": "電源オフ"
|
||||
},
|
||||
@@ -1470,7 +1446,7 @@
|
||||
"Pressure": "プレッシャー"
|
||||
},
|
||||
"Prevent idle for media": {
|
||||
"Prevent idle for media": ""
|
||||
"Prevent idle for media": "メディアのアイドル状態を防止"
|
||||
},
|
||||
"Prevent screen timeout": {
|
||||
"Prevent screen timeout": "画面のタイムアウトを防止"
|
||||
@@ -1502,9 +1478,6 @@
|
||||
"Profile image is too large. Please use a smaller image.": {
|
||||
"Profile image is too large. Please use a smaller image.": "プロフィール画像が大きすぎます。より小さい画像を使用してください。"
|
||||
},
|
||||
"QML, JavaScript, Go": {
|
||||
"QML, JavaScript, Go": "QML, JavaScript, Go"
|
||||
},
|
||||
"Quick access to application launcher": {
|
||||
"Quick access to application launcher": "アプリケーションランチャーへのクイックアクセス"
|
||||
},
|
||||
@@ -1556,14 +1529,23 @@
|
||||
"Resources": {
|
||||
"Resources": "リソース"
|
||||
},
|
||||
"Restart": {
|
||||
"Restart": "再起動"
|
||||
},
|
||||
"Restart DMS": {
|
||||
"Restart DMS": ""
|
||||
},
|
||||
"Restart the DankMaterialShell": {
|
||||
"Restart the DankMaterialShell": ""
|
||||
},
|
||||
"Resume": {
|
||||
"Resume": "レジュメ"
|
||||
},
|
||||
"Revert": {
|
||||
"Revert": ""
|
||||
"Revert": "戻す"
|
||||
},
|
||||
"Reverting in:": {
|
||||
"Reverting in:": ""
|
||||
"Reverting in:": "元に戻す:"
|
||||
},
|
||||
"Right": {
|
||||
"Right": "右"
|
||||
@@ -1604,9 +1586,6 @@
|
||||
"Science": {
|
||||
"Science": "科学"
|
||||
},
|
||||
"Scroll through windows, rather than workspaces": {
|
||||
"Scroll through windows, rather than workspaces": "ワークスペースではなくウィンドウをスクロール"
|
||||
},
|
||||
"Search file contents": {
|
||||
"Search file contents": "ファイルの内容を検索"
|
||||
},
|
||||
@@ -1688,12 +1667,33 @@
|
||||
"Show Dock": {
|
||||
"Show Dock": "ドックを表示"
|
||||
},
|
||||
"Show Hibernate": {
|
||||
"Show Hibernate": ""
|
||||
},
|
||||
"Show Line Numbers": {
|
||||
"Show Line Numbers": "行番号を表示"
|
||||
},
|
||||
"Show Lock": {
|
||||
"Show Lock": ""
|
||||
},
|
||||
"Show Log Out": {
|
||||
"Show Log Out": ""
|
||||
},
|
||||
"Show Power Actions": {
|
||||
"Show Power Actions": "電源アクションを表示"
|
||||
},
|
||||
"Show Power Off": {
|
||||
"Show Power Off": ""
|
||||
},
|
||||
"Show Reboot": {
|
||||
"Show Reboot": ""
|
||||
},
|
||||
"Show Restart DMS": {
|
||||
"Show Restart DMS": ""
|
||||
},
|
||||
"Show Suspend": {
|
||||
"Show Suspend": ""
|
||||
},
|
||||
"Show Workspace Apps": {
|
||||
"Show Workspace Apps": "ワークスペースアプリを表示"
|
||||
},
|
||||
@@ -1865,12 +1865,6 @@
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: ナビゲーション • ←→↑↓: グリッドナビゲーション • Enter/Space: 選択"
|
||||
},
|
||||
"Technical Details": {
|
||||
"Technical Details": "技術的な詳細"
|
||||
},
|
||||
"Temperature": {
|
||||
"Temperature": "温度"
|
||||
},
|
||||
"Terminal custom additional parameters": {
|
||||
"Terminal custom additional parameters": "端末のカスタム追加パラメーター"
|
||||
},
|
||||
@@ -1997,9 +1991,6 @@
|
||||
"Use animated wave progress bars for media playback": {
|
||||
"Use animated wave progress bars for media playback": "アニメーション化されたウェーブの進行状況バーをメディア再生に使用"
|
||||
},
|
||||
"Use automatic location detection (geoclue2)": {
|
||||
"Use automatic location detection (geoclue2)": "自動位置検出 (geoclue2) を使用"
|
||||
},
|
||||
"Use custom command for update your system": {
|
||||
"Use custom command for update your system": "カスタムコマンドを使用してシステムを更新"
|
||||
},
|
||||
@@ -2037,7 +2028,7 @@
|
||||
"VPN status and quick connect": "VPNステータスとクイック接続"
|
||||
},
|
||||
"VRR: ": {
|
||||
"VRR: ": ""
|
||||
"VRR: ": "VRR: "
|
||||
},
|
||||
"Vibrant palette with playful saturation.": {
|
||||
"Vibrant palette with playful saturation.": "遊び心のある彩度の鮮やかなパレット。"
|
||||
@@ -2105,9 +2096,6 @@
|
||||
"Wind": {
|
||||
"Wind": "風"
|
||||
},
|
||||
"Window Scrolling": {
|
||||
"Window Scrolling": "ウィンドウスクロール"
|
||||
},
|
||||
"Workspace": {
|
||||
"Workspace": "ワークスペース"
|
||||
},
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"Applications": {
|
||||
"Applications": "Aplikacje"
|
||||
},
|
||||
"Apply": {
|
||||
"Apply": "Zastosuj"
|
||||
},
|
||||
"Apply GTK Colors": {
|
||||
"Apply GTK Colors": "Zastosuj kolory GTK"
|
||||
},
|
||||
@@ -167,9 +164,6 @@
|
||||
"Auto-hide Dock": {
|
||||
"Auto-hide Dock": "Automatyczne ukrywanie doku"
|
||||
},
|
||||
"Auto-location": {
|
||||
"Auto-location": "Automatyczna lokalizacja"
|
||||
},
|
||||
"Auto-saving...": {
|
||||
"Auto-saving...": "Automatyczne zapisywanie..."
|
||||
},
|
||||
@@ -230,9 +224,6 @@
|
||||
"Battery level and power management": {
|
||||
"Battery level and power management": "Poziom baterii i zarządzanie zasilaniem"
|
||||
},
|
||||
"Battery not detected - only AC power settings available": {
|
||||
"Battery not detected - only AC power settings available": "Nie wykryto baterii - dostępne tylko ustawienia po podłączeniu do zasilacza"
|
||||
},
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "Powiąż ekran blokady z sygnałami dbus z loginctl. Wyłącz, jeśli używasz zewnętrznego ekranu blokady"
|
||||
},
|
||||
@@ -398,9 +389,6 @@
|
||||
"Compositor": {
|
||||
"Compositor": "Kompozytor"
|
||||
},
|
||||
"Compositor:": {
|
||||
"Compositor:": "Kompozytor:"
|
||||
},
|
||||
"Configuration activated": {
|
||||
"Configuration activated": "Konfiguracja aktywowana"
|
||||
},
|
||||
@@ -434,9 +422,6 @@
|
||||
"Connecting to Device": {
|
||||
"Connecting to Device": "Łączenie z urządzeniem"
|
||||
},
|
||||
"Connection failed. Check password and try again.": {
|
||||
"Connection failed. Check password and try again.": "Połączenie nieudane. Sprawdź hasło i spróbuj ponownie."
|
||||
},
|
||||
"Contrast": {
|
||||
"Contrast": "Kontrast"
|
||||
},
|
||||
@@ -461,9 +446,6 @@
|
||||
"Copied!": {
|
||||
"Copied!": "Skopiowane!"
|
||||
},
|
||||
"Copy": {
|
||||
"Copy": "Kopiuj"
|
||||
},
|
||||
"Copy PID": {
|
||||
"Copy PID": "Kopiuj PID"
|
||||
},
|
||||
@@ -515,6 +497,9 @@
|
||||
"Customizable empty space": {
|
||||
"Customizable empty space": "Dostosowywalna pusta przestrzeń"
|
||||
},
|
||||
"Customize which actions appear in the power menu": {
|
||||
"Customize which actions appear in the power menu": ""
|
||||
},
|
||||
"DEMO MODE - Click anywhere to exit": {
|
||||
"DEMO MODE - Click anywhere to exit": "TRYB DEMO - Kliknij gdziekolwiek aby wyjść"
|
||||
},
|
||||
@@ -542,9 +527,6 @@
|
||||
"Dank Bar Widget Transparency": {
|
||||
"Dank Bar Widget Transparency": "Przezroczystość widżetu Dank Bar"
|
||||
},
|
||||
"Dank Suite:": {
|
||||
"Dank Suite:": "Dank Suite:"
|
||||
},
|
||||
"DankBar Font Scale": {
|
||||
"DankBar Font Scale": "Skala czcionki DankBar"
|
||||
},
|
||||
@@ -566,6 +548,9 @@
|
||||
"Default": {
|
||||
"Default": "Domyślne"
|
||||
},
|
||||
"Default selected action": {
|
||||
"Default selected action": ""
|
||||
},
|
||||
"Defaults": {
|
||||
"Defaults": "Domyślne"
|
||||
},
|
||||
@@ -842,9 +827,6 @@
|
||||
"Format Legend": {
|
||||
"Format Legend": "Legenda formatowania"
|
||||
},
|
||||
"Framework:": {
|
||||
"Framework:": "Framework:"
|
||||
},
|
||||
"Fun": {
|
||||
"Fun": "Zabawa"
|
||||
},
|
||||
@@ -866,9 +848,6 @@
|
||||
"Gamma control not available. Requires DMS API v6+.": {
|
||||
"Gamma control not available. Requires DMS API v6+.": "Kontrola gamma niedostępna. Wymaga DMS API w wersji 6+."
|
||||
},
|
||||
"Geoclue service not running - cannot auto-detect location": {
|
||||
"Geoclue service not running - cannot auto-detect location": "Usługa Geoclue nie działa - nie można automatycznie wykryć lokalizacji"
|
||||
},
|
||||
"Github:": {
|
||||
"Github:": "Github:"
|
||||
},
|
||||
@@ -902,15 +881,9 @@
|
||||
"Hex": {
|
||||
"Hex": ""
|
||||
},
|
||||
"Hex:": {
|
||||
"Hex:": "Hex:"
|
||||
},
|
||||
"Hibernate": {
|
||||
"Hibernate": "Hibernacja"
|
||||
},
|
||||
"Hibernate system after": {
|
||||
"Hibernate system after": "Hibernuj komputer po"
|
||||
},
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": {
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": "Ukryj dok, gdy nie jest używany, i odkryj go po najechaniu kursorem w jego pobliże"
|
||||
},
|
||||
@@ -1001,9 +974,6 @@
|
||||
"Kill Process": {
|
||||
"Kill Process": "Zabij proces"
|
||||
},
|
||||
"Language:": {
|
||||
"Language:": "Język:"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "Ostatnio uruchomiony %1"
|
||||
},
|
||||
@@ -1058,6 +1028,9 @@
|
||||
"Location Search": {
|
||||
"Location Search": "Wyszukiwanie lokalizacji"
|
||||
},
|
||||
"Lock": {
|
||||
"Lock": ""
|
||||
},
|
||||
"Lock Screen": {
|
||||
"Lock Screen": "Ekran blokady"
|
||||
},
|
||||
@@ -1166,9 +1139,6 @@
|
||||
"Mode: ": {
|
||||
"Mode: ": ""
|
||||
},
|
||||
"Monitor": {
|
||||
"Monitor": "Monitor"
|
||||
},
|
||||
"Monitor Selection:": {
|
||||
"Monitor Selection:": "Wybór monitora:"
|
||||
},
|
||||
@@ -1328,6 +1298,9 @@
|
||||
"Only adjust gamma based on time or location rules.": {
|
||||
"Only adjust gamma based on time or location rules.": "Dostosuj gamma tylko na podstawie reguł czasu lub lokalizacji."
|
||||
},
|
||||
"Only visible if hibernate is supported by your system": {
|
||||
"Only visible if hibernate is supported by your system": ""
|
||||
},
|
||||
"Opacity": {
|
||||
"Opacity": "Przezroczystość"
|
||||
},
|
||||
@@ -1457,6 +1430,9 @@
|
||||
"Power Action Confirmation": {
|
||||
"Power Action Confirmation": "Potwierdzenie działania zasilania"
|
||||
},
|
||||
"Power Menu Customization": {
|
||||
"Power Menu Customization": ""
|
||||
},
|
||||
"Power Off": {
|
||||
"Power Off": "Wyłącz komputer"
|
||||
},
|
||||
@@ -1502,9 +1478,6 @@
|
||||
"Profile image is too large. Please use a smaller image.": {
|
||||
"Profile image is too large. Please use a smaller image.": "Zdjęcie profilowe jest za duże. Użyj mniejszego zdjęcia."
|
||||
},
|
||||
"QML, JavaScript, Go": {
|
||||
"QML, JavaScript, Go": "QML, JavaScript, Go"
|
||||
},
|
||||
"Quick access to application launcher": {
|
||||
"Quick access to application launcher": "Szybki dostęp do uruchamiania aplikacji"
|
||||
},
|
||||
@@ -1556,6 +1529,15 @@
|
||||
"Resources": {
|
||||
"Resources": "Źródła"
|
||||
},
|
||||
"Restart": {
|
||||
"Restart": ""
|
||||
},
|
||||
"Restart DMS": {
|
||||
"Restart DMS": ""
|
||||
},
|
||||
"Restart the DankMaterialShell": {
|
||||
"Restart the DankMaterialShell": ""
|
||||
},
|
||||
"Resume": {
|
||||
"Resume": "Wznów"
|
||||
},
|
||||
@@ -1604,9 +1586,6 @@
|
||||
"Science": {
|
||||
"Science": "Nauka"
|
||||
},
|
||||
"Scroll through windows, rather than workspaces": {
|
||||
"Scroll through windows, rather than workspaces": "Przewijaj okna zamiast obszarów roboczych"
|
||||
},
|
||||
"Search file contents": {
|
||||
"Search file contents": "Przeszukaj zawartość plików"
|
||||
},
|
||||
@@ -1688,12 +1667,33 @@
|
||||
"Show Dock": {
|
||||
"Show Dock": "Pokaż dok"
|
||||
},
|
||||
"Show Hibernate": {
|
||||
"Show Hibernate": ""
|
||||
},
|
||||
"Show Line Numbers": {
|
||||
"Show Line Numbers": "Pokaż numery wierszy"
|
||||
},
|
||||
"Show Lock": {
|
||||
"Show Lock": ""
|
||||
},
|
||||
"Show Log Out": {
|
||||
"Show Log Out": ""
|
||||
},
|
||||
"Show Power Actions": {
|
||||
"Show Power Actions": "Pokaż akcje zasilania"
|
||||
},
|
||||
"Show Power Off": {
|
||||
"Show Power Off": ""
|
||||
},
|
||||
"Show Reboot": {
|
||||
"Show Reboot": ""
|
||||
},
|
||||
"Show Restart DMS": {
|
||||
"Show Restart DMS": ""
|
||||
},
|
||||
"Show Suspend": {
|
||||
"Show Suspend": ""
|
||||
},
|
||||
"Show Workspace Apps": {
|
||||
"Show Workspace Apps": "Pokaż aplikacje z obszaru roboczego"
|
||||
},
|
||||
@@ -1865,12 +1865,6 @@
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Nawigacja • ←→↑↓: Nawigacja po siatce • Enter/Spacja: Wybierz"
|
||||
},
|
||||
"Technical Details": {
|
||||
"Technical Details": "Szczegóły techniczne"
|
||||
},
|
||||
"Temperature": {
|
||||
"Temperature": "Temperatura"
|
||||
},
|
||||
"Terminal custom additional parameters": {
|
||||
"Terminal custom additional parameters": "Niestandardowe dodatkowe parametry terminala"
|
||||
},
|
||||
@@ -1997,9 +1991,6 @@
|
||||
"Use animated wave progress bars for media playback": {
|
||||
"Use animated wave progress bars for media playback": "Używaj animowanych pasków postępu fali do odtwarzania multimediów"
|
||||
},
|
||||
"Use automatic location detection (geoclue2)": {
|
||||
"Use automatic location detection (geoclue2)": "Użyj automatycznego wykrywania lokalizacji (geoclue2)"
|
||||
},
|
||||
"Use custom command for update your system": {
|
||||
"Use custom command for update your system": "Użyj niestandardowego polecenia do aktualizacji systemu"
|
||||
},
|
||||
@@ -2105,9 +2096,6 @@
|
||||
"Wind": {
|
||||
"Wind": "Wiatr"
|
||||
},
|
||||
"Window Scrolling": {
|
||||
"Window Scrolling": "Przewijanie okna"
|
||||
},
|
||||
"Workspace": {
|
||||
"Workspace": "Obszar roboczy"
|
||||
},
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"Applications": {
|
||||
"Applications": "Aplicativos"
|
||||
},
|
||||
"Apply": {
|
||||
"Apply": "Aplicar"
|
||||
},
|
||||
"Apply GTK Colors": {
|
||||
"Apply GTK Colors": "Aplicar cores no GTK"
|
||||
},
|
||||
@@ -167,9 +164,6 @@
|
||||
"Auto-hide Dock": {
|
||||
"Auto-hide Dock": "Esconder Automaticamente o Dock"
|
||||
},
|
||||
"Auto-location": {
|
||||
"Auto-location": "Localização-Automática"
|
||||
},
|
||||
"Auto-saving...": {
|
||||
"Auto-saving...": "Salvando automáticamente..."
|
||||
},
|
||||
@@ -230,9 +224,6 @@
|
||||
"Battery level and power management": {
|
||||
"Battery level and power management": "Nível de bateria e manejamento de energia"
|
||||
},
|
||||
"Battery not detected - only AC power settings available": {
|
||||
"Battery not detected - only AC power settings available": "Bateria não detectada - apenas configurações de tomada disponíveis"
|
||||
},
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "Vincular o bloqueio de tela aos sinais do DBus do loginctl. Desative se estiver usando um bloqueio de tela externo"
|
||||
},
|
||||
@@ -398,9 +389,6 @@
|
||||
"Compositor": {
|
||||
"Compositor": "Compositor"
|
||||
},
|
||||
"Compositor:": {
|
||||
"Compositor:": "Compositor:"
|
||||
},
|
||||
"Configuration activated": {
|
||||
"Configuration activated": "Configuração ativada"
|
||||
},
|
||||
@@ -434,9 +422,6 @@
|
||||
"Connecting to Device": {
|
||||
"Connecting to Device": ""
|
||||
},
|
||||
"Connection failed. Check password and try again.": {
|
||||
"Connection failed. Check password and try again.": "Erro ao conectar. Cheque a senha e tente novamente."
|
||||
},
|
||||
"Contrast": {
|
||||
"Contrast": "Contraste"
|
||||
},
|
||||
@@ -461,9 +446,6 @@
|
||||
"Copied!": {
|
||||
"Copied!": "Copiado!"
|
||||
},
|
||||
"Copy": {
|
||||
"Copy": "Copiar"
|
||||
},
|
||||
"Copy PID": {
|
||||
"Copy PID": "Copiar PID"
|
||||
},
|
||||
@@ -515,6 +497,9 @@
|
||||
"Customizable empty space": {
|
||||
"Customizable empty space": "Espaço vazio customizável"
|
||||
},
|
||||
"Customize which actions appear in the power menu": {
|
||||
"Customize which actions appear in the power menu": ""
|
||||
},
|
||||
"DEMO MODE - Click anywhere to exit": {
|
||||
"DEMO MODE - Click anywhere to exit": "MODO DEMONSTRAÇÃO - Clique em qualquer lugar para sair"
|
||||
},
|
||||
@@ -542,9 +527,6 @@
|
||||
"Dank Bar Widget Transparency": {
|
||||
"Dank Bar Widget Transparency": "Transparência dos Widgets da Dank Bar"
|
||||
},
|
||||
"Dank Suite:": {
|
||||
"Dank Suite:": "Suíte Dank:"
|
||||
},
|
||||
"DankBar Font Scale": {
|
||||
"DankBar Font Scale": "Escala das fontes no Dank Bar"
|
||||
},
|
||||
@@ -566,6 +548,9 @@
|
||||
"Default": {
|
||||
"Default": "Padrão"
|
||||
},
|
||||
"Default selected action": {
|
||||
"Default selected action": ""
|
||||
},
|
||||
"Defaults": {
|
||||
"Defaults": "Padrões"
|
||||
},
|
||||
@@ -842,9 +827,6 @@
|
||||
"Format Legend": {
|
||||
"Format Legend": "Formatar Legenda"
|
||||
},
|
||||
"Framework:": {
|
||||
"Framework:": "Estrutura:"
|
||||
},
|
||||
"Fun": {
|
||||
"Fun": "Diversão"
|
||||
},
|
||||
@@ -866,9 +848,6 @@
|
||||
"Gamma control not available. Requires DMS API v6+.": {
|
||||
"Gamma control not available. Requires DMS API v6+.": "Controle de gama não disponível. Necessário DMS API v6+."
|
||||
},
|
||||
"Geoclue service not running - cannot auto-detect location": {
|
||||
"Geoclue service not running - cannot auto-detect location": "Serviço do Geoclue não está rodando - não foi possível detectar a localização automaticamente"
|
||||
},
|
||||
"Github:": {
|
||||
"Github:": "Github:"
|
||||
},
|
||||
@@ -902,15 +881,9 @@
|
||||
"Hex": {
|
||||
"Hex": ""
|
||||
},
|
||||
"Hex:": {
|
||||
"Hex:": "Hex:"
|
||||
},
|
||||
"Hibernate": {
|
||||
"Hibernate": "Hibernar"
|
||||
},
|
||||
"Hibernate system after": {
|
||||
"Hibernate system after": "Hibernar sistema após"
|
||||
},
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": {
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": "Esconder a dock quando não usada e mostrar ao passar o mouse próximo da área"
|
||||
},
|
||||
@@ -1001,9 +974,6 @@
|
||||
"Kill Process": {
|
||||
"Kill Process": "Matar Processo"
|
||||
},
|
||||
"Language:": {
|
||||
"Language:": "Linguagem:"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "Lançado pela última vez em %1"
|
||||
},
|
||||
@@ -1058,6 +1028,9 @@
|
||||
"Location Search": {
|
||||
"Location Search": "Procurar Localização"
|
||||
},
|
||||
"Lock": {
|
||||
"Lock": ""
|
||||
},
|
||||
"Lock Screen": {
|
||||
"Lock Screen": "Tela de Bloqueio"
|
||||
},
|
||||
@@ -1166,9 +1139,6 @@
|
||||
"Mode: ": {
|
||||
"Mode: ": ""
|
||||
},
|
||||
"Monitor": {
|
||||
"Monitor": "Monitor"
|
||||
},
|
||||
"Monitor Selection:": {
|
||||
"Monitor Selection:": "Seleção de Monitor:"
|
||||
},
|
||||
@@ -1328,6 +1298,9 @@
|
||||
"Only adjust gamma based on time or location rules.": {
|
||||
"Only adjust gamma based on time or location rules.": "Apenas ajustar gama baseada em regras de tempo ou localização."
|
||||
},
|
||||
"Only visible if hibernate is supported by your system": {
|
||||
"Only visible if hibernate is supported by your system": ""
|
||||
},
|
||||
"Opacity": {
|
||||
"Opacity": "Opacidade"
|
||||
},
|
||||
@@ -1457,6 +1430,9 @@
|
||||
"Power Action Confirmation": {
|
||||
"Power Action Confirmation": "Confirmação de Ação de Energia"
|
||||
},
|
||||
"Power Menu Customization": {
|
||||
"Power Menu Customization": ""
|
||||
},
|
||||
"Power Off": {
|
||||
"Power Off": "Desligar"
|
||||
},
|
||||
@@ -1502,9 +1478,6 @@
|
||||
"Profile image is too large. Please use a smaller image.": {
|
||||
"Profile image is too large. Please use a smaller image.": "A imagem de perfil é muito grande. Por favor use uma imagem menor."
|
||||
},
|
||||
"QML, JavaScript, Go": {
|
||||
"QML, JavaScript, Go": "QML, JavaScript, Go"
|
||||
},
|
||||
"Quick access to application launcher": {
|
||||
"Quick access to application launcher": "Acesso rápido ao lançador de aplicativos"
|
||||
},
|
||||
@@ -1556,6 +1529,15 @@
|
||||
"Resources": {
|
||||
"Resources": "Recursos"
|
||||
},
|
||||
"Restart": {
|
||||
"Restart": ""
|
||||
},
|
||||
"Restart DMS": {
|
||||
"Restart DMS": ""
|
||||
},
|
||||
"Restart the DankMaterialShell": {
|
||||
"Restart the DankMaterialShell": ""
|
||||
},
|
||||
"Resume": {
|
||||
"Resume": ""
|
||||
},
|
||||
@@ -1604,9 +1586,6 @@
|
||||
"Science": {
|
||||
"Science": "Ciência"
|
||||
},
|
||||
"Scroll through windows, rather than workspaces": {
|
||||
"Scroll through windows, rather than workspaces": "Role pelas janelas, ao invés de áreas de trabalho"
|
||||
},
|
||||
"Search file contents": {
|
||||
"Search file contents": "Pesquisar conteúdos de arquivos"
|
||||
},
|
||||
@@ -1688,12 +1667,33 @@
|
||||
"Show Dock": {
|
||||
"Show Dock": "Mostrar Dock"
|
||||
},
|
||||
"Show Hibernate": {
|
||||
"Show Hibernate": ""
|
||||
},
|
||||
"Show Line Numbers": {
|
||||
"Show Line Numbers": "Mostrar Numeração de Linha"
|
||||
},
|
||||
"Show Lock": {
|
||||
"Show Lock": ""
|
||||
},
|
||||
"Show Log Out": {
|
||||
"Show Log Out": ""
|
||||
},
|
||||
"Show Power Actions": {
|
||||
"Show Power Actions": "Mostrar Ações de Energia"
|
||||
},
|
||||
"Show Power Off": {
|
||||
"Show Power Off": ""
|
||||
},
|
||||
"Show Reboot": {
|
||||
"Show Reboot": ""
|
||||
},
|
||||
"Show Restart DMS": {
|
||||
"Show Restart DMS": ""
|
||||
},
|
||||
"Show Suspend": {
|
||||
"Show Suspend": ""
|
||||
},
|
||||
"Show Workspace Apps": {
|
||||
"Show Workspace Apps": "Mostrar Aplicativos da Área de Trabalho Virtual"
|
||||
},
|
||||
@@ -1865,12 +1865,6 @@
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Navegação • ←→↑↓: Navegação em Grade • Enter/Espaço: Selecionar"
|
||||
},
|
||||
"Technical Details": {
|
||||
"Technical Details": "Detalhes Técnicos"
|
||||
},
|
||||
"Temperature": {
|
||||
"Temperature": "Temperatura"
|
||||
},
|
||||
"Terminal custom additional parameters": {
|
||||
"Terminal custom additional parameters": "Parâmetros adicionais para o terminal"
|
||||
},
|
||||
@@ -1997,9 +1991,6 @@
|
||||
"Use animated wave progress bars for media playback": {
|
||||
"Use animated wave progress bars for media playback": "Usar barras de progresso de ondas animadas para reprodução de mídia"
|
||||
},
|
||||
"Use automatic location detection (geoclue2)": {
|
||||
"Use automatic location detection (geoclue2)": "Usar detecção automática de localização (geoclue2)"
|
||||
},
|
||||
"Use custom command for update your system": {
|
||||
"Use custom command for update your system": "Usar comando personalizado para atualizar seu sistema"
|
||||
},
|
||||
@@ -2105,9 +2096,6 @@
|
||||
"Wind": {
|
||||
"Wind": "Vento"
|
||||
},
|
||||
"Window Scrolling": {
|
||||
"Window Scrolling": "Rolagem de Janelas"
|
||||
},
|
||||
"Workspace": {
|
||||
"Workspace": "Área de Trabalho"
|
||||
},
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"Applications": {
|
||||
"Applications": "Uygulamalar"
|
||||
},
|
||||
"Apply": {
|
||||
"Apply": "Uygula"
|
||||
},
|
||||
"Apply GTK Colors": {
|
||||
"Apply GTK Colors": "GTK Renklerini Uygula"
|
||||
},
|
||||
@@ -167,9 +164,6 @@
|
||||
"Auto-hide Dock": {
|
||||
"Auto-hide Dock": "Dock'u Otomatik Gizle"
|
||||
},
|
||||
"Auto-location": {
|
||||
"Auto-location": "Otomatik konum"
|
||||
},
|
||||
"Auto-saving...": {
|
||||
"Auto-saving...": "Otomatik kaydetme..."
|
||||
},
|
||||
@@ -230,9 +224,6 @@
|
||||
"Battery level and power management": {
|
||||
"Battery level and power management": "Batarya seviyesi ve güç yönetimi"
|
||||
},
|
||||
"Battery not detected - only AC power settings available": {
|
||||
"Battery not detected - only AC power settings available": "Batarya tespit edilmedi - sadece AC güç ayarları kullanılabilir"
|
||||
},
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "Kilit ekranını loginctl'den gelen dbus sinyallerine bağlayın. Harici bir kilit ekranı kullanıyorsanız devre dışı bırakın"
|
||||
},
|
||||
@@ -312,7 +303,7 @@
|
||||
"Center Section": "Orta Bölüm"
|
||||
},
|
||||
"Changes:": {
|
||||
"Changes:": ""
|
||||
"Changes:": "Değişiklikler:"
|
||||
},
|
||||
"Check for system updates": {
|
||||
"Check for system updates": "Sistem güncellemelerini kontrol et"
|
||||
@@ -398,9 +389,6 @@
|
||||
"Compositor": {
|
||||
"Compositor": "Kompozitör"
|
||||
},
|
||||
"Compositor:": {
|
||||
"Compositor:": "Kompozitör:"
|
||||
},
|
||||
"Configuration activated": {
|
||||
"Configuration activated": "Yapılandırma aktifleştirildi"
|
||||
},
|
||||
@@ -414,7 +402,7 @@
|
||||
"Confirm": "Onayla"
|
||||
},
|
||||
"Confirm Display Changes": {
|
||||
"Confirm Display Changes": ""
|
||||
"Confirm Display Changes": "Ekran Değişikliklerini Onaylayın"
|
||||
},
|
||||
"Confirm passkey for ": {
|
||||
"Confirm passkey for ": "Şunun için şifreyi onayla: "
|
||||
@@ -434,9 +422,6 @@
|
||||
"Connecting to Device": {
|
||||
"Connecting to Device": "Cihaza Bağlanma"
|
||||
},
|
||||
"Connection failed. Check password and try again.": {
|
||||
"Connection failed. Check password and try again.": "Bağlantı başarısız. Parolayı kontrol edin ve tekrar deneyin."
|
||||
},
|
||||
"Contrast": {
|
||||
"Contrast": "Kontrast"
|
||||
},
|
||||
@@ -461,9 +446,6 @@
|
||||
"Copied!": {
|
||||
"Copied!": "Kopyalandı!"
|
||||
},
|
||||
"Copy": {
|
||||
"Copy": "Kopyala"
|
||||
},
|
||||
"Copy PID": {
|
||||
"Copy PID": "PID'i Kopyala"
|
||||
},
|
||||
@@ -515,6 +497,9 @@
|
||||
"Customizable empty space": {
|
||||
"Customizable empty space": "Özelleştirilebilir boş alan"
|
||||
},
|
||||
"Customize which actions appear in the power menu": {
|
||||
"Customize which actions appear in the power menu": ""
|
||||
},
|
||||
"DEMO MODE - Click anywhere to exit": {
|
||||
"DEMO MODE - Click anywhere to exit": "DEMO MODU - Çıkmak için herhangi bir yere tıklayın"
|
||||
},
|
||||
@@ -542,9 +527,6 @@
|
||||
"Dank Bar Widget Transparency": {
|
||||
"Dank Bar Widget Transparency": "Dank Bar Widget Şeffaflığı"
|
||||
},
|
||||
"Dank Suite:": {
|
||||
"Dank Suite:": "Dank Suite:"
|
||||
},
|
||||
"DankBar Font Scale": {
|
||||
"DankBar Font Scale": "DankBar Yazı Tipi Ölçeği"
|
||||
},
|
||||
@@ -566,6 +548,9 @@
|
||||
"Default": {
|
||||
"Default": "Varsayılan"
|
||||
},
|
||||
"Default selected action": {
|
||||
"Default selected action": ""
|
||||
},
|
||||
"Defaults": {
|
||||
"Defaults": "Varsayılanlar"
|
||||
},
|
||||
@@ -591,7 +576,7 @@
|
||||
"Disable Autoconnect": "Otomatik Bağlanmayı Devre Dışı Bırak"
|
||||
},
|
||||
"Disabled": {
|
||||
"Disabled": ""
|
||||
"Disabled": "Devre Dışı"
|
||||
},
|
||||
"Disconnect": {
|
||||
"Disconnect": "Bağlantıyı Kes"
|
||||
@@ -621,7 +606,7 @@
|
||||
"Display currently focused application title": "Şu anda odaklanmış uygulamanın başlığını göster"
|
||||
},
|
||||
"Display settings for ": {
|
||||
"Display settings for ": ""
|
||||
"Display settings for ": "Ekran ayarları: "
|
||||
},
|
||||
"Display volume and brightness percentage values by default in OSD popups": {
|
||||
"Display volume and brightness percentage values by default in OSD popups": "OSD açılır pencerelerinde varsayılan olarak ses seviyesi ve parlaklık yüzdelik değerlerini göster"
|
||||
@@ -699,7 +684,7 @@
|
||||
"Enable loginctl lock integration": "loginctl kilit entegrasyonunu etkinleştir"
|
||||
},
|
||||
"Enabled": {
|
||||
"Enabled": ""
|
||||
"Enabled": "Etkin"
|
||||
},
|
||||
"End": {
|
||||
"End": "Son"
|
||||
@@ -842,9 +827,6 @@
|
||||
"Format Legend": {
|
||||
"Format Legend": "Biçim Açıklaması"
|
||||
},
|
||||
"Framework:": {
|
||||
"Framework:": "Framework:"
|
||||
},
|
||||
"Fun": {
|
||||
"Fun": "Eğlence"
|
||||
},
|
||||
@@ -866,9 +848,6 @@
|
||||
"Gamma control not available. Requires DMS API v6+.": {
|
||||
"Gamma control not available. Requires DMS API v6+.": "Gama kontrolü mevcut değil. DMS API V6+ gerekir."
|
||||
},
|
||||
"Geoclue service not running - cannot auto-detect location": {
|
||||
"Geoclue service not running - cannot auto-detect location": "Geoclue hizmeti çalışmıyor - konum otomatik olarak algılanamıyor"
|
||||
},
|
||||
"Github:": {
|
||||
"Github:": "Github:"
|
||||
},
|
||||
@@ -902,15 +881,9 @@
|
||||
"Hex": {
|
||||
"Hex": "Hex"
|
||||
},
|
||||
"Hex:": {
|
||||
"Hex:": "Hex:"
|
||||
},
|
||||
"Hibernate": {
|
||||
"Hibernate": "Hazırda Beklet"
|
||||
},
|
||||
"Hibernate system after": {
|
||||
"Hibernate system after": "Şu zaman sonra sistemi hazırda beklet"
|
||||
},
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": {
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": "Kullanılmadığında dock'u gizle ve dock alanının yakınına geldiğinizde göster"
|
||||
},
|
||||
@@ -966,7 +939,7 @@
|
||||
"Individual Batteries": "Tekil Piller"
|
||||
},
|
||||
"Inhibit idle timeout when audio or video is playing": {
|
||||
"Inhibit idle timeout when audio or video is playing": ""
|
||||
"Inhibit idle timeout when audio or video is playing": "Ses veya video oynatılırken boşta kalma süresini engelle"
|
||||
},
|
||||
"Input Devices": {
|
||||
"Input Devices": "Giriş Aygıtları"
|
||||
@@ -993,7 +966,7 @@
|
||||
"Jobs: ": "İşler:"
|
||||
},
|
||||
"Keep Changes": {
|
||||
"Keep Changes": ""
|
||||
"Keep Changes": "Değişiklikleri Tut"
|
||||
},
|
||||
"Keyboard Layout Name": {
|
||||
"Keyboard Layout Name": "Klavye Düzeni Adı"
|
||||
@@ -1001,9 +974,6 @@
|
||||
"Kill Process": {
|
||||
"Kill Process": "Süreci Öldür"
|
||||
},
|
||||
"Language:": {
|
||||
"Language:": "Dil:"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "Son başlatma %1"
|
||||
},
|
||||
@@ -1058,6 +1028,9 @@
|
||||
"Location Search": {
|
||||
"Location Search": "Konum Arama"
|
||||
},
|
||||
"Lock": {
|
||||
"Lock": "Kilitle"
|
||||
},
|
||||
"Lock Screen": {
|
||||
"Lock Screen": "Kilit Ekranı"
|
||||
},
|
||||
@@ -1164,10 +1137,7 @@
|
||||
"Mode:": "Mod:"
|
||||
},
|
||||
"Mode: ": {
|
||||
"Mode: ": ""
|
||||
},
|
||||
"Monitor": {
|
||||
"Monitor": "Monitör"
|
||||
"Mode: ": "Mod: "
|
||||
},
|
||||
"Monitor Selection:": {
|
||||
"Monitor Selection:": "Monitör Seçimi:"
|
||||
@@ -1328,6 +1298,9 @@
|
||||
"Only adjust gamma based on time or location rules.": {
|
||||
"Only adjust gamma based on time or location rules.": "Gamayı yalnızca zaman veya konum kurallarına göre ayarlayın."
|
||||
},
|
||||
"Only visible if hibernate is supported by your system": {
|
||||
"Only visible if hibernate is supported by your system": ""
|
||||
},
|
||||
"Opacity": {
|
||||
"Opacity": "Opaklık"
|
||||
},
|
||||
@@ -1449,7 +1422,7 @@
|
||||
"Position": "Pozisyon"
|
||||
},
|
||||
"Position: ": {
|
||||
"Position: ": ""
|
||||
"Position: ": "Pozisyon: "
|
||||
},
|
||||
"Power & Security": {
|
||||
"Power & Security": "Güç & Güvenlik"
|
||||
@@ -1457,6 +1430,9 @@
|
||||
"Power Action Confirmation": {
|
||||
"Power Action Confirmation": "Güç Eylemi Onayı"
|
||||
},
|
||||
"Power Menu Customization": {
|
||||
"Power Menu Customization": ""
|
||||
},
|
||||
"Power Off": {
|
||||
"Power Off": "Kapat"
|
||||
},
|
||||
@@ -1470,7 +1446,7 @@
|
||||
"Pressure": "Basınç"
|
||||
},
|
||||
"Prevent idle for media": {
|
||||
"Prevent idle for media": ""
|
||||
"Prevent idle for media": "Medya için boşta kalmayı önle"
|
||||
},
|
||||
"Prevent screen timeout": {
|
||||
"Prevent screen timeout": "Ekran zaman aşımını önle"
|
||||
@@ -1502,9 +1478,6 @@
|
||||
"Profile image is too large. Please use a smaller image.": {
|
||||
"Profile image is too large. Please use a smaller image.": "Profil resmi çok büyük. Lütfen daha küçük bir resim kullanın."
|
||||
},
|
||||
"QML, JavaScript, Go": {
|
||||
"QML, JavaScript, Go": "QML, Javascript, Go"
|
||||
},
|
||||
"Quick access to application launcher": {
|
||||
"Quick access to application launcher": "Uygulama başlatıcısına hızlı erişim"
|
||||
},
|
||||
@@ -1556,14 +1529,23 @@
|
||||
"Resources": {
|
||||
"Resources": "Kaynaklar"
|
||||
},
|
||||
"Restart": {
|
||||
"Restart": "Yeniden Başlat"
|
||||
},
|
||||
"Restart DMS": {
|
||||
"Restart DMS": ""
|
||||
},
|
||||
"Restart the DankMaterialShell": {
|
||||
"Restart the DankMaterialShell": ""
|
||||
},
|
||||
"Resume": {
|
||||
"Resume": "Sürdür"
|
||||
},
|
||||
"Revert": {
|
||||
"Revert": ""
|
||||
"Revert": "Geri Al"
|
||||
},
|
||||
"Reverting in:": {
|
||||
"Reverting in:": ""
|
||||
"Reverting in:": "Geri dönülüyor:"
|
||||
},
|
||||
"Right": {
|
||||
"Right": "Sağ"
|
||||
@@ -1604,9 +1586,6 @@
|
||||
"Science": {
|
||||
"Science": "Bilim"
|
||||
},
|
||||
"Scroll through windows, rather than workspaces": {
|
||||
"Scroll through windows, rather than workspaces": "Çalışma alanları yerine pencereler arasında gezin"
|
||||
},
|
||||
"Search file contents": {
|
||||
"Search file contents": "Dosya içeriklerini ara"
|
||||
},
|
||||
@@ -1688,12 +1667,33 @@
|
||||
"Show Dock": {
|
||||
"Show Dock": "Dock'u Göster"
|
||||
},
|
||||
"Show Hibernate": {
|
||||
"Show Hibernate": ""
|
||||
},
|
||||
"Show Line Numbers": {
|
||||
"Show Line Numbers": "Satır Numaralarını Göster"
|
||||
},
|
||||
"Show Lock": {
|
||||
"Show Lock": ""
|
||||
},
|
||||
"Show Log Out": {
|
||||
"Show Log Out": ""
|
||||
},
|
||||
"Show Power Actions": {
|
||||
"Show Power Actions": "Güç Eylemlerini Göster"
|
||||
},
|
||||
"Show Power Off": {
|
||||
"Show Power Off": ""
|
||||
},
|
||||
"Show Reboot": {
|
||||
"Show Reboot": ""
|
||||
},
|
||||
"Show Restart DMS": {
|
||||
"Show Restart DMS": ""
|
||||
},
|
||||
"Show Suspend": {
|
||||
"Show Suspend": ""
|
||||
},
|
||||
"Show Workspace Apps": {
|
||||
"Show Workspace Apps": "Çalışma Alanı Uygulamalarını Göster"
|
||||
},
|
||||
@@ -1865,12 +1865,6 @@
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Yön • ←→↑↓: Izgara Yönü • Enter/Space: Seç"
|
||||
},
|
||||
"Technical Details": {
|
||||
"Technical Details": "Teknik Detaylar"
|
||||
},
|
||||
"Temperature": {
|
||||
"Temperature": "Sıcaklık"
|
||||
},
|
||||
"Terminal custom additional parameters": {
|
||||
"Terminal custom additional parameters": "Terminal özel ek parametreleri"
|
||||
},
|
||||
@@ -1997,9 +1991,6 @@
|
||||
"Use animated wave progress bars for media playback": {
|
||||
"Use animated wave progress bars for media playback": "Medya oynatımı için animasyonlu dalga ilerleme çubukları kullanın"
|
||||
},
|
||||
"Use automatic location detection (geoclue2)": {
|
||||
"Use automatic location detection (geoclue2)": "Otomatik konum algılama özelliğini kullan (geoclue2)"
|
||||
},
|
||||
"Use custom command for update your system": {
|
||||
"Use custom command for update your system": "Sistemi güncellemek için özel komut kullan"
|
||||
},
|
||||
@@ -2037,7 +2028,7 @@
|
||||
"VPN status and quick connect": "VPN durumu ve hızlı bağlanma"
|
||||
},
|
||||
"VRR: ": {
|
||||
"VRR: ": ""
|
||||
"VRR: ": "VRR: "
|
||||
},
|
||||
"Vibrant palette with playful saturation.": {
|
||||
"Vibrant palette with playful saturation.": "Oynak doygunluğa sahip canlı palet"
|
||||
@@ -2105,9 +2096,6 @@
|
||||
"Wind": {
|
||||
"Wind": "Rüzgar"
|
||||
},
|
||||
"Window Scrolling": {
|
||||
"Window Scrolling": "Pencere Kaydırma"
|
||||
},
|
||||
"Workspace": {
|
||||
"Workspace": "Çalışma Alanı"
|
||||
},
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"Applications": {
|
||||
"Applications": "应用程序"
|
||||
},
|
||||
"Apply": {
|
||||
"Apply": "应用"
|
||||
},
|
||||
"Apply GTK Colors": {
|
||||
"Apply GTK Colors": "应用 GTK 配色"
|
||||
},
|
||||
@@ -167,9 +164,6 @@
|
||||
"Auto-hide Dock": {
|
||||
"Auto-hide Dock": "自动隐藏程序坞"
|
||||
},
|
||||
"Auto-location": {
|
||||
"Auto-location": "自动定位"
|
||||
},
|
||||
"Auto-saving...": {
|
||||
"Auto-saving...": "自动保存中..."
|
||||
},
|
||||
@@ -230,9 +224,6 @@
|
||||
"Battery level and power management": {
|
||||
"Battery level and power management": "电池电量与电源管理"
|
||||
},
|
||||
"Battery not detected - only AC power settings available": {
|
||||
"Battery not detected - only AC power settings available": "未检测到电池,仅电源设置可用"
|
||||
},
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "将锁屏绑定到来自 loginctl 的 dbus 信号。如使用外部锁屏程序,请禁用此项"
|
||||
},
|
||||
@@ -312,7 +303,7 @@
|
||||
"Center Section": "中间区域"
|
||||
},
|
||||
"Changes:": {
|
||||
"Changes:": ""
|
||||
"Changes:": "更改:"
|
||||
},
|
||||
"Check for system updates": {
|
||||
"Check for system updates": "检查系统更新"
|
||||
@@ -398,9 +389,6 @@
|
||||
"Compositor": {
|
||||
"Compositor": "合成器"
|
||||
},
|
||||
"Compositor:": {
|
||||
"Compositor:": "合成器:"
|
||||
},
|
||||
"Configuration activated": {
|
||||
"Configuration activated": "已应用配置"
|
||||
},
|
||||
@@ -414,7 +402,7 @@
|
||||
"Confirm": "确认"
|
||||
},
|
||||
"Confirm Display Changes": {
|
||||
"Confirm Display Changes": ""
|
||||
"Confirm Display Changes": "确认显示更改"
|
||||
},
|
||||
"Confirm passkey for ": {
|
||||
"Confirm passkey for ": "确认密钥 "
|
||||
@@ -434,9 +422,6 @@
|
||||
"Connecting to Device": {
|
||||
"Connecting to Device": "连接设备中"
|
||||
},
|
||||
"Connection failed. Check password and try again.": {
|
||||
"Connection failed. Check password and try again.": "连接失败,请检查密码后重试。"
|
||||
},
|
||||
"Contrast": {
|
||||
"Contrast": "对比度"
|
||||
},
|
||||
@@ -461,9 +446,6 @@
|
||||
"Copied!": {
|
||||
"Copied!": "复制成功!"
|
||||
},
|
||||
"Copy": {
|
||||
"Copy": "复制"
|
||||
},
|
||||
"Copy PID": {
|
||||
"Copy PID": "复制进程ID"
|
||||
},
|
||||
@@ -515,6 +497,9 @@
|
||||
"Customizable empty space": {
|
||||
"Customizable empty space": "可调节留白"
|
||||
},
|
||||
"Customize which actions appear in the power menu": {
|
||||
"Customize which actions appear in the power menu": ""
|
||||
},
|
||||
"DEMO MODE - Click anywhere to exit": {
|
||||
"DEMO MODE - Click anywhere to exit": "演示模式 - 点击任意位置退出"
|
||||
},
|
||||
@@ -542,9 +527,6 @@
|
||||
"Dank Bar Widget Transparency": {
|
||||
"Dank Bar Widget Transparency": "Dank Bar 小组件透明度"
|
||||
},
|
||||
"Dank Suite:": {
|
||||
"Dank Suite:": "Dank 套件:"
|
||||
},
|
||||
"DankBar Font Scale": {
|
||||
"DankBar Font Scale": "Dank Bar 字体缩放"
|
||||
},
|
||||
@@ -566,6 +548,9 @@
|
||||
"Default": {
|
||||
"Default": "默认"
|
||||
},
|
||||
"Default selected action": {
|
||||
"Default selected action": ""
|
||||
},
|
||||
"Defaults": {
|
||||
"Defaults": "复位"
|
||||
},
|
||||
@@ -591,7 +576,7 @@
|
||||
"Disable Autoconnect": "禁用自动连接"
|
||||
},
|
||||
"Disabled": {
|
||||
"Disabled": ""
|
||||
"Disabled": "已关闭"
|
||||
},
|
||||
"Disconnect": {
|
||||
"Disconnect": "断开连接"
|
||||
@@ -621,7 +606,7 @@
|
||||
"Display currently focused application title": "显示当前聚焦应用的标题"
|
||||
},
|
||||
"Display settings for ": {
|
||||
"Display settings for ": ""
|
||||
"Display settings for ": "显示设置 "
|
||||
},
|
||||
"Display volume and brightness percentage values by default in OSD popups": {
|
||||
"Display volume and brightness percentage values by default in OSD popups": "在OSD弹窗中默认显示音量与亮度数值"
|
||||
@@ -699,7 +684,7 @@
|
||||
"Enable loginctl lock integration": "启用 loginctl 锁定集成"
|
||||
},
|
||||
"Enabled": {
|
||||
"Enabled": ""
|
||||
"Enabled": "已开启"
|
||||
},
|
||||
"End": {
|
||||
"End": "结束"
|
||||
@@ -842,9 +827,6 @@
|
||||
"Format Legend": {
|
||||
"Format Legend": "参考格式"
|
||||
},
|
||||
"Framework:": {
|
||||
"Framework:": "框架:"
|
||||
},
|
||||
"Fun": {
|
||||
"Fun": "娱乐"
|
||||
},
|
||||
@@ -866,9 +848,6 @@
|
||||
"Gamma control not available. Requires DMS API v6+.": {
|
||||
"Gamma control not available. Requires DMS API v6+.": "伽玛控制不可用,需要 DMS API v6+。"
|
||||
},
|
||||
"Geoclue service not running - cannot auto-detect location": {
|
||||
"Geoclue service not running - cannot auto-detect location": "Geoclue 服务未运行 - 无法自动检测位置"
|
||||
},
|
||||
"Github:": {
|
||||
"Github:": "Github:"
|
||||
},
|
||||
@@ -902,15 +881,9 @@
|
||||
"Hex": {
|
||||
"Hex": "十六进制"
|
||||
},
|
||||
"Hex:": {
|
||||
"Hex:": "十六进制颜色码:"
|
||||
},
|
||||
"Hibernate": {
|
||||
"Hibernate": "休眠"
|
||||
},
|
||||
"Hibernate system after": {
|
||||
"Hibernate system after": "在此时间后休眠系统"
|
||||
},
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": {
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": "在未使用时隐藏程序坞,鼠标悬停到程序坞区域时显示"
|
||||
},
|
||||
@@ -966,7 +939,7 @@
|
||||
"Individual Batteries": "分别显示电池"
|
||||
},
|
||||
"Inhibit idle timeout when audio or video is playing": {
|
||||
"Inhibit idle timeout when audio or video is playing": ""
|
||||
"Inhibit idle timeout when audio or video is playing": "在播放音频或视频时,禁止待机超时"
|
||||
},
|
||||
"Input Devices": {
|
||||
"Input Devices": "输入设备"
|
||||
@@ -993,7 +966,7 @@
|
||||
"Jobs: ": "任务: "
|
||||
},
|
||||
"Keep Changes": {
|
||||
"Keep Changes": ""
|
||||
"Keep Changes": "保持更改"
|
||||
},
|
||||
"Keyboard Layout Name": {
|
||||
"Keyboard Layout Name": "键盘布局名称"
|
||||
@@ -1001,9 +974,6 @@
|
||||
"Kill Process": {
|
||||
"Kill Process": "结束进程"
|
||||
},
|
||||
"Language:": {
|
||||
"Language:": "开发语言:"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "上次启动于 %1"
|
||||
},
|
||||
@@ -1058,6 +1028,9 @@
|
||||
"Location Search": {
|
||||
"Location Search": "位置搜索"
|
||||
},
|
||||
"Lock": {
|
||||
"Lock": "锁定"
|
||||
},
|
||||
"Lock Screen": {
|
||||
"Lock Screen": "锁屏"
|
||||
},
|
||||
@@ -1164,10 +1137,7 @@
|
||||
"Mode:": "模式:"
|
||||
},
|
||||
"Mode: ": {
|
||||
"Mode: ": ""
|
||||
},
|
||||
"Monitor": {
|
||||
"Monitor": "显示器"
|
||||
"Mode: ": "模式: "
|
||||
},
|
||||
"Monitor Selection:": {
|
||||
"Monitor Selection:": "选择显示器:"
|
||||
@@ -1328,6 +1298,9 @@
|
||||
"Only adjust gamma based on time or location rules.": {
|
||||
"Only adjust gamma based on time or location rules.": "根据时间或位置调节伽马值。"
|
||||
},
|
||||
"Only visible if hibernate is supported by your system": {
|
||||
"Only visible if hibernate is supported by your system": ""
|
||||
},
|
||||
"Opacity": {
|
||||
"Opacity": "不透明度"
|
||||
},
|
||||
@@ -1449,7 +1422,7 @@
|
||||
"Position": "位置"
|
||||
},
|
||||
"Position: ": {
|
||||
"Position: ": ""
|
||||
"Position: ": "位置: "
|
||||
},
|
||||
"Power & Security": {
|
||||
"Power & Security": "电源与安全"
|
||||
@@ -1457,6 +1430,9 @@
|
||||
"Power Action Confirmation": {
|
||||
"Power Action Confirmation": "电源操作确认"
|
||||
},
|
||||
"Power Menu Customization": {
|
||||
"Power Menu Customization": ""
|
||||
},
|
||||
"Power Off": {
|
||||
"Power Off": "关机"
|
||||
},
|
||||
@@ -1470,7 +1446,7 @@
|
||||
"Pressure": "气压"
|
||||
},
|
||||
"Prevent idle for media": {
|
||||
"Prevent idle for media": ""
|
||||
"Prevent idle for media": "防止媒体播放时进入待机状态"
|
||||
},
|
||||
"Prevent screen timeout": {
|
||||
"Prevent screen timeout": "防止屏幕超时"
|
||||
@@ -1502,9 +1478,6 @@
|
||||
"Profile image is too large. Please use a smaller image.": {
|
||||
"Profile image is too large. Please use a smaller image.": "个人资料图片过大,请选择更小的图片。"
|
||||
},
|
||||
"QML, JavaScript, Go": {
|
||||
"QML, JavaScript, Go": "QML, JavaScript, Go"
|
||||
},
|
||||
"Quick access to application launcher": {
|
||||
"Quick access to application launcher": "快捷访问应用启动器"
|
||||
},
|
||||
@@ -1556,14 +1529,23 @@
|
||||
"Resources": {
|
||||
"Resources": "资源"
|
||||
},
|
||||
"Restart": {
|
||||
"Restart": "重启"
|
||||
},
|
||||
"Restart DMS": {
|
||||
"Restart DMS": ""
|
||||
},
|
||||
"Restart the DankMaterialShell": {
|
||||
"Restart the DankMaterialShell": ""
|
||||
},
|
||||
"Resume": {
|
||||
"Resume": "恢复"
|
||||
},
|
||||
"Revert": {
|
||||
"Revert": ""
|
||||
"Revert": "恢复: "
|
||||
},
|
||||
"Reverting in:": {
|
||||
"Reverting in:": ""
|
||||
"Reverting in:": "恢复于:"
|
||||
},
|
||||
"Right": {
|
||||
"Right": "右侧"
|
||||
@@ -1604,9 +1586,6 @@
|
||||
"Science": {
|
||||
"Science": "科学"
|
||||
},
|
||||
"Scroll through windows, rather than workspaces": {
|
||||
"Scroll through windows, rather than workspaces": "滚动窗口,而非工作区"
|
||||
},
|
||||
"Search file contents": {
|
||||
"Search file contents": "检索文件内容"
|
||||
},
|
||||
@@ -1688,12 +1667,33 @@
|
||||
"Show Dock": {
|
||||
"Show Dock": "显示程序坞"
|
||||
},
|
||||
"Show Hibernate": {
|
||||
"Show Hibernate": ""
|
||||
},
|
||||
"Show Line Numbers": {
|
||||
"Show Line Numbers": "显示行号"
|
||||
},
|
||||
"Show Lock": {
|
||||
"Show Lock": ""
|
||||
},
|
||||
"Show Log Out": {
|
||||
"Show Log Out": ""
|
||||
},
|
||||
"Show Power Actions": {
|
||||
"Show Power Actions": "显示电源操作"
|
||||
},
|
||||
"Show Power Off": {
|
||||
"Show Power Off": ""
|
||||
},
|
||||
"Show Reboot": {
|
||||
"Show Reboot": ""
|
||||
},
|
||||
"Show Restart DMS": {
|
||||
"Show Restart DMS": ""
|
||||
},
|
||||
"Show Suspend": {
|
||||
"Show Suspend": ""
|
||||
},
|
||||
"Show Workspace Apps": {
|
||||
"Show Workspace Apps": "显示工作区内应用"
|
||||
},
|
||||
@@ -1865,12 +1865,6 @@
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: 导航 • ←→↑↓: 网格导航 • 回车/空格: 选中"
|
||||
},
|
||||
"Technical Details": {
|
||||
"Technical Details": "技术细节"
|
||||
},
|
||||
"Temperature": {
|
||||
"Temperature": "色温"
|
||||
},
|
||||
"Terminal custom additional parameters": {
|
||||
"Terminal custom additional parameters": "终端自定义附加参数"
|
||||
},
|
||||
@@ -1997,9 +1991,6 @@
|
||||
"Use animated wave progress bars for media playback": {
|
||||
"Use animated wave progress bars for media playback": "进行媒体播放时显示动画波形进度条"
|
||||
},
|
||||
"Use automatic location detection (geoclue2)": {
|
||||
"Use automatic location detection (geoclue2)": "使用自动位置检测 (geoclue2)"
|
||||
},
|
||||
"Use custom command for update your system": {
|
||||
"Use custom command for update your system": "使用自定义命令来更新系统"
|
||||
},
|
||||
@@ -2037,7 +2028,7 @@
|
||||
"VPN status and quick connect": "VPN 状态与快速连接"
|
||||
},
|
||||
"VRR: ": {
|
||||
"VRR: ": ""
|
||||
"VRR: ": "可变刷新率: "
|
||||
},
|
||||
"Vibrant palette with playful saturation.": {
|
||||
"Vibrant palette with playful saturation.": "充满活力的调色板,有着俏皮的饱和度。"
|
||||
@@ -2105,9 +2096,6 @@
|
||||
"Wind": {
|
||||
"Wind": "风速"
|
||||
},
|
||||
"Window Scrolling": {
|
||||
"Window Scrolling": "窗口滚动"
|
||||
},
|
||||
"Workspace": {
|
||||
"Workspace": "工作区"
|
||||
},
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"Applications": {
|
||||
"Applications": "應用程式"
|
||||
},
|
||||
"Apply": {
|
||||
"Apply": "套用"
|
||||
},
|
||||
"Apply GTK Colors": {
|
||||
"Apply GTK Colors": "套用 GTK 顏色"
|
||||
},
|
||||
@@ -167,9 +164,6 @@
|
||||
"Auto-hide Dock": {
|
||||
"Auto-hide Dock": "自動隱藏 Dock"
|
||||
},
|
||||
"Auto-location": {
|
||||
"Auto-location": "自動定位"
|
||||
},
|
||||
"Auto-saving...": {
|
||||
"Auto-saving...": "自動保存..."
|
||||
},
|
||||
@@ -230,9 +224,6 @@
|
||||
"Battery level and power management": {
|
||||
"Battery level and power management": "電量與電源管理"
|
||||
},
|
||||
"Battery not detected - only AC power settings available": {
|
||||
"Battery not detected - only AC power settings available": "未偵測到電池 - 僅提供交流電源設定"
|
||||
},
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": {
|
||||
"Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen": "將鎖定畫面綁定到 loginctl 的 dbus 訊號。如果使用外部鎖屏,請停用"
|
||||
},
|
||||
@@ -398,9 +389,6 @@
|
||||
"Compositor": {
|
||||
"Compositor": "合成器"
|
||||
},
|
||||
"Compositor:": {
|
||||
"Compositor:": "合成器:"
|
||||
},
|
||||
"Configuration activated": {
|
||||
"Configuration activated": "配置已啟動"
|
||||
},
|
||||
@@ -434,9 +422,6 @@
|
||||
"Connecting to Device": {
|
||||
"Connecting to Device": ""
|
||||
},
|
||||
"Connection failed. Check password and try again.": {
|
||||
"Connection failed. Check password and try again.": "連線失敗。請檢查密碼並重試。"
|
||||
},
|
||||
"Contrast": {
|
||||
"Contrast": "對比"
|
||||
},
|
||||
@@ -461,9 +446,6 @@
|
||||
"Copied!": {
|
||||
"Copied!": "已複製!"
|
||||
},
|
||||
"Copy": {
|
||||
"Copy": "複製"
|
||||
},
|
||||
"Copy PID": {
|
||||
"Copy PID": "複製 PID"
|
||||
},
|
||||
@@ -515,6 +497,9 @@
|
||||
"Customizable empty space": {
|
||||
"Customizable empty space": "可自訂空白空間"
|
||||
},
|
||||
"Customize which actions appear in the power menu": {
|
||||
"Customize which actions appear in the power menu": ""
|
||||
},
|
||||
"DEMO MODE - Click anywhere to exit": {
|
||||
"DEMO MODE - Click anywhere to exit": "演示模式 - 點擊任意處關閉"
|
||||
},
|
||||
@@ -542,9 +527,6 @@
|
||||
"Dank Bar Widget Transparency": {
|
||||
"Dank Bar Widget Transparency": "Dank Bar 部件透明度"
|
||||
},
|
||||
"Dank Suite:": {
|
||||
"Dank Suite:": "Dank 套件:"
|
||||
},
|
||||
"DankBar Font Scale": {
|
||||
"DankBar Font Scale": "Dank Bar 字體縮放"
|
||||
},
|
||||
@@ -566,6 +548,9 @@
|
||||
"Default": {
|
||||
"Default": "預設"
|
||||
},
|
||||
"Default selected action": {
|
||||
"Default selected action": ""
|
||||
},
|
||||
"Defaults": {
|
||||
"Defaults": "預設"
|
||||
},
|
||||
@@ -842,9 +827,6 @@
|
||||
"Format Legend": {
|
||||
"Format Legend": "格式說明"
|
||||
},
|
||||
"Framework:": {
|
||||
"Framework:": "框架:"
|
||||
},
|
||||
"Fun": {
|
||||
"Fun": "有趣的"
|
||||
},
|
||||
@@ -866,9 +848,6 @@
|
||||
"Gamma control not available. Requires DMS API v6+.": {
|
||||
"Gamma control not available. Requires DMS API v6+.": "Gamma 控制不可用。需要 DMS API v6+。"
|
||||
},
|
||||
"Geoclue service not running - cannot auto-detect location": {
|
||||
"Geoclue service not running - cannot auto-detect location": "Geoclue 服務未運作 - 無法自動偵測位置"
|
||||
},
|
||||
"Github:": {
|
||||
"Github:": "Github:"
|
||||
},
|
||||
@@ -902,15 +881,9 @@
|
||||
"Hex": {
|
||||
"Hex": ""
|
||||
},
|
||||
"Hex:": {
|
||||
"Hex:": "色碼:"
|
||||
},
|
||||
"Hibernate": {
|
||||
"Hibernate": "休眠"
|
||||
},
|
||||
"Hibernate system after": {
|
||||
"Hibernate system after": "系統休眠之後"
|
||||
},
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": {
|
||||
"Hide the dock when not in use and reveal it when hovering near the dock area": "不使用時隱藏 Dock,並在 Dock 區域附近懸停時顯示 Dock"
|
||||
},
|
||||
@@ -1001,9 +974,6 @@
|
||||
"Kill Process": {
|
||||
"Kill Process": "結束程序"
|
||||
},
|
||||
"Language:": {
|
||||
"Language:": "語言:"
|
||||
},
|
||||
"Last launched %1": {
|
||||
"Last launched %1": "上次啟動於 %1"
|
||||
},
|
||||
@@ -1058,6 +1028,9 @@
|
||||
"Location Search": {
|
||||
"Location Search": "位置搜尋"
|
||||
},
|
||||
"Lock": {
|
||||
"Lock": ""
|
||||
},
|
||||
"Lock Screen": {
|
||||
"Lock Screen": "鎖定螢幕"
|
||||
},
|
||||
@@ -1166,9 +1139,6 @@
|
||||
"Mode: ": {
|
||||
"Mode: ": ""
|
||||
},
|
||||
"Monitor": {
|
||||
"Monitor": "螢幕"
|
||||
},
|
||||
"Monitor Selection:": {
|
||||
"Monitor Selection:": "螢幕選擇:"
|
||||
},
|
||||
@@ -1328,6 +1298,9 @@
|
||||
"Only adjust gamma based on time or location rules.": {
|
||||
"Only adjust gamma based on time or location rules.": "僅根據時間或位置規則調整 gamma。"
|
||||
},
|
||||
"Only visible if hibernate is supported by your system": {
|
||||
"Only visible if hibernate is supported by your system": ""
|
||||
},
|
||||
"Opacity": {
|
||||
"Opacity": "不透明度"
|
||||
},
|
||||
@@ -1457,6 +1430,9 @@
|
||||
"Power Action Confirmation": {
|
||||
"Power Action Confirmation": "電源操作確認"
|
||||
},
|
||||
"Power Menu Customization": {
|
||||
"Power Menu Customization": ""
|
||||
},
|
||||
"Power Off": {
|
||||
"Power Off": "關機"
|
||||
},
|
||||
@@ -1502,9 +1478,6 @@
|
||||
"Profile image is too large. Please use a smaller image.": {
|
||||
"Profile image is too large. Please use a smaller image.": "個人資料圖片太大。請使用較小的圖片。"
|
||||
},
|
||||
"QML, JavaScript, Go": {
|
||||
"QML, JavaScript, Go": "QML, JavaScript, Go"
|
||||
},
|
||||
"Quick access to application launcher": {
|
||||
"Quick access to application launcher": "快速存取應用程式啟動器"
|
||||
},
|
||||
@@ -1556,6 +1529,15 @@
|
||||
"Resources": {
|
||||
"Resources": "資源"
|
||||
},
|
||||
"Restart": {
|
||||
"Restart": ""
|
||||
},
|
||||
"Restart DMS": {
|
||||
"Restart DMS": ""
|
||||
},
|
||||
"Restart the DankMaterialShell": {
|
||||
"Restart the DankMaterialShell": ""
|
||||
},
|
||||
"Resume": {
|
||||
"Resume": ""
|
||||
},
|
||||
@@ -1604,9 +1586,6 @@
|
||||
"Science": {
|
||||
"Science": "科學"
|
||||
},
|
||||
"Scroll through windows, rather than workspaces": {
|
||||
"Scroll through windows, rather than workspaces": "滾動窗口,而不是工作區"
|
||||
},
|
||||
"Search file contents": {
|
||||
"Search file contents": "搜尋檔案內容"
|
||||
},
|
||||
@@ -1688,12 +1667,33 @@
|
||||
"Show Dock": {
|
||||
"Show Dock": "顯示 Dock"
|
||||
},
|
||||
"Show Hibernate": {
|
||||
"Show Hibernate": ""
|
||||
},
|
||||
"Show Line Numbers": {
|
||||
"Show Line Numbers": "顯示行數"
|
||||
},
|
||||
"Show Lock": {
|
||||
"Show Lock": ""
|
||||
},
|
||||
"Show Log Out": {
|
||||
"Show Log Out": ""
|
||||
},
|
||||
"Show Power Actions": {
|
||||
"Show Power Actions": "顯示電源選項"
|
||||
},
|
||||
"Show Power Off": {
|
||||
"Show Power Off": ""
|
||||
},
|
||||
"Show Reboot": {
|
||||
"Show Reboot": ""
|
||||
},
|
||||
"Show Restart DMS": {
|
||||
"Show Restart DMS": ""
|
||||
},
|
||||
"Show Suspend": {
|
||||
"Show Suspend": ""
|
||||
},
|
||||
"Show Workspace Apps": {
|
||||
"Show Workspace Apps": "顯示工作區應用程式"
|
||||
},
|
||||
@@ -1865,12 +1865,6 @@
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
|
||||
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: 切換焦點 • ←→↑↓: 切換焦點 • Enter/Space: 選擇"
|
||||
},
|
||||
"Technical Details": {
|
||||
"Technical Details": "技術細節"
|
||||
},
|
||||
"Temperature": {
|
||||
"Temperature": "溫度"
|
||||
},
|
||||
"Terminal custom additional parameters": {
|
||||
"Terminal custom additional parameters": "自訂終端附加參數"
|
||||
},
|
||||
@@ -1997,9 +1991,6 @@
|
||||
"Use animated wave progress bars for media playback": {
|
||||
"Use animated wave progress bars for media playback": "在媒體播放使用動畫波浪進度條"
|
||||
},
|
||||
"Use automatic location detection (geoclue2)": {
|
||||
"Use automatic location detection (geoclue2)": "使用自動位置偵測(geoclue2)"
|
||||
},
|
||||
"Use custom command for update your system": {
|
||||
"Use custom command for update your system": "使用自訂指令更新您的系統"
|
||||
},
|
||||
@@ -2105,9 +2096,6 @@
|
||||
"Wind": {
|
||||
"Wind": "風速"
|
||||
},
|
||||
"Window Scrolling": {
|
||||
"Window Scrolling": "視窗滾動"
|
||||
},
|
||||
"Workspace": {
|
||||
"Workspace": "工作區"
|
||||
},
|
||||
|
||||
@@ -1161,6 +1161,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Customize which actions appear in the power menu",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "DEMO MODE - Click anywhere to exit",
|
||||
"translation": "",
|
||||
@@ -1273,6 +1280,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Default selected action",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Defaults",
|
||||
"translation": "",
|
||||
@@ -2386,6 +2400,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Lock",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Lock Screen",
|
||||
"translation": "",
|
||||
@@ -3009,6 +3030,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Only visible if hibernate is supported by your system",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Opacity",
|
||||
"translation": "",
|
||||
@@ -3310,6 +3338,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Power Menu Customization",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Power Off",
|
||||
"translation": "",
|
||||
@@ -3534,6 +3569,20 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Restart DMS",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Restart the DankMaterialShell",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Resume",
|
||||
"translation": "",
|
||||
@@ -3835,6 +3884,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Hibernate",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Line Numbers",
|
||||
"translation": "",
|
||||
@@ -3842,6 +3898,20 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Lock",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Log Out",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Power Actions",
|
||||
"translation": "",
|
||||
@@ -3849,6 +3919,34 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Power Off",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Reboot",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Restart DMS",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Suspend",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "Show Workspace Apps",
|
||||
"translation": "",
|
||||
|
||||
Reference in New Issue
Block a user