diff --git a/Cargo.lock b/Cargo.lock index edd6d962..4d7a9824 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,12 +107,6 @@ dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.0" @@ -337,7 +331,7 @@ dependencies = [ "async-task", "concurrent-queue", "fastrand 2.1.1", - "futures-lite 2.3.0", + "futures-lite 2.4.0", "slab", ] @@ -349,7 +343,7 @@ checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ "async-lock 3.4.0", "blocking", - "futures-lite 2.3.0", + "futures-lite 2.4.0", ] [[package]] @@ -382,10 +376,10 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.4.0", "parking", "polling 3.7.3", - "rustix 0.38.37", + "rustix 0.38.38", "slab", "tracing", "windows-sys 0.59.0", @@ -419,7 +413,7 @@ checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ "async-io 2.3.4", "blocking", - "futures-lite 2.3.0", + "futures-lite 2.4.0", ] [[package]] @@ -435,7 +429,7 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.37", + "rustix 0.38.38", "windows-sys 0.48.0", ] @@ -453,8 +447,8 @@ dependencies = [ "blocking", "cfg-if", "event-listener 5.3.1", - "futures-lite 2.3.0", - "rustix 0.38.37", + "futures-lite 2.4.0", + "rustix 0.38.38", "tracing", ] @@ -481,7 +475,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.37", + "rustix 0.38.38", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -515,7 +509,7 @@ name = "atomicwrites" version = "0.4.2" source = "git+https://github.com/jackpot51/rust-atomicwrites#043ab4859d53ffd3d55334685303d8df39c9f768" dependencies = [ - "rustix 0.38.37", + "rustix 0.38.38", "tempfile", "windows-sys 0.48.0", ] @@ -583,7 +577,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide 0.8.0", + "miniz_oxide", "object", "rustc-demangle", "windows-targets 0.52.6", @@ -679,7 +673,7 @@ dependencies = [ "async-channel", "async-task", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.4.0", "piper", ] @@ -781,7 +775,7 @@ dependencies = [ "bitflags 2.6.0", "log", "polling 3.7.3", - "rustix 0.38.37", + "rustix 0.38.38", "slab", "thiserror", ] @@ -793,7 +787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", - "rustix 0.38.37", + "rustix 0.38.38", "wayland-backend", "wayland-client", ] @@ -1091,7 +1085,7 @@ dependencies = [ "once_cell", "rand", "rust-embed 8.5.0", - "rustix 0.38.37", + "rustix 0.38.38", "serde", "switcheroo-control", "tokio", @@ -1110,6 +1104,24 @@ dependencies = [ "serde", ] +[[package]] +name = "cosmic-applet-a11y" +version = "0.1.0" +dependencies = [ + "cosmic-dbus-a11y", + "cosmic-time", + "i18n-embed 0.14.1", + "i18n-embed-fl 0.8.0", + "libcosmic", + "once_cell", + "rust-embed 8.5.0", + "tokio", + "tracing", + "tracing-log", + "tracing-subscriber", + "zbus 4.4.0", +] + [[package]] name = "cosmic-applet-audio" version = "0.1.1" @@ -1204,7 +1216,7 @@ dependencies = [ "memmap2 0.9.5", "once_cell", "rust-embed 8.5.0", - "rustix 0.38.37", + "rustix 0.38.38", "tokio", "tracing", "tracing-log", @@ -1266,7 +1278,7 @@ dependencies = [ "logind-zbus", "once_cell", "rust-embed 8.5.0", - "rustix 0.38.37", + "rustix 0.38.38", "tracing", "tracing-log", "tracing-subscriber", @@ -1352,6 +1364,7 @@ name = "cosmic-applets" version = "0.1.1" dependencies = [ "cosmic-app-list", + "cosmic-applet-a11y", "cosmic-applet-audio", "cosmic-applet-battery", "cosmic-applet-bluetooth", @@ -1395,7 +1408,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1417,12 +1430,20 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "quote", "syn 1.0.109", ] +[[package]] +name = "cosmic-dbus-a11y" +version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings?branch=a11y#ed426a515c5c63f22f85b5027d4ff01967e1cc6f" +dependencies = [ + "zbus 4.4.0", +] + [[package]] name = "cosmic-dbus-networkmanager" version = "0.1.0" @@ -1521,7 +1542,7 @@ dependencies = [ "itertools 0.13.0", "libpulse-binding", "log", - "rustix 0.38.37", + "rustix 0.38.38", "secure-string", "thiserror", "tokio", @@ -1557,7 +1578,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "almost", "cosmic-config", @@ -2024,7 +2045,7 @@ dependencies = [ "bytemuck", "drm-ffi", "drm-fourcc", - "rustix 0.38.37", + "rustix 0.38.38", ] [[package]] @@ -2034,7 +2055,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" dependencies = [ "drm-sys", - "rustix 0.38.37", + "rustix 0.38.38", ] [[package]] @@ -2167,15 +2188,14 @@ dependencies = [ [[package]] name = "exr" -version = "1.72.0" +version = "1.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" dependencies = [ "bit_field", - "flume", "half", "lebe", - "miniz_oxide 0.7.4", + "miniz_oxide", "rayon-core", "smallvec", "zune-inflate", @@ -2214,9 +2234,9 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdeflate" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] @@ -2260,7 +2280,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", - "miniz_oxide 0.8.0", + "miniz_oxide", ] [[package]] @@ -2322,15 +2342,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "spin", -] - [[package]] name = "fnv" version = "1.0.7" @@ -2546,9 +2557,9 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "3f1fa2f9765705486b33fd2acf1577f8ec449c2ba1f318ae5447697b7c08d210" dependencies = [ "fastrand 2.1.1", "futures-core", @@ -2987,7 +2998,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "dnd", "iced_accessibility", @@ -3005,7 +3016,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "accesskit", "accesskit_winit", @@ -3014,7 +3025,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "bitflags 2.6.0", "bytes", @@ -3038,7 +3049,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "futures", "iced_core", @@ -3064,7 +3075,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "bitflags 2.6.0", "bytemuck", @@ -3086,7 +3097,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3098,7 +3109,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "bytes", "dnd", @@ -3113,7 +3124,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "bytemuck", "cosmic-text", @@ -3129,7 +3140,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "as-raw-xcb-connection", "bitflags 2.6.0", @@ -3145,7 +3156,7 @@ dependencies = [ "raw-window-handle", "resvg", "rustc-hash 2.0.0", - "rustix 0.38.37", + "rustix 0.38.38", "smithay-client-toolkit", "thiserror", "tiny-xlib", @@ -3160,7 +3171,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "dnd", "iced_renderer", @@ -3178,7 +3189,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "dnd", "iced_futures", @@ -3919,7 +3930,7 @@ checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#842cd2ec9418e64911c60588fe70a1ce9c45a1b7" +source = "git+https://github.com/pop-os/libcosmic#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "apply", "ashpd 0.9.2", @@ -3948,7 +3959,7 @@ dependencies = [ "palette", "rfd", "ron", - "rustix 0.38.37", + "rustix 0.38.38", "serde", "shlex", "slotmap", @@ -3983,9 +3994,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libpulse-binding" @@ -4257,15 +4268,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -5105,7 +5107,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.8.0", + "miniz_oxide", ] [[package]] @@ -5134,7 +5136,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.37", + "rustix 0.38.38", "tracing", "windows-sys 0.59.0", ] @@ -5241,7 +5243,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.37", + "rustix 0.38.38", ] [[package]] @@ -5640,9 +5642,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags 2.6.0", "errno", @@ -5751,9 +5753,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] @@ -5772,9 +5774,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", @@ -5927,7 +5929,7 @@ dependencies = [ "log", "memmap2 0.9.5", "pkg-config", - "rustix 0.38.37", + "rustix 0.38.38", "thiserror", "wayland-backend", "wayland-client", @@ -5999,7 +6001,7 @@ dependencies = [ "objc", "raw-window-handle", "redox_syscall 0.4.1", - "rustix 0.38.37", + "rustix 0.38.38", "tiny-xlib", "wasm-bindgen", "wayland-backend", @@ -6010,15 +6012,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "spirv" version = "0.3.0+sdk-1.3.268.0" @@ -6186,7 +6179,7 @@ dependencies = [ "cfg-if", "fastrand 2.1.1", "once_cell", - "rustix 0.38.37", + "rustix 0.38.38", "windows-sys 0.59.0", ] @@ -6688,9 +6681,9 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "ustr" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e904a2279a4a36d2356425bb20be271029cc650c335bc82af8bfae30085a3d0" +checksum = "18b19e258aa08450f93369cf56dd78063586adf19e92a75b338a800f799a0208" dependencies = [ "ahash", "byteorder", @@ -6871,7 +6864,7 @@ checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.37", + "rustix 0.38.38", "scoped-tls", "smallvec", "wayland-sys", @@ -6884,7 +6877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" dependencies = [ "bitflags 2.6.0", - "rustix 0.38.37", + "rustix 0.38.38", "wayland-backend", "wayland-scanner", ] @@ -6906,7 +6899,7 @@ version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" dependencies = [ - "rustix 0.38.37", + "rustix 0.38.38", "wayland-client", "xcursor", ] @@ -6971,7 +6964,7 @@ dependencies = [ "bitflags 2.6.0", "downcast-rs", "io-lifetimes 2.0.3", - "rustix 0.38.37", + "rustix 0.38.38", "wayland-backend", "wayland-scanner", ] @@ -7148,7 +7141,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -7489,7 +7482,7 @@ dependencies = [ "pin-project", "raw-window-handle", "redox_syscall 0.4.1", - "rustix 0.38.37", + "rustix 0.38.38", "sctk-adwaita", "smithay-client-toolkit", "smol_str", @@ -7564,7 +7557,7 @@ dependencies = [ "libc", "libloading", "once_cell", - "rustix 0.38.37", + "rustix 0.38.38", "x11rb-protocol", ] diff --git a/Cargo.toml b/Cargo.toml index b753bebe..0c340a60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ members = [ "cosmic-applet-workspaces", "cosmic-panel-button", "cosmic-applet-input-sources", + "cosmic-applet-a11y", ] resolver = "2" @@ -69,7 +70,6 @@ freedesktop-desktop-entry = "0.7.5" [profile.release] lto = "fat" - [workspace.metadata.cargo-machete] ignored = ["libcosmic"] # [patch."https://github.com/pop-os/libcosmic"] diff --git a/cosmic-applet-a11y/Cargo.toml b/cosmic-applet-a11y/Cargo.toml new file mode 100644 index 00000000..83dcdb3a --- /dev/null +++ b/cosmic-applet-a11y/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "cosmic-applet-a11y" +version = "0.1.0" +edition = "2021" + +[dependencies] +cosmic-dbus-a11y = { git = "https://github.com/pop-os/dbus-settings-bindings", branch = "a11y" } +# cosmic-dbus-a11y = { path = "../../dbus-settings-bindings/a11y" } +cosmic-time.workspace = true +i18n-embed-fl.workspace = true +i18n-embed.workspace = true +libcosmic.workspace = true +rust-embed.workspace = true +once_cell = "1" +tokio = { version = "1.36.0", features = ["sync", "time", "macros"] } +tracing-log.workspace = true +tracing-subscriber.workspace = true +tracing.workspace = true +zbus.workspace = true diff --git a/cosmic-applet-a11y/data/com.system76.CosmicAppletA11y.desktop b/cosmic-applet-a11y/data/com.system76.CosmicAppletA11y.desktop new file mode 100644 index 00000000..86a10ca5 --- /dev/null +++ b/cosmic-applet-a11y/data/com.system76.CosmicAppletA11y.desktop @@ -0,0 +1,18 @@ +[Desktop Entry] +Name=Accessibility +Type=Application +Exec=cosmic-applet-a11y +Terminal=false +Categories=COSMIC; +Keywords=COSMIC;Iced; +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=preferences-desktop-accessibility +StartupNotify=true +NoDisplay=true +X-CosmicApplet=true +# Indicates that the auto-hover click should go to the "end" of the hover popup +X-CosmicHoverPopup=Center +X-OverflowPriority=10 +X-CosmicApplet=true +X-CosmicHoverPopup=Auto +X-OverflowPriority=10 \ No newline at end of file diff --git a/cosmic-applet-a11y/data/icons/scalable/apps/com.system76.CosmicAppletA11y-symbolic.svg b/cosmic-applet-a11y/data/icons/scalable/apps/com.system76.CosmicAppletA11y-symbolic.svg new file mode 100644 index 00000000..f5121b5a --- /dev/null +++ b/cosmic-applet-a11y/data/icons/scalable/apps/com.system76.CosmicAppletA11y-symbolic.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/cosmic-applet-a11y/i18n.toml b/cosmic-applet-a11y/i18n.toml new file mode 100644 index 00000000..05c50ba2 --- /dev/null +++ b/cosmic-applet-a11y/i18n.toml @@ -0,0 +1,4 @@ +fallback_language = "en" + +[fluent] +assets_dir = "i18n" \ No newline at end of file diff --git a/cosmic-applet-a11y/i18n/en/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/en/cosmic_applet_a11y.ftl new file mode 100644 index 00000000..902732ed --- /dev/null +++ b/cosmic-applet-a11y/i18n/en/cosmic_applet_a11y.ftl @@ -0,0 +1 @@ +accessibility = Accessibility diff --git a/cosmic-applet-a11y/src/app.rs b/cosmic-applet-a11y/src/app.rs new file mode 100644 index 00000000..9a003590 --- /dev/null +++ b/cosmic-applet-a11y/src/app.rs @@ -0,0 +1,235 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use crate::{ + backend::{self, A11yRequest}, + fl, +}; +use cosmic::{ + applet::{ + menu_button, padded_control, + token::subscription::{activation_token_subscription, TokenRequest, TokenUpdate}, + }, + cctk::sctk::reexports::calloop, + cosmic_theme::Spacing, + iced::{ + alignment::Horizontal, + platform_specific::shell::wayland::commands::popup::{destroy_popup, get_popup}, + widget::{column, container, row, slider}, + window, Alignment, Length, Subscription, + }, + iced_core::{alignment::Vertical, Background, Border, Color, Shadow}, + iced_runtime::core::layout::Limits, + iced_widget::{Column, Row}, + theme, + widget::{divider, horizontal_space, icon, scrollable, text, vertical_space}, + Element, Task, +}; +use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline}; + +use std::{collections::HashMap, path::PathBuf, time::Duration}; +use tokio::sync::mpsc::UnboundedSender; + +static ENABLED: Lazy = Lazy::new(id::Toggler::unique); + +pub fn run() -> cosmic::iced::Result { + cosmic::applet::run::(()) +} + +#[derive(Clone, Default)] +struct CosmicA11yApplet { + core: cosmic::app::Core, + icon_name: String, + a11y_enabled: bool, + popup: Option, + a11y_sender: Option>, + timeline: Timeline, + token_tx: Option>, +} + +#[derive(Debug, Clone)] +enum Message { + TogglePopup, + CloseRequested(window::Id), + Errored(String), + Enabled(chain::Toggler, bool), + Frame(Instant), + Token(TokenUpdate), + OpenSettings, + Update(backend::Update), +} + +impl cosmic::Application for CosmicA11yApplet { + type Message = Message; + type Executor = cosmic::SingleThreadExecutor; + type Flags = (); + const APP_ID: &'static str = "com.system76.CosmicAppletA11y"; + + fn init( + core: cosmic::app::Core, + _flags: Self::Flags, + ) -> ( + Self, + cosmic::iced::Task>, + ) { + ( + Self { + core, + token_tx: None, + + ..Default::default() + }, + Task::none(), + ) + } + + fn core(&self) -> &cosmic::app::Core { + &self.core + } + + fn core_mut(&mut self) -> &mut cosmic::app::Core { + &mut self.core + } + + fn update( + &mut self, + message: Self::Message, + ) -> cosmic::iced::Task> { + match message { + Message::Frame(now) => self.timeline.now(now), + Message::Enabled(chain, enabled) => { + self.timeline.set_chain(chain).start(); + self.a11y_enabled = enabled; + if let Some(tx) = &self.a11y_sender { + let _ = tx.send(A11yRequest::Status(enabled)); + } + } + Message::Errored(why) => { + tracing::error!("{}", why); + } + Message::TogglePopup => { + if let Some(p) = self.popup.take() { + return destroy_popup(p); + } else { + self.timeline = Timeline::new(); + + let new_id = window::Id::unique(); + self.popup.replace(new_id); + + let mut popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + Some((1, 1)), + None, + None, + ); + popup_settings.positioner.size_limits = Limits::NONE + .max_width(372.0) + .min_width(300.0) + .min_height(200.0) + .max_height(1080.0); + + return get_popup(popup_settings); + } + } + Message::CloseRequested(id) => { + if Some(id) == self.popup { + self.popup = None; + } + } + Message::OpenSettings => { + let exec = "cosmic-settings a11y".to_string(); + if let Some(tx) = self.token_tx.as_ref() { + let _ = tx.send(TokenRequest { + app_id: Self::APP_ID.to_string(), + exec, + }); + } else { + tracing::error!("Wayland tx is None"); + }; + } + Message::Token(u) => match u { + TokenUpdate::Init(tx) => { + self.token_tx = Some(tx); + } + TokenUpdate::Finished => { + self.token_tx = None; + } + TokenUpdate::ActivationToken { token, .. } => { + let mut cmd = std::process::Command::new("cosmic-settings"); + cmd.arg("a11y"); + if let Some(token) = token { + cmd.env("XDG_ACTIVATION_TOKEN", &token); + cmd.env("DESKTOP_STARTUP_ID", &token); + } + tokio::spawn(cosmic::process::spawn(cmd)); + } + }, + Message::Update(update) => match update { + backend::Update::Error(err) => { + tracing::error!("{err}"); + } + backend::Update::Status(enabled) => { + self.a11y_enabled = enabled; + } + backend::Update::Init(enabled, tx) => { + self.a11y_enabled = enabled; + self.a11y_sender = Some(tx); + } + }, + } + Task::none() + } + + fn view(&self) -> Element { + self.core + .applet + .icon_button("preferences-desktop-accessibility") + .on_press_down(Message::TogglePopup) + .into() + } + + fn view_window(&self, _id: window::Id) -> Element { + let Spacing { + space_xxs, space_s, .. + } = theme::active().cosmic().spacing; + + let toggle = padded_control( + anim!( + //toggler + ENABLED, + &self.timeline, + fl!("accessibility"), + self.a11y_enabled, + Message::Enabled, + ) + .text_size(14) + .width(Length::Fill), + ); + + self.core + .applet + .popup_container(toggle.padding([8, 8])) + .max_width(372.) + .max_height(600.) + .into() + } + + fn subscription(&self) -> Subscription { + Subscription::batch(vec![ + backend::subscription().map(Message::Update), + self.timeline + .as_subscription() + .map(|(_, now)| Message::Frame(now)), + activation_token_subscription(0).map(Message::Token), + ]) + } + + fn on_close_requested(&self, id: window::Id) -> Option { + Some(Message::CloseRequested(id)) + } + + fn style(&self) -> Option { + Some(cosmic::applet::style()) + } +} diff --git a/cosmic-applet-a11y/src/backend/mod.rs b/cosmic-applet-a11y/src/backend/mod.rs new file mode 100644 index 00000000..ff9551a0 --- /dev/null +++ b/cosmic-applet-a11y/src/backend/mod.rs @@ -0,0 +1,139 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use cosmic::iced::futures::FutureExt; +use cosmic::{ + iced::{ + self, + futures::{self, select, SinkExt, StreamExt}, + Subscription, + }, + iced_futures::stream, +}; +use cosmic_dbus_a11y::*; +use std::{fmt::Debug, hash::Hash}; +use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender}; +use zbus::{Connection, Result}; + +#[derive(Debug, Clone)] +pub enum Update { + Error(String), + Status(bool), + Init(bool, UnboundedSender), +} + +pub enum A11yRequest { + Status(bool), +} + +#[derive(Debug)] +pub enum State { + Ready, + Waiting(Connection, u8, bool, UnboundedReceiver), + Finished, +} + +pub fn subscription() -> iced::Subscription { + struct MyId; + + Subscription::run_with_id( + std::any::TypeId::of::(), + stream::channel(50, move |mut output| async move { + let mut state = State::Ready; + + loop { + state = start_listening(state, &mut output).await; + } + }), + ) +} + +async fn start_listening( + state: State, + output: &mut futures::channel::mpsc::Sender, +) -> State { + match state { + State::Ready => { + let conn = match Connection::session().await.map_err(|e| e.to_string()) { + Ok(conn) => conn, + Err(e) => { + _ = output.send(Update::Error(e)).await; + return State::Finished; + } + }; + let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); + let mut enabled = false; + if let Ok(proxy) = StatusProxy::new(&conn).await { + if let Ok(status) = proxy.screen_reader_enabled().await { + enabled = status; + } + } + _ = output.send(Update::Init(enabled, tx)); + State::Waiting(conn, 20, enabled, rx) + } + State::Waiting(conn, mut retry, mut enabled, mut rx) => { + let Ok(proxy) = StatusProxy::new(&conn).await else { + if retry == 0 { + tracing::error!("Accessibility Status is unavailable."); + return State::Finished; + } else { + _ = tokio::time::sleep(tokio::time::Duration::from_secs( + 2_u64.pow(retry as u32), + )) + .await; + retry -= 1; + return State::Waiting(conn, retry, enabled, rx); + } + }; + retry = 20; + + let mut watch_changes = proxy.receive_screen_reader_enabled_changed().await; + + if let Ok(status) = proxy.screen_reader_enabled().await { + if enabled != status { + _ = output.send(Update::Status(enabled)); + } + enabled = status; + } + + loop { + if let Ok(status) = proxy.screen_reader_enabled().await { + if enabled != status { + _ = output.send(Update::Status(enabled)); + } + enabled = status; + } + + let mut next_change = Box::pin(watch_changes.next()).fuse(); + let mut next_request = Box::pin(rx.recv()).fuse(); + + select! { + v = next_request => { + match v { + Some(A11yRequest::Status(is_enabled)) => { + // Set status + enabled = is_enabled; + _ = proxy.set_is_enabled(true).await; + _ = proxy.set_screen_reader_enabled(true).await; + } + None => return State::Finished, + } + } + v = next_change => { + match v { + Some(f) => { + if let Ok(enabled) = f.get().await { + _ = output.send(Update::Status(enabled)); + } + } + None => break, + }; + } + } + } + + State::Waiting(conn, retry, enabled, rx) + } + State::Finished => iced::futures::future::pending().await, + } +} diff --git a/cosmic-applet-a11y/src/lib.rs b/cosmic-applet-a11y/src/lib.rs new file mode 100644 index 00000000..b22bcfcc --- /dev/null +++ b/cosmic-applet-a11y/src/lib.rs @@ -0,0 +1,13 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +mod app; +mod backend; +mod localize; + +use localize::localize; + +pub fn run() -> cosmic::iced::Result { + localize(); + app::run() +} diff --git a/cosmic-applet-a11y/src/localize.rs b/cosmic-applet-a11y/src/localize.rs new file mode 100644 index 00000000..b69ee397 --- /dev/null +++ b/cosmic-applet-a11y/src/localize.rs @@ -0,0 +1,48 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use i18n_embed::{ + fluent::{fluent_language_loader, FluentLanguageLoader}, + DefaultLocalizer, LanguageLoader, Localizer, +}; +use once_cell::sync::Lazy; +use rust_embed::RustEmbed; + +#[derive(RustEmbed)] +#[folder = "i18n/"] +struct Localizations; + +pub static LANGUAGE_LOADER: Lazy = Lazy::new(|| { + let loader: FluentLanguageLoader = fluent_language_loader!(); + + loader + .load_fallback_language(&Localizations) + .expect("Error while loading fallback language"); + + loader +}); + +#[macro_export] +macro_rules! fl { + ($message_id:literal) => {{ + i18n_embed_fl::fl!($crate::localize::LANGUAGE_LOADER, $message_id) + }}; + + ($message_id:literal, $($args:expr),*) => {{ + i18n_embed_fl::fl!($crate::localize::LANGUAGE_LOADER, $message_id, $($args), *) + }}; +} + +// Get the `Localizer` to be used for localizing this library. +pub fn localizer() -> Box { + Box::from(DefaultLocalizer::new(&*LANGUAGE_LOADER, &Localizations)) +} + +pub fn localize() { + let localizer = localizer(); + let requested_languages = i18n_embed::DesktopLanguageRequester::requested_languages(); + + if let Err(error) = localizer.select(&requested_languages) { + eprintln!("Error while loading language for App List {}", error); + } +} diff --git a/cosmic-applet-a11y/src/main.rs b/cosmic-applet-a11y/src/main.rs new file mode 100644 index 00000000..d659d1cb --- /dev/null +++ b/cosmic-applet-a11y/src/main.rs @@ -0,0 +1,13 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +const VERSION: &str = env!("CARGO_PKG_VERSION"); + +fn main() -> cosmic::iced::Result { + tracing_subscriber::fmt::init(); + let _ = tracing_log::LogTracer::init(); + + tracing::info!("Starting battery applet with version {VERSION}"); + + cosmic_applet_battery::run() +} diff --git a/cosmic-applets/Cargo.toml b/cosmic-applets/Cargo.toml index 612748d0..24d5931a 100644 --- a/cosmic-applets/Cargo.toml +++ b/cosmic-applets/Cargo.toml @@ -7,6 +7,7 @@ license = "GPL-3.0-only" [dependencies] cosmic-app-list = { path = "../cosmic-app-list" } cosmic-applet-audio = { path = "../cosmic-applet-audio" } +cosmic-applet-a11y = { path = "../cosmic-applet-a11y" } cosmic-applet-battery = { path = "../cosmic-applet-battery" } cosmic-applet-bluetooth = { path = "../cosmic-applet-bluetooth" } cosmic-applet-minimize = { path = "../cosmic-applet-minimize" } @@ -17,8 +18,8 @@ cosmic-applet-status-area = { path = "../cosmic-applet-status-area" } cosmic-applet-tiling = { path = "../cosmic-applet-tiling" } cosmic-applet-time = { path = "../cosmic-applet-time" } cosmic-applet-workspaces = { path = "../cosmic-applet-workspaces" } -cosmic-applet-input-sources = { path = "../cosmic-applet-input-sources"} -cosmic-panel-button = { path = "../cosmic-panel-button"} +cosmic-applet-input-sources = { path = "../cosmic-applet-input-sources" } +cosmic-panel-button = { path = "../cosmic-panel-button" } libcosmic.workspace = true tracing.workspace = true tracing-subscriber.workspace = true diff --git a/cosmic-applets/src/main.rs b/cosmic-applets/src/main.rs index 14eed075..93b3ec76 100644 --- a/cosmic-applets/src/main.rs +++ b/cosmic-applets/src/main.rs @@ -18,6 +18,7 @@ fn main() -> cosmic::iced::Result { match cmd { "cosmic-app-list" => cosmic_app_list::run(), + "cosmic-applet-a11y" => cosmic_applet_a11y::run(), "cosmic-applet-audio" => cosmic_applet_audio::run(), "cosmic-applet-battery" => cosmic_applet_battery::run(), "cosmic-applet-bluetooth" => cosmic_applet_bluetooth::run(), diff --git a/justfile b/justfile index 5680f1bb..54e11026 100644 --- a/justfile +++ b/justfile @@ -58,7 +58,7 @@ _install_metainfo: install -Dm0644 {{metainfo-src}} {{metainfo-dst}} # Installs files into the system -install: (_install_bin 'cosmic-applets') (_link_applet 'cosmic-panel-button') (_install_applet 'com.system76.CosmicAppList' 'cosmic-app-list') (_install_default_schema 'cosmic-app-list') (_install_applet 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio') (_install_applet 'com.system76.CosmicAppletInputSources' 'cosmic-applet-input-sources') (_install_applet 'com.system76.CosmicAppletBattery' 'cosmic-applet-battery') (_install_applet 'com.system76.CosmicAppletBluetooth' 'cosmic-applet-bluetooth') (_install_applet 'com.system76.CosmicAppletMinimize' 'cosmic-applet-minimize') (_install_applet 'com.system76.CosmicAppletNetwork' 'cosmic-applet-network') (_install_applet 'com.system76.CosmicAppletNotifications' 'cosmic-applet-notifications') (_install_applet 'com.system76.CosmicAppletPower' 'cosmic-applet-power') (_install_applet 'com.system76.CosmicAppletStatusArea' 'cosmic-applet-status-area') (_install_applet 'com.system76.CosmicAppletTiling' 'cosmic-applet-tiling') (_install_applet 'com.system76.CosmicAppletTime' 'cosmic-applet-time') (_install_applet 'com.system76.CosmicAppletWorkspaces' 'cosmic-applet-workspaces') (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button') (_install_button 'com.system76.CosmicPanelLauncherButton' 'cosmic-panel-launcher-button') (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button') (_install_metainfo) +install: (_install_bin 'cosmic-applets') (_link_applet 'cosmic-panel-button') (_install_applet 'com.system76.CosmicAppList' 'cosmic-app-list') (_install_default_schema 'cosmic-app-list') (_install_applet 'com.system76.CosmicAppletA11y' 'cosmic-applet-a11y') (_install_applet 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio') (_install_applet 'com.system76.CosmicAppletInputSources' 'cosmic-applet-input-sources') (_install_applet 'com.system76.CosmicAppletBattery' 'cosmic-applet-battery') (_install_applet 'com.system76.CosmicAppletBluetooth' 'cosmic-applet-bluetooth') (_install_applet 'com.system76.CosmicAppletMinimize' 'cosmic-applet-minimize') (_install_applet 'com.system76.CosmicAppletNetwork' 'cosmic-applet-network') (_install_applet 'com.system76.CosmicAppletNotifications' 'cosmic-applet-notifications') (_install_applet 'com.system76.CosmicAppletPower' 'cosmic-applet-power') (_install_applet 'com.system76.CosmicAppletStatusArea' 'cosmic-applet-status-area') (_install_applet 'com.system76.CosmicAppletTiling' 'cosmic-applet-tiling') (_install_applet 'com.system76.CosmicAppletTime' 'cosmic-applet-time') (_install_applet 'com.system76.CosmicAppletWorkspaces' 'cosmic-applet-workspaces') (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button') (_install_button 'com.system76.CosmicPanelLauncherButton' 'cosmic-panel-launcher-button') (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button') (_install_metainfo) # Vendor Cargo dependencies locally vendor: