From c1fbeb3f5ea4ae4c0af9e4c4f53a19812ca1a7e5 Mon Sep 17 00:00:00 2001 From: bbedward Date: Tue, 6 Jan 2026 16:01:28 -0500 Subject: [PATCH] network: listen to NM Wired interface + use nmcli for route metrics - Some other misc floating window change, too lazy to separate the commit --- core/go.mod | 26 +-- core/go.sum | 29 ++++ core/internal/config/embedded/niri-binds.kdl | 5 - core/internal/keybinds/providers/niri.go | 10 +- core/internal/keybinds/providers/niri_test.go | 33 ++-- .../server/network/backend_networkmanager.go | 1 + .../network/backend_networkmanager_signals.go | 128 ++++++++------ .../backend_networkmanager_signals_test.go | 4 +- core/internal/server/network/priority.go | 163 ++++++++++++------ quickshell/Modals/Greeter/GreeterModal.qml | 2 +- quickshell/Modals/PolkitAuthModal.qml | 12 +- quickshell/Modals/WifiPasswordModal.qml | 29 +++- quickshell/Modules/Settings/NetworkTab.qml | 4 +- quickshell/Modules/Settings/ThemeBrowser.qml | 5 - quickshell/Services/DMSNetworkService.qml | 1 - quickshell/Widgets/FloatingWindowControls.qml | 21 +-- 16 files changed, 285 insertions(+), 188 deletions(-) diff --git a/core/go.mod b/core/go.mod index a33a2cf1..33c7962a 100644 --- a/core/go.mod +++ b/core/go.mod @@ -9,28 +9,28 @@ require ( github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/log v0.4.2 github.com/fsnotify/fsnotify v1.9.0 - github.com/godbus/dbus/v5 v5.2.0 + github.com/godbus/dbus/v5 v5.2.2 github.com/holoplot/go-evdev v0.0.0-20250804134636-ab1d56a1fe83 github.com/pilebones/go-udev v0.9.1 - github.com/sblinch/kdl-go v0.0.0-20250930225324-bf4099d4614a - github.com/spf13/cobra v1.10.1 + github.com/sblinch/kdl-go v0.0.0-20251203232544-981d4ecc17c3 + github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.11.1 go.etcd.io/bbolt v1.4.3 - golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 + golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 golang.org/x/image v0.34.0 ) require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect - github.com/clipperhouse/displaywidth v0.6.0 // indirect + github.com/clipperhouse/displaywidth v0.6.2 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.3.0 // indirect - github.com/cloudflare/circl v1.6.1 // indirect + github.com/cloudflare/circl v1.6.2 // indirect github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg/v2 v2.0.2 // indirect - github.com/go-git/go-billy/v6 v6.0.0-20251126203821-7f9c95185ee0 // indirect + github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd // indirect github.com/go-logfmt/logfmt v0.6.1 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect @@ -38,21 +38,21 @@ require ( github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/sergi/go-diff v1.4.0 // indirect github.com/stretchr/objx v0.5.3 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/net v0.48.0 // indirect ) require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/colorprofile v0.3.3 // indirect + github.com/charmbracelet/colorprofile v0.4.1 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.11.2 // indirect + github.com/charmbracelet/x/ansi v0.11.3 // indirect github.com/charmbracelet/x/cellbuf v0.0.14 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/go-git/go-git/v6 v6.0.0-20251128074608-48f817f57805 + github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19 github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 github.com/mattn/go-isatty v0.0.20 // indirect @@ -66,7 +66,7 @@ require ( github.com/spf13/afero v1.15.0 github.com/spf13/pflag v1.0.10 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/sys v0.38.0 + golang.org/x/sys v0.39.0 golang.org/x/text v0.32.0 gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/core/go.sum b/core/go.sum index 55b2e392..85f3b336 100644 --- a/core/go.sum +++ b/core/go.sum @@ -18,6 +18,8 @@ github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlv github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI= github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4= +github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= +github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= @@ -26,18 +28,24 @@ github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsy github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= github.com/charmbracelet/x/ansi v0.11.2 h1:XAG3FSjiVtFvgEgGrNBkCNNYrsucAt8c6bfxHyROLLs= github.com/charmbracelet/x/ansi v0.11.2/go.mod h1:9tY2bzX5SiJCU0iWyskjBeI2BRQfvPqI+J760Mjf+Rg= +github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI= +github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI= github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s= github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= +github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo= +github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cloudflare/circl v1.6.2 h1:hL7VBpHHKzrV5WTfHCaBsgx/HGbBYlgrwvNXEVDYYsQ= +github.com/cloudflare/circl v1.6.2/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= @@ -58,15 +66,22 @@ github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo= github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs= github.com/go-git/go-billy/v6 v6.0.0-20251126203821-7f9c95185ee0 h1:eY5aB2GXiVdgTueBcqsBt53WuJTRZAuCdIS/86Pcq5c= github.com/go-git/go-billy/v6 v6.0.0-20251126203821-7f9c95185ee0/go.mod h1:0NjwVNrwtVFZBReAp5OoGklGJIgJFEbVyHneAr4lc8k= +github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd h1:Gd/f9cGi/3h1JOPaa6er+CkKUGyGX2DBJdFbDKVO+R0= +github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd/go.mod h1:d3XQcsHu1idnquxt48kAv+h+1MUiYKLH/e7LAzjP+pI= github.com/go-git/go-git-fixtures/v5 v5.1.1 h1:OH8i1ojV9bWfr0ZfasfpgtUXQHQyVS8HXik/V1C099w= github.com/go-git/go-git-fixtures/v5 v5.1.1/go.mod h1:Altk43lx3b1ks+dVoAG2300o5WWUnktvfY3VI6bcaXU= +github.com/go-git/go-git-fixtures/v5 v5.1.2-0.20251229094738-4b14af179146 h1:xYfxAopYyL44ot6dMBIb1Z1njFM0ZBQ99HdIB99KxLs= github.com/go-git/go-git/v6 v6.0.0-20251128074608-48f817f57805 h1:jxQ3BzYeErNRvlI/4+0mpwqMzvB4g97U+ksfgvrUEbY= github.com/go-git/go-git/v6 v6.0.0-20251128074608-48f817f57805/go.mod h1:dIwT3uWK1ooHInyVnK2JS5VfQ3peVGYaw2QPqX7uFvs= +github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19 h1:0lz2eJScP8v5YZQsrEw+ggWC5jNySjg4bIZo5BIh6iI= +github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19/go.mod h1:L+Evfcs7EdTqxwv854354cb6+++7TFL3hJn3Wy4g+3w= github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE= github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8= github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= +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/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= @@ -114,12 +129,16 @@ github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sblinch/kdl-go v0.0.0-20250930225324-bf4099d4614a h1:8ZZwZWIQKC0YVMyaCkbrdeI8faTjD1QBrRAAWc1TjMI= github.com/sblinch/kdl-go v0.0.0-20250930225324-bf4099d4614a/go.mod h1:b3oNGuAKOQzhsCKmuLc/urEOPzgHj6fB8vl8bwTBh28= +github.com/sblinch/kdl-go v0.0.0-20251203232544-981d4ecc17c3 h1:msKaIZrrNpvofLPDzNBW3152PJBsnPZsoNNosOCS+C0= +github.com/sblinch/kdl-go v0.0.0-20251203232544-981d4ecc17c3/go.mod h1:b3oNGuAKOQzhsCKmuLc/urEOPzgHj6fB8vl8bwTBh28= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -133,22 +152,32 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY= golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8= golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/core/internal/config/embedded/niri-binds.kdl b/core/internal/config/embedded/niri-binds.kdl index 4e64e136..19887b39 100644 --- a/core/internal/config/embedded/niri-binds.kdl +++ b/core/internal/config/embedded/niri-binds.kdl @@ -1,8 +1,3 @@ -// ! DO NOT EDIT ! -// ! AUTO-GENERATED BY DMS ! -// ! CHANGES WILL BE OVERWRITTEN ! -// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE ! - binds { // === System & Overview === Mod+D repeat=false { toggle-overview; } diff --git a/core/internal/keybinds/providers/niri.go b/core/internal/keybinds/providers/niri.go index 7bc73653..da853625 100644 --- a/core/internal/keybinds/providers/niri.go +++ b/core/internal/keybinds/providers/niri.go @@ -461,16 +461,9 @@ func (n *NiriProvider) getBindSortPriority(action string) int { } } -const dmsWarningHeader = `// ! DO NOT EDIT ! -// ! AUTO-GENERATED BY DMS ! -// ! CHANGES WILL BE OVERWRITTEN ! -// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE ! - -` - func (n *NiriProvider) generateBindsContent(binds map[string]*overrideBind) string { if len(binds) == 0 { - return dmsWarningHeader + "binds {}\n" + return "binds {}\n" } var regularBinds, recentWindowsBinds []*overrideBind @@ -497,7 +490,6 @@ func (n *NiriProvider) generateBindsContent(binds map[string]*overrideBind) stri var sb strings.Builder - sb.WriteString(dmsWarningHeader) sb.WriteString("binds {\n") for _, bind := range regularBinds { n.writeBindNode(&sb, bind, " ") diff --git a/core/internal/keybinds/providers/niri_test.go b/core/internal/keybinds/providers/niri_test.go index 456074e9..9ac6fcd1 100644 --- a/core/internal/keybinds/providers/niri_test.go +++ b/core/internal/keybinds/providers/niri_test.go @@ -6,13 +6,6 @@ import ( "testing" ) -const testHeader = `// ! DO NOT EDIT ! -// ! AUTO-GENERATED BY DMS ! -// ! CHANGES WILL BE OVERWRITTEN ! -// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE ! - -` - func TestNiriProviderName(t *testing.T) { provider := NewNiriProvider("") if provider.Name() != "niri" { @@ -204,7 +197,7 @@ func TestNiriGenerateBindsContent(t *testing.T) { { name: "empty binds", binds: map[string]*overrideBind{}, - expected: testHeader + "binds {}\n", + expected: "binds {}\n", }, { name: "simple spawn bind", @@ -215,7 +208,7 @@ func TestNiriGenerateBindsContent(t *testing.T) { Description: "Open Terminal", }, }, - expected: testHeader + `binds { + expected: `binds { Mod+T hotkey-overlay-title="Open Terminal" { spawn "kitty"; } } `, @@ -229,7 +222,7 @@ func TestNiriGenerateBindsContent(t *testing.T) { Description: "Application Launcher", }, }, - expected: testHeader + `binds { + expected: `binds { Mod+Space hotkey-overlay-title="Application Launcher" { spawn "dms" "ipc" "call" "spotlight" "toggle"; } } `, @@ -243,7 +236,7 @@ func TestNiriGenerateBindsContent(t *testing.T) { Options: map[string]any{"allow-when-locked": true}, }, }, - expected: testHeader + `binds { + expected: `binds { XF86AudioMute allow-when-locked=true { spawn "dms" "ipc" "call" "audio" "mute"; } } `, @@ -257,7 +250,7 @@ func TestNiriGenerateBindsContent(t *testing.T) { Description: "Close Window", }, }, - expected: testHeader + `binds { + expected: `binds { Mod+Q hotkey-overlay-title="Close Window" { close-window; } } `, @@ -270,7 +263,7 @@ func TestNiriGenerateBindsContent(t *testing.T) { Action: "next-window", }, }, - expected: testHeader + `binds { + expected: `binds { } recent-windows { @@ -422,7 +415,7 @@ func TestNiriGenerateBindsContentNumericArgs(t *testing.T) { Description: "Focus Workspace 1", }, }, - expected: testHeader + `binds { + expected: `binds { Mod+1 hotkey-overlay-title="Focus Workspace 1" { focus-workspace 1; } } `, @@ -436,7 +429,7 @@ func TestNiriGenerateBindsContentNumericArgs(t *testing.T) { Description: "Focus Workspace 10", }, }, - expected: testHeader + `binds { + expected: `binds { Mod+0 hotkey-overlay-title="Focus Workspace 10" { focus-workspace 10; } } `, @@ -450,7 +443,7 @@ func TestNiriGenerateBindsContentNumericArgs(t *testing.T) { Description: "Adjust Column Width -10%", }, }, - expected: testHeader + `binds { + expected: `binds { Super+Minus hotkey-overlay-title="Adjust Column Width -10%" { set-column-width "-10%"; } } `, @@ -464,7 +457,7 @@ func TestNiriGenerateBindsContentNumericArgs(t *testing.T) { Description: "Adjust Column Width +10%", }, }, - expected: testHeader + `binds { + expected: `binds { Super+Equal hotkey-overlay-title="Adjust Column Width +10%" { set-column-width "+10%"; } } `, @@ -493,7 +486,7 @@ func TestNiriGenerateActionWithUnquotedPercentArg(t *testing.T) { } content := provider.generateBindsContent(binds) - expected := testHeader + `binds { + expected := `binds { Super+Equal hotkey-overlay-title="Adjust Window Height +10%" { set-window-height "+10%"; } } ` @@ -514,7 +507,7 @@ func TestNiriGenerateSpawnWithNumericArgs(t *testing.T) { } content := provider.generateBindsContent(binds) - expected := testHeader + `binds { + expected := `binds { XF86AudioLowerVolume allow-when-locked=true { spawn "dms" "ipc" "call" "audio" "decrement" "3"; } } ` @@ -535,7 +528,7 @@ func TestNiriGenerateSpawnNumericArgFromCLI(t *testing.T) { } content := provider.generateBindsContent(binds) - expected := testHeader + `binds { + expected := `binds { XF86AudioLowerVolume allow-when-locked=true { spawn "dms" "ipc" "call" "audio" "decrement" "3"; } } ` diff --git a/core/internal/server/network/backend_networkmanager.go b/core/internal/server/network/backend_networkmanager.go index 588f76f8..9c48f562 100644 --- a/core/internal/server/network/backend_networkmanager.go +++ b/core/internal/server/network/backend_networkmanager.go @@ -13,6 +13,7 @@ const ( dbusNMPath = "/org/freedesktop/NetworkManager" dbusNMInterface = "org.freedesktop.NetworkManager" dbusNMDeviceInterface = "org.freedesktop.NetworkManager.Device" + dbusNMWiredInterface = "org.freedesktop.NetworkManager.Device.Wired" dbusNMWirelessInterface = "org.freedesktop.NetworkManager.Device.Wireless" dbusNMAccessPointInterface = "org.freedesktop.NetworkManager.AccessPoint" dbusPropsInterface = "org.freedesktop.DBus.Properties" diff --git a/core/internal/server/network/backend_networkmanager_signals.go b/core/internal/server/network/backend_networkmanager_signals.go index 2a0a158c..5274ed0c 100644 --- a/core/internal/server/network/backend_networkmanager_signals.go +++ b/core/internal/server/network/backend_networkmanager_signals.go @@ -81,44 +81,24 @@ func (b *NetworkManagerBackend) startSignalPump() error { return err } - if b.wifiDevice != nil { - dev := b.wifiDevice.(gonetworkmanager.Device) + for _, info := range b.wifiDevices { if err := conn.AddMatchSignal( - dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())), + dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())), dbus.WithMatchInterface(dbusPropsInterface), dbus.WithMatchMember("PropertiesChanged"), ); err != nil { - conn.RemoveMatchSignal( - dbus.WithMatchObjectPath(dbus.ObjectPath(dbusNMPath)), - dbus.WithMatchInterface(dbusPropsInterface), - dbus.WithMatchMember("PropertiesChanged"), - ) conn.RemoveSignal(signals) conn.Close() return err } } - if b.ethernetDevice != nil { - dev := b.ethernetDevice.(gonetworkmanager.Device) + for _, info := range b.ethernetDevices { if err := conn.AddMatchSignal( - dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())), + dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())), dbus.WithMatchInterface(dbusPropsInterface), dbus.WithMatchMember("PropertiesChanged"), ); err != nil { - conn.RemoveMatchSignal( - dbus.WithMatchObjectPath(dbus.ObjectPath(dbusNMPath)), - dbus.WithMatchInterface(dbusPropsInterface), - dbus.WithMatchMember("PropertiesChanged"), - ) - if b.wifiDevice != nil { - dev := b.wifiDevice.(gonetworkmanager.Device) - conn.RemoveMatchSignal( - dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())), - dbus.WithMatchInterface(dbusPropsInterface), - dbus.WithMatchMember("PropertiesChanged"), - ) - } conn.RemoveSignal(signals) conn.Close() return err @@ -157,19 +137,17 @@ func (b *NetworkManagerBackend) stopSignalPump() { dbus.WithMatchMember("PropertiesChanged"), ) - if b.wifiDevice != nil { - dev := b.wifiDevice.(gonetworkmanager.Device) + for _, info := range b.wifiDevices { b.dbusConn.RemoveMatchSignal( - dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())), + dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())), dbus.WithMatchInterface(dbusPropsInterface), dbus.WithMatchMember("PropertiesChanged"), ) } - if b.ethernetDevice != nil { - dev := b.ethernetDevice.(gonetworkmanager.Device) + for _, info := range b.ethernetDevices { b.dbusConn.RemoveMatchSignal( - dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())), + dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())), dbus.WithMatchInterface(dbusPropsInterface), dbus.WithMatchMember("PropertiesChanged"), ) @@ -232,7 +210,10 @@ func (b *NetworkManagerBackend) handleDBusSignal(sig *dbus.Signal) { b.handleNetworkManagerChange(changes) case dbusNMDeviceInterface: - b.handleDeviceChange(changes) + b.handleDeviceChange(sig.Path, changes) + + case dbusNMWiredInterface: + b.handleWiredChange(changes) case dbusNMWirelessInterface: b.handleWiFiChange(changes) @@ -278,9 +259,10 @@ func (b *NetworkManagerBackend) handleNetworkManagerChange(changes map[string]db } } -func (b *NetworkManagerBackend) handleDeviceChange(changes map[string]dbus.Variant) { +func (b *NetworkManagerBackend) handleDeviceChange(devicePath dbus.ObjectPath, changes map[string]dbus.Variant) { var needsUpdate bool var stateChanged bool + var managedChanged bool for key := range changes { switch key { @@ -289,21 +271,61 @@ func (b *NetworkManagerBackend) handleDeviceChange(changes map[string]dbus.Varia needsUpdate = true case "Ip4Config": needsUpdate = true + case "Managed": + managedChanged = true default: continue } } - if needsUpdate { - b.updateEthernetState() - b.updateWiFiState() - if stateChanged { - b.updatePrimaryConnection() + if managedChanged { + if managedVariant, ok := changes["Managed"]; ok { + if managed, ok := managedVariant.Value().(bool); ok && managed { + b.handleDeviceAdded(devicePath) + return + } } - if b.onStateChange != nil { - b.onStateChange() + } + + if !needsUpdate { + return + } + + b.updateAllEthernetDevices() + b.updateEthernetState() + b.updateAllWiFiDevices() + b.updateWiFiState() + if stateChanged { + b.listEthernetConnections() + b.updatePrimaryConnection() + } + if b.onStateChange != nil { + b.onStateChange() + } +} + +func (b *NetworkManagerBackend) handleWiredChange(changes map[string]dbus.Variant) { + var needsUpdate bool + + for key := range changes { + switch key { + case "Carrier", "Speed", "HwAddress": + needsUpdate = true + default: + continue } } + + if !needsUpdate { + return + } + + b.updateAllEthernetDevices() + b.updateEthernetState() + b.updatePrimaryConnection() + if b.onStateChange != nil { + b.onStateChange() + } } func (b *NetworkManagerBackend) handleWiFiChange(changes map[string]dbus.Variant) { @@ -369,6 +391,18 @@ func (b *NetworkManagerBackend) handleDeviceAdded(devicePath dbus.ObjectPath) { return } + if devType != gonetworkmanager.NmDeviceTypeEthernet && devType != gonetworkmanager.NmDeviceTypeWifi { + return + } + + if b.dbusConn != nil { + b.dbusConn.AddMatchSignal( + dbus.WithMatchObjectPath(devicePath), + dbus.WithMatchInterface(dbusPropsInterface), + dbus.WithMatchMember("PropertiesChanged"), + ) + } + managed, _ := dev.GetPropertyManaged() if !managed { return @@ -398,14 +432,6 @@ func (b *NetworkManagerBackend) handleDeviceAdded(devicePath dbus.ObjectPath) { b.ethernetDevice = dev } - if b.dbusConn != nil { - b.dbusConn.AddMatchSignal( - dbus.WithMatchObjectPath(devicePath), - dbus.WithMatchInterface(dbusPropsInterface), - dbus.WithMatchMember("PropertiesChanged"), - ) - } - b.updateAllEthernetDevices() b.updateEthernetState() b.listEthernetConnections() @@ -430,14 +456,6 @@ func (b *NetworkManagerBackend) handleDeviceAdded(devicePath dbus.ObjectPath) { b.wifiDev = w } - if b.dbusConn != nil { - b.dbusConn.AddMatchSignal( - dbus.WithMatchObjectPath(devicePath), - dbus.WithMatchInterface(dbusPropsInterface), - dbus.WithMatchMember("PropertiesChanged"), - ) - } - b.updateAllWiFiDevices() b.updateWiFiState() } diff --git a/core/internal/server/network/backend_networkmanager_signals_test.go b/core/internal/server/network/backend_networkmanager_signals_test.go index af8d0252..6b58684a 100644 --- a/core/internal/server/network/backend_networkmanager_signals_test.go +++ b/core/internal/server/network/backend_networkmanager_signals_test.go @@ -159,7 +159,7 @@ func TestNetworkManagerBackend_HandleDeviceChange(t *testing.T) { } assert.NotPanics(t, func() { - backend.handleDeviceChange(changes) + backend.handleDeviceChange("/org/freedesktop/NetworkManager/Devices/1", changes) }) } @@ -174,7 +174,7 @@ func TestNetworkManagerBackend_HandleDeviceChange_Ip4Config(t *testing.T) { } assert.NotPanics(t, func() { - backend.handleDeviceChange(changes) + backend.handleDeviceChange("/org/freedesktop/NetworkManager/Devices/1", changes) }) } diff --git a/core/internal/server/network/priority.go b/core/internal/server/network/priority.go index c894ebad..b5836a2c 100644 --- a/core/internal/server/network/priority.go +++ b/core/internal/server/network/priority.go @@ -2,9 +2,21 @@ package network import ( "fmt" + "os/exec" "time" - "github.com/Wifx/gonetworkmanager/v2" + "github.com/AvengeMedia/DankMaterialShell/core/internal/log" + "github.com/godbus/dbus/v5" +) + +const ( + priorityHigh = int32(100) + priorityLow = int32(10) + priorityDefault = int32(0) + + metricPreferred = int64(100) + metricNonPreferred = int64(300) + metricDefault = int64(100) ) func (m *Manager) SetConnectionPreference(pref ConnectionPreference) error { @@ -36,83 +48,124 @@ func (m *Manager) SetConnectionPreference(pref ConnectionPreference) error { } func (m *Manager) prioritizeWiFi() error { - if err := m.setConnectionMetrics("802-11-wireless", 50); err != nil { - return err + if err := m.setConnectionPriority("802-11-wireless", priorityHigh, metricPreferred); err != nil { + log.Warnf("Failed to set WiFi priority: %v", err) } - if err := m.setConnectionMetrics("802-3-ethernet", 100); err != nil { - return err + if err := m.setConnectionPriority("802-3-ethernet", priorityLow, metricNonPreferred); err != nil { + log.Warnf("Failed to set Ethernet priority: %v", err) } + m.reapplyActiveConnections() m.notifySubscribers() return nil } func (m *Manager) prioritizeEthernet() error { - if err := m.setConnectionMetrics("802-3-ethernet", 50); err != nil { - return err + if err := m.setConnectionPriority("802-3-ethernet", priorityHigh, metricPreferred); err != nil { + log.Warnf("Failed to set Ethernet priority: %v", err) } - if err := m.setConnectionMetrics("802-11-wireless", 100); err != nil { - return err + if err := m.setConnectionPriority("802-11-wireless", priorityLow, metricNonPreferred); err != nil { + log.Warnf("Failed to set WiFi priority: %v", err) } + m.reapplyActiveConnections() m.notifySubscribers() return nil } func (m *Manager) balancePriorities() error { - if err := m.setConnectionMetrics("802-3-ethernet", 50); err != nil { - return err + if err := m.setConnectionPriority("802-3-ethernet", priorityDefault, metricDefault); err != nil { + log.Warnf("Failed to reset Ethernet priority: %v", err) } - if err := m.setConnectionMetrics("802-11-wireless", 50); err != nil { - return err + if err := m.setConnectionPriority("802-11-wireless", priorityDefault, metricDefault); err != nil { + log.Warnf("Failed to reset WiFi priority: %v", err) } + m.reapplyActiveConnections() m.notifySubscribers() return nil } -func (m *Manager) setConnectionMetrics(connType string, metric uint32) error { - settingsMgr, err := gonetworkmanager.NewSettings() +func (m *Manager) reapplyActiveConnections() { + m.stateMutex.RLock() + ethDev := m.state.EthernetDevice + wifiDev := m.state.WiFiDevice + m.stateMutex.RUnlock() + + if ethDev != "" { + exec.Command("nmcli", "dev", "reapply", ethDev).Run() + } + if wifiDev != "" { + exec.Command("nmcli", "dev", "reapply", wifiDev).Run() + } +} + +func (m *Manager) setConnectionPriority(connType string, autoconnectPriority int32, routeMetric int64) error { + conn, err := dbus.ConnectSystemBus() if err != nil { - return fmt.Errorf("failed to get settings: %w", err) + return fmt.Errorf("failed to connect to system bus: %w", err) + } + defer conn.Close() + + settingsObj := conn.Object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager/Settings") + + var connPaths []dbus.ObjectPath + if err := settingsObj.Call("org.freedesktop.NetworkManager.Settings.ListConnections", 0).Store(&connPaths); err != nil { + return fmt.Errorf("failed to list connections: %w", err) } - connections, err := settingsMgr.ListConnections() - if err != nil { - return fmt.Errorf("failed to get connections: %w", err) - } + for _, connPath := range connPaths { + connObj := conn.Object("org.freedesktop.NetworkManager", connPath) - for _, conn := range connections { - connSettings, err := conn.GetSettings() - if err != nil { + var settings map[string]map[string]dbus.Variant + if err := connObj.Call("org.freedesktop.NetworkManager.Settings.Connection.GetSettings", 0).Store(&settings); err != nil { continue } - if connMeta, ok := connSettings["connection"]; ok { - if cType, ok := connMeta["type"].(string); ok && cType == connType { - if connSettings["ipv4"] == nil { - connSettings["ipv4"] = make(map[string]any) - } - if ipv4Map := connSettings["ipv4"]; ipv4Map != nil { - ipv4Map["route-metric"] = int64(metric) - } - - if connSettings["ipv6"] == nil { - connSettings["ipv6"] = make(map[string]any) - } - if ipv6Map := connSettings["ipv6"]; ipv6Map != nil { - ipv6Map["route-metric"] = int64(metric) - } - - err = conn.Update(connSettings) - if err != nil { - continue - } - } + connSection, ok := settings["connection"] + if !ok { + continue } + + typeVariant, ok := connSection["type"] + if !ok { + continue + } + + cType, ok := typeVariant.Value().(string) + if !ok || cType != connType { + continue + } + + connName := "" + if idVariant, ok := connSection["id"]; ok { + connName, _ = idVariant.Value().(string) + } + + if connName == "" { + continue + } + + if err := exec.Command("nmcli", "con", "mod", connName, + "connection.autoconnect-priority", fmt.Sprintf("%d", autoconnectPriority)).Run(); err != nil { + log.Warnf("Failed to set autoconnect-priority for %v: %v", connName, err) + continue + } + + if err := exec.Command("nmcli", "con", "mod", connName, + "ipv4.route-metric", fmt.Sprintf("%d", routeMetric)).Run(); err != nil { + log.Warnf("Failed to set ipv4.route-metric for %v: %v", connName, err) + } + + if err := exec.Command("nmcli", "con", "mod", connName, + "ipv6.route-metric", fmt.Sprintf("%d", routeMetric)).Run(); err != nil { + log.Warnf("Failed to set ipv6.route-metric for %v: %v", connName, err) + } + + log.Infof("Updated %v: autoconnect-priority=%d, route-metric=%d", connName, autoconnectPriority, routeMetric) } return nil @@ -125,14 +178,18 @@ func (m *Manager) GetConnectionPreference() ConnectionPreference { } func (m *Manager) WasRecentlyFailed(ssid string) bool { - if nm, ok := m.backend.(*NetworkManagerBackend); ok { - nm.failedMutex.RLock() - defer nm.failedMutex.RUnlock() - - if nm.lastFailedSSID == ssid { - elapsed := time.Now().Unix() - nm.lastFailedTime - return elapsed < 10 - } + nm, ok := m.backend.(*NetworkManagerBackend) + if !ok { + return false } - return false + + nm.failedMutex.RLock() + defer nm.failedMutex.RUnlock() + + if nm.lastFailedSSID != ssid { + return false + } + + elapsed := time.Now().Unix() - nm.lastFailedTime + return elapsed < 10 } diff --git a/quickshell/Modals/Greeter/GreeterModal.qml b/quickshell/Modals/Greeter/GreeterModal.qml index e2dd6551..1d4bcf33 100644 --- a/quickshell/Modals/Greeter/GreeterModal.qml +++ b/quickshell/Modals/Greeter/GreeterModal.qml @@ -213,7 +213,7 @@ FloatingWindow { spacing: Theme.spacingXS DankActionButton { - visible: windowControls.supported + visible: windowControls.supported && windowControls.canMaximize iconName: root.maximized ? "fullscreen_exit" : "fullscreen" iconSize: Theme.iconSize - 4 iconColor: Theme.surfaceText diff --git a/quickshell/Modals/PolkitAuthModal.qml b/quickshell/Modals/PolkitAuthModal.qml index 68bd63c7..16c75049 100644 --- a/quickshell/Modals/PolkitAuthModal.qml +++ b/quickshell/Modals/PolkitAuthModal.qml @@ -117,7 +117,7 @@ FloatingWindow { onDoubleClicked: windowControls.tryToggleMaximize() } - Row { + Item { id: headerRow anchors.left: parent.left anchors.right: parent.right @@ -125,9 +125,13 @@ FloatingWindow { anchors.leftMargin: Theme.spacingM anchors.rightMargin: Theme.spacingM anchors.topMargin: Theme.spacingM + height: Math.max(titleColumn.height, buttonRow.height) Column { - width: parent.width - 60 + id: titleColumn + anchors.left: parent.left + anchors.right: buttonRow.left + anchors.rightMargin: Theme.spacingM spacing: Theme.spacingXS StyledText { @@ -162,10 +166,12 @@ FloatingWindow { } Row { + id: buttonRow + anchors.right: parent.right spacing: Theme.spacingXS DankActionButton { - visible: windowControls.supported + visible: windowControls.supported && windowControls.canMaximize iconName: root.maximized ? "fullscreen_exit" : "fullscreen" iconSize: Theme.iconSize - 4 iconColor: Theme.surfaceText diff --git a/quickshell/Modals/WifiPasswordModal.qml b/quickshell/Modals/WifiPasswordModal.qml index 95fa91c1..dafc15ef 100644 --- a/quickshell/Modals/WifiPasswordModal.qml +++ b/quickshell/Modals/WifiPasswordModal.qml @@ -44,12 +44,18 @@ FloatingWindow { property int calculatedHeight: { let h = headerHeight + buttonRowHeight + Theme.spacingL * 2; h += fieldsInfo.length * inputFieldWithSpacing; - if (showUsernameField) h += inputFieldWithSpacing; - if (showPasswordField) h += inputFieldWithSpacing; - if (showAnonField) h += inputFieldWithSpacing; - if (showDomainField) h += inputFieldWithSpacing; - if (showShowPasswordCheckbox) h += checkboxRowHeight; - if (showSavePasswordCheckbox) h += checkboxRowHeight; + if (showUsernameField) + h += inputFieldWithSpacing; + if (showPasswordField) + h += inputFieldWithSpacing; + if (showAnonField) + h += inputFieldWithSpacing; + if (showDomainField) + h += inputFieldWithSpacing; + if (showShowPasswordCheckbox) + h += checkboxRowHeight; + if (showSavePasswordCheckbox) + h += checkboxRowHeight; return h; } @@ -267,11 +273,14 @@ FloatingWindow { width: parent.width - Theme.spacingL * 2 spacing: Theme.spacingM - Row { + Item { width: contentCol.width + height: Math.max(headerCol.height, buttonRow.height) MouseArea { - width: parent.width - 60 + anchors.left: parent.left + anchors.right: buttonRow.left + anchors.rightMargin: Theme.spacingM height: headerCol.height onPressed: windowControls.tryStartMove() onDoubleClicked: windowControls.tryToggleMaximize() @@ -327,10 +336,12 @@ FloatingWindow { } Row { + id: buttonRow + anchors.right: parent.right spacing: Theme.spacingXS DankActionButton { - visible: windowControls.supported + visible: windowControls.supported && windowControls.canMaximize iconName: root.maximized ? "fullscreen_exit" : "fullscreen" iconSize: Theme.iconSize - 4 iconColor: Theme.surfaceText diff --git a/quickshell/Modules/Settings/NetworkTab.qml b/quickshell/Modules/Settings/NetworkTab.qml index e60de248..f13d1cce 100644 --- a/quickshell/Modules/Settings/NetworkTab.qml +++ b/quickshell/Modules/Settings/NetworkTab.qml @@ -399,14 +399,14 @@ Item { text: "•" font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceVariantText - visible: modelData.ip && modelData.ip.length > 0 + visible: (modelData.ip || "").length > 0 } StyledText { text: modelData.ip || "" font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceVariantText - visible: modelData.ip && modelData.ip.length > 0 + visible: (modelData.ip || "").length > 0 } } } diff --git a/quickshell/Modules/Settings/ThemeBrowser.qml b/quickshell/Modules/Settings/ThemeBrowser.qml index 6a586228..a86eae84 100644 --- a/quickshell/Modules/Settings/ThemeBrowser.qml +++ b/quickshell/Modules/Settings/ThemeBrowser.qml @@ -328,7 +328,6 @@ FloatingWindow { anchors.top: browserSearchField.bottom anchors.topMargin: Theme.spacingM anchors.bottom: parent.bottom - anchors.bottomMargin: Theme.spacingM Item { anchors.fill: parent @@ -366,10 +365,6 @@ FloatingWindow { id: themeBrowserList anchors.fill: parent - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - anchors.bottomMargin: Theme.spacingS spacing: Theme.spacingS model: ScriptModel { values: root.filteredThemes diff --git a/quickshell/Services/DMSNetworkService.qml b/quickshell/Services/DMSNetworkService.qml index a67aae25..56958f59 100644 --- a/quickshell/Services/DMSNetworkService.qml +++ b/quickshell/Services/DMSNetworkService.qml @@ -323,7 +323,6 @@ Singleton { } } - userPreference = state.preference || "auto"; isConnecting = state.isConnecting || false; connectingSSID = state.connectingSSID || ""; connectionError = state.lastError || ""; diff --git a/quickshell/Widgets/FloatingWindowControls.qml b/quickshell/Widgets/FloatingWindowControls.qml index 48608936..b56291e6 100644 --- a/quickshell/Widgets/FloatingWindowControls.qml +++ b/quickshell/Widgets/FloatingWindowControls.qml @@ -6,6 +6,7 @@ Item { readonly property real edgeSize: 8 required property var targetWindow property bool supported: typeof targetWindow.startSystemMove === "function" + readonly property bool canMaximize: targetWindow.minimumSize.width !== targetWindow.maximumSize.width || targetWindow.minimumSize.height !== targetWindow.maximumSize.height anchors.fill: parent @@ -16,19 +17,19 @@ Item { } function tryStartResize(edges) { - if (!supported) + if (!supported || !canMaximize) return; targetWindow.startSystemResize(edges); } function tryToggleMaximize() { - if (!supported) + if (!supported || !canMaximize) return; targetWindow.maximized = !targetWindow.maximized; } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize height: root.edgeSize anchors.left: parent.left anchors.right: parent.right @@ -40,7 +41,7 @@ Item { } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize width: root.edgeSize anchors.left: parent.left anchors.top: parent.top @@ -52,7 +53,7 @@ Item { } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize width: root.edgeSize anchors.right: parent.right anchors.top: parent.top @@ -64,7 +65,7 @@ Item { } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize width: root.edgeSize height: root.edgeSize anchors.left: parent.left @@ -74,7 +75,7 @@ Item { } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize width: root.edgeSize height: root.edgeSize anchors.right: parent.right @@ -84,7 +85,7 @@ Item { } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize height: root.edgeSize anchors.left: parent.left anchors.right: parent.right @@ -96,7 +97,7 @@ Item { } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize width: root.edgeSize height: root.edgeSize anchors.left: parent.left @@ -106,7 +107,7 @@ Item { } MouseArea { - visible: root.supported + visible: root.supported && root.canMaximize width: root.edgeSize height: root.edgeSize anchors.right: parent.right