feat: add user accounts page
Co-authored-by: Antoine C <hi@acolombier.dev>
This commit is contained in:
parent
00b8b2bb96
commit
8e5afbfbfc
14 changed files with 1179 additions and 147 deletions
263
Cargo.lock
generated
263
Cargo.lock
generated
|
|
@ -98,6 +98,17 @@ dependencies = [
|
|||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "accounts-zbus"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"tracing",
|
||||
"zbus 4.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
|
|
@ -445,7 +456,7 @@ checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
|
|||
dependencies = [
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand 2.2.0",
|
||||
"fastrand 2.3.0",
|
||||
"futures-lite 2.5.0",
|
||||
"slab",
|
||||
]
|
||||
|
|
@ -494,7 +505,7 @@ dependencies = [
|
|||
"futures-lite 2.5.0",
|
||||
"parking",
|
||||
"polling 3.7.4",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"slab",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
|
|
@ -544,7 +555,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"event-listener 3.1.0",
|
||||
"futures-lite 1.13.0",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
|
@ -563,7 +574,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"event-listener 5.3.1",
|
||||
"futures-lite 2.5.0",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
|
@ -590,7 +601,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"windows-sys 0.59.0",
|
||||
|
|
@ -624,7 +635,7 @@ name = "atomicwrites"
|
|||
version = "0.4.2"
|
||||
source = "git+https://github.com/jackpot51/rust-atomicwrites#043ab4859d53ffd3d55334685303d8df39c9f768"
|
||||
dependencies = [
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"tempfile",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
|
@ -857,7 +868,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "bluez-zbus"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
|
|
@ -996,7 +1007,7 @@ dependencies = [
|
|||
"bitflags 2.6.0",
|
||||
"log",
|
||||
"polling 3.7.4",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"slab",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
|
@ -1008,16 +1019,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
|
||||
dependencies = [
|
||||
"calloop",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc"
|
||||
checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
|
|
@ -1080,9 +1091,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.38"
|
||||
version = "0.4.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
|
|
@ -1106,9 +1117,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.22"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69371e34337c4c984bbe322360c2547210bf632eb2814bbe78a6e87a2935bd2b"
|
||||
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -1116,9 +1127,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.22"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e24c1b4099818523236a8ca881d2b45db98dadfb4625cf6608c12069fcbbde1"
|
||||
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -1140,9 +1151,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
|
|
@ -1348,18 +1359,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.33"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b"
|
||||
checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd"
|
||||
dependencies = [
|
||||
"const_format_proc_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_format_proc_macros"
|
||||
version = "0.2.33"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1"
|
||||
checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1462,7 +1473,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-comp-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-comp#e3b41c5c554cc5aadf44183866ff4df7c2957d09"
|
||||
source = "git+https://github.com/pop-os/cosmic-comp#9b50d0f50606891440cf9844304ae3c8b14034db"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"input",
|
||||
|
|
@ -1472,7 +1483,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"atomicwrites",
|
||||
"cosmic-config-derive",
|
||||
|
|
@ -1494,7 +1505,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
|
|
@ -1503,7 +1514,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-dbus-networkmanager"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"derive_builder",
|
||||
|
|
@ -1514,6 +1525,19 @@ dependencies = [
|
|||
"zvariant 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmic-freedesktop-icons"
|
||||
version = "0.2.6"
|
||||
source = "git+https://github.com/pop-os/freedesktop-icons#3a202b17c8d4d63e2f073210260773855276c604"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"once_cell",
|
||||
"rust-ini",
|
||||
"thiserror 1.0.69",
|
||||
"tracing",
|
||||
"xdg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmic-idle-config"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1537,7 +1561,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-panel-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-panel#734e3fafe2eafea1cb3cece7d0b4ddf72a2c4323"
|
||||
source = "git+https://github.com/pop-os/cosmic-panel#1c9c4e2a2cf27efd0ca77b5ec21bc6f7fa92d9da"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cosmic-config",
|
||||
|
|
@ -1594,6 +1618,7 @@ dependencies = [
|
|||
name = "cosmic-settings"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"accounts-zbus",
|
||||
"anyhow",
|
||||
"as-result",
|
||||
"ashpd 0.9.2",
|
||||
|
|
@ -1642,6 +1667,7 @@ dependencies = [
|
|||
"regex",
|
||||
"ron",
|
||||
"rust-embed",
|
||||
"rustix 0.38.42",
|
||||
"secure-string",
|
||||
"serde",
|
||||
"slab",
|
||||
|
|
@ -1660,12 +1686,13 @@ dependencies = [
|
|||
"ustr",
|
||||
"xkb-data",
|
||||
"zbus 4.4.0",
|
||||
"zbus_polkit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmic-settings-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-settings-daemon#f079ab7f98132787de385934915547f333dfbddc"
|
||||
source = "git+https://github.com/pop-os/cosmic-settings-daemon#e87f5859a2e932ef14746affd01cc67ed4f93cf1"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"serde",
|
||||
|
|
@ -1678,7 +1705,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-settings-daemon"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"zbus 4.4.0",
|
||||
]
|
||||
|
|
@ -1710,7 +1737,7 @@ dependencies = [
|
|||
"libpulse-binding",
|
||||
"log",
|
||||
"pipewire",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"secure-string",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
|
|
@ -1764,7 +1791,7 @@ dependencies = [
|
|||
"rayon",
|
||||
"rustc-hash 1.1.0",
|
||||
"rustybuzz",
|
||||
"self_cell 1.0.4",
|
||||
"self_cell 1.1.0",
|
||||
"smol_str",
|
||||
"swash",
|
||||
"sys-locale",
|
||||
|
|
@ -1778,7 +1805,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-theme"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"almost",
|
||||
"cosmic-config",
|
||||
|
|
@ -2186,7 +2213,7 @@ dependencies = [
|
|||
"bytemuck",
|
||||
"drm-ffi",
|
||||
"drm-fourcc",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2196,7 +2223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6"
|
||||
dependencies = [
|
||||
"drm-sys",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2382,15 +2409,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.2.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb"
|
||||
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
|
@ -2705,7 +2732,7 @@ version = "2.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1"
|
||||
dependencies = [
|
||||
"fastrand 2.2.0",
|
||||
"fastrand 2.3.0",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"parking",
|
||||
|
|
@ -3052,7 +3079,7 @@ checksum = "f558a64ac9af88b5ba400d99b579451af0d39c6d360980045b91aac966d705e2"
|
|||
[[package]]
|
||||
name = "hostname1-zbus"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"zbus 4.4.0",
|
||||
]
|
||||
|
|
@ -3153,7 +3180,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"dnd",
|
||||
"iced_accessibility",
|
||||
|
|
@ -3171,7 +3198,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_accessibility"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"accesskit_winit",
|
||||
|
|
@ -3180,7 +3207,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_core"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bytes",
|
||||
|
|
@ -3205,7 +3232,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_futures"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"iced_core",
|
||||
|
|
@ -3231,7 +3258,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_graphics"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bytemuck",
|
||||
|
|
@ -3253,7 +3280,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_renderer"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"iced_graphics",
|
||||
"iced_tiny_skia",
|
||||
|
|
@ -3265,7 +3292,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_runtime"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cosmic-client-toolkit",
|
||||
|
|
@ -3281,7 +3308,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_tiny_skia"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cosmic-text",
|
||||
|
|
@ -3297,7 +3324,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_wgpu"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"as-raw-xcb-connection",
|
||||
"bitflags 2.6.0",
|
||||
|
|
@ -3314,7 +3341,7 @@ dependencies = [
|
|||
"raw-window-handle",
|
||||
"resvg",
|
||||
"rustc-hash 2.1.0",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"thiserror 1.0.69",
|
||||
"tiny-xlib",
|
||||
"wayland-backend",
|
||||
|
|
@ -3328,7 +3355,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_widget"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"cosmic-client-toolkit",
|
||||
"dnd",
|
||||
|
|
@ -3347,7 +3374,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_winit"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"cosmic-client-toolkit",
|
||||
"dnd",
|
||||
|
|
@ -4069,9 +4096,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.74"
|
||||
version = "0.3.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705"
|
||||
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -4127,9 +4154,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "jxl-grid"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13a28ba2734da33624db4b426b44750a7b1238e6cba65d27b7d84bf3cba7f507"
|
||||
checksum = "80f25f406f215f07f0b994801bc2d6adbfcd5710fcdd8f12d662e80700469e6c"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
|
@ -4324,25 +4351,25 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.167"
|
||||
version = "0.2.168"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
|
||||
checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
|
||||
|
||||
[[package]]
|
||||
name = "libcosmic"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#ff0ba4860c9ba732e601485f1952fde5fe5f6952"
|
||||
source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40"
|
||||
dependencies = [
|
||||
"apply",
|
||||
"ashpd 0.9.2",
|
||||
"chrono",
|
||||
"cosmic-client-toolkit",
|
||||
"cosmic-config",
|
||||
"cosmic-freedesktop-icons",
|
||||
"cosmic-settings-daemon",
|
||||
"cosmic-theme",
|
||||
"css-color",
|
||||
"derive_setters",
|
||||
"freedesktop-icons",
|
||||
"iced",
|
||||
"iced_accessibility",
|
||||
"iced_core",
|
||||
|
|
@ -4504,7 +4531,7 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
|||
[[package]]
|
||||
name = "locale1"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"zbus 4.4.0",
|
||||
]
|
||||
|
|
@ -4578,9 +4605,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lyon_algorithms"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3bca95f9a4955b3e4a821fbbcd5edfbd9be2a9a50bb5758173e5358bfb4c623"
|
||||
checksum = "f13c9be19d257c7d37e70608ed858e8eab4b2afcea2e3c9a622e892acbf43c08"
|
||||
dependencies = [
|
||||
"lyon_path",
|
||||
"num-traits",
|
||||
|
|
@ -5555,7 +5582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"fastrand 2.2.0",
|
||||
"fastrand 2.3.0",
|
||||
"futures-io",
|
||||
]
|
||||
|
||||
|
|
@ -5595,9 +5622,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
|||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.14"
|
||||
version = "0.17.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0"
|
||||
checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crc32fast",
|
||||
|
|
@ -5632,7 +5659,7 @@ dependencies = [
|
|||
"concurrent-queue",
|
||||
"hermit-abi 0.4.0",
|
||||
"pin-project-lite",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
|
@ -5737,7 +5764,7 @@ dependencies = [
|
|||
"hex",
|
||||
"lazy_static",
|
||||
"procfs-core",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6260,15 +6287,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.41"
|
||||
version = "0.38.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
|
||||
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.14",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6356,14 +6383,14 @@ version = "0.10.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
|
||||
dependencies = [
|
||||
"self_cell 1.0.4",
|
||||
"self_cell 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "1.0.4"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
|
||||
checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
|
|
@ -6603,7 +6630,7 @@ dependencies = [
|
|||
"log",
|
||||
"memmap2 0.9.5",
|
||||
"pkg-config",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"thiserror 1.0.69",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
|
|
@ -6667,7 +6694,7 @@ dependencies = [
|
|||
"cocoa",
|
||||
"core-graphics",
|
||||
"drm",
|
||||
"fastrand 2.2.0",
|
||||
"fastrand 2.3.0",
|
||||
"foreign-types",
|
||||
"js-sys",
|
||||
"log",
|
||||
|
|
@ -6675,7 +6702,7 @@ dependencies = [
|
|||
"objc",
|
||||
"raw-window-handle",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"tiny-xlib",
|
||||
"wasm-bindgen",
|
||||
"wayland-backend",
|
||||
|
|
@ -6868,7 +6895,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"superblock",
|
||||
"thiserror 2.0.4",
|
||||
"thiserror 2.0.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6933,9 +6960,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand 2.2.0",
|
||||
"fastrand 2.3.0",
|
||||
"once_cell",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
|
|
@ -6965,11 +6992,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.4"
|
||||
version = "2.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f49a1853cf82743e3b7950f77e0f4d622ca36cf4317cba00c767838bac8d490"
|
||||
checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.4",
|
||||
"thiserror-impl 2.0.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6985,9 +7012,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.4"
|
||||
version = "2.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8381894bb3efe0c4acac3ded651301ceee58a15d47c2e34885ed1908ad667061"
|
||||
checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -7049,7 +7076,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "timedate-zbus"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"zbus 4.4.0",
|
||||
]
|
||||
|
|
@ -7158,9 +7185,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.16"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1"
|
||||
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
|
|
@ -7436,7 +7463,7 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|||
[[package]]
|
||||
name = "upower_dbus"
|
||||
version = "0.3.2"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
|
||||
source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_repr",
|
||||
|
|
@ -7587,9 +7614,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.97"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c"
|
||||
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
|
|
@ -7598,13 +7625,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.97"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd"
|
||||
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
|
|
@ -7613,9 +7639,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.47"
|
||||
version = "0.4.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d"
|
||||
checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
|
|
@ -7626,9 +7652,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.97"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051"
|
||||
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
|
@ -7636,9 +7662,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.97"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d"
|
||||
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -7649,9 +7675,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.97"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49"
|
||||
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-timer"
|
||||
|
|
@ -7676,7 +7702,7 @@ checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6"
|
|||
dependencies = [
|
||||
"cc",
|
||||
"downcast-rs",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"scoped-tls",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
|
|
@ -7689,7 +7715,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"wayland-backend",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
|
@ -7711,7 +7737,7 @@ version = "0.31.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c"
|
||||
dependencies = [
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"wayland-client",
|
||||
"xcursor",
|
||||
]
|
||||
|
|
@ -7776,7 +7802,7 @@ dependencies = [
|
|||
"bitflags 2.6.0",
|
||||
"downcast-rs",
|
||||
"io-lifetimes 2.0.4",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"wayland-backend",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
|
@ -7795,9 +7821,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.74"
|
||||
version = "0.3.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c"
|
||||
checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -8347,7 +8373,7 @@ dependencies = [
|
|||
"pin-project",
|
||||
"raw-window-handle",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"sctk-adwaita",
|
||||
"smithay-client-toolkit",
|
||||
"smol_str",
|
||||
|
|
@ -8431,7 +8457,7 @@ dependencies = [
|
|||
"libc",
|
||||
"libloading",
|
||||
"once_cell",
|
||||
"rustix 0.38.41",
|
||||
"rustix 0.38.42",
|
||||
"x11rb-protocol",
|
||||
]
|
||||
|
||||
|
|
@ -8466,7 +8492,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "xdg-shell-wrapper-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-panel#734e3fafe2eafea1cb3cece7d0b4ddf72a2c4323"
|
||||
source = "git+https://github.com/pop-os/cosmic-panel#1c9c4e2a2cf27efd0ca77b5ec21bc6f7fa92d9da"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"wayland-protocols-wlr",
|
||||
|
|
@ -8696,6 +8722,19 @@ dependencies = [
|
|||
"zvariant 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_polkit"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00a29bfa927b29f91b7feb4e1990f2dd1b4604072f493dc2f074cf59e4e0ba90"
|
||||
dependencies = [
|
||||
"enumflags2",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"static_assertions",
|
||||
"zbus 4.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeno"
|
||||
version = "0.2.3"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ edition = "2021"
|
|||
license = "GPL-3.0-only"
|
||||
|
||||
[dependencies]
|
||||
accounts-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
|
||||
anyhow = "1.0"
|
||||
as-result = "0.2.1"
|
||||
ashpd = { version = "0.9", default-features = false, features = [
|
||||
|
|
@ -57,7 +58,7 @@ sunrise = "1.0.1"
|
|||
tachyonix = "0.3.1"
|
||||
timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
|
||||
tokio = { workspace = true, features = ["fs", "io-util", "sync"] }
|
||||
tracing = "0.1.40"
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = "0.3.18"
|
||||
udev = { version = "0.9.0", optional = true }
|
||||
upower_dbus = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
|
||||
|
|
@ -65,10 +66,12 @@ bluez-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings", optiona
|
|||
url = "2.5.2"
|
||||
xkb-data = "0.2.1"
|
||||
zbus = { version = "4.4.0", features = ["tokio"], optional = true }
|
||||
zbus_polkit = { version = "4.0.0" }
|
||||
ustr = "1.0.0"
|
||||
fontdb = "0.16.2"
|
||||
fixed_decimal = "0.5.6"
|
||||
mime = "0.3.17"
|
||||
rustix = "0.38.41"
|
||||
|
||||
[dependencies.cosmic-settings-subscriptions]
|
||||
git = "https://github.com/pop-os/cosmic-settings-subscriptions"
|
||||
|
|
@ -104,6 +107,7 @@ linux = [
|
|||
"page-power",
|
||||
"page-region",
|
||||
"page-sound",
|
||||
"page-users",
|
||||
"page-window-management",
|
||||
"page-workspaces",
|
||||
"xdg-portal",
|
||||
|
|
@ -129,6 +133,7 @@ page-networking = [
|
|||
page-power = ["dep:upower_dbus", "dep:zbus"]
|
||||
page-region = ["dep:lichen-system", "dep:locale1"]
|
||||
page-sound = ["dep:cosmic-settings-subscriptions"]
|
||||
page-users = ["dep:accounts-zbus"]
|
||||
page-window-management = ["dep:cosmic-settings-config"]
|
||||
page-workspaces = ["dep:cosmic-comp-config"]
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ impl SettingsApp {
|
|||
PageCommands::Time => self.pages.page_id::<time::Page>(),
|
||||
#[cfg(feature = "page-input")]
|
||||
PageCommands::Touchpad => self.pages.page_id::<input::touchpad::Page>(),
|
||||
#[cfg(feature = "page-users")]
|
||||
PageCommands::Users => self.pages.page_id::<system::users::Page>(),
|
||||
#[cfg(feature = "page-networking")]
|
||||
PageCommands::Vpn => self.pages.page_id::<networking::vpn::Page>(),
|
||||
|
|
@ -504,6 +505,13 @@ impl cosmic::Application for SettingsApp {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "page-users")]
|
||||
crate::pages::Message::User(message) => {
|
||||
if let Some(page) = self.pages.page_mut::<system::users::Page>() {
|
||||
return page.update(message).map(Into::into);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "page-input")]
|
||||
crate::pages::Message::SystemShortcuts(message) => {
|
||||
if let Some(page) = self
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ pub enum PageCommands {
|
|||
#[cfg(feature = "page-input")]
|
||||
Touchpad,
|
||||
/// Users settings page
|
||||
#[cfg(feature = "page-users")]
|
||||
Users,
|
||||
/// VPN settings page
|
||||
#[cfg(feature = "page-networking")]
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ pub enum Message {
|
|||
Region(time::region::Message),
|
||||
#[cfg(feature = "page-sound")]
|
||||
Sound(sound::Message),
|
||||
#[cfg(feature = "page-users")]
|
||||
User(system::users::Message),
|
||||
#[cfg(feature = "page-input")]
|
||||
SystemShortcuts(input::keyboard::shortcuts::ShortcutMessage),
|
||||
#[cfg(feature = "page-input")]
|
||||
|
|
|
|||
|
|
@ -100,6 +100,10 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
&mut self,
|
||||
_sender: mpsc::Sender<crate::pages::Message>,
|
||||
) -> Task<crate::pages::Message> {
|
||||
if let Some(handle) = self.on_enter_handle.take() {
|
||||
handle.abort();
|
||||
}
|
||||
|
||||
let (task, on_enter_handle) = Task::future(async move {
|
||||
let mut list = mime_apps::List::default();
|
||||
list.load_from_paths(&mime_apps::list_paths());
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ pub mod about;
|
|||
#[cfg(feature = "page-default-apps")]
|
||||
pub mod default_apps;
|
||||
pub mod firmware;
|
||||
#[cfg(feature = "page-users")]
|
||||
pub mod users;
|
||||
|
||||
use cosmic_settings_page as page;
|
||||
|
|
@ -29,16 +30,23 @@ impl page::AutoBind<crate::pages::Message> for Page {
|
|||
fn sub_pages(
|
||||
mut page: page::Insert<crate::pages::Message>,
|
||||
) -> page::Insert<crate::pages::Message> {
|
||||
page = page.sub_page::<users::Page>();
|
||||
#[cfg(feature = "page-users")]
|
||||
{
|
||||
page = page.sub_page::<users::Page>();
|
||||
}
|
||||
|
||||
#[cfg(feature = "page-about")]
|
||||
{
|
||||
page = page.sub_page::<about::Page>();
|
||||
}
|
||||
|
||||
page = page.sub_page::<firmware::Page>();
|
||||
|
||||
#[cfg(feature = "page-default-apps")]
|
||||
{
|
||||
page = page.sub_page::<default_apps::Page>();
|
||||
}
|
||||
|
||||
page
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
use slotmap::SlotMap;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Page {
|
||||
entity: page::Entity,
|
||||
}
|
||||
|
||||
impl page::Page<crate::pages::Message> for Page {
|
||||
fn set_id(&mut self, entity: page::Entity) {
|
||||
self.entity = entity;
|
||||
}
|
||||
|
||||
fn content(
|
||||
&self,
|
||||
sections: &mut SlotMap<section::Entity, Section<crate::pages::Message>>,
|
||||
) -> Option<page::Content> {
|
||||
Some(vec![sections.insert(Section::default())])
|
||||
}
|
||||
|
||||
fn info(&self) -> page::Info {
|
||||
page::Info::new("users", "system-users-symbolic")
|
||||
.title(fl!("users"))
|
||||
.description(fl!("users", "desc"))
|
||||
}
|
||||
}
|
||||
|
||||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
137
cosmic-settings/src/pages/system/users/getent.rs
Normal file
137
cosmic-settings/src/pages/system/users/getent.rs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright 2024 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::process::Stdio;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn passwd(range: (u64, u64)) -> Vec<PasswdUser> {
|
||||
let spawn_res = std::process::Command::new("getent")
|
||||
.arg("passwd")
|
||||
.stdin(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn();
|
||||
|
||||
let mut users = Vec::new();
|
||||
|
||||
if let Ok(mut child) = spawn_res {
|
||||
let stdout = child.stdout.take().unwrap();
|
||||
let mut reader = BufReader::new(stdout);
|
||||
let mut line = String::new();
|
||||
|
||||
loop {
|
||||
line.clear();
|
||||
match reader.read_line(&mut line) {
|
||||
Ok(0) | Err(_) => break,
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if let Ok(user) = line.trim().parse::<PasswdUser>() {
|
||||
if user.uid >= range.0 && user.uid <= range.1 {
|
||||
users.push(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
users
|
||||
}
|
||||
|
||||
pub fn group() -> Vec<Group> {
|
||||
let spawn_res = std::process::Command::new("getent")
|
||||
.arg("group")
|
||||
.stdin(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn();
|
||||
|
||||
let mut groups = Vec::new();
|
||||
|
||||
if let Ok(mut child) = spawn_res {
|
||||
let stdout = child.stdout.take().unwrap();
|
||||
let mut reader = BufReader::new(stdout);
|
||||
let mut line = String::new();
|
||||
|
||||
loop {
|
||||
line.clear();
|
||||
match reader.read_line(&mut line) {
|
||||
Ok(0) | Err(_) => break,
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if let Ok(group) = line.trim().parse::<Group>() {
|
||||
groups.push(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groups
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Group {
|
||||
pub uid: u64,
|
||||
pub name: Box<str>,
|
||||
pub users: Vec<Box<str>>,
|
||||
}
|
||||
|
||||
impl FromStr for Group {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(line: &str) -> Result<Self, Self::Err> {
|
||||
let mut fields = line.split(':');
|
||||
|
||||
Ok(Group {
|
||||
name: fields.next().ok_or(())?.into(),
|
||||
uid: fields.nth(1).ok_or(())?.parse().map_err(|_| ())?,
|
||||
users: fields
|
||||
.next()
|
||||
.ok_or(())?
|
||||
.split(',')
|
||||
.map(Box::from)
|
||||
.collect::<Vec<_>>(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct PasswdUser {
|
||||
pub uid: u64,
|
||||
pub username: Box<str>,
|
||||
pub full_name: Box<str>,
|
||||
}
|
||||
|
||||
impl FromStr for PasswdUser {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(line: &str) -> Result<Self, Self::Err> {
|
||||
let mut fields = line.split(':');
|
||||
|
||||
Ok(PasswdUser {
|
||||
username: fields.next().ok_or(())?.into(),
|
||||
uid: fields.nth(1).ok_or(())?.parse().map_err(|_| ())?,
|
||||
full_name: fields.nth(1).ok_or(())?.split(',').next().ok_or(())?.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PasswdUser;
|
||||
|
||||
#[test]
|
||||
fn passwd() {
|
||||
const EXAMPLE: &str =
|
||||
"speech-dispatcher:x:109:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false";
|
||||
|
||||
assert_eq!(
|
||||
EXAMPLE.parse::<PasswdUser>(),
|
||||
Ok(PasswdUser {
|
||||
username: Box::from("speech-dispatcher"),
|
||||
uid: 109,
|
||||
full_name: Box::from("Speech Dispatcher")
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
818
cosmic-settings/src/pages/system/users/mod.rs
Normal file
818
cosmic-settings/src/pages/system/users/mod.rs
Normal file
|
|
@ -0,0 +1,818 @@
|
|||
// Copyright 2024 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
mod getent;
|
||||
|
||||
use cosmic::{
|
||||
dialog::file_chooser,
|
||||
iced::{Alignment, Length},
|
||||
theme,
|
||||
widget::{self, column, icon, settings, text},
|
||||
Apply, Element,
|
||||
};
|
||||
use cosmic_settings_page::{self as page, section, Section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
future::Future,
|
||||
io::{BufRead, BufReader},
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
};
|
||||
use url::Url;
|
||||
use zbus_polkit::policykit1::CheckAuthorizationFlags;
|
||||
|
||||
use crate::pages;
|
||||
|
||||
const DEFAULT_ICON_FILE: &str = "/usr/share/pixmaps/faces/pop-robot.png";
|
||||
const USERS_ADMIN_POLKIT_POLICY_ID: &str = "com.system76.CosmicSettings.Users.Admin";
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct User {
|
||||
id: u64,
|
||||
profile_icon: Option<icon::Handle>,
|
||||
full_name: String,
|
||||
password: String,
|
||||
username: String,
|
||||
full_name_edit: bool,
|
||||
password_edit: bool,
|
||||
username_edit: bool,
|
||||
is_admin: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum EditorField {
|
||||
FullName,
|
||||
Password,
|
||||
Username,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Dialog {
|
||||
AddNewUser(User),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Page {
|
||||
on_enter_handle: Option<cosmic::iced::task::Handle>,
|
||||
current_user_id: u64,
|
||||
entity: page::Entity,
|
||||
users: Vec<User>,
|
||||
selected_user_idx: Option<usize>,
|
||||
dialog: Option<Dialog>,
|
||||
default_icon: icon::Handle,
|
||||
password_label: String,
|
||||
username_label: String,
|
||||
fullname_label: String,
|
||||
}
|
||||
|
||||
impl Default for Page {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
on_enter_handle: None,
|
||||
current_user_id: 0,
|
||||
entity: page::Entity::default(),
|
||||
users: Vec::default(),
|
||||
selected_user_idx: None,
|
||||
dialog: None,
|
||||
default_icon: icon::from_path(PathBuf::from(DEFAULT_ICON_FILE)),
|
||||
password_label: crate::fl!("password"),
|
||||
username_label: crate::fl!("username"),
|
||||
fullname_label: crate::fl!("full-name"),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Message {
|
||||
ApplyEdit(usize, EditorField),
|
||||
ChangedAccountType(u64, bool),
|
||||
DeletedUser(u64),
|
||||
Dialog(Option<Dialog>),
|
||||
Edit(usize, EditorField, String),
|
||||
LoadedIcon(u64, icon::Handle),
|
||||
LoadPage(u64, Vec<User>),
|
||||
NewUser(String, String, String, bool),
|
||||
None,
|
||||
SelectProfileImage(u64),
|
||||
SelectedProfileImage(u64, Arc<Result<Url, file_chooser::Error>>),
|
||||
SelectUser(usize),
|
||||
SelectedUserDelete(u64),
|
||||
SelectedUserSetAdmin(u64, bool),
|
||||
ToggleEdit(usize, EditorField),
|
||||
}
|
||||
|
||||
impl From<Message> for crate::app::Message {
|
||||
fn from(message: Message) -> Self {
|
||||
crate::pages::Message::User(message).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Message> for crate::pages::Message {
|
||||
fn from(message: Message) -> Self {
|
||||
crate::pages::Message::User(message)
|
||||
}
|
||||
}
|
||||
|
||||
impl page::Page<crate::pages::Message> for Page {
|
||||
fn set_id(&mut self, entity: page::Entity) {
|
||||
self.entity = entity;
|
||||
}
|
||||
|
||||
fn content(
|
||||
&self,
|
||||
sections: &mut SlotMap<section::Entity, Section<crate::pages::Message>>,
|
||||
) -> Option<page::Content> {
|
||||
Some(vec![sections.insert(user_list())])
|
||||
}
|
||||
|
||||
fn info(&self) -> page::Info {
|
||||
page::Info::new("users", "system-users-symbolic")
|
||||
.title(fl!("users"))
|
||||
.description(fl!("users", "desc"))
|
||||
}
|
||||
|
||||
fn dialog(&self) -> Option<Element<pages::Message>> {
|
||||
let dialog = self.dialog.as_ref()?;
|
||||
let theme = cosmic::theme::active();
|
||||
let theme = theme.cosmic();
|
||||
|
||||
let dialog_element = match dialog {
|
||||
Dialog::AddNewUser(user) => {
|
||||
let full_name_input = widget::container(
|
||||
widget::text_input("", &user.full_name)
|
||||
.label(&self.fullname_label)
|
||||
.on_input(|value| {
|
||||
Message::Dialog(Some(Dialog::AddNewUser(User {
|
||||
full_name: value,
|
||||
..user.clone()
|
||||
})))
|
||||
}),
|
||||
)
|
||||
.padding([0, theme.space_s().into()]);
|
||||
|
||||
let username_input = widget::container(
|
||||
widget::text_input("", &user.username)
|
||||
.label(&self.username_label)
|
||||
.on_input(|value| {
|
||||
Message::Dialog(Some(Dialog::AddNewUser(User {
|
||||
username: value,
|
||||
..user.clone()
|
||||
})))
|
||||
}),
|
||||
)
|
||||
.padding([0, theme.space_s().into()]);
|
||||
|
||||
let password_input = widget::container(
|
||||
widget::text_input("", &user.password)
|
||||
.password()
|
||||
.label(&self.password_label)
|
||||
.on_input(|value| {
|
||||
Message::Dialog(Some(Dialog::AddNewUser(User {
|
||||
password: value,
|
||||
..user.clone()
|
||||
})))
|
||||
}),
|
||||
)
|
||||
.padding([0, theme.space_s().into()]);
|
||||
|
||||
let admin_toggler = widget::toggler(user.is_admin).on_toggle(|value| {
|
||||
Message::Dialog(Some(Dialog::AddNewUser(User {
|
||||
is_admin: value,
|
||||
..user.clone()
|
||||
})))
|
||||
});
|
||||
|
||||
let add_user_button = widget::button::suggested(fl!("add-user"))
|
||||
.on_press(())
|
||||
.apply(Element::from)
|
||||
.map(|_| {
|
||||
Message::NewUser(
|
||||
user.username.clone(),
|
||||
user.full_name.clone(),
|
||||
user.password.clone(),
|
||||
user.is_admin,
|
||||
)
|
||||
});
|
||||
|
||||
let cancel_button =
|
||||
widget::button::standard(fl!("cancel")).on_press(Message::Dialog(None));
|
||||
|
||||
widget::dialog()
|
||||
.title(fl!("add-user"))
|
||||
.control(
|
||||
widget::ListColumn::default()
|
||||
.add(full_name_input)
|
||||
.add(username_input)
|
||||
.add(password_input)
|
||||
.add(settings::item_row(vec![
|
||||
column::with_capacity(2)
|
||||
.push(text::body(crate::fl!("administrator")))
|
||||
.push(text::caption(crate::fl!("administrator", "desc")))
|
||||
.into(),
|
||||
widget::horizontal_space().width(Length::Fill).into(),
|
||||
admin_toggler.into(),
|
||||
])),
|
||||
)
|
||||
.primary_action(add_user_button)
|
||||
.secondary_action(cancel_button)
|
||||
.apply(cosmic::Element::from)
|
||||
}
|
||||
};
|
||||
|
||||
dialog_element.map(crate::pages::Message::User).into()
|
||||
}
|
||||
|
||||
fn on_enter(
|
||||
&mut self,
|
||||
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
|
||||
) -> cosmic::Task<crate::pages::Message> {
|
||||
if let Some(handle) = self.on_enter_handle.take() {
|
||||
handle.abort();
|
||||
}
|
||||
|
||||
let (task, handle) = cosmic::task::future(async { Self::reload().await }).abortable();
|
||||
self.on_enter_handle = Some(handle);
|
||||
task
|
||||
}
|
||||
|
||||
fn on_leave(&mut self) -> cosmic::Task<crate::pages::Message> {
|
||||
if let Some(handle) = self.on_enter_handle.take() {
|
||||
handle.abort();
|
||||
}
|
||||
|
||||
cosmic::Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
impl Page {
|
||||
pub async fn reload() -> Message {
|
||||
let passwd_users = getent::passwd(uid_range());
|
||||
let mut users = Vec::with_capacity(passwd_users.len());
|
||||
let groups = getent::group();
|
||||
|
||||
let uid = rustix::process::getuid().as_raw() as u64;
|
||||
|
||||
let admin_group = groups.iter().find(|g| &*g.name == "sudo");
|
||||
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
tracing::error!("unable to access dbus system service");
|
||||
return Message::LoadPage(uid, Vec::new());
|
||||
};
|
||||
|
||||
for user in passwd_users {
|
||||
let Ok(user_proxy) = accounts_zbus::UserProxy::from_uid(&conn, user.uid).await else {
|
||||
continue;
|
||||
};
|
||||
|
||||
users.push(User {
|
||||
id: user.uid,
|
||||
profile_icon: user_proxy
|
||||
.icon_file()
|
||||
.await
|
||||
.ok()
|
||||
.map(|path| icon::from_path(PathBuf::from(path))),
|
||||
is_admin: match user_proxy.account_type().await {
|
||||
Ok(1) => true,
|
||||
Ok(_) => false,
|
||||
Err(_) => {
|
||||
admin_group.map_or(false, |group| group.users.contains(&user.username))
|
||||
}
|
||||
},
|
||||
username: String::from(user.username),
|
||||
full_name: String::from(user.full_name),
|
||||
password: String::new(),
|
||||
full_name_edit: false,
|
||||
password_edit: false,
|
||||
username_edit: false,
|
||||
});
|
||||
}
|
||||
|
||||
Message::LoadPage(uid, users)
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> cosmic::Task<crate::app::Message> {
|
||||
match message {
|
||||
Message::None => (),
|
||||
|
||||
Message::ChangedAccountType(uid, is_admin) => {
|
||||
for user in &mut self.users {
|
||||
if user.id == uid {
|
||||
user.is_admin = is_admin;
|
||||
return cosmic::Task::none();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Message::LoadedIcon(uid, handle) => {
|
||||
for user in &mut self.users {
|
||||
if user.id == uid {
|
||||
user.profile_icon = Some(handle);
|
||||
return cosmic::Task::none();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Message::SelectProfileImage(uid) => {
|
||||
return cosmic::task::future(async move {
|
||||
let dialog_result = file_chooser::open::Dialog::new()
|
||||
.title(fl!("wallpaper", "folder-dialog"))
|
||||
.accept_label(fl!("dialog-add"))
|
||||
.modal(false)
|
||||
.open_file()
|
||||
.await
|
||||
.map(|response| response.url().to_owned());
|
||||
|
||||
Message::SelectedProfileImage(uid, Arc::new(dialog_result))
|
||||
});
|
||||
}
|
||||
|
||||
Message::SelectedProfileImage(uid, image_result) => {
|
||||
let url = match Arc::into_inner(image_result).unwrap() {
|
||||
Ok(url) => url,
|
||||
Err(why) => {
|
||||
tracing::error!(?why, "failed to get image file");
|
||||
return cosmic::Task::none();
|
||||
}
|
||||
};
|
||||
|
||||
return cosmic::task::future(async move {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
return Message::None;
|
||||
};
|
||||
|
||||
let Ok(user) = accounts_zbus::UserProxy::from_uid(&conn, uid).await else {
|
||||
return Message::None;
|
||||
};
|
||||
|
||||
let Ok(path) = url.to_file_path() else {
|
||||
tracing::error!("selected image is not a file path");
|
||||
return Message::None;
|
||||
};
|
||||
|
||||
let result = request_permission_on_denial(&conn, || {
|
||||
user.set_icon_file(path.to_str().unwrap())
|
||||
})
|
||||
.await;
|
||||
|
||||
if let Err(why) = result {
|
||||
tracing::error!(?why, "failed to set profile icon");
|
||||
return Message::None;
|
||||
}
|
||||
|
||||
Message::LoadedIcon(uid, icon::from_path(path))
|
||||
});
|
||||
}
|
||||
|
||||
Message::Edit(id, field, value) => {
|
||||
if let Some(user) = self.users.get_mut(id) {
|
||||
match field {
|
||||
EditorField::FullName => user.full_name = value,
|
||||
EditorField::Password => user.password = value,
|
||||
EditorField::Username => user.username = value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Message::ToggleEdit(id, field) => {
|
||||
if let Some(user) = self.users.get_mut(id) {
|
||||
match field {
|
||||
EditorField::FullName => user.full_name_edit = !user.full_name_edit,
|
||||
EditorField::Password => user.password_edit = !user.password_edit,
|
||||
EditorField::Username => user.username_edit = !user.username_edit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Message::ApplyEdit(id, field) => {
|
||||
if let Some(user) = self.users.get_mut(id) {
|
||||
let uid = user.id;
|
||||
|
||||
match field {
|
||||
EditorField::FullName => {
|
||||
let full_name = user.full_name.clone();
|
||||
return cosmic::Task::future(async move {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(user) = accounts_zbus::UserProxy::from_uid(&conn, uid).await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
_ = request_permission_on_denial(&conn, || {
|
||||
user.set_real_name(&full_name)
|
||||
})
|
||||
.await;
|
||||
})
|
||||
.discard();
|
||||
}
|
||||
|
||||
EditorField::Password => {
|
||||
let password = std::mem::take(&mut user.password);
|
||||
|
||||
return cosmic::Task::future(async move {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(user) = accounts_zbus::UserProxy::from_uid(&conn, uid).await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
match request_permission_on_denial(&conn, || {
|
||||
user.set_password(&password, "")
|
||||
})
|
||||
.await
|
||||
{
|
||||
Err(why) => {
|
||||
tracing::error!(?why, "failed to set password");
|
||||
}
|
||||
|
||||
Ok(_) => (),
|
||||
}
|
||||
})
|
||||
.discard();
|
||||
}
|
||||
|
||||
EditorField::Username => {
|
||||
let username = user.username.clone();
|
||||
return cosmic::Task::future(async move {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(user) = accounts_zbus::UserProxy::from_uid(&conn, uid).await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
_ = request_permission_on_denial(&conn, || {
|
||||
user.set_user_name(&username)
|
||||
})
|
||||
.await;
|
||||
})
|
||||
.discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Message::LoadPage(uid, users) => {
|
||||
self.current_user_id = uid;
|
||||
self.users = users;
|
||||
}
|
||||
|
||||
Message::SelectUser(user_idx) => {
|
||||
match self.selected_user_idx {
|
||||
Some(currently_selected_idx) if currently_selected_idx == user_idx => {
|
||||
self.selected_user_idx = None;
|
||||
}
|
||||
_ => {
|
||||
self.selected_user_idx = Some(user_idx);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Message::SelectedUserDelete(uid) => {
|
||||
return cosmic::task::future(async move {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
return Message::None;
|
||||
};
|
||||
|
||||
let accounts = accounts_zbus::AccountsProxy::new(&conn).await.unwrap();
|
||||
|
||||
let result = request_permission_on_denial(&conn, || {
|
||||
accounts.delete_user(uid as i64, false)
|
||||
})
|
||||
.await;
|
||||
|
||||
if let Err(why) = result {
|
||||
tracing::error!(?why, "failed to delete user account");
|
||||
return Message::None;
|
||||
}
|
||||
|
||||
Message::DeletedUser(uid)
|
||||
});
|
||||
}
|
||||
|
||||
Message::DeletedUser(uid) => {
|
||||
self.users.retain(|user| user.id != uid);
|
||||
}
|
||||
|
||||
Message::Dialog(dialog) => {
|
||||
self.dialog = dialog;
|
||||
}
|
||||
|
||||
Message::NewUser(username, full_name, password, is_admin) => {
|
||||
self.dialog = None;
|
||||
|
||||
return cosmic::task::future(async move {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
return Message::None;
|
||||
};
|
||||
|
||||
let accounts = accounts_zbus::AccountsProxy::new(&conn).await.unwrap();
|
||||
|
||||
let user_result = request_permission_on_denial(&conn, || {
|
||||
accounts.create_user(&username, &full_name, if is_admin { 1 } else { 0 })
|
||||
})
|
||||
.await;
|
||||
|
||||
let user_object_path = match user_result {
|
||||
Ok(path) => path,
|
||||
|
||||
Err(why) => {
|
||||
tracing::error!(?why, "failed to create user account");
|
||||
return Message::None;
|
||||
}
|
||||
};
|
||||
|
||||
match accounts_zbus::UserProxy::new(&conn, user_object_path).await {
|
||||
Ok(user) => {
|
||||
_ = user.set_password(&password, "").await;
|
||||
_ = user.set_icon_file(DEFAULT_ICON_FILE).await
|
||||
}
|
||||
|
||||
Err(why) => {
|
||||
tracing::error!(?why, "failed to get user by object path");
|
||||
}
|
||||
}
|
||||
|
||||
Self::reload().await
|
||||
});
|
||||
}
|
||||
|
||||
Message::SelectedUserSetAdmin(uid, is_admin) => {
|
||||
return cosmic::task::future(async move {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
return Message::None;
|
||||
};
|
||||
|
||||
let Ok(user) = accounts_zbus::UserProxy::from_uid(&conn, uid).await else {
|
||||
return Message::None;
|
||||
};
|
||||
|
||||
let result = request_permission_on_denial(&conn, || async {
|
||||
user.set_account_type(if is_admin { 1 } else { 0 }).await
|
||||
})
|
||||
.await;
|
||||
|
||||
if let Err(why) = result {
|
||||
tracing::error!(?why, "failed to change account type of user");
|
||||
return Message::None;
|
||||
}
|
||||
|
||||
Message::ChangedAccountType(uid, is_admin)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
cosmic::Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
fn user_list() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let user_type_standard = descriptions.insert(fl!("users", "standard"));
|
||||
let user_type_admin = descriptions.insert(fl!("users", "admin"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
let theme = cosmic::theme::active();
|
||||
let theme = theme.cosmic();
|
||||
|
||||
let cosmic::cosmic_theme::Spacing {
|
||||
space_xxs, space_m, ..
|
||||
} = theme::active().cosmic().spacing;
|
||||
|
||||
let users_list = page
|
||||
.users
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(idx, user)| {
|
||||
let expanded =
|
||||
matches!(page.selected_user_idx, Some(user_idx) if user_idx == idx);
|
||||
|
||||
let username =
|
||||
widget::editable_input("", &user.username, user.username_edit, move |_| {
|
||||
Message::ToggleEdit(idx, EditorField::Username)
|
||||
})
|
||||
.on_input(move |name| Message::Edit(idx, EditorField::Username, name))
|
||||
.on_submit(Message::ApplyEdit(idx, EditorField::Username));
|
||||
|
||||
let password =
|
||||
widget::editable_input("", &user.password, user.password_edit, move |_| {
|
||||
Message::ToggleEdit(idx, EditorField::Password)
|
||||
})
|
||||
.on_input(move |pass| Message::Edit(idx, EditorField::Password, pass))
|
||||
.on_submit(Message::ApplyEdit(idx, EditorField::Password))
|
||||
.password();
|
||||
|
||||
let fullname = widget::editable_input(
|
||||
"",
|
||||
&user.full_name,
|
||||
user.full_name_edit,
|
||||
move |_| Message::ToggleEdit(idx, EditorField::FullName),
|
||||
)
|
||||
.on_input(move |name| Message::Edit(idx, EditorField::FullName, name))
|
||||
.on_submit(Message::ApplyEdit(idx, EditorField::FullName));
|
||||
|
||||
let fullname_text = text::body(&user.full_name);
|
||||
|
||||
let account_type = text::caption(if user.is_admin {
|
||||
&descriptions[user_type_admin]
|
||||
} else {
|
||||
&descriptions[user_type_standard]
|
||||
});
|
||||
|
||||
let expanded_details = expanded.then(|| {
|
||||
let mut details_list = widget::list_column()
|
||||
.add(settings::item(&page.fullname_label, fullname))
|
||||
.add(settings::item(&page.username_label, username))
|
||||
.add(settings::item(&page.password_label, password))
|
||||
.add(settings::item_row(vec![
|
||||
column::with_capacity(2)
|
||||
.push(text::body(crate::fl!("administrator")))
|
||||
.push(text::caption(crate::fl!("administrator", "desc")))
|
||||
.into(),
|
||||
widget::horizontal_space().width(Length::Fill).into(),
|
||||
widget::toggler(user.is_admin)
|
||||
.on_toggle(|enabled| {
|
||||
Message::SelectedUserSetAdmin(user.id, enabled)
|
||||
})
|
||||
.into(),
|
||||
]));
|
||||
|
||||
if page.users.len() > 1 {
|
||||
details_list = details_list.add(settings::item_row(vec![
|
||||
widget::horizontal_space().width(Length::Fill).into(),
|
||||
widget::button::destructive(crate::fl!("remove-user"))
|
||||
.on_press(Message::SelectedUserDelete(user.id))
|
||||
.into(),
|
||||
]));
|
||||
}
|
||||
|
||||
details_list.apply(cosmic::Element::from)
|
||||
});
|
||||
|
||||
let profile_icon_handle = user
|
||||
.profile_icon
|
||||
.clone()
|
||||
.unwrap_or_else(|| page.default_icon.clone());
|
||||
|
||||
let profile_icon = widget::button::icon(profile_icon_handle)
|
||||
.large()
|
||||
.on_press(Message::SelectProfileImage(user.id));
|
||||
|
||||
let account_details_content = settings::item_row(vec![
|
||||
widget::row::with_capacity(2)
|
||||
.push(profile_icon)
|
||||
.push(
|
||||
column::with_capacity(2)
|
||||
.push(fullname_text)
|
||||
.push(account_type),
|
||||
)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(theme.space_xxs())
|
||||
.into(),
|
||||
widget::horizontal_space().width(Length::Fill).into(),
|
||||
icon::from_name(if expanded {
|
||||
"go-up-symbolic"
|
||||
} else {
|
||||
"go-next-symbolic"
|
||||
})
|
||||
.icon()
|
||||
.size(16)
|
||||
.into(),
|
||||
]);
|
||||
|
||||
let account_details = Some(
|
||||
widget::button::custom(account_details_content)
|
||||
.padding([space_xxs, space_m])
|
||||
.on_press(Message::SelectUser(idx))
|
||||
.class(cosmic::theme::Button::ListItem)
|
||||
.selected(expanded)
|
||||
.apply(cosmic::Element::from),
|
||||
);
|
||||
|
||||
vec![account_details, expanded_details]
|
||||
})
|
||||
.flatten()
|
||||
.fold(
|
||||
widget::list_column()
|
||||
.spacing(0)
|
||||
.padding(0)
|
||||
.divider_padding(0)
|
||||
.list_item_padding(0),
|
||||
widget::ListColumn::add,
|
||||
)
|
||||
.apply(|list| cosmic::Element::from(settings::section::with_column(list)));
|
||||
|
||||
let add_user = widget::button::standard(crate::fl!("add-user"))
|
||||
.on_press(Message::Dialog(Some(Dialog::AddNewUser(User::default()))))
|
||||
.apply(widget::container)
|
||||
.width(Length::Fill)
|
||||
.align_x(Alignment::End);
|
||||
|
||||
widget::column::with_capacity(2)
|
||||
.push(users_list)
|
||||
.push(add_user)
|
||||
.spacing(space_m)
|
||||
.apply(Element::from)
|
||||
.map(crate::pages::Message::User)
|
||||
})
|
||||
}
|
||||
|
||||
async fn check_authorization(conn: &zbus::Connection) -> anyhow::Result<()> {
|
||||
let proxy = zbus_polkit::policykit1::AuthorityProxy::new(conn).await?;
|
||||
let subject = zbus_polkit::policykit1::Subject::new_for_owner(std::process::id(), None, None)?;
|
||||
proxy
|
||||
.check_authorization(
|
||||
&subject,
|
||||
USERS_ADMIN_POLKIT_POLICY_ID,
|
||||
&HashMap::new(),
|
||||
CheckAuthorizationFlags::AllowUserInteraction.into(),
|
||||
"",
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn uid_range() -> (u64, u64) {
|
||||
let (mut min, mut max) = (1000, 60000);
|
||||
let Ok(file) = std::fs::File::open("/etc/login.defs") else {
|
||||
return (min, max);
|
||||
};
|
||||
|
||||
let mut reader = BufReader::new(file);
|
||||
let mut line = String::new();
|
||||
|
||||
loop {
|
||||
line.clear();
|
||||
match reader.read_line(&mut line) {
|
||||
Ok(0) | Err(_) => break,
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let line = line.trim();
|
||||
|
||||
let variable = if line.starts_with("UID_MIN ") {
|
||||
&mut min
|
||||
} else if line.starts_with("UID_MAX ") {
|
||||
&mut max
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Some(value) = line
|
||||
.split_ascii_whitespace()
|
||||
.nth(1)
|
||||
.and_then(|value| value.parse::<u64>().ok())
|
||||
{
|
||||
*variable = value;
|
||||
}
|
||||
}
|
||||
|
||||
(min, max)
|
||||
}
|
||||
|
||||
async fn request_permission_on_denial<T, Fun, Fut>(
|
||||
conn: &zbus::Connection,
|
||||
action: Fun,
|
||||
) -> zbus::Result<T>
|
||||
where
|
||||
Fun: Fn() -> Fut,
|
||||
Fut: Future<Output = zbus::Result<T>>,
|
||||
{
|
||||
match action().await {
|
||||
Ok(value) => Ok(value),
|
||||
Err(why) => {
|
||||
if permission_was_denied(&why) {
|
||||
_ = check_authorization(conn).await;
|
||||
action().await
|
||||
} else {
|
||||
Err(why)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn permission_was_denied(result: &zbus::Error) -> bool {
|
||||
match result {
|
||||
zbus::Error::MethodError(name, _, _)
|
||||
if name.as_str() == "org.freedesktop.Accounts.Error.PermissionDenied" =>
|
||||
{
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
1
debian/install
vendored
1
debian/install
vendored
|
|
@ -29,6 +29,7 @@
|
|||
/usr/share/applications/com.system76.CosmicSettings.Wireless.desktop
|
||||
/usr/share/applications/com.system76.CosmicSettings.Workspaces.desktop
|
||||
/usr/share/metainfo/com.system76.CosmicSettings.metainfo.xml
|
||||
/usr/share/polkit-1/actions/com.system76.CosmicSettings.Users.policy
|
||||
/usr/share/polkit-1/rules.d/cosmic-settings.rules
|
||||
/usr/share/cosmic/com.system76.CosmicTheme.Dark
|
||||
/usr/share/cosmic/com.system76.CosmicTheme.Dark.Builder
|
||||
|
|
|
|||
|
|
@ -772,6 +772,18 @@ firmware = Firmware
|
|||
|
||||
users = Users
|
||||
.desc = Authentication and user accounts.
|
||||
.admin = Admin
|
||||
.standard = Standard
|
||||
.profile-add = Choose profile image
|
||||
|
||||
administrator = Administrator
|
||||
.desc = Administrators can change settings for all users, add and remove other users.
|
||||
|
||||
add-user = Add user
|
||||
remove-user = Remove user
|
||||
full-name = Full name
|
||||
username = Username
|
||||
password = Password
|
||||
|
||||
## System: Default Applications
|
||||
|
||||
|
|
|
|||
10
justfile
10
justfile
|
|
@ -20,6 +20,12 @@ metainfo := appid + '.metainfo.xml'
|
|||
metainfo-src := 'resources' / metainfo
|
||||
metainfo-dst := clean(rootdir / prefix) / 'share' / 'metainfo' / metainfo
|
||||
|
||||
polkit-actions-src := 'resources' / 'polkit-1' / 'actions'
|
||||
polkit-actions-dst := clean(rootdir / prefix) / 'share' / 'polkit-1' / 'actions'
|
||||
|
||||
policy-users-src := polkit-actions-src / appid + '.Users.policy'
|
||||
policy-users-dst := polkit-actions-dst / appid + '.Users.policy'
|
||||
|
||||
polkit-rules-src := 'resources' / 'polkit-1' / 'rules.d' / 'cosmic-settings.rules'
|
||||
polkit-rules-dst := clean(rootdir / prefix) / 'share' / 'polkit-1' / 'rules.d' / 'cosmic-settings.rules'
|
||||
|
||||
|
|
@ -91,10 +97,12 @@ install-desktop-entries:
|
|||
install -Dm0644 'resources/{{entry-workspaces}}' '{{appdir}}/{{entry-workspaces}}'
|
||||
|
||||
# Install everything
|
||||
install: install-desktop-entries (install-bin bin-src bin-dest) (install-file metainfo-src metainfo-dst) (install-file polkit-rules-src polkit-rules-dst)
|
||||
install: install-desktop-entries (install-bin bin-src bin-dest) (install-file metainfo-src metainfo-dst) install-polkit-files
|
||||
find 'resources'/'default_schema' -type f -exec echo {} \; | rev | cut -d'/' -f-3 | rev | xargs -d '\n' -I {} install -Dm0644 'resources'/'default_schema'/{} {{default-schema-target}}/{}
|
||||
find 'resources'/'icons' -type f -exec echo {} \; | rev | cut -d'/' -f-3 | rev | xargs -d '\n' -I {} install -Dm0644 'resources'/'icons'/{} {{iconsdir}}/{}
|
||||
|
||||
install-polkit-files: (install-file polkit-rules-src polkit-rules-dst) (install-file policy-users-src policy-users-dst)
|
||||
|
||||
[private]
|
||||
install-cmd options src dest:
|
||||
install {{options}} {{src}} {{dest}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
|
||||
<policyconfig>
|
||||
<vendor>System76</vendor>
|
||||
<vendor_url>https://system76.com/</vendor_url>
|
||||
|
||||
<action id="com.system76.CosmicSettings.Users.Admin">
|
||||
<description>Manage user accounts</description>
|
||||
<message>Authentication is required to change user data</message>
|
||||
<defaults>
|
||||
<allow_any>no</allow_any>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.accounts.user-administration org.freedesktop.accounts.change-own-user-data org.freedesktop.accounts.change-own-password org.freedesktop.realmd.configure-realm org.freedesktop.realmd.login-policy org.freedesktop.MalcontentControl.administration com.endlessm.ParentalControls.AppFilter.ReadAny com.endlessm.ParentalControls.AppFilter.ChangeAny com.endlessm.ParentalControls.AppFilter.ReadOwn com.endlessm.ParentalControls.AppFilter.ChangeOwn</annotate>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
||||
Loading…
Add table
Add a link
Reference in a new issue