mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-05-12 07:19:41 -04:00
Compare commits
120 Commits
8271d8423d
...
v1.4.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f24cf37ca | ||
|
|
01218f34cb | ||
|
|
9da58d8296 | ||
|
|
af0038e634 | ||
|
|
05c312b9eb | ||
|
|
89d5c958c4 | ||
|
|
e4d86ad595 | ||
|
|
532b54a028 | ||
|
|
504d027c3f | ||
|
|
e8f95f4533 | ||
|
|
b83256c83a | ||
|
|
8e2cd21be8 | ||
|
|
c5413608da | ||
|
|
586bcad442 | ||
|
|
3b3d10f730 | ||
|
|
4834891b36 | ||
|
|
f60e65aecb | ||
|
|
01387b0123 | ||
|
|
1476658c23 | ||
|
|
7861c6e316 | ||
|
|
d2247d7b24 | ||
|
|
2ff78d4a02 | ||
|
|
785243ce5f | ||
|
|
0e1b868384 | ||
|
|
2b08e800e8 | ||
|
|
74e4f8ea1e | ||
|
|
9c58569b4c | ||
|
|
29de677e00 | ||
|
|
fae4944845 | ||
|
|
07a0ac4b7d | ||
|
|
b2d8f4d73b | ||
|
|
fe58c45233 | ||
|
|
3ea4e389eb | ||
|
|
7276f295fc | ||
|
|
93ed96a789 | ||
|
|
bea325e94c | ||
|
|
2f8f1c30ad | ||
|
|
f859a14173 | ||
|
|
153f39da48 | ||
|
|
e4accdd1c7 | ||
|
|
a2c89e0a8c | ||
|
|
e282831c2e | ||
|
|
5c5ff6195a | ||
|
|
c4bbf54679 | ||
|
|
98acafb4b8 | ||
|
|
da20681fc0 | ||
|
|
b38cb961b2 | ||
|
|
7a0bb07518 | ||
|
|
403e3e90a2 | ||
|
|
50b91f14b6 | ||
|
|
b3df47fce0 | ||
|
|
09bd65d746 | ||
|
|
020d56ab7f | ||
|
|
f3bee65da9 | ||
|
|
b14b0946e2 | ||
|
|
ca44205f1c | ||
|
|
2d39e8fd2a | ||
|
|
6d4df6e927 | ||
|
|
b8ab86e6c0 | ||
|
|
837329a6d8 | ||
|
|
8c6c2ffd23 | ||
|
|
ad3c8b6755 | ||
|
|
03a8e1e0d5 | ||
|
|
4d4d3c20a1 | ||
|
|
cef16d6bc9 | ||
|
|
aafaad1791 | ||
|
|
7906fdc2b0 | ||
|
|
397650ca52 | ||
|
|
826207006a | ||
|
|
58c2fcd31c | ||
|
|
b2a2b425ec | ||
|
|
942c9c9609 | ||
|
|
46d6e1cff3 | ||
|
|
a4137c57c1 | ||
|
|
1ad8b627f1 | ||
|
|
58a02ce290 | ||
|
|
8e1ad1a2be | ||
|
|
68cd7ab32c | ||
|
|
f649ce9a8e | ||
|
|
c4df242f07 | ||
|
|
26846c8d55 | ||
|
|
31b44a667c | ||
|
|
4f3b73ee21 | ||
|
|
4cfae91f02 | ||
|
|
8d947a6e95 | ||
|
|
1e84d4252c | ||
|
|
76072e1d4c | ||
|
|
6408dce4a9 | ||
|
|
0b2e1cca38 | ||
|
|
c1bfd8c0b7 | ||
|
|
90ffa5833b | ||
|
|
169c669286 | ||
|
|
f8350deafc | ||
|
|
0286a1b80b | ||
|
|
7c3e6c1f02 | ||
|
|
d2d72db3c9 | ||
|
|
f81f861408 | ||
|
|
af494543f5 | ||
|
|
db4de55338 | ||
|
|
37ecbbbbde | ||
|
|
d6a6d2a438 | ||
|
|
bf1c6eec74 | ||
|
|
0ddae80584 | ||
|
|
5c96c03bfa | ||
|
|
dfe36e47d8 | ||
|
|
63e1b75e57 | ||
|
|
29efdd8598 | ||
|
|
34d03cf11b | ||
|
|
c339389d44 | ||
|
|
af5f6eb656 | ||
|
|
a6d28e2553 | ||
|
|
6213267908 | ||
|
|
d084114149 | ||
|
|
f6d99eca0d | ||
|
|
722eb3289e | ||
|
|
b7f2bdcb2d | ||
|
|
11c20db6e6 | ||
|
|
8a4e3f8bb1 | ||
|
|
bc8fe97c13 | ||
|
|
47262155aa |
13
.github/workflows/run-obs.yml
vendored
13
.github/workflows/run-obs.yml
vendored
@@ -9,8 +9,8 @@ on:
|
||||
type: choice
|
||||
options:
|
||||
- dms
|
||||
- dms-greeter
|
||||
- dms-git
|
||||
- dms-greeter
|
||||
- all
|
||||
default: "dms"
|
||||
rebuild_release:
|
||||
@@ -119,8 +119,9 @@ jobs:
|
||||
echo "🔄 Manual rebuild requested: $PKG (db$REBUILD)"
|
||||
|
||||
elif [[ "$PKG" == "all" ]]; then
|
||||
# Check each stable package and build list of those needing updates
|
||||
# Check each package and build list of those needing updates
|
||||
PACKAGES_TO_UPDATE=()
|
||||
check_dms_git && PACKAGES_TO_UPDATE+=("dms-git")
|
||||
if check_dms_stable; then
|
||||
PACKAGES_TO_UPDATE+=("dms")
|
||||
if [[ -n "$LATEST_TAG" ]]; then
|
||||
@@ -139,7 +140,7 @@ jobs:
|
||||
else
|
||||
echo "packages=" >> $GITHUB_OUTPUT
|
||||
echo "has_updates=false" >> $GITHUB_OUTPUT
|
||||
echo "✓ Both packages up to date"
|
||||
echo "✓ All packages up to date"
|
||||
fi
|
||||
|
||||
elif [[ "$PKG" == "dms-git" ]]; then
|
||||
@@ -244,7 +245,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Update dms-git spec version
|
||||
if: contains(steps.packages.outputs.packages, 'dms-git')
|
||||
if: contains(steps.packages.outputs.packages, 'dms-git') || steps.packages.outputs.packages == 'all'
|
||||
run: |
|
||||
COMMIT_HASH=$(git rev-parse --short=8 HEAD)
|
||||
COMMIT_COUNT=$(git rev-list --count HEAD)
|
||||
@@ -265,7 +266,7 @@ jobs:
|
||||
} > distro/opensuse/dms-git.spec
|
||||
|
||||
- name: Update Debian dms-git changelog version
|
||||
if: contains(steps.packages.outputs.packages, 'dms-git')
|
||||
if: contains(steps.packages.outputs.packages, 'dms-git') || steps.packages.outputs.packages == 'all'
|
||||
run: |
|
||||
COMMIT_HASH=$(git rev-parse --short=8 HEAD)
|
||||
COMMIT_COUNT=$(git rev-list --count HEAD)
|
||||
@@ -388,7 +389,7 @@ jobs:
|
||||
UPLOADED_PACKAGES=()
|
||||
SKIPPED_PACKAGES=()
|
||||
|
||||
# PACKAGES can be space-separated list (e.g., "dms dms-greeter" from "all" check)
|
||||
# PACKAGES can be space-separated list (e.g., "dms-git dms" from "all" check)
|
||||
# Loop through each package and upload
|
||||
for PKG in $PACKAGES; do
|
||||
echo ""
|
||||
|
||||
16
.github/workflows/run-ppa.yml
vendored
16
.github/workflows/run-ppa.yml
vendored
@@ -4,15 +4,9 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
package:
|
||||
description: "Package to upload"
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- dms
|
||||
- dms-greeter
|
||||
- dms-git
|
||||
- all
|
||||
default: "dms"
|
||||
description: "Package to upload (dms, dms-git, dms-greeter, or all)"
|
||||
required: false
|
||||
default: "dms-git"
|
||||
rebuild_release:
|
||||
description: "Release number for rebuilds (e.g., 2, 3, 4 for ppa2, ppa3, ppa4)"
|
||||
required: false
|
||||
@@ -145,7 +139,7 @@ jobs:
|
||||
fi
|
||||
else
|
||||
# Fallback
|
||||
echo "packages=dms" >> $GITHUB_OUTPUT
|
||||
echo "packages=dms-git" >> $GITHUB_OUTPUT
|
||||
echo "has_updates=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
@@ -215,7 +209,7 @@ jobs:
|
||||
echo "✓ Using rebuild release number: ppa$REBUILD_RELEASE"
|
||||
fi
|
||||
|
||||
# PACKAGES can be space-separated list (e.g., "dms-git dms dms-greeter" from "all" check)
|
||||
# PACKAGES can be space-separated list (e.g., "dms-git dms" from "all" check)
|
||||
# Loop through each package and upload
|
||||
for PKG in $PACKAGES; do
|
||||
# Map package to PPA name
|
||||
|
||||
@@ -16,8 +16,6 @@ require (
|
||||
github.com/sblinch/kdl-go v0.0.0-20260121213736-8b7053306ca6
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.3.0
|
||||
github.com/yuin/goldmark v1.7.16
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
go.etcd.io/bbolt v1.4.3
|
||||
@@ -34,19 +32,15 @@ require (
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/fogleman/gg v1.3.0 // indirect
|
||||
github.com/go-git/gcfg/v2 v2.0.2 // indirect
|
||||
github.com/go-git/go-billy/v6 v6.0.0-20260209124918-37866f83c2d3 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.1 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/kevinburke/ssh_config v1.6.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/pjbgf/sha1cd v0.5.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sergi/go-diff v1.4.0 // indirect
|
||||
github.com/stretchr/objx v0.5.3 // indirect
|
||||
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
||||
golang.org/x/crypto v0.48.0 // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
)
|
||||
|
||||
12
core/go.sum
12
core/go.sum
@@ -58,8 +58,6 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
@@ -77,8 +75,6 @@ github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
|
||||
github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
@@ -119,8 +115,6 @@ github.com/pilebones/go-udev v0.9.1 h1:uN72M1C1fgzhsVmBGEM8w9RD1JY4iVsPZpr+Z6rb3
|
||||
github.com/pilebones/go-udev v0.9.1/go.mod h1:Bgcl07crebF3JSeS4+nuaRvhWFdCeFoBhXXeAp93XNo=
|
||||
github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0=
|
||||
github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
@@ -148,12 +142,6 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5 h1:HCOe2bSjkhZyYoyyNaXNzh4DJZll6inVJQQw+8228Zk=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.3.0 h1:chdyhEfRtUPgQtuPeaWVGQ/TQx4rE1PqeoW3U+53t34=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.3.0/go.mod h1:O4MbzsotGCvy8upYPCR91j81dr5XLT7heuljcNXW+oQ=
|
||||
github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0=
|
||||
github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM=
|
||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE=
|
||||
github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
|
||||
@@ -1062,62 +1062,6 @@ func (_c *MockBackend_GetWiFiNetworkDetails_Call) RunAndReturn(run func(string)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetWiFiQRCodeContent provides a mock function with given fields: ssid
|
||||
func (_m *MockBackend) GetWiFiQRCodeContent(ssid string) (string, error) {
|
||||
ret := _m.Called(ssid)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetWiFiQRCodeContent")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
|
||||
return rf(ssid)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string) string); ok {
|
||||
r0 = rf(ssid)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(ssid)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockBackend_GetWiFiQRCodeContent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWiFiQRCodeContent'
|
||||
type MockBackend_GetWiFiQRCodeContent_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetWiFiQRCodeContent is a helper method to define mock.On call
|
||||
// - ssid string
|
||||
func (_e *MockBackend_Expecter) GetWiFiQRCodeContent(ssid interface{}) *MockBackend_GetWiFiQRCodeContent_Call {
|
||||
return &MockBackend_GetWiFiQRCodeContent_Call{Call: _e.mock.On("GetWiFiQRCodeContent", ssid)}
|
||||
}
|
||||
|
||||
func (_c *MockBackend_GetWiFiQRCodeContent_Call) Run(run func(ssid string)) *MockBackend_GetWiFiQRCodeContent_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBackend_GetWiFiQRCodeContent_Call) Return(_a0 string, _a1 error) *MockBackend_GetWiFiQRCodeContent_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBackend_GetWiFiQRCodeContent_Call) RunAndReturn(run func(string) (string, error)) *MockBackend_GetWiFiQRCodeContent_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetWiredConnections provides a mock function with no fields
|
||||
func (_m *MockBackend) GetWiredConnections() ([]network.WiredConnection, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -10,7 +10,6 @@ type Backend interface {
|
||||
ScanWiFi() error
|
||||
ScanWiFiDevice(device string) error
|
||||
GetWiFiNetworkDetails(ssid string) (*NetworkInfoResponse, error)
|
||||
GetWiFiQRCodeContent(ssid string) (string, error)
|
||||
GetWiFiDevices() []WiFiDevice
|
||||
|
||||
ConnectWiFi(req ConnectionRequest) error
|
||||
|
||||
@@ -111,10 +111,6 @@ func (b *HybridIwdNetworkdBackend) GetWiFiNetworkDetails(ssid string) (*NetworkI
|
||||
return b.wifi.GetWiFiNetworkDetails(ssid)
|
||||
}
|
||||
|
||||
func (b *HybridIwdNetworkdBackend) GetWiFiQRCodeContent(ssid string) (string, error) {
|
||||
return b.wifi.GetWiFiQRCodeContent(ssid)
|
||||
}
|
||||
|
||||
func (b *HybridIwdNetworkdBackend) ConnectWiFi(req ConnectionRequest) error {
|
||||
if err := b.wifi.ConnectWiFi(req); err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
import "fmt"
|
||||
|
||||
func (b *IWDBackend) GetWiredConnections() ([]WiredConnection, error) {
|
||||
return nil, fmt.Errorf("wired connections not supported by iwd")
|
||||
@@ -115,19 +112,3 @@ func (b *IWDBackend) getWiFiDevicesLocked() []WiFiDevice {
|
||||
Networks: b.state.WiFiNetworks,
|
||||
}}
|
||||
}
|
||||
|
||||
func (b *IWDBackend) GetWiFiQRCodeContent(ssid string) (string, error) {
|
||||
path := iwdConfigPath(ssid)
|
||||
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("no saved iwd config for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
passphrase, err := parseIWDPassphrase(string(data))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read passphrase for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
return FormatWiFiQRString("WPA", ssid, passphrase), nil
|
||||
}
|
||||
|
||||
@@ -18,10 +18,6 @@ func (b *SystemdNetworkdBackend) GetWiFiNetworkDetails(ssid string) (*NetworkInf
|
||||
return nil, fmt.Errorf("WiFi details not supported by networkd backend")
|
||||
}
|
||||
|
||||
func (b *SystemdNetworkdBackend) GetWiFiQRCodeContent(ssid string) (string, error) {
|
||||
return "", fmt.Errorf("WiFi QR Code not supported by networkd backend")
|
||||
}
|
||||
|
||||
func (b *SystemdNetworkdBackend) ConnectWiFi(req ConnectionRequest) error {
|
||||
return fmt.Errorf("WiFi connect not supported by networkd backend")
|
||||
}
|
||||
|
||||
@@ -196,65 +196,6 @@ func (b *NetworkManagerBackend) GetWiFiNetworkDetails(ssid string) (*NetworkInfo
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *NetworkManagerBackend) GetWiFiQRCodeContent(ssid string) (string, error) {
|
||||
conn, err := b.findConnection(ssid)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("no saved connection for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
connSettings, err := conn.GetSettings()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get settings for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
secSettings, ok := connSettings["802-11-wireless-security"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("network `%s` has no security settings", ssid)
|
||||
}
|
||||
|
||||
keyMgmt, ok := secSettings["key-mgmt"].(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("failed to identify security type of network `%s`", ssid)
|
||||
}
|
||||
|
||||
var securityType string
|
||||
switch keyMgmt {
|
||||
case "none":
|
||||
authAlg, _ := secSettings["auth-alg"].(string)
|
||||
switch authAlg {
|
||||
case "open":
|
||||
securityType = "nopass"
|
||||
default:
|
||||
securityType = "WEP"
|
||||
}
|
||||
case "ieee8021x":
|
||||
securityType = "WEP"
|
||||
default:
|
||||
securityType = "WPA"
|
||||
}
|
||||
|
||||
if securityType != "WPA" {
|
||||
return "", fmt.Errorf("QR code generation only supports WPA connections, `%s` uses %s", ssid, securityType)
|
||||
}
|
||||
|
||||
secrets, err := conn.GetSecrets("802-11-wireless-security")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to retrieve connection secrets for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
secSecrets, ok := secrets["802-11-wireless-security"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("failed to retrieve password for `%s`", ssid)
|
||||
}
|
||||
|
||||
psk, ok := secSecrets["psk"].(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("failed to retrieve password for `%s`", ssid)
|
||||
}
|
||||
|
||||
return FormatWiFiQRString(securityType, ssid, psk), nil
|
||||
}
|
||||
|
||||
func (b *NetworkManagerBackend) ConnectWiFi(req ConnectionRequest) error {
|
||||
devInfo, err := b.getWifiDeviceForConnection(req.Device)
|
||||
if err != nil {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/models"
|
||||
@@ -41,10 +40,6 @@ func HandleRequest(conn net.Conn, req models.Request, manager *Manager) {
|
||||
handleSetPreference(conn, req, manager)
|
||||
case "network.info":
|
||||
handleGetNetworkInfo(conn, req, manager)
|
||||
case "network.qrcode":
|
||||
handleGetNetworkQRCode(conn, req, manager)
|
||||
case "network.delete-qrcode":
|
||||
handleDeleteQRCode(conn, req, manager)
|
||||
case "network.ethernet.info":
|
||||
handleGetWiredNetworkInfo(conn, req, manager)
|
||||
case "network.subscribe":
|
||||
@@ -325,42 +320,6 @@ func handleGetNetworkInfo(conn net.Conn, req models.Request, manager *Manager) {
|
||||
models.Respond(conn, req.ID, network)
|
||||
}
|
||||
|
||||
func handleGetNetworkQRCode(conn net.Conn, req models.Request, manager *Manager) {
|
||||
ssid, err := params.String(req.Params, "ssid")
|
||||
if err != nil {
|
||||
models.RespondError(conn, req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
content, err := manager.GetNetworkQRCode(ssid)
|
||||
if err != nil {
|
||||
models.RespondError(conn, req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
models.Respond(conn, req.ID, content)
|
||||
}
|
||||
|
||||
func handleDeleteQRCode(conn net.Conn, req models.Request, _ *Manager) {
|
||||
path, err := params.String(req.Params, "path")
|
||||
if err != nil {
|
||||
models.RespondError(conn, req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if !isValidQRCodePath(path) {
|
||||
models.RespondError(conn, req.ID, "invalid QR code path")
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.Remove(path); err != nil {
|
||||
models.RespondError(conn, req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "QR code file deleted"})
|
||||
}
|
||||
|
||||
func handleGetWiredNetworkInfo(conn net.Conn, req models.Request, manager *Manager) {
|
||||
uuid, err := params.String(req.Params, "uuid")
|
||||
if err != nil {
|
||||
|
||||
@@ -6,8 +6,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
|
||||
"github.com/yeqown/go-qrcode/v2"
|
||||
"github.com/yeqown/go-qrcode/writer/standard"
|
||||
)
|
||||
|
||||
func NewManager() (*Manager, error) {
|
||||
@@ -440,43 +438,6 @@ func (m *Manager) GetNetworkInfoDetailed(ssid string) (*NetworkInfoResponse, err
|
||||
return m.backend.GetWiFiNetworkDetails(ssid)
|
||||
}
|
||||
|
||||
func (m *Manager) GetNetworkQRCode(ssid string) ([2]string, error) {
|
||||
content, err := m.backend.GetWiFiQRCodeContent(ssid)
|
||||
if err != nil {
|
||||
return [2]string{}, err
|
||||
}
|
||||
|
||||
qrc, err := qrcode.New(content)
|
||||
if err != nil {
|
||||
return [2]string{}, fmt.Errorf("failed to create QR code for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
pathThemed, pathNormal := qrCodePaths(ssid)
|
||||
|
||||
wThemed, err := standard.New(
|
||||
pathThemed,
|
||||
standard.WithBuiltinImageEncoder(standard.PNG_FORMAT),
|
||||
standard.WithBgTransparent(),
|
||||
standard.WithFgColorRGBHex("#ffffff"),
|
||||
)
|
||||
if err != nil {
|
||||
return [2]string{}, fmt.Errorf("failed to create QR code writer: %w", err)
|
||||
}
|
||||
if err := qrc.Save(wThemed); err != nil {
|
||||
return [2]string{}, fmt.Errorf("failed to save QR code for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
wNormal, err := standard.New(pathNormal, standard.WithBuiltinImageEncoder(standard.PNG_FORMAT))
|
||||
if err != nil {
|
||||
return [2]string{}, fmt.Errorf("failed to create QR code writer: %w", err)
|
||||
}
|
||||
if err := qrc.Save(wNormal); err != nil {
|
||||
return [2]string{}, fmt.Errorf("failed to save QR code for `%s`: %w", ssid, err)
|
||||
}
|
||||
|
||||
return [2]string{pathThemed, pathNormal}, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ToggleWiFi() error {
|
||||
enabled, err := m.backend.GetWiFiEnabled()
|
||||
if err != nil {
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const qrCodeTmpPrefix = "/tmp/dank-wifi-qrcode-"
|
||||
|
||||
func FormatWiFiQRString(securityType, ssid, password string) string {
|
||||
return fmt.Sprintf("WIFI:T:%s;S:%s;P:%s;;", securityType, ssid, password)
|
||||
}
|
||||
|
||||
func qrCodePaths(ssid string) (themed, normal string) {
|
||||
safe := sanitizeSSIDForPath(ssid)
|
||||
themed = fmt.Sprintf("%s%s-themed.png", qrCodeTmpPrefix, safe)
|
||||
normal = fmt.Sprintf("%s%s-normal.png", qrCodeTmpPrefix, safe)
|
||||
return
|
||||
}
|
||||
|
||||
func isValidQRCodePath(path string) bool {
|
||||
clean := filepath.Clean(path)
|
||||
return strings.HasPrefix(clean, qrCodeTmpPrefix) && strings.HasSuffix(clean, ".png")
|
||||
}
|
||||
|
||||
var safePathChar = regexp.MustCompile(`[^a-zA-Z0-9_-]`)
|
||||
|
||||
func sanitizeSSIDForPath(ssid string) string {
|
||||
return safePathChar.ReplaceAllString(ssid, "_")
|
||||
}
|
||||
|
||||
var iwdVerbatimSSID = regexp.MustCompile(`^[a-zA-Z0-9 _-]+$`)
|
||||
|
||||
func iwdConfigPath(ssid string) string {
|
||||
switch {
|
||||
case iwdVerbatimSSID.MatchString(ssid):
|
||||
return fmt.Sprintf("/var/lib/iwd/%s.psk", ssid)
|
||||
default:
|
||||
return fmt.Sprintf("/var/lib/iwd/=%x.psk", []byte(ssid))
|
||||
}
|
||||
}
|
||||
|
||||
func parseIWDPassphrase(data string) (string, error) {
|
||||
inSecurity := false
|
||||
for _, line := range strings.Split(data, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
switch {
|
||||
case line == "[Security]":
|
||||
inSecurity = true
|
||||
case strings.HasPrefix(line, "["):
|
||||
inSecurity = false
|
||||
case inSecurity && strings.HasPrefix(line, "Passphrase="):
|
||||
return strings.TrimPrefix(line, "Passphrase="), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no passphrase found in iwd config")
|
||||
}
|
||||
@@ -27,12 +27,12 @@ override_dh_auto_build:
|
||||
# Verify core directory exists (native package format has source at root)
|
||||
test -d core || (echo "ERROR: core directory not found!" && exit 1)
|
||||
|
||||
# Pin go.mod and vendor/modules.txt to the installed Go toolchain version
|
||||
GO_INSTALLED=$$(go version | grep -oP 'go\K[0-9]+\.[0-9]+'); \
|
||||
sed -i "s/^go [0-9]\+\.[0-9]\+\(\.[0-9]*\)\?$$/go $${GO_INSTALLED}/" core/go.mod; \
|
||||
sed -i "s/^\(## explicit; go \)[0-9]\+\.[0-9]\+\(\.[0-9]*\)\?$$/\1$${GO_INSTALLED}/" core/vendor/modules.txt
|
||||
# Patch go.mod to use Go 1.24 base version (Debian 13 has 1.23.x, may vary)
|
||||
sed -i 's/^go 1\.24\.[0-9]*/go 1.24/' core/go.mod
|
||||
|
||||
# Build dms-cli (single shell to preserve variables; arch: Debian amd64/arm64 -> Makefile amd64/arm64)
|
||||
# Build dms-cli from source using vendored dependencies
|
||||
# Extract version info and build in single shell to preserve variables
|
||||
# Architecture mapping: Debian amd64/arm64 -> Makefile amd64/arm64
|
||||
VERSION="$(UPSTREAM_VERSION)"; \
|
||||
COMMIT=$$(echo "$(UPSTREAM_VERSION)" | grep -oP '(?<=git)[0-9]+\.[a-f0-9]+' | cut -d. -f2 | head -c8 || echo "unknown"); \
|
||||
if [ "$(DEB_HOST_ARCH)" = "amd64" ]; then \
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<service name="download_url">
|
||||
<param name="protocol">https</param>
|
||||
<param name="host">github.com</param>
|
||||
<param name="path">/AvengeMedia/DankMaterialShell/releases/download/v1.4.3/dms-qml.tar.gz</param>
|
||||
<param name="path">/AvengeMedia/DankMaterialShell/releases/download/v1.4.2/dms-qml.tar.gz</param>
|
||||
<param name="filename">dms-qml.tar.gz</param>
|
||||
</service>
|
||||
</services>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
dms-greeter (1.4.3db1) unstable; urgency=medium
|
||||
dms-greeter (1.4.2db8) unstable; urgency=medium
|
||||
|
||||
* Update to v1.4.3 stable release
|
||||
* Initial Debian OBS package
|
||||
* Port from Ubuntu/Fedora packaging
|
||||
|
||||
-- Avenge Media <AvengeMedia.US@gmail.com> Tue, 25 Feb 2026 02:40:00 +0000
|
||||
-- Avenge Media <AvengeMedia.US@gmail.com> Sat, 21 Feb 2026 00:00:00 +0000
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
%global debug_package %{nil}
|
||||
%global version {{{ git_repo_version }}}
|
||||
%global pkg_summary DankMaterialShell - Material 3 inspired shell for Wayland compositors
|
||||
%global go_toolchain_version 1.25.7
|
||||
|
||||
Name: dms
|
||||
Epoch: 2
|
||||
@@ -15,12 +14,12 @@ License: MIT
|
||||
URL: https://github.com/AvengeMedia/DankMaterialShell
|
||||
VCS: {{{ git_repo_vcs }}}
|
||||
Source0: {{{ git_repo_pack }}}
|
||||
Source1: https://go.dev/dl/go%{go_toolchain_version}.linux-amd64.tar.gz
|
||||
Source2: https://go.dev/dl/go%{go_toolchain_version}.linux-arm64.tar.gz
|
||||
|
||||
BuildRequires: git-core
|
||||
BuildRequires: gzip
|
||||
BuildRequires: golang >= 1.24
|
||||
BuildRequires: make
|
||||
BuildRequires: wget
|
||||
BuildRequires: systemd-rpm-macros
|
||||
|
||||
# Core requirements
|
||||
@@ -29,7 +28,7 @@ Requires: accountsservice
|
||||
Requires: dms-cli = %{epoch}:%{version}-%{release}
|
||||
Requires: dgop
|
||||
|
||||
# Core utilities (Recommended for DMS functionality)
|
||||
# Core utilities (Highly recommended for DMS functionality)
|
||||
Recommends: cava
|
||||
Recommends: danksearch
|
||||
Recommends: matugen
|
||||
@@ -67,28 +66,6 @@ Provides native DBus bindings, NetworkManager integration, and system utilities.
|
||||
VERSION="%{version}"
|
||||
COMMIT=$(echo "%{version}" | grep -oP '[a-f0-9]{7,}' | head -n1 || echo "unknown")
|
||||
|
||||
# Use pinned bundled Go toolchain (deterministic across chroots)
|
||||
case "%{_arch}" in
|
||||
x86_64)
|
||||
GO_TARBALL="%{_sourcedir}/go%{go_toolchain_version}.linux-amd64.tar.gz"
|
||||
;;
|
||||
aarch64)
|
||||
GO_TARBALL="%{_sourcedir}/go%{go_toolchain_version}.linux-arm64.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported architecture for bundled Go: %{_arch}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
rm -rf .go
|
||||
tar -xzf "$GO_TARBALL"
|
||||
mv go .go
|
||||
export GOROOT="$PWD/.go"
|
||||
export PATH="$GOROOT/bin:$PATH"
|
||||
export GOTOOLCHAIN=local
|
||||
go version
|
||||
|
||||
cd core
|
||||
make dist VERSION="$VERSION" COMMIT="$COMMIT"
|
||||
|
||||
|
||||
@@ -56,10 +56,8 @@ mkdir -p $HOME $GOCACHE $GOMODCACHE
|
||||
# OBS has no network access, so use local toolchain only
|
||||
export GOTOOLCHAIN=local
|
||||
|
||||
# Pin go.mod and vendor/modules.txt to the installed Go toolchain version
|
||||
GO_INSTALLED=$(go version | grep -oP 'go\K[0-9]+\.[0-9]+')
|
||||
sed -i "s/^go [0-9]\+\.[0-9]\+\(\.[0-9]*\)\?$/go ${GO_INSTALLED}/" core/go.mod
|
||||
sed -i "s/^\(## explicit; go \)[0-9]\+\.[0-9]\+\(\.[0-9]*\)\?$/\1${GO_INSTALLED}/" core/vendor/modules.txt
|
||||
# Patch go.mod to use base Go version (e.g., go 1.24 instead of go 1.24.6)
|
||||
sed -i 's/^go 1\.24\.[0-9]*/go 1.24/' core/go.mod
|
||||
|
||||
# Extract version info for embedding in binary
|
||||
VERSION="%{version}"
|
||||
|
||||
@@ -419,9 +419,6 @@ if [[ "$UPLOAD_OPENSUSE" == true ]] && [[ -f "distro/opensuse/$PACKAGE.spec" ]];
|
||||
sed -i "s/VERSION_PLACEHOLDER/${DMS_GREETER_BASE_VERSION}/g" "$WORK_DIR/$PACKAGE.spec"
|
||||
sed -i "s/RELEASE_PLACEHOLDER/${DMS_GREETER_RELEASE}/g" "$WORK_DIR/$PACKAGE.spec"
|
||||
sed -i "s/CHANGELOG_DATE_PLACEHOLDER/${CHANGELOG_DATE}/g" "$WORK_DIR/$PACKAGE.spec"
|
||||
# Explicitly set Version:/Release: in case the spec uses %{version} macro
|
||||
sed -i "s/^Version:.*/Version: ${DMS_GREETER_BASE_VERSION}/" "$WORK_DIR/$PACKAGE.spec"
|
||||
sed -i "s/^Release:.*/Release: ${DMS_GREETER_RELEASE}%{?dist}/" "$WORK_DIR/$PACKAGE.spec"
|
||||
fi
|
||||
|
||||
if [[ -f "$WORK_DIR/.osc/$PACKAGE.spec" ]]; then
|
||||
@@ -816,9 +813,6 @@ if [[ "$UPLOAD_DEBIAN" == true ]] && [[ -d "distro/debian/$PACKAGE/debian" ]]; t
|
||||
sed -i "s/VERSION_PLACEHOLDER/${DMS_GREETER_BASE_VERSION}/g" "$WORK_DIR/$PACKAGE.spec"
|
||||
sed -i "s/RELEASE_PLACEHOLDER/${DMS_GREETER_RELEASE}/g" "$WORK_DIR/$PACKAGE.spec"
|
||||
sed -i "s/CHANGELOG_DATE_PLACEHOLDER/${CHANGELOG_DATE}/g" "$WORK_DIR/$PACKAGE.spec"
|
||||
# Explicitly set Version:/Release: in case the spec uses %{version} macro
|
||||
sed -i "s/^Version:.*/Version: ${DMS_GREETER_BASE_VERSION}/" "$WORK_DIR/$PACKAGE.spec"
|
||||
sed -i "s/^Release:.*/Release: ${DMS_GREETER_RELEASE}%{?dist}/" "$WORK_DIR/$PACKAGE.spec"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
The Wolverine
|
||||
Saffron Bloom
|
||||
|
||||
@@ -365,23 +365,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: wifiQRCodeModalLoader
|
||||
active: false
|
||||
|
||||
Component.onCompleted: {
|
||||
PopoutService.wifiQRCodeModalLoader = wifiQRCodeModalLoader;
|
||||
}
|
||||
|
||||
WifiQRCodeModal {
|
||||
id: wifiQRCodeModalItem
|
||||
|
||||
Component.onCompleted: {
|
||||
PopoutService.wifiQRCodeModal = wifiQRCodeModalItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: polkitAuthModalLoader
|
||||
active: false
|
||||
|
||||
@@ -162,11 +162,6 @@ Item {
|
||||
}
|
||||
]
|
||||
|
||||
property string fileSearchType: "all"
|
||||
property string fileSearchExt: ""
|
||||
property string fileSearchFolder: ""
|
||||
property string fileSearchSort: "score"
|
||||
|
||||
property string pluginFilter: ""
|
||||
property string activePluginName: ""
|
||||
property var activePluginCategories: []
|
||||
@@ -351,10 +346,6 @@ Item {
|
||||
previousSearchMode = "all";
|
||||
autoSwitchedToFiles = false;
|
||||
isFileSearching = false;
|
||||
fileSearchType = "all";
|
||||
fileSearchExt = "";
|
||||
fileSearchFolder = "";
|
||||
fileSearchSort = "score";
|
||||
sections = [];
|
||||
flatModel = [];
|
||||
selectedFlatIndex = 0;
|
||||
@@ -408,34 +399,6 @@ Item {
|
||||
performSearch();
|
||||
}
|
||||
|
||||
function setFileSearchType(type) {
|
||||
if (fileSearchType === type)
|
||||
return;
|
||||
fileSearchType = type;
|
||||
performFileSearch();
|
||||
}
|
||||
|
||||
function setFileSearchExt(ext) {
|
||||
if (fileSearchExt === ext)
|
||||
return;
|
||||
fileSearchExt = ext;
|
||||
performFileSearch();
|
||||
}
|
||||
|
||||
function setFileSearchFolder(folder) {
|
||||
if (fileSearchFolder === folder)
|
||||
return;
|
||||
fileSearchFolder = folder;
|
||||
performFileSearch();
|
||||
}
|
||||
|
||||
function setFileSearchSort(sort) {
|
||||
if (fileSearchSort === sort)
|
||||
return;
|
||||
fileSearchSort = sort;
|
||||
performFileSearch();
|
||||
}
|
||||
|
||||
function clearPluginFilter() {
|
||||
if (pluginFilter) {
|
||||
pluginFilter = "";
|
||||
@@ -864,20 +827,10 @@ Item {
|
||||
var params = {
|
||||
limit: 20,
|
||||
fuzzy: true,
|
||||
sort: fileSearchSort || "score",
|
||||
sort: "score",
|
||||
desc: true
|
||||
};
|
||||
|
||||
if (DSearchService.supportsTypeFilter) {
|
||||
params.type = (fileSearchType && fileSearchType !== "all") ? fileSearchType : "all";
|
||||
}
|
||||
if (fileSearchExt) {
|
||||
params.ext = fileSearchExt;
|
||||
}
|
||||
if (fileSearchFolder) {
|
||||
params.folder = fileSearchFolder;
|
||||
}
|
||||
|
||||
DSearchService.search(fileQuery, params, function (response) {
|
||||
isFileSearching = false;
|
||||
if (response.error)
|
||||
@@ -887,73 +840,34 @@ Item {
|
||||
|
||||
for (var i = 0; i < hits.length; i++) {
|
||||
var hit = hits[i];
|
||||
var docTypes = hit.locations?.doc_type;
|
||||
var isDir = docTypes ? !!docTypes["dir"] : false;
|
||||
fileItems.push(transformFileResult({
|
||||
path: hit.id || "",
|
||||
score: hit.score || 0,
|
||||
is_dir: isDir
|
||||
score: hit.score || 0
|
||||
}));
|
||||
}
|
||||
|
||||
var fileSections = [];
|
||||
var showType = fileSearchType || "all";
|
||||
|
||||
if (showType === "all" && DSearchService.supportsTypeFilter) {
|
||||
var onlyFiles = [];
|
||||
var onlyDirs = [];
|
||||
for (var j = 0; j < fileItems.length; j++) {
|
||||
if (fileItems[j].data?.is_dir)
|
||||
onlyDirs.push(fileItems[j]);
|
||||
else
|
||||
onlyFiles.push(fileItems[j]);
|
||||
}
|
||||
if (onlyFiles.length > 0) {
|
||||
fileSections.push({
|
||||
id: "files",
|
||||
title: I18n.tr("Files"),
|
||||
icon: "insert_drive_file",
|
||||
priority: 4,
|
||||
items: onlyFiles,
|
||||
collapsed: collapsedSections["files"] || false,
|
||||
flatStartIndex: 0
|
||||
});
|
||||
}
|
||||
if (onlyDirs.length > 0) {
|
||||
fileSections.push({
|
||||
id: "folders",
|
||||
title: I18n.tr("Folders"),
|
||||
icon: "folder",
|
||||
priority: 4.1,
|
||||
items: onlyDirs,
|
||||
collapsed: collapsedSections["folders"] || false,
|
||||
flatStartIndex: 0
|
||||
});
|
||||
}
|
||||
} else {
|
||||
var filesIcon = showType === "dir" ? "folder" : showType === "file" ? "insert_drive_file" : "folder";
|
||||
var filesTitle = showType === "dir" ? I18n.tr("Folders") : I18n.tr("Files");
|
||||
if (fileItems.length > 0) {
|
||||
fileSections.push({
|
||||
id: "files",
|
||||
title: filesTitle,
|
||||
icon: filesIcon,
|
||||
priority: 4,
|
||||
items: fileItems,
|
||||
collapsed: collapsedSections["files"] || false,
|
||||
flatStartIndex: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
var fileSection = {
|
||||
id: "files",
|
||||
title: I18n.tr("Files"),
|
||||
icon: "folder",
|
||||
priority: 4,
|
||||
items: fileItems,
|
||||
collapsed: collapsedSections["files"] || false,
|
||||
flatStartIndex: 0
|
||||
};
|
||||
|
||||
var newSections;
|
||||
if (searchMode === "files") {
|
||||
newSections = fileSections;
|
||||
newSections = fileItems.length > 0 ? [fileSection] : [];
|
||||
} else {
|
||||
var existingNonFile = sections.filter(function (s) {
|
||||
return s.id !== "files" && s.id !== "folders";
|
||||
return s.id !== "files";
|
||||
});
|
||||
newSections = existingNonFile.concat(fileSections);
|
||||
if (fileItems.length > 0) {
|
||||
newSections = existingNonFile.concat([fileSection]);
|
||||
} else {
|
||||
newSections = existingNonFile;
|
||||
}
|
||||
}
|
||||
newSections.sort(function (a, b) {
|
||||
return a.priority - b.priority;
|
||||
@@ -999,7 +913,7 @@ Item {
|
||||
}
|
||||
|
||||
function transformFileResult(file) {
|
||||
return Transform.transformFileResult(file, I18n.tr("Open"), I18n.tr("Open folder"), I18n.tr("Copy path"), I18n.tr("Open in terminal"));
|
||||
return Transform.transformFileResult(file, I18n.tr("Open"), I18n.tr("Open folder"), I18n.tr("Copy path"));
|
||||
}
|
||||
|
||||
function detectTrigger(query) {
|
||||
@@ -1667,9 +1581,6 @@ Item {
|
||||
case "copy_path":
|
||||
copyToClipboard(item.data.path);
|
||||
break;
|
||||
case "open_terminal":
|
||||
openTerminal(item.data.path);
|
||||
break;
|
||||
case "copy":
|
||||
copyToClipboard(item.name);
|
||||
break;
|
||||
@@ -1751,16 +1662,6 @@ Item {
|
||||
Qt.openUrlExternally("file://" + folder);
|
||||
}
|
||||
|
||||
function openTerminal(path) {
|
||||
if (!path)
|
||||
return;
|
||||
var terminal = Quickshell.env("TERMINAL") || "xterm";
|
||||
Quickshell.execDetached({
|
||||
command: [terminal],
|
||||
workingDirectory: path
|
||||
});
|
||||
}
|
||||
|
||||
function copyToClipboard(text) {
|
||||
if (!text)
|
||||
return;
|
||||
|
||||
@@ -107,10 +107,6 @@ Item {
|
||||
spotlightContent.controller.activePluginId = "";
|
||||
spotlightContent.controller.activePluginName = "";
|
||||
spotlightContent.controller.pluginFilter = "";
|
||||
spotlightContent.controller.fileSearchType = "all";
|
||||
spotlightContent.controller.fileSearchExt = "";
|
||||
spotlightContent.controller.fileSearchFolder = "";
|
||||
spotlightContent.controller.fileSearchSort = "score";
|
||||
spotlightContent.controller.collapsedSections = {};
|
||||
spotlightContent.controller.selectedFlatIndex = 0;
|
||||
spotlightContent.controller.selectedItem = null;
|
||||
|
||||
@@ -116,43 +116,31 @@ function transformBuiltInLauncherItem(item, pluginId, openLabel) {
|
||||
};
|
||||
}
|
||||
|
||||
function transformFileResult(file, openLabel, openFolderLabel, copyPathLabel, openTerminalLabel) {
|
||||
function transformFileResult(file, openLabel, openFolderLabel, copyPathLabel) {
|
||||
var filename = file.path ? file.path.split("/").pop() : "";
|
||||
var dirname = file.path ? file.path.substring(0, file.path.lastIndexOf("/")) : "";
|
||||
var isDir = file.is_dir || false;
|
||||
|
||||
var actions = [];
|
||||
if (isDir) {
|
||||
if (openTerminalLabel) {
|
||||
actions.push({
|
||||
name: openTerminalLabel,
|
||||
icon: "terminal",
|
||||
action: "open_terminal"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
actions.push({
|
||||
name: openFolderLabel,
|
||||
icon: "folder_open",
|
||||
action: "open_folder"
|
||||
});
|
||||
}
|
||||
actions.push({
|
||||
name: copyPathLabel,
|
||||
icon: "content_copy",
|
||||
action: "copy_path"
|
||||
});
|
||||
|
||||
return {
|
||||
id: file.path || "",
|
||||
type: "file",
|
||||
name: filename,
|
||||
subtitle: dirname,
|
||||
icon: isDir ? "folder" : Utils.getFileIcon(filename),
|
||||
icon: Utils.getFileIcon(filename),
|
||||
iconType: "material",
|
||||
section: "files",
|
||||
data: file,
|
||||
actions: actions,
|
||||
actions: [
|
||||
{
|
||||
name: openFolderLabel,
|
||||
icon: "folder_open",
|
||||
action: "open_folder"
|
||||
},
|
||||
{
|
||||
name: copyPathLabel,
|
||||
icon: "content_copy",
|
||||
action: "copy_path"
|
||||
}
|
||||
],
|
||||
primaryAction: {
|
||||
name: openLabel,
|
||||
icon: "open_in_new",
|
||||
|
||||
@@ -549,151 +549,8 @@ FocusScope {
|
||||
}
|
||||
|
||||
Item {
|
||||
id: fileFilterRow
|
||||
width: parent.width
|
||||
height: showFileFilters ? fileFilterContent.height : 0
|
||||
visible: showFileFilters
|
||||
|
||||
readonly property bool showFileFilters: controller.searchMode === "files"
|
||||
|
||||
Behavior on height {
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: fileFilterContent
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Row {
|
||||
id: typeChips
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 2
|
||||
visible: DSearchService.supportsTypeFilter
|
||||
|
||||
Repeater {
|
||||
model: [
|
||||
{
|
||||
id: "all",
|
||||
label: I18n.tr("All"),
|
||||
icon: "search"
|
||||
},
|
||||
{
|
||||
id: "file",
|
||||
label: I18n.tr("Files"),
|
||||
icon: "insert_drive_file"
|
||||
},
|
||||
{
|
||||
id: "dir",
|
||||
label: I18n.tr("Folders"),
|
||||
icon: "folder"
|
||||
}
|
||||
]
|
||||
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
width: chipContent.width + Theme.spacingM * 2
|
||||
height: sortDropdown.height
|
||||
radius: Theme.cornerRadius
|
||||
color: controller.fileSearchType === modelData.id || chipArea.containsMouse ? Theme.primaryContainer : "transparent"
|
||||
|
||||
Row {
|
||||
id: chipContent
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
DankIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: modelData.icon
|
||||
size: 14
|
||||
color: controller.fileSearchType === modelData.id ? Theme.primary : Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: modelData.label
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: controller.fileSearchType === modelData.id ? Theme.primary : Theme.surfaceText
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: chipArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: controller.setFileSearchType(modelData.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: 20
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.outlineMedium
|
||||
visible: typeChips.visible
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
id: sortDropdown
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Math.min(130, parent.width / 3)
|
||||
compactMode: true
|
||||
dropdownWidth: 130
|
||||
popupWidth: 150
|
||||
maxPopupHeight: 200
|
||||
currentValue: {
|
||||
switch (controller.fileSearchSort) {
|
||||
case "score":
|
||||
return I18n.tr("Score");
|
||||
case "name":
|
||||
return I18n.tr("Name");
|
||||
case "modified":
|
||||
return I18n.tr("Modified");
|
||||
case "size":
|
||||
return I18n.tr("Size");
|
||||
default:
|
||||
return I18n.tr("Score");
|
||||
}
|
||||
}
|
||||
options: [I18n.tr("Score"), I18n.tr("Name"), I18n.tr("Modified"), I18n.tr("Size")]
|
||||
|
||||
onValueChanged: value => {
|
||||
var sortMap = {};
|
||||
sortMap[I18n.tr("Score")] = "score";
|
||||
sortMap[I18n.tr("Name")] = "name";
|
||||
sortMap[I18n.tr("Modified")] = "modified";
|
||||
sortMap[I18n.tr("Size")] = "size";
|
||||
controller.setFileSearchSort(sortMap[value] || "score");
|
||||
}
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
id: extFilterField
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Math.min(100, parent.width / 4)
|
||||
height: sortDropdown.height
|
||||
placeholderText: I18n.tr("ext")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
showClearButton: text.length > 0
|
||||
|
||||
onTextChanged: {
|
||||
controller.setFileSearchExt(text.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: parent.height - searchField.height - categoryRow.height - fileFilterRow.height - actionPanel.height - Theme.spacingXS * ((categoryRow.visible ? 1 : 0) + (fileFilterRow.visible ? 1 : 0) + 2)
|
||||
height: parent.height - searchField.height - categoryRow.height - actionPanel.height - Theme.spacingXS * (categoryRow.visible ? 3 : 2)
|
||||
opacity: root.parentModal?.isClosing ? 0 : 1
|
||||
|
||||
ResultsList {
|
||||
@@ -729,9 +586,6 @@ FocusScope {
|
||||
function onSearchQueryRequested(query) {
|
||||
searchField.text = query;
|
||||
}
|
||||
function onModeChanged() {
|
||||
extFilterField.text = "";
|
||||
}
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
|
||||
@@ -113,7 +113,6 @@ Rectangle {
|
||||
font.family: Theme.fontFamily
|
||||
color: Theme.surfaceVariantText
|
||||
elide: Text.ElideRight
|
||||
clip: true
|
||||
visible: (root.item?.subtitle ?? "").length > 0
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
@@ -182,7 +181,7 @@ Rectangle {
|
||||
case "plugin":
|
||||
return I18n.tr("Plugin");
|
||||
case "file":
|
||||
return root.item.data?.is_dir ? I18n.tr("Folder") : I18n.tr("File");
|
||||
return I18n.tr("File");
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -435,15 +435,7 @@ Item {
|
||||
var mode = root.controller?.searchMode ?? "all";
|
||||
switch (mode) {
|
||||
case "files":
|
||||
var fileType = root.controller?.fileSearchType ?? "all";
|
||||
switch (fileType) {
|
||||
case "dir":
|
||||
return "folder_open";
|
||||
case "file":
|
||||
return "insert_drive_file";
|
||||
default:
|
||||
return "folder_open";
|
||||
}
|
||||
return "folder_open";
|
||||
case "plugins":
|
||||
return "extension";
|
||||
case "apps":
|
||||
@@ -473,15 +465,7 @@ Item {
|
||||
return I18n.tr("Type to search files");
|
||||
if (root.controller.searchQuery.length < 2)
|
||||
return I18n.tr("Type at least 2 characters");
|
||||
var fileType = root.controller?.fileSearchType ?? "all";
|
||||
switch (fileType) {
|
||||
case "dir":
|
||||
return I18n.tr("No folders found");
|
||||
case "file":
|
||||
return I18n.tr("No files found");
|
||||
default:
|
||||
return I18n.tr("No results found");
|
||||
}
|
||||
return I18n.tr("No files found");
|
||||
case "plugins":
|
||||
return hasQuery ? I18n.tr("No plugin results") : I18n.tr("Browse or search plugins");
|
||||
case "apps":
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Effects
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Modals.Common
|
||||
import qs.Modals.FileBrowser
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
DankModal {
|
||||
id: root
|
||||
visible: false
|
||||
layerNamespace: "dms:wifi-qrcode"
|
||||
|
||||
property bool disablePopupTransparency: true
|
||||
property string wifiSSID: ""
|
||||
property string themedQrCodePath: ""
|
||||
property string normalQrCodePath: ""
|
||||
modalWidth: 420
|
||||
modalHeight: 480
|
||||
onBackgroundClicked: hide()
|
||||
onOpened: {
|
||||
Qt.callLater(() => {
|
||||
modalFocusScope.forceActiveFocus();
|
||||
contentLoader.item.wifiSSID = wifiSSID;
|
||||
contentLoader.item.themedQrCodePath = themedQrCodePath;
|
||||
contentLoader.item.saveBrowserLoader = saveBrowserLoader;
|
||||
});
|
||||
}
|
||||
|
||||
function show(ssid) {
|
||||
wifiSSID = ssid;
|
||||
fetchNetworkQRCode(ssid);
|
||||
}
|
||||
|
||||
function hide() {
|
||||
if (themedQrCodePath !== "") {
|
||||
deleteQRCodeFile(themedQrCodePath);
|
||||
}
|
||||
if (normalQrCodePath !== "") {
|
||||
deleteQRCodeFile(normalQrCodePath);
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
function fetchNetworkQRCode(ssid) {
|
||||
// TODO: Add loading UI?
|
||||
|
||||
DMSService.sendRequest("network.qrcode", {
|
||||
ssid: ssid
|
||||
}, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError("Failed to fetch network QR code: ", JSON.stringify(response.error));
|
||||
} else if (response.result) {
|
||||
themedQrCodePath = response.result[0];
|
||||
normalQrCodePath = response.result[1];
|
||||
open();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteQRCodeFile(path) {
|
||||
DMSService.sendRequest("network.delete-qrcode", {
|
||||
path: path
|
||||
}, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError(`Failed to remove QR code at ${path}: `, JSON.stringify(response.error));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: saveBrowserLoader
|
||||
active: false
|
||||
|
||||
FileBrowserSurfaceModal {
|
||||
id: saveBrowser
|
||||
|
||||
browserTitle: I18n.tr("Save QR Code")
|
||||
browserIcon: "qr_code"
|
||||
browserType: "default"
|
||||
fileExtensions: ["*.png"]
|
||||
allowStacking: true
|
||||
saveMode: true
|
||||
defaultFileName: `${root.wifiSSID ?? "wifi-qrcode"}.png`
|
||||
onFileSelected: path => {
|
||||
const cleanPath = decodeURI(path.toString().replace(/^file:\/\//, ''));
|
||||
const fileName = cleanPath.split('/').pop();
|
||||
const fileUrl = "file://" + cleanPath;
|
||||
|
||||
copyQrCodeProcess.exec(["cp", root.normalQrCodePath, cleanPath, "-f"])
|
||||
}
|
||||
|
||||
Process {
|
||||
id: copyQrCodeProcess
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
saveBrowser.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
content: Component {
|
||||
Item {
|
||||
id: theItem
|
||||
property alias themedQrCodePath: qrCodeImg.source
|
||||
property var saveBrowserLoader: null
|
||||
property string wifiSSID: ""
|
||||
anchors.fill: parent
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingL
|
||||
|
||||
RowLayout {
|
||||
id: modalTitle
|
||||
width: parent.width
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("WiFi QR code for ") + theItem.wifiSSID
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Bold
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
iconName: "save"
|
||||
iconSize: Theme.iconSize - 4
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: {
|
||||
saveBrowserLoader.active = true;
|
||||
if (saveBrowserLoader.item) {
|
||||
saveBrowserLoader.item.open();
|
||||
}
|
||||
}
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
iconName: "close"
|
||||
iconSize: Theme.iconSize - 4
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: root.hide()
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: qrCodeImg
|
||||
height: parent.height - parent.spacing - modalTitle.height
|
||||
width: height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
MultiEffect {
|
||||
source: qrCodeImg
|
||||
anchors.fill: source
|
||||
colorization: 1.0
|
||||
colorizationColor: Theme.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,7 +651,6 @@ Rectangle {
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: pinButton
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: optionsButton.width + Theme.spacingM + Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -712,19 +711,6 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: qrCodeButton
|
||||
visible: modelData.secured && modelData.saved
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: optionsButton.width + pinWifiRow.width + 3 * Theme.spacingM + Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconName: "qr_code"
|
||||
buttonSize: 28
|
||||
onClicked: {
|
||||
PopoutService.showWifiQRCodeModal(modelData.ssid);
|
||||
}
|
||||
}
|
||||
|
||||
DankRipple {
|
||||
id: wifiRipple
|
||||
cornerRadius: parent.radius
|
||||
@@ -733,7 +719,7 @@ Rectangle {
|
||||
MouseArea {
|
||||
id: networkMouseArea
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: optionsButton.width + pinWifiRow.width + (qrCodeButton.visible ? qrCodeButton.width : 0) + Theme.spacingS * 5 + Theme.spacingM
|
||||
anchors.rightMargin: optionsButton.width + Theme.spacingM + Theme.spacingS + pinWifiRow.width + Theme.spacingS * 4
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onPressed: mouse => wifiRipple.trigger(mouse.x, mouse.y)
|
||||
|
||||
@@ -624,7 +624,7 @@ PanelWindow {
|
||||
Item {
|
||||
id: topBarCore
|
||||
anchors.fill: parent
|
||||
layer.enabled: false
|
||||
layer.enabled: true
|
||||
|
||||
property bool autoHide: barConfig?.autoHide ?? false
|
||||
property bool revealSticky: false
|
||||
|
||||
@@ -167,22 +167,9 @@ DankPopout {
|
||||
}
|
||||
|
||||
Column {
|
||||
id: headerInfoColumn
|
||||
spacing: Theme.spacingXS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width - Theme.iconSizeLarge - 32 - Theme.spacingM * 2
|
||||
readonly property string timeInfoText: {
|
||||
if (!BatteryService.batteryAvailable)
|
||||
return "Power profile management available";
|
||||
const time = BatteryService.formatTimeRemaining();
|
||||
if (time !== "Unknown") {
|
||||
return BatteryService.isCharging ? `Time until full: ${time}` : `Time remaining: ${time}`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
readonly property bool showPowerRate: BatteryService.batteryAvailable && Math.abs(BatteryService.changeRate) > 0.05
|
||||
readonly property bool isOnAC: BatteryService.batteryAvailable && (BatteryService.isCharging || BatteryService.isPluggedIn)
|
||||
readonly property bool isDischarging: BatteryService.batteryAvailable && !BatteryService.isCharging && !BatteryService.isPluggedIn
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
@@ -220,35 +207,21 @@ DankPopout {
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
visible: headerInfoColumn.timeInfoText.length > 0
|
||||
|
||||
StyledText {
|
||||
id: powerRateText
|
||||
text: `${headerInfoColumn.isOnAC ? "+" : (headerInfoColumn.isDischarging ? "-" : "")}${Math.abs(BatteryService.changeRate).toFixed(1)}W`
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: {
|
||||
if (headerInfoColumn.isOnAC) {
|
||||
return Theme.primary;
|
||||
}
|
||||
if (headerInfoColumn.isDischarging) {
|
||||
return Theme.warning;
|
||||
}
|
||||
return Theme.surfaceTextMedium;
|
||||
StyledText {
|
||||
text: {
|
||||
if (!BatteryService.batteryAvailable)
|
||||
return "Power profile management available";
|
||||
const time = BatteryService.formatTimeRemaining();
|
||||
if (time !== "Unknown") {
|
||||
return BatteryService.isCharging ? `Time until full: ${time}` : `Time remaining: ${time}`;
|
||||
}
|
||||
font.weight: Font.Medium
|
||||
visible: headerInfoColumn.showPowerRate
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: headerInfoColumn.timeInfoText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
elide: Text.ElideRight
|
||||
width: parent.width - (powerRateText.visible ? (powerRateText.implicitWidth + parent.spacing) : 0)
|
||||
return "";
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
visible: text.length > 0
|
||||
elide: Text.ElideRight
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,21 +29,12 @@ Loader {
|
||||
|
||||
readonly property bool orientationMatches: (axis?.isVertical ?? false) === isInColumn
|
||||
|
||||
readonly property bool widgetEnabled: widgetData?.enabled !== false
|
||||
|
||||
active: orientationMatches && getWidgetVisible(widgetId, DgopService.dgopAvailable) && (widgetId !== "music" || MprisController.activePlayer !== null)
|
||||
sourceComponent: getWidgetComponent(widgetId, components)
|
||||
opacity: getWidgetEnabled(widgetData?.enabled) ? 1 : 0
|
||||
|
||||
signal contentItemReady(var item)
|
||||
|
||||
Binding {
|
||||
target: root.item
|
||||
when: root.item && !root.widgetEnabled
|
||||
property: "visible"
|
||||
value: false
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: root.item
|
||||
when: root.item && "parentScreen" in root.item
|
||||
@@ -278,4 +269,8 @@ Loader {
|
||||
|
||||
return widgetVisibility[widgetId] ?? true;
|
||||
}
|
||||
|
||||
function getWidgetEnabled(enabled) {
|
||||
return enabled !== false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ BasePill {
|
||||
|
||||
property var widgetData: null
|
||||
property string mountPath: (widgetData && widgetData.mountPath !== undefined) ? widgetData.mountPath : "/"
|
||||
property int diskUsageMode: (widgetData && widgetData.diskUsageMode !== undefined) ? widgetData.diskUsageMode : 0
|
||||
property bool isHovered: mouseArea.containsMouse
|
||||
property bool isAutoHideBar: false
|
||||
|
||||
@@ -131,13 +130,7 @@ BasePill {
|
||||
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
|
||||
return "--";
|
||||
}
|
||||
if (!root.selectedMount) return "--";
|
||||
switch (root.diskUsageMode) {
|
||||
case 1: return root.selectedMount.size || "--";
|
||||
case 2: return root.selectedMount.avail || "--";
|
||||
case 3: return (root.selectedMount.avail || "--") + " / " + (root.selectedMount.size || "--");
|
||||
default: return root.diskUsagePercent.toFixed(0);
|
||||
}
|
||||
return root.diskUsagePercent.toFixed(0);
|
||||
}
|
||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText)
|
||||
color: Theme.widgetTextColor
|
||||
@@ -185,13 +178,7 @@ BasePill {
|
||||
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
|
||||
return "--%";
|
||||
}
|
||||
if (!root.selectedMount) return "--%";
|
||||
switch (root.diskUsageMode) {
|
||||
case 1: return root.selectedMount.size || "--";
|
||||
case 2: return root.selectedMount.avail || "--";
|
||||
case 3: return (root.selectedMount.avail || "--") + " / " + (root.selectedMount.size || "--");
|
||||
default: return root.diskUsagePercent.toFixed(0) + "%";
|
||||
}
|
||||
return root.diskUsagePercent.toFixed(0) + "%";
|
||||
}
|
||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText)
|
||||
color: Theme.widgetTextColor
|
||||
@@ -202,14 +189,7 @@ BasePill {
|
||||
StyledTextMetrics {
|
||||
id: diskBaseline
|
||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText)
|
||||
text: {
|
||||
switch (root.diskUsageMode) {
|
||||
case 3: return "888.8G / 888.8G";
|
||||
case 1:
|
||||
case 2: return "888.8G";
|
||||
default: return "100%";
|
||||
}
|
||||
}
|
||||
text: "100%"
|
||||
}
|
||||
|
||||
width: Math.max(diskBaseline.width, paintedWidth)
|
||||
|
||||
@@ -14,7 +14,6 @@ BasePill {
|
||||
property var widgetData: null
|
||||
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
|
||||
property bool showSwap: (widgetData && widgetData.showSwap !== undefined) ? widgetData.showSwap : false
|
||||
property bool showInGb: (widgetData && widgetData.showInGb !== undefined) ? widgetData.showInGb : false
|
||||
readonly property real swapUsage: DgopService.totalSwapKB > 0 ? (DgopService.usedSwapKB / DgopService.totalSwapKB) * 100 : 0
|
||||
|
||||
signal ramClicked
|
||||
@@ -60,10 +59,6 @@ BasePill {
|
||||
return "--";
|
||||
}
|
||||
|
||||
if (root.showInGb) {
|
||||
return (DgopService.usedMemoryMB / 1024).toFixed(1);
|
||||
}
|
||||
|
||||
return DgopService.memoryUsage.toFixed(0);
|
||||
}
|
||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText)
|
||||
@@ -118,14 +113,13 @@ BasePill {
|
||||
id: ramBaseline
|
||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText)
|
||||
text: {
|
||||
let baseText = root.showInGb ? "88.8 GB" : "88%";
|
||||
if (!root.showSwap) {
|
||||
return baseText;
|
||||
return "88%";
|
||||
}
|
||||
if (root.swapUsage < 10) {
|
||||
return baseText + " · 0%";
|
||||
return "88% · 0%";
|
||||
}
|
||||
return baseText + " · 88%";
|
||||
return "88% · 88%";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,16 +127,10 @@ BasePill {
|
||||
id: ramText
|
||||
text: {
|
||||
if (DgopService.memoryUsage === undefined || DgopService.memoryUsage === null || DgopService.memoryUsage === 0) {
|
||||
return root.showInGb ? "-- GB" : "--%";
|
||||
}
|
||||
|
||||
let ramText = "";
|
||||
if (root.showInGb) {
|
||||
ramText = (DgopService.usedMemoryMB / 1024).toFixed(1) + " GB";
|
||||
} else {
|
||||
ramText = DgopService.memoryUsage.toFixed(0) + "%";
|
||||
return "--%";
|
||||
}
|
||||
|
||||
let ramText = DgopService.memoryUsage.toFixed(0) + "%";
|
||||
if (root.showSwap && DgopService.totalSwapKB > 0) {
|
||||
return ramText + " · " + root.swapUsage.toFixed(0) + "%";
|
||||
}
|
||||
|
||||
@@ -41,11 +41,6 @@ Singleton {
|
||||
property string lockDateFormat: ""
|
||||
property bool lockScreenShowPowerActions: true
|
||||
property bool lockScreenShowProfileImage: true
|
||||
property bool powerActionConfirm: true
|
||||
property real powerActionHoldDuration: 0.5
|
||||
property var powerMenuActions: ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]
|
||||
property string powerMenuDefaultAction: "logout"
|
||||
property bool powerMenuGridLayout: false
|
||||
property var screenPreferences: ({})
|
||||
property int animationSpeed: 2
|
||||
property string wallpaperFillMode: "Fill"
|
||||
@@ -80,11 +75,6 @@ Singleton {
|
||||
lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : "";
|
||||
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true;
|
||||
lockScreenShowProfileImage = settings.lockScreenShowProfileImage !== undefined ? settings.lockScreenShowProfileImage : true;
|
||||
powerActionConfirm = settings.powerActionConfirm !== undefined ? settings.powerActionConfirm : true;
|
||||
powerActionHoldDuration = settings.powerActionHoldDuration !== undefined ? settings.powerActionHoldDuration : 0.5;
|
||||
powerMenuActions = settings.powerMenuActions !== undefined ? settings.powerMenuActions : ["reboot", "logout", "poweroff", "lock", "suspend", "restart"];
|
||||
powerMenuDefaultAction = settings.powerMenuDefaultAction !== undefined ? settings.powerMenuDefaultAction : "logout";
|
||||
powerMenuGridLayout = settings.powerMenuGridLayout !== undefined ? settings.powerMenuGridLayout : false;
|
||||
screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({});
|
||||
animationSpeed = settings.animationSpeed !== undefined ? settings.animationSpeed : 2;
|
||||
wallpaperFillMode = settings.wallpaperFillMode !== undefined ? settings.wallpaperFillMode : "Fill";
|
||||
|
||||
@@ -1231,12 +1231,6 @@ Item {
|
||||
LockPowerMenu {
|
||||
id: powerMenu
|
||||
showLogout: false
|
||||
powerActionConfirmOverride: GreetdSettings.powerActionConfirm
|
||||
powerActionHoldDurationOverride: GreetdSettings.powerActionHoldDuration
|
||||
powerMenuActionsOverride: GreetdSettings.powerMenuActions
|
||||
powerMenuDefaultActionOverride: GreetdSettings.powerMenuDefaultAction
|
||||
powerMenuGridLayoutOverride: GreetdSettings.powerMenuGridLayout
|
||||
requiredActions: ["poweroff"]
|
||||
onClosed: {
|
||||
if (isPrimaryScreen && inputField && inputField.forceActiveFocus) {
|
||||
Qt.callLater(() => inputField.forceActiveFocus());
|
||||
|
||||
@@ -24,20 +24,13 @@ Rectangle {
|
||||
property real holdProgress: 0
|
||||
property bool showHoldHint: false
|
||||
|
||||
property var powerActionConfirmOverride: undefined
|
||||
property var powerActionHoldDurationOverride: undefined
|
||||
property var powerMenuActionsOverride: undefined
|
||||
property var powerMenuDefaultActionOverride: undefined
|
||||
property var powerMenuGridLayoutOverride: undefined
|
||||
property var requiredActions: []
|
||||
|
||||
readonly property bool needsConfirmation: powerActionConfirmOverride !== undefined ? powerActionConfirmOverride : SettingsData.powerActionConfirm
|
||||
readonly property int holdDurationMs: (powerActionHoldDurationOverride !== undefined ? powerActionHoldDurationOverride : SettingsData.powerActionHoldDuration) * 1000
|
||||
readonly property bool needsConfirmation: SettingsData.powerActionConfirm
|
||||
readonly property int holdDurationMs: SettingsData.powerActionHoldDuration * 1000
|
||||
|
||||
signal closed
|
||||
|
||||
function updateVisibleActions() {
|
||||
const allActions = powerMenuActionsOverride !== undefined ? powerMenuActionsOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuActions) ? SettingsData.powerMenuActions : ["logout", "suspend", "hibernate", "reboot", "poweroff"]);
|
||||
const allActions = (typeof SettingsData !== "undefined" && SettingsData.powerMenuActions) ? SettingsData.powerMenuActions : ["logout", "suspend", "hibernate", "reboot", "poweroff"];
|
||||
const hibernateSupported = (typeof SessionService !== "undefined" && SessionService.hibernateSupported) || false;
|
||||
let filtered = allActions.filter(action => {
|
||||
if (action === "hibernate" && !hibernateSupported)
|
||||
@@ -51,14 +44,9 @@ Rectangle {
|
||||
return true;
|
||||
});
|
||||
|
||||
for (const action of requiredActions) {
|
||||
if (!filtered.includes(action))
|
||||
filtered.push(action);
|
||||
}
|
||||
|
||||
visibleActions = filtered;
|
||||
|
||||
useGridLayout = powerMenuGridLayoutOverride !== undefined ? powerMenuGridLayoutOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuGridLayout !== undefined) ? SettingsData.powerMenuGridLayout : false);
|
||||
useGridLayout = (typeof SettingsData !== "undefined" && SettingsData.powerMenuGridLayout !== undefined) ? SettingsData.powerMenuGridLayout : false;
|
||||
if (!useGridLayout)
|
||||
return;
|
||||
const count = visibleActions.length;
|
||||
@@ -85,7 +73,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
function getDefaultActionIndex() {
|
||||
const defaultAction = powerMenuDefaultActionOverride !== undefined ? powerMenuDefaultActionOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuDefaultAction) ? SettingsData.powerMenuDefaultAction : "suspend");
|
||||
const defaultAction = (typeof SettingsData !== "undefined" && SettingsData.powerMenuDefaultAction) ? SettingsData.powerMenuDefaultAction : "suspend";
|
||||
const index = visibleActions.indexOf(defaultAction);
|
||||
return index >= 0 ? index : 0;
|
||||
}
|
||||
@@ -792,9 +780,8 @@ Rectangle {
|
||||
}
|
||||
|
||||
StyledText {
|
||||
readonly property real totalMs: root.holdDurationMs
|
||||
readonly property real totalMs: SettingsData.powerActionHoldDuration * 1000
|
||||
readonly property int remainingMs: Math.ceil(totalMs * (1 - root.holdProgress))
|
||||
readonly property real durationSec: root.holdDurationMs / 1000
|
||||
text: {
|
||||
if (root.showHoldHint)
|
||||
return I18n.tr("Hold longer to confirm");
|
||||
@@ -805,7 +792,7 @@ Rectangle {
|
||||
}
|
||||
if (totalMs < 1000)
|
||||
return I18n.tr("Hold to confirm (%1 ms)").arg(totalMs);
|
||||
return I18n.tr("Hold to confirm (%1s)").arg(durationSec);
|
||||
return I18n.tr("Hold to confirm (%1s)").arg(SettingsData.powerActionHoldDuration);
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
|
||||
|
||||
@@ -351,7 +351,6 @@ Item {
|
||||
Loader {
|
||||
id: contentLoader
|
||||
anchors.fill: parent
|
||||
active: root.widgetEnabled && root.activeComponent !== null
|
||||
sourceComponent: root.activeComponent
|
||||
|
||||
function reloadComponent() {
|
||||
|
||||
@@ -1281,15 +1281,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
iconName: "qr_code"
|
||||
buttonSize: 28
|
||||
visible: modelData.secured && modelData.saved
|
||||
onClicked: {
|
||||
PopoutService.showWifiQRCodeModal(modelData.ssid);
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
iconName: isPinned ? "push_pin" : "push_pin"
|
||||
buttonSize: 28
|
||||
|
||||
@@ -216,15 +216,6 @@ Rectangle {
|
||||
onToggled: checked => root.updateConfig("showMemoryGraph", checked)
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
x: Theme.spacingM
|
||||
text: I18n.tr("Show Memory in GB")
|
||||
visible: root.cfg.showMemory
|
||||
checked: root.cfg.showInGb ?? false
|
||||
onToggled: checked => root.updateConfig("showInGb", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
DankToggle {
|
||||
|
||||
@@ -398,14 +398,10 @@ Item {
|
||||
widgetObj.runningAppsCurrentWorkspace = SettingsData.runningAppsCurrentWorkspace;
|
||||
widgetObj.runningAppsCurrentMonitor = false;
|
||||
}
|
||||
if (widgetId === "diskUsage") {
|
||||
if (widgetId === "diskUsage")
|
||||
widgetObj.mountPath = "/";
|
||||
widgetObj.diskUsageMode = 0;
|
||||
}
|
||||
if (widgetId === "cpuUsage" || widgetId === "memUsage" || widgetId === "cpuTemp" || widgetId === "gpuTemp")
|
||||
widgetObj.minimumWidth = true;
|
||||
if (widgetId === "memUsage")
|
||||
widgetObj.showInGb = false;
|
||||
|
||||
var widgets = getWidgetsForSection(targetSection).slice();
|
||||
widgets.push(widgetObj);
|
||||
@@ -429,7 +425,7 @@ Item {
|
||||
"id": widget.id,
|
||||
"enabled": widget.enabled
|
||||
};
|
||||
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"];
|
||||
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "minimumWidth", "showSwap", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (widget[keys[i]] !== undefined)
|
||||
result[keys[i]] = widget[keys[i]];
|
||||
@@ -540,30 +536,6 @@ Item {
|
||||
setWidgetsForSection(sectionId, widgets);
|
||||
}
|
||||
|
||||
function handleShowInGbChanged(sectionId, widgetIndex, enabled) {
|
||||
var widgets = getWidgetsForSection(sectionId).slice();
|
||||
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
|
||||
setWidgetsForSection(sectionId, widgets);
|
||||
return;
|
||||
}
|
||||
var newWidget = cloneWidgetData(widgets[widgetIndex]);
|
||||
newWidget.showInGb = enabled;
|
||||
widgets[widgetIndex] = newWidget;
|
||||
setWidgetsForSection(sectionId, widgets);
|
||||
}
|
||||
|
||||
function handleDiskUsageModeChanged(sectionId, widgetIndex, mode) {
|
||||
var widgets = getWidgetsForSection(sectionId).slice();
|
||||
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
|
||||
setWidgetsForSection(sectionId, widgets);
|
||||
return;
|
||||
}
|
||||
var newWidget = cloneWidgetData(widgets[widgetIndex]);
|
||||
newWidget.diskUsageMode = mode;
|
||||
widgets[widgetIndex] = newWidget;
|
||||
setWidgetsForSection(sectionId, widgets);
|
||||
}
|
||||
|
||||
function handleOverflowSettingChanged(sectionId, widgetIndex, settingName, value) {
|
||||
var widgets = getWidgetsForSection(sectionId).slice();
|
||||
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
|
||||
@@ -629,8 +601,6 @@ Item {
|
||||
item.pciId = widget.pciId;
|
||||
if (widget.mountPath !== undefined)
|
||||
item.mountPath = widget.mountPath;
|
||||
if (widget.diskUsageMode !== undefined)
|
||||
item.diskUsageMode = widget.diskUsageMode;
|
||||
if (widget.showNetworkIcon !== undefined)
|
||||
item.showNetworkIcon = widget.showNetworkIcon;
|
||||
if (widget.showBluetoothIcon !== undefined)
|
||||
@@ -659,8 +629,6 @@ Item {
|
||||
item.minimumWidth = widget.minimumWidth;
|
||||
if (widget.showSwap !== undefined)
|
||||
item.showSwap = widget.showSwap;
|
||||
if (widget.showInGb !== undefined)
|
||||
item.showInGb = widget.showInGb;
|
||||
if (widget.mediaSize !== undefined)
|
||||
item.mediaSize = widget.mediaSize;
|
||||
if (widget.clockCompactMode !== undefined)
|
||||
@@ -957,12 +925,6 @@ Item {
|
||||
onShowSwapChanged: (sectionId, index, enabled) => {
|
||||
widgetsTab.handleShowSwapChanged(sectionId, index, enabled);
|
||||
}
|
||||
onShowInGbChanged: (sectionId, index, enabled) => {
|
||||
widgetsTab.handleShowInGbChanged(sectionId, index, enabled);
|
||||
}
|
||||
onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => {
|
||||
widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode);
|
||||
}
|
||||
onCompactModeChanged: (widgetId, value) => {
|
||||
widgetsTab.handleCompactModeChanged(sectionId, widgetId, value);
|
||||
}
|
||||
@@ -1021,12 +983,6 @@ Item {
|
||||
onShowSwapChanged: (sectionId, index, enabled) => {
|
||||
widgetsTab.handleShowSwapChanged(sectionId, index, enabled);
|
||||
}
|
||||
onShowInGbChanged: (sectionId, index, enabled) => {
|
||||
widgetsTab.handleShowInGbChanged(sectionId, index, enabled);
|
||||
}
|
||||
onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => {
|
||||
widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode);
|
||||
}
|
||||
onCompactModeChanged: (widgetId, value) => {
|
||||
widgetsTab.handleCompactModeChanged(sectionId, widgetId, value);
|
||||
}
|
||||
@@ -1085,12 +1041,6 @@ Item {
|
||||
onShowSwapChanged: (sectionId, index, enabled) => {
|
||||
widgetsTab.handleShowSwapChanged(sectionId, index, enabled);
|
||||
}
|
||||
onShowInGbChanged: (sectionId, index, enabled) => {
|
||||
widgetsTab.handleShowInGbChanged(sectionId, index, enabled);
|
||||
}
|
||||
onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => {
|
||||
widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode);
|
||||
}
|
||||
onCompactModeChanged: (widgetId, value) => {
|
||||
widgetsTab.handleCompactModeChanged(sectionId, widgetId, value);
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@ Column {
|
||||
signal privacySettingChanged(string sectionId, int widgetIndex, string settingName, bool value)
|
||||
signal minimumWidthChanged(string sectionId, int widgetIndex, bool enabled)
|
||||
signal showSwapChanged(string sectionId, int widgetIndex, bool enabled)
|
||||
signal showInGbChanged(string sectionId, int widgetIndex, bool enabled)
|
||||
signal diskUsageModeChanged(string sectionId, int widgetIndex, int mode)
|
||||
signal overflowSettingChanged(string sectionId, int widgetIndex, string settingName, var value)
|
||||
|
||||
function cloneWidgetData(widget) {
|
||||
@@ -39,7 +37,7 @@ Column {
|
||||
"id": widget.id,
|
||||
"enabled": widget.enabled
|
||||
};
|
||||
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"];
|
||||
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "minimumWidth", "showSwap", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (widget[keys[i]] !== undefined)
|
||||
result[keys[i]] = widget[keys[i]];
|
||||
@@ -69,6 +67,53 @@ Column {
|
||||
color: Theme.surfaceText
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
height: 1
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Theme.spacingXS
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: root.sectionId === "center"
|
||||
|
||||
DankActionButton {
|
||||
id: indexCenterButton
|
||||
buttonSize: 28
|
||||
iconName: "format_list_numbered"
|
||||
iconSize: 16
|
||||
iconColor: SettingsData.centeringMode === "index" ? Theme.primary : Theme.outline
|
||||
onClicked: {
|
||||
console.log("Centering mode changed to: index");
|
||||
SettingsData.set("centeringMode", "index");
|
||||
}
|
||||
onEntered: {
|
||||
sharedTooltip.show("Index Centering", indexCenterButton, 0, 0, "bottom");
|
||||
}
|
||||
onExited: {
|
||||
sharedTooltip.hide();
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: geometricCenterButton
|
||||
buttonSize: 28
|
||||
iconName: "center_focus_weak"
|
||||
iconSize: 16
|
||||
iconColor: SettingsData.centeringMode === "geometric" ? Theme.primary : Theme.outline
|
||||
onClicked: {
|
||||
console.log("Centering mode changed to: geometric");
|
||||
SettingsData.set("centeringMode", "geometric");
|
||||
}
|
||||
onEntered: {
|
||||
sharedTooltip.show("Geometric Centering", geometricCenterButton, 0, 0, "bottom");
|
||||
}
|
||||
onExited: {
|
||||
sharedTooltip.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
@@ -90,7 +135,6 @@ Column {
|
||||
height: 70
|
||||
z: held ? 2 : 1
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: itemBackground
|
||||
|
||||
@@ -231,34 +275,6 @@ Column {
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: diskMenuButton
|
||||
visible: modelData.id === "diskUsage"
|
||||
buttonSize: 32
|
||||
iconName: "more_vert"
|
||||
iconSize: 18
|
||||
iconColor: Theme.outline
|
||||
onClicked: {
|
||||
diskUsageContextMenu.widgetData = modelData;
|
||||
diskUsageContextMenu.sectionId = root.sectionId;
|
||||
diskUsageContextMenu.widgetIndex = index;
|
||||
|
||||
var buttonPos = diskMenuButton.mapToItem(root, 0, 0);
|
||||
var xPos = buttonPos.x - diskUsageContextMenu.width - Theme.spacingS;
|
||||
if (xPos < 0)
|
||||
xPos = buttonPos.x + diskMenuButton.width + Theme.spacingS;
|
||||
var yPos = buttonPos.y - diskUsageContextMenu.height / 2 + diskMenuButton.height / 2;
|
||||
if (yPos < 0)
|
||||
yPos = Theme.spacingS;
|
||||
else if (yPos + diskUsageContextMenu.height > root.height)
|
||||
yPos = root.height - diskUsageContextMenu.height - Theme.spacingS;
|
||||
|
||||
diskUsageContextMenu.x = xPos;
|
||||
diskUsageContextMenu.y = yPos;
|
||||
diskUsageContextMenu.open();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 32
|
||||
height: 32
|
||||
@@ -338,36 +354,23 @@ Column {
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: memMenuButton
|
||||
id: showSwapButton
|
||||
buttonSize: 28
|
||||
visible: modelData.id === "memUsage"
|
||||
buttonSize: 32
|
||||
iconName: "more_vert"
|
||||
iconSize: 18
|
||||
iconColor: Theme.outline
|
||||
iconName: "swap_horiz"
|
||||
iconSize: 16
|
||||
iconColor: (modelData.showSwap !== undefined ? modelData.showSwap : false) ? Theme.primary : Theme.outline
|
||||
onClicked: {
|
||||
memUsageContextMenu.widgetData = modelData;
|
||||
memUsageContextMenu.sectionId = root.sectionId;
|
||||
memUsageContextMenu.widgetIndex = index;
|
||||
|
||||
var buttonPos = memMenuButton.mapToItem(root, 0, 0);
|
||||
var popupWidth = memUsageContextMenu.width;
|
||||
var popupHeight = memUsageContextMenu.height;
|
||||
|
||||
var xPos = buttonPos.x - popupWidth - Theme.spacingS;
|
||||
if (xPos < 0) {
|
||||
xPos = buttonPos.x + memMenuButton.width + Theme.spacingS;
|
||||
}
|
||||
|
||||
var yPos = buttonPos.y - popupHeight / 2 + memMenuButton.height / 2;
|
||||
if (yPos < 0) {
|
||||
yPos = Theme.spacingS;
|
||||
} else if (yPos + popupHeight > root.height) {
|
||||
yPos = root.height - popupHeight - Theme.spacingS;
|
||||
}
|
||||
|
||||
memUsageContextMenu.x = xPos;
|
||||
memUsageContextMenu.y = yPos;
|
||||
memUsageContextMenu.open();
|
||||
var currentEnabled = modelData.showSwap !== undefined ? modelData.showSwap : false;
|
||||
root.showSwapChanged(root.sectionId, index, !currentEnabled);
|
||||
}
|
||||
onEntered: {
|
||||
var currentEnabled = modelData.showSwap !== undefined ? modelData.showSwap : false;
|
||||
const tooltipText = currentEnabled ? "Hide Swap" : "Show Swap";
|
||||
sharedTooltip.show(tooltipText, showSwapButton, 0, 0, "bottom");
|
||||
}
|
||||
onExited: {
|
||||
sharedTooltip.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,257 +799,6 @@ Column {
|
||||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: memUsageContextMenu
|
||||
|
||||
property var widgetData: null
|
||||
property string sectionId: ""
|
||||
property int widgetIndex: -1
|
||||
|
||||
width: 200
|
||||
height: 80
|
||||
padding: 0
|
||||
modal: true
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
background: Rectangle {
|
||||
color: Theme.surfaceContainer
|
||||
radius: Theme.cornerRadius
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||
border.width: 0
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingS
|
||||
spacing: 2
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: swapToggleArea.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
|
||||
|
||||
DankIcon {
|
||||
name: "swap_horiz"
|
||||
size: 16
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Show Swap")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Normal
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: swapToggle
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 40
|
||||
height: 20
|
||||
checked: memUsageContextMenu.widgetData?.showSwap ?? false
|
||||
onToggled: {
|
||||
root.showSwapChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, toggled);
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: swapToggleArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onPressed: {
|
||||
swapToggle.checked = !swapToggle.checked;
|
||||
root.showSwapChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, swapToggle.checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: gbToggleArea.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
|
||||
|
||||
DankIcon {
|
||||
name: "straighten"
|
||||
size: 16
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Show in GB")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Normal
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: gbToggle
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 40
|
||||
height: 20
|
||||
checked: memUsageContextMenu.widgetData?.showInGb ?? false
|
||||
onToggled: {
|
||||
root.showInGbChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, toggled);
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: gbToggleArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onPressed: {
|
||||
gbToggle.checked = !gbToggle.checked;
|
||||
root.showInGbChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, gbToggle.checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: diskUsageContextMenu
|
||||
|
||||
property var widgetData: null
|
||||
property string sectionId: ""
|
||||
property int widgetIndex: -1
|
||||
readonly property var currentWidgetData: (widgetIndex >= 0 && widgetIndex < root.items.length) ? root.items[widgetIndex] : widgetData
|
||||
|
||||
width: 240
|
||||
height: diskMenuColumn.implicitHeight + Theme.spacingS * 2
|
||||
padding: 0
|
||||
modal: true
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
background: Rectangle {
|
||||
color: Theme.surfaceContainer
|
||||
radius: Theme.cornerRadius
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||
border.width: 0
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
Column {
|
||||
id: diskMenuColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingS
|
||||
spacing: 2
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: "transparent"
|
||||
|
||||
StyledText {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: I18n.tr("Disk Usage Display")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: [
|
||||
{ label: I18n.tr("Percentage"), mode: 0, icon: "percent" },
|
||||
{ label: I18n.tr("Total"), mode: 1, icon: "storage" },
|
||||
{ label: I18n.tr("Remaining"), mode: 2, icon: "hourglass_empty" },
|
||||
{ label: I18n.tr("Remaining / Total"), mode: 3, icon: "pie_chart" }
|
||||
]
|
||||
|
||||
delegate: Rectangle {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
width: diskMenuColumn.width
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: diskOptionArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||
|
||||
function isSelected() {
|
||||
return (diskUsageContextMenu.currentWidgetData?.diskUsageMode ?? 0) === modelData.mode;
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankIcon {
|
||||
name: modelData.icon
|
||||
size: 16
|
||||
color: isSelected() ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: modelData.label
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: isSelected() ? Theme.primary : Theme.surfaceText
|
||||
font.weight: isSelected() ? Font.Medium : Font.Normal
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: "check"
|
||||
size: 16
|
||||
color: Theme.primary
|
||||
visible: isSelected()
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: diskOptionArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.diskUsageModeChanged(diskUsageContextMenu.sectionId, diskUsageContextMenu.widgetIndex, modelData.mode);
|
||||
diskUsageContextMenu.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: controlCenterContextMenu
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Singleton {
|
||||
id: root
|
||||
|
||||
readonly property string currentVersion: "1.4"
|
||||
readonly property bool changelogEnabled: false
|
||||
readonly property bool changelogEnabled: true
|
||||
|
||||
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation)) + "/DankMaterialShell"
|
||||
readonly property string changelogMarkerPath: configDir + "/.changelog-" + currentVersion
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
@@ -11,9 +13,6 @@ Singleton {
|
||||
|
||||
property bool dsearchAvailable: false
|
||||
property int searchIdCounter: 0
|
||||
property int indexVersion: 0
|
||||
property bool supportsTypeFilter: false
|
||||
property bool versionChecked: false
|
||||
|
||||
signal searchResultsReceived(var results)
|
||||
signal statsReceived(var stats)
|
||||
@@ -27,157 +26,118 @@ Singleton {
|
||||
stdout: SplitParser {
|
||||
onRead: line => {
|
||||
if (line && line.trim().length > 0) {
|
||||
root.dsearchAvailable = true;
|
||||
root.dsearchAvailable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: exitCode => {
|
||||
if (exitCode !== 0) {
|
||||
root.dsearchAvailable = false;
|
||||
} else {
|
||||
root._checkVersion();
|
||||
root.dsearchAvailable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _checkVersion() {
|
||||
Proc.runCommand("dsearch-version", ["dsearch", "version", "--json"], (stdout, exitCode) => {
|
||||
root.versionChecked = true;
|
||||
if (exitCode !== 0)
|
||||
return;
|
||||
const response = JSON.parse(stdout);
|
||||
root.indexVersion = response.index_schema || 0;
|
||||
root.supportsTypeFilter = root.indexVersion >= 2;
|
||||
});
|
||||
}
|
||||
|
||||
function ping(callback) {
|
||||
if (!dsearchAvailable) {
|
||||
if (callback) {
|
||||
callback({
|
||||
"error": "dsearch not available"
|
||||
});
|
||||
callback({ "error": "dsearch not available" })
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
Proc.runCommand("dsearch-ping", ["dsearch", "ping", "--json"], (stdout, exitCode) => {
|
||||
if (callback) {
|
||||
if (exitCode === 0) {
|
||||
try {
|
||||
const response = JSON.parse(stdout);
|
||||
callback({
|
||||
"result": response
|
||||
});
|
||||
const response = JSON.parse(stdout)
|
||||
callback({ "result": response })
|
||||
} catch (e) {
|
||||
callback({
|
||||
"error": "failed to parse ping response"
|
||||
});
|
||||
callback({ "error": "failed to parse ping response" })
|
||||
}
|
||||
} else {
|
||||
callback({
|
||||
"error": "ping failed"
|
||||
});
|
||||
callback({ "error": "ping failed" })
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function search(query, params, callback) {
|
||||
if (!query || query.length === 0) {
|
||||
if (callback) {
|
||||
callback({
|
||||
"error": "query is required"
|
||||
});
|
||||
callback({ "error": "query is required" })
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
if (!dsearchAvailable) {
|
||||
if (callback) {
|
||||
callback({
|
||||
"error": "dsearch not available"
|
||||
});
|
||||
callback({ "error": "dsearch not available" })
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
const args = ["dsearch", "search", query, "--json"];
|
||||
const args = ["dsearch", "search", query, "--json"]
|
||||
|
||||
if (params) {
|
||||
if (params.limit !== undefined) {
|
||||
args.push("-n", String(params.limit));
|
||||
}
|
||||
if (params.type) {
|
||||
args.push("-t", params.type);
|
||||
args.push("-n", String(params.limit))
|
||||
}
|
||||
if (params.ext) {
|
||||
args.push("-e", params.ext);
|
||||
}
|
||||
if (params.folder) {
|
||||
args.push("--folder", params.folder);
|
||||
args.push("-e", params.ext)
|
||||
}
|
||||
if (params.field) {
|
||||
args.push("-f", params.field);
|
||||
args.push("-f", params.field)
|
||||
}
|
||||
if (params.fuzzy) {
|
||||
args.push("--fuzzy");
|
||||
args.push("--fuzzy")
|
||||
}
|
||||
if (params.sort) {
|
||||
args.push("--sort", params.sort);
|
||||
args.push("--sort", params.sort)
|
||||
}
|
||||
if (params.desc !== undefined) {
|
||||
args.push("--desc=" + (params.desc ? "true" : "false"));
|
||||
args.push("--desc=" + (params.desc ? "true" : "false"))
|
||||
}
|
||||
if (params.minSize !== undefined) {
|
||||
args.push("--min-size", String(params.minSize));
|
||||
args.push("--min-size", String(params.minSize))
|
||||
}
|
||||
if (params.maxSize !== undefined) {
|
||||
args.push("--max-size", String(params.maxSize));
|
||||
args.push("--max-size", String(params.maxSize))
|
||||
}
|
||||
}
|
||||
|
||||
Proc.runCommand("dsearch-search", args, (stdout, exitCode) => {
|
||||
if (exitCode === 0) {
|
||||
try {
|
||||
const response = JSON.parse(stdout);
|
||||
searchResultsReceived(response);
|
||||
const response = JSON.parse(stdout)
|
||||
searchResultsReceived(response)
|
||||
if (callback) {
|
||||
callback({
|
||||
"result": response
|
||||
});
|
||||
callback({ "result": response })
|
||||
}
|
||||
} catch (e) {
|
||||
const error = "failed to parse search response";
|
||||
errorOccurred(error);
|
||||
const error = "failed to parse search response"
|
||||
errorOccurred(error)
|
||||
if (callback) {
|
||||
callback({
|
||||
"error": error
|
||||
});
|
||||
callback({ "error": error })
|
||||
}
|
||||
}
|
||||
} else if (exitCode === 124) {
|
||||
const error = "search timed out";
|
||||
errorOccurred(error);
|
||||
const error = "search timed out"
|
||||
errorOccurred(error)
|
||||
if (callback) {
|
||||
callback({
|
||||
"error": error
|
||||
});
|
||||
callback({ "error": error })
|
||||
}
|
||||
} else {
|
||||
const error = "search failed";
|
||||
errorOccurred(error);
|
||||
const error = "search failed"
|
||||
errorOccurred(error)
|
||||
if (callback) {
|
||||
callback({
|
||||
"error": error
|
||||
});
|
||||
callback({ "error": error })
|
||||
}
|
||||
}
|
||||
}, 100, 5000);
|
||||
}, 100, 5000)
|
||||
}
|
||||
|
||||
function rediscover() {
|
||||
checkProcess.running = true;
|
||||
checkProcess.running = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ Singleton {
|
||||
property var notificationModal: null
|
||||
property var wifiPasswordModal: null
|
||||
property var wifiPasswordModalLoader: null
|
||||
property var wifiQRCodeModal: null
|
||||
property var wifiQRCodeModalLoader: null
|
||||
property var polkitAuthModal: null
|
||||
property var polkitAuthModalLoader: null
|
||||
property var bluetoothPairingModal: null
|
||||
@@ -663,13 +661,6 @@ Singleton {
|
||||
wifiPasswordModal.show(ssid);
|
||||
}
|
||||
|
||||
function showWifiQRCodeModal(ssid) {
|
||||
if (wifiQRCodeModalLoader)
|
||||
wifiQRCodeModalLoader.active = true;
|
||||
if (wifiQRCodeModal)
|
||||
wifiQRCodeModal.show(ssid);
|
||||
}
|
||||
|
||||
function showHiddenNetworkModal() {
|
||||
if (wifiPasswordModalLoader)
|
||||
wifiPasswordModalLoader.active = true;
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.5-beta
|
||||
v1.4.3
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Effects
|
||||
import qs.Common
|
||||
import qs.Widgets
|
||||
@@ -19,30 +18,9 @@ Rectangle {
|
||||
|
||||
signal imageSaved(string filePath)
|
||||
|
||||
property string _pendingSavePath: ""
|
||||
property var _attachedWindow: root.Window.window
|
||||
|
||||
on_AttachedWindowChanged: {
|
||||
if (_attachedWindow && _pendingSavePath !== "") {
|
||||
Qt.callLater(function () {
|
||||
if (root._pendingSavePath !== "") {
|
||||
let path = root._pendingSavePath;
|
||||
root._pendingSavePath = "";
|
||||
root.saveImageToFile(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function saveImageToFile(filePath) {
|
||||
if (activeImage.status !== Image.Ready)
|
||||
return false;
|
||||
|
||||
if (!activeImage.Window.window) {
|
||||
_pendingSavePath = filePath;
|
||||
return true;
|
||||
}
|
||||
|
||||
activeImage.grabToImage(function (result) {
|
||||
if (result && result.saveToFile(filePath)) {
|
||||
root.imageSaved(filePath);
|
||||
|
||||
@@ -289,7 +289,7 @@ Item {
|
||||
visible: false
|
||||
color: "transparent"
|
||||
Component.onCompleted: {
|
||||
if (typeof updatesEnabled !== "undefined" && !root.overlayContent)
|
||||
if (typeof updatesEnabled !== "undefined")
|
||||
updatesEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,10 @@ return {
|
||||
priority = 1000,
|
||||
config = function()
|
||||
require('base16-colorscheme').setup({
|
||||
|
||||
base00 = '{{colors.background.dark.hex}}',
|
||||
base01 = '{{colors.surface_container_low.dark.hex}}',
|
||||
base02 = '{{colors.surface_container.dark.hex}}',
|
||||
base03 = '{{dank16.color8.dark.hex}}',
|
||||
base0B = '{{dank16.color3.dark.hex}}',
|
||||
base00 = '{{dank16.color0.default.hex}}',
|
||||
base01 = '{{dank16.color0.default.hex}}',
|
||||
base02 = '{{dank16.color8.default.hex}}',
|
||||
base03 = '{{dank16.color8.default.hex}}',
|
||||
base04 = '{{dank16.color7.default.hex}}',
|
||||
base05 = '{{dank16.color15.default.hex}}',
|
||||
base06 = '{{dank16.color15.default.hex}}',
|
||||
@@ -17,12 +15,65 @@ return {
|
||||
base08 = '{{dank16.color9.default.hex}}',
|
||||
base09 = '{{dank16.color9.default.hex}}',
|
||||
base0A = '{{dank16.color12.default.hex}}',
|
||||
base0B = '{{dank16.color10.default.hex}}',
|
||||
base0C = '{{dank16.color14.default.hex}}',
|
||||
base0D = '{{dank16.color12.default.hex}}',
|
||||
base0E = '{{dank16.color13.default.hex}}',
|
||||
base0F = '{{dank16.color13.default.hex}}',
|
||||
})
|
||||
|
||||
vim.api.nvim_set_hl(0, 'Visual', {
|
||||
bg = '{{dank16.color8.default.hex}}',
|
||||
fg = '{{dank16.color15.default.hex}}',
|
||||
bold = true
|
||||
})
|
||||
vim.api.nvim_set_hl(0, 'Statusline', {
|
||||
bg = '{{dank16.color12.default.hex}}',
|
||||
fg = '{{dank16.color0.default.hex}}',
|
||||
})
|
||||
vim.api.nvim_set_hl(0, 'LineNr', { fg = '{{dank16.color8.default.hex}}' })
|
||||
vim.api.nvim_set_hl(0, 'CursorLineNr', { fg = '{{dank16.color14.default.hex}}', bold = true })
|
||||
|
||||
vim.api.nvim_set_hl(0, 'Statement', {
|
||||
fg = '{{dank16.color13.default.hex}}',
|
||||
bold = true
|
||||
})
|
||||
vim.api.nvim_set_hl(0, 'Keyword', { link = 'Statement' })
|
||||
vim.api.nvim_set_hl(0, 'Repeat', { link = 'Statement' })
|
||||
vim.api.nvim_set_hl(0, 'Conditional', { link = 'Statement' })
|
||||
|
||||
vim.api.nvim_set_hl(0, 'Function', {
|
||||
fg = '{{dank16.color12.default.hex}}',
|
||||
bold = true
|
||||
})
|
||||
vim.api.nvim_set_hl(0, 'Macro', {
|
||||
fg = '{{dank16.color12.default.hex}}',
|
||||
italic = true
|
||||
})
|
||||
vim.api.nvim_set_hl(0, '@function.macro', { link = 'Macro' })
|
||||
|
||||
vim.api.nvim_set_hl(0, 'Type', {
|
||||
fg = '{{dank16.color14.default.hex}}',
|
||||
bold = true,
|
||||
italic = true
|
||||
})
|
||||
vim.api.nvim_set_hl(0, 'Structure', { link = 'Type' })
|
||||
|
||||
vim.api.nvim_set_hl(0, 'String', {
|
||||
fg = '{{dank16.color10.default.hex}}',
|
||||
italic = true
|
||||
})
|
||||
|
||||
vim.api.nvim_set_hl(0, 'Operator', { fg = '{{dank16.color7.default.hex}}' })
|
||||
vim.api.nvim_set_hl(0, 'Delimiter', { fg = '{{dank16.color7.default.hex}}' })
|
||||
vim.api.nvim_set_hl(0, '@punctuation.bracket', { link = 'Delimiter' })
|
||||
vim.api.nvim_set_hl(0, '@punctuation.delimiter', { link = 'Delimiter' })
|
||||
|
||||
vim.api.nvim_set_hl(0, 'Comment', {
|
||||
fg = '{{dank16.color8.default.hex}}',
|
||||
italic = true
|
||||
})
|
||||
|
||||
local current_file_path = vim.fn.stdpath("config") .. "/lua/plugins/dankcolors.lua"
|
||||
if not _G._matugen_theme_watcher then
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
Reference in New Issue
Block a user