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: