git.lucas.co / cce-status-interface
status bar
git clone https://git.lucas.co/cce-status-interface.git

commitf7272f93a566dd13b729e6175ac9516fcfaf5e61
parentee3c6925a5
authorLucas Galante <[email protected]>
date2026-05-23 15:34
Refactor status interface and main loop

 Cargo.lock           | 587 +++++++++++++++++++++++++++------------------------
 Cargo.toml           |   7 +-
 src/bin/dbus_test.rs | 181 ++++++++++++++++
 src/main.rs          | 563 ++++++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 1019 insertions(+), 319 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index da8327a..6caa068 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,6 +18,12 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
 
+[[package]]
+name = "adler2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+
 [[package]]
 name = "ahash"
 version = "0.8.12"
@@ -31,15 +37,6 @@ dependencies = [
  "zerocopy",
 ]
 
-[[package]]
-name = "aho-corasick"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
-dependencies = [
- "memchr",
-]
-
 [[package]]
 name = "android-activity"
 version = "0.6.1"
@@ -74,12 +71,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "anyhow"
-version = "1.0.102"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
-
 [[package]]
 name = "arrayref"
 version = "0.3.9"
@@ -109,24 +100,26 @@ dependencies = [
 
 [[package]]
 name = "async-broadcast"
-version = "0.4.1"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d26004fe83b2d1cd3a97609b21e39f9a31535822210fe83205d2ce48866ea61"
+checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
 dependencies = [
  "event-listener",
+ "event-listener-strategy",
  "futures-core",
- "parking_lot",
+ "pin-project-lite",
 ]
 
 [[package]]
 name = "async-channel"
-version = "1.9.0"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
+checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
 dependencies = [
  "concurrent-queue",
- "event-listener",
+ "event-listener-strategy",
  "futures-core",
+ "pin-project-lite",
 ]
 
 [[package]]
@@ -143,24 +136,91 @@ dependencies = [
  "slab",
 ]
 
+[[package]]
+name = "async-fs"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5"
+dependencies = [
+ "async-lock",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-io"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-io",
+ "futures-lite",
+ "parking",
+ "polling",
+ "rustix 1.1.4",
+ "slab",
+ "windows-sys 0.61.2",
+]
+
 [[package]]
 name = "async-lock"
-version = "2.8.0"
+version = "3.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-process"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
+checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
 dependencies = [
+ "async-channel",
+ "async-io",
+ "async-lock",
+ "async-signal",
+ "async-task",
+ "blocking",
+ "cfg-if",
  "event-listener",
+ "futures-lite",
+ "rustix 1.1.4",
 ]
 
 [[package]]
 name = "async-recursion"
-version = "0.3.2"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7d78656ba01f1b93024b7c3a0467f1608e4be67d725749fdcd7d2c7678fd7a2"
+checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn",
+]
+
+[[package]]
+name = "async-signal"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485"
+dependencies = [
+ "async-io",
+ "async-lock",
+ "atomic-waker",
+ "cfg-if",
+ "futures-core",
+ "futures-io",
+ "rustix 1.1.4",
+ "signal-hook-registry",
+ "slab",
+ "windows-sys 0.61.2",
 ]
 
 [[package]]
@@ -177,7 +237,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -228,6 +288,15 @@ version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
 
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "block2"
 version = "0.5.1"
@@ -237,6 +306,19 @@ dependencies = [
  "objc2",
 ]
 
+[[package]]
+name = "blocking"
+version = "1.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
+dependencies = [
+ "async-channel",
+ "async-task",
+ "futures-io",
+ "futures-lite",
+ "piper",
+]
+
 [[package]]
 name = "bumpalo"
 version = "3.20.3"
@@ -260,15 +342,9 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
-[[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
 [[package]]
 name = "bytes"
 version = "1.11.1"
@@ -346,14 +422,15 @@ dependencies = [
  "chrono",
  "clear-ui",
  "glyphon",
+ "png",
  "pollster",
  "serde",
  "serde_json",
- "stray",
  "tokio",
  "tokio-stream",
  "wgpu",
  "winit",
+ "zbus",
 ]
 
 [[package]]
@@ -460,6 +537,24 @@ dependencies = [
  "unicode-segmentation",
 ]
 
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "crossbeam-deque"
 version = "0.8.6"
@@ -486,40 +581,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
 
 [[package]]
-name = "cursor-icon"
-version = "1.2.0"
+name = "crypto-common"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
-
-[[package]]
-name = "derivative"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
+ "generic-array",
+ "typenum",
 ]
 
 [[package]]
-name = "dirs"
-version = "4.0.0"
+name = "cursor-icon"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
-dependencies = [
- "dirs-sys",
-]
+checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
 
 [[package]]
-name = "dirs-sys"
-version = "0.3.7"
+name = "digest"
+version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
 dependencies = [
- "libc",
- "redox_users",
- "winapi",
+ "block-buffer",
+ "crypto-common",
 ]
 
 [[package]]
@@ -564,6 +648,12 @@ version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
 
+[[package]]
+name = "endi"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
+
 [[package]]
 name = "enumflags2"
 version = "0.7.12"
@@ -582,7 +672,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -622,9 +712,24 @@ dependencies = [
 
 [[package]]
 name = "event-listener"
-version = "2.5.3"
+version = "5.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "event-listener-strategy"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
+dependencies = [
+ "event-listener",
+ "pin-project-lite",
+]
 
 [[package]]
 name = "fastrand"
@@ -632,12 +737,31 @@ version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
 
+[[package]]
+name = "fdeflate"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
+dependencies = [
+ "simd-adler32",
+]
+
 [[package]]
 name = "find-msvc-tools"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
 
+[[package]]
+name = "flate2"
+version = "1.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
 [[package]]
 name = "foldhash"
 version = "0.1.5"
@@ -694,7 +818,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -747,12 +871,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
 dependencies = [
  "futures-core",
+ "futures-io",
  "futures-sink",
  "futures-task",
+ "memchr",
  "pin-project-lite",
  "slab",
 ]
 
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
 [[package]]
 name = "gethostname"
 version = "1.1.0"
@@ -988,7 +1124,7 @@ dependencies = [
  "quote",
  "rustc_version",
  "simd_cesu8",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -1016,7 +1152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
 dependencies = [
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -1058,12 +1194,6 @@ version = "3.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
 
-[[package]]
-name = "lazy_static"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-
 [[package]]
 name = "libc"
 version = "0.2.186"
@@ -1161,15 +1291,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "memoffset"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
-dependencies = [
- "autocfg",
-]
-
 [[package]]
 name = "memoffset"
 version = "0.9.1"
@@ -1194,6 +1315,16 @@ dependencies = [
  "paste",
 ]
 
+[[package]]
+name = "miniz_oxide"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
+dependencies = [
+ "adler2",
+ "simd-adler32",
+]
+
 [[package]]
 name = "mio"
 version = "1.2.0"
@@ -1268,15 +1399,15 @@ dependencies = [
 
 [[package]]
 name = "nix"
-version = "0.23.2"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
+checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
 dependencies = [
- "bitflags 1.3.2",
- "cc",
+ "bitflags 2.11.1",
  "cfg-if",
+ "cfg_aliases",
  "libc",
- "memoffset 0.6.5",
+ "memoffset",
 ]
 
 [[package]]
@@ -1304,10 +1435,10 @@ version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
 dependencies = [
- "proc-macro-crate 3.5.0",
+ "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -1549,9 +1680,9 @@ dependencies = [
 
 [[package]]
 name = "ordered-stream"
-version = "0.0.1"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44630c059eacfd6e08bdaa51b1db2ce33119caa4ddc1235e923109aa5f25ccb1"
+checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
 dependencies = [
  "futures-core",
  "pin-project-lite",
@@ -1624,7 +1755,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -1633,6 +1764,17 @@ version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
 
+[[package]]
+name = "piper"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
+dependencies = [
+ "atomic-waker",
+ "fastrand",
+ "futures-io",
+]
+
 [[package]]
 name = "pkg-config"
 version = "0.3.33"
@@ -1645,6 +1787,19 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
 
+[[package]]
+name = "png"
+version = "0.17.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
+dependencies = [
+ "bitflags 1.3.2",
+ "crc32fast",
+ "fdeflate",
+ "flate2",
+ "miniz_oxide",
+]
+
 [[package]]
 name = "polling"
 version = "3.11.0"
@@ -1680,23 +1835,13 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
 
-[[package]]
-name = "proc-macro-crate"
-version = "1.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
-dependencies = [
- "once_cell",
- "toml_edit 0.19.15",
-]
-
 [[package]]
 name = "proc-macro-crate"
 version = "3.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
 dependencies = [
- "toml_edit 0.25.11+spec-1.1.0",
+ "toml_edit",
 ]
 
 [[package]]
@@ -1843,46 +1988,6 @@ dependencies = [
  "bitflags 2.11.1",
 ]
 
-[[package]]
-name = "redox_users"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
-dependencies = [
- "getrandom 0.2.17",
- "libredox",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "regex"
-version = "1.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-automata",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.8.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
-
 [[package]]
 name = "renderdoc-sys"
 version = "1.1.0"
@@ -2038,7 +2143,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -2062,24 +2167,20 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
 name = "sha1"
-version = "0.6.1"
+version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
 dependencies = [
- "sha1_smol",
+ "cfg-if",
+ "cpufeatures",
+ "digest",
 ]
 
-[[package]]
-name = "sha1_smol"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
-
 [[package]]
 name = "shlex"
 version = "1.3.0"
@@ -2096,6 +2197,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "simd-adler32"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
+
 [[package]]
 name = "simd_cesu8"
 version = "1.1.1"
@@ -2202,24 +2309,6 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 
-[[package]]
-name = "stray"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "358c1637c5ba4ccf1b6a0698de81454db644866cc426d1abc6d357b2efede511"
-dependencies = [
- "anyhow",
- "byteorder",
- "chrono",
- "log",
- "serde",
- "thiserror 1.0.69",
- "tokio",
- "tokio-stream",
- "tracing",
- "zbus",
-]
-
 [[package]]
 name = "strict-num"
 version = "0.1.1"
@@ -2245,7 +2334,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "rustversion",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -2265,17 +2354,6 @@ dependencies = [
  "zeno",
 ]
 
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
 [[package]]
 name = "syn"
 version = "2.0.117"
@@ -2344,7 +2422,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -2355,7 +2433,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -2423,7 +2501,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -2437,12 +2515,6 @@ dependencies = [
  "tokio",
 ]
 
-[[package]]
-name = "toml_datetime"
-version = "0.6.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
-
 [[package]]
 name = "toml_datetime"
 version = "1.1.1+spec-1.1.0"
@@ -2452,17 +2524,6 @@ dependencies = [
  "serde_core",
 ]
 
-[[package]]
-name = "toml_edit"
-version = "0.19.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
-dependencies = [
- "indexmap",
- "toml_datetime 0.6.11",
- "winnow 0.5.40",
-]
-
 [[package]]
 name = "toml_edit"
 version = "0.25.11+spec-1.1.0"
@@ -2470,9 +2531,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b"
 dependencies = [
  "indexmap",
- "toml_datetime 1.1.1+spec-1.1.0",
+ "toml_datetime",
  "toml_parser",
- "winnow 1.0.3",
+ "winnow",
 ]
 
 [[package]]
@@ -2481,7 +2542,7 @@ version = "1.1.2+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
 dependencies = [
- "winnow 1.0.3",
+ "winnow",
 ]
 
 [[package]]
@@ -2503,7 +2564,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -2533,13 +2594,19 @@ version = "0.25.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
 
+[[package]]
+name = "typenum"
+version = "1.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
+
 [[package]]
 name = "uds_windows"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
 dependencies = [
- "memoffset 0.9.1",
+ "memoffset",
  "tempfile",
  "windows-sys 0.61.2",
 ]
@@ -2677,7 +2744,7 @@ dependencies = [
  "bumpalo",
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
  "wasm-bindgen-shared",
 ]
 
@@ -2928,22 +2995,6 @@ dependencies = [
  "web-sys",
 ]
 
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
 [[package]]
 name = "winapi-util"
 version = "0.1.11"
@@ -2953,12 +3004,6 @@ dependencies = [
  "windows-sys 0.61.2",
 ]
 
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
 [[package]]
 name = "windows"
 version = "0.58.0"
@@ -3003,7 +3048,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -3014,7 +3059,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -3025,7 +3070,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -3036,7 +3081,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -3225,15 +3270,6 @@ dependencies = [
  "xkbcommon-dl",
 ]
 
-[[package]]
-name = "winnow"
-version = "0.5.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
-dependencies = [
- "memchr",
-]
-
 [[package]]
 name = "winnow"
 version = "1.0.3"
@@ -3287,6 +3323,16 @@ version = "0.3.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b"
 
+[[package]]
+name = "xdg-home"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
+dependencies = [
+ "libc",
+ "windows-sys 0.59.0",
+]
+
 [[package]]
 name = "xkbcommon-dl"
 version = "0.4.2"
@@ -3320,39 +3366,37 @@ checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1"
 
 [[package]]
 name = "zbus"
-version = "2.3.2"
+version = "4.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d8f1a037b2c4a67d9654dc7bdfa8ff2e80555bbefdd3c1833c1d1b27c963a6b"
+checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
 dependencies = [
  "async-broadcast",
- "async-channel",
  "async-executor",
+ "async-fs",
+ "async-io",
  "async-lock",
+ "async-process",
  "async-recursion",
  "async-task",
  "async-trait",
- "byteorder",
- "derivative",
- "dirs",
+ "blocking",
  "enumflags2",
  "event-listener",
  "futures-core",
  "futures-sink",
  "futures-util",
  "hex",
- "lazy_static",
  "nix",
- "once_cell",
  "ordered-stream",
  "rand",
  "serde",
  "serde_repr",
  "sha1",
  "static_assertions",
- "tokio",
  "tracing",
  "uds_windows",
- "winapi",
+ "windows-sys 0.52.0",
+ "xdg-home",
  "zbus_macros",
  "zbus_names",
  "zvariant",
@@ -3360,22 +3404,22 @@ dependencies = [
 
 [[package]]
 name = "zbus_macros"
-version = "2.3.2"
+version = "4.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f8fb5186d1c87ae88cf234974c240671238b4a679158ad3b94ec465237349a6"
+checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
 dependencies = [
- "proc-macro-crate 1.3.1",
+ "proc-macro-crate",
  "proc-macro2",
  "quote",
- "regex",
- "syn 1.0.109",
+ "syn",
+ "zvariant_utils",
 ]
 
 [[package]]
 name = "zbus_names"
-version = "2.6.1"
+version = "3.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d"
+checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
 dependencies = [
  "serde",
  "static_assertions",
@@ -3405,7 +3449,7 @@ checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn",
 ]
 
 [[package]]
@@ -3416,13 +3460,12 @@ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
 
 [[package]]
 name = "zvariant"
-version = "3.15.2"
+version = "4.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db"
+checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
 dependencies = [
- "byteorder",
+ "endi",
  "enumflags2",
- "libc",
  "serde",
  "static_assertions",
  "zvariant_derive",
@@ -3430,24 +3473,24 @@ dependencies = [
 
 [[package]]
 name = "zvariant_derive"
-version = "3.15.2"
+version = "4.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9"
+checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
 dependencies = [
- "proc-macro-crate 1.3.1",
+ "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn",
  "zvariant_utils",
 ]
 
 [[package]]
 name = "zvariant_utils"
-version = "1.0.1"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200"
+checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 902cea7..cdc0dfa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,11 @@ tokio = { version = "1", features = ["full"] }
 serde = { version = "1", features = ["derive"] }
 serde_json = "1"
 chrono = "0.4"
-stray = "0.1"
 tokio-stream = "0.1"
+zbus = "4"
+png = "0.17"
+
+
+
+
 
diff --git a/src/bin/dbus_test.rs b/src/bin/dbus_test.rs
new file mode 100644
index 0000000..ab20bd3
--- /dev/null
+++ b/src/bin/dbus_test.rs
@@ -0,0 +1,181 @@
+use zbus::{proxy, Connection};
+
+#[derive(Debug, Clone)]
+pub struct NotifierAddress {
+    pub destination: String,
+    pub path: String,
+}
+
+impl NotifierAddress {
+    pub fn from_notifier_service(service: &str, sender: &str) -> Result<Self, String> {
+        if service.starts_with('/') {
+            Ok(NotifierAddress {
+                destination: sender.to_string(),
+                path: service.to_string(),
+            })
+        } else if let Some((destination, path)) = service.split_once('/') {
+            Ok(NotifierAddress {
+                destination: destination.to_string(),
+                path: format!("/{}", path),
+            })
+        } else if service.contains(':') {
+            let split = service.split(':').collect::<Vec<&str>>();
+            Ok(NotifierAddress {
+                destination: format!(":{}", split[1]),
+                path: "/StatusNotifierItem".to_string(),
+            })
+        } else {
+            Ok(NotifierAddress {
+                destination: service.to_string(),
+                path: "/StatusNotifierItem".to_string(),
+            })
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct TrayPixmap {
+    pub width: i32,
+    pub height: i32,
+    pub pixels: Vec<u8>,
+}
+
+#[derive(Debug, Clone)]
+pub struct TrayItem {
+    pub id: String,
+    pub icon_name: Option<String>,
+    pub icon_theme_path: Option<String>,
+    pub pixmaps: Option<Vec<TrayPixmap>>,
+    pub title: Option<String>,
+}
+
+#[proxy(
+    interface = "org.kde.StatusNotifierItem",
+    default_path = "/StatusNotifierItem"
+)]
+trait StatusNotifierItem {
+    #[zbus(property)]
+    fn id(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn category(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn status(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn title(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn icon_name(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn icon_theme_path(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn icon_pixmap(&self) -> zbus::Result<Vec<(i32, i32, Vec<u8>)>>;
+}
+
+#[proxy(
+    interface = "org.kde.StatusNotifierWatcher",
+    default_path = "/StatusNotifierWatcher"
+)]
+trait StatusNotifierWatcher {
+    #[zbus(property)]
+    fn registered_status_notifier_items(&self) -> zbus::Result<Vec<String>>;
+}
+
+async fn fetch_tray_item(conn: &Connection, addr: &NotifierAddress) -> Result<TrayItem, zbus::Error> {
+    let proxy = StatusNotifierItemProxy::builder(conn)
+        .destination(addr.destination.clone())?
+        .path(addr.path.clone())?
+        .build()
+        .await?;
+
+    println!("Querying properties for destination='{}', path='{}'...", addr.destination, addr.path);
+    
+    let id_res = proxy.id().await;
+    println!("  id result: {:?}", id_res);
+    
+    let category_res = proxy.category().await;
+    println!("  category result: {:?}", category_res);
+
+    let status_res = proxy.status().await;
+    println!("  status result: {:?}", status_res);
+
+    let icon_name_res = proxy.icon_name().await;
+    println!("  icon_name result: {:?}", icon_name_res);
+
+    let icon_theme_path_res = proxy.icon_theme_path().await;
+    println!("  icon_theme_path result: {:?}", icon_theme_path_res);
+
+    let title_res = proxy.title().await;
+    println!("  title result: {:?}", title_res);
+
+    let pixmap_res = proxy.icon_pixmap().await;
+    println!("  pixmap result: ({} pixmaps or error: {:?})", 
+        pixmap_res.as_ref().map(|v| v.len()).unwrap_or(0),
+        pixmap_res.as_ref().err()
+    );
+
+    let id = format!("{}/{}", addr.destination, addr.path.trim_start_matches('/'));
+    let icon_name = icon_name_res.ok();
+    let icon_theme_path = icon_theme_path_res.ok();
+    let title = title_res.ok();
+
+    let pixmaps = pixmap_res.ok().map(|v| {
+        v.into_iter()
+            .map(|(w, h, pixels)| TrayPixmap {
+                width: w,
+                height: h,
+                pixels,
+            })
+            .collect()
+    });
+
+    Ok(TrayItem {
+        id,
+        icon_name,
+        icon_theme_path,
+        pixmaps,
+        title,
+    })
+}
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    let conn = Connection::session().await?;
+    
+    let watcher_proxy = StatusNotifierWatcherProxy::builder(&conn)
+        .destination("org.kde.StatusNotifierWatcher")?
+        .path("/StatusNotifierWatcher")?
+        .build()
+        .await?;
+        
+    let items = watcher_proxy.registered_status_notifier_items().await?;
+    println!("Registered status notifier items from watcher: {:?}", items);
+
+    for item in items {
+        println!("======================================");
+        // An item string can be like ":1.5631/org/ayatana/NotificationItem/dropbox_client_1112673"
+        // Let's parse it using split_once('/')
+        let addr = if let Some((destination, path)) = item.split_once('/') {
+            NotifierAddress {
+                destination: destination.to_string(),
+                path: format!("/{}", path),
+            }
+        } else {
+            NotifierAddress {
+                destination: item.clone(),
+                path: "/StatusNotifierItem".to_string(),
+            }
+        };
+        
+        match fetch_tray_item(&conn, &addr).await {
+            Ok(item) => println!("SUCCESS: {:?}", item.id),
+            Err(e) => println!("ERROR for {}: {:?}", item, e),
+        }
+    }
+
+    Ok(())
+}
diff --git a/src/main.rs b/src/main.rs
index cf34851..eda6875 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,8 +10,10 @@ use glyphon::{
     TextAtlas, TextBounds, TextRenderer, Viewport,
 };
 use clear_ui::color;
-use stray::StatusNotifierWatcher;
-use stray::message::NotifierItemMessage;
+// zbus D-Bus Integration
+
+
+
 
 #[derive(Debug, Clone)]
 struct TrayPixmap {
@@ -505,11 +507,13 @@ impl StatusApp {
         // 5b. System Tray Icons (render to the left of the CPU/stats block)
         self.tray_item_bounds.clear();
         if !self.tray_items.is_empty() {
+            println!("[status-tray-render] Rendering {} tray items (screen size: {}x{})", self.tray_items.len(), sw, sh);
             right_x -= 16.0 * s; // Separator padding
             let mut sorted_tray: Vec<&TrayItem> = self.tray_items.values().collect();
             sorted_tray.sort_by_key(|item| &item.id);
 
             for item in sorted_tray.iter().rev() {
+                println!("[status-tray-render] Item ID: '{}', icon_name: {:?}, pixmaps is Some: {}", item.id, item.icon_name, item.pixmaps.is_some());
                 let icon_size = 16.0 * s;
                 right_x -= icon_size;
                 let x = right_x;
@@ -532,17 +536,60 @@ impl StatusApp {
                         // Find pixmap closest to 16 pixels wide
                         if let Some(pixmap) = pixmaps.iter().min_by_key(|p| (p.width - 16).abs()) {
                             if pixmap.width > 0 && pixmap.height > 0 {
-                                let pixel_w = icon_size / pixmap.width as f32;
-                                let pixel_h = icon_size / pixmap.height as f32;
+                                // Calculate average brightness of visible pixels to see if we need to recolor
+                                let mut total_brightness = 0.0;
+                                let mut visible_pixel_count = 0;
                                 for row in 0..pixmap.height {
                                     for col in 0..pixmap.width {
                                         let idx = ((row * pixmap.width + col) * 4) as usize;
                                         if idx + 3 < pixmap.pixels.len() {
                                             let a = pixmap.pixels[idx] as f32 / 255.0;
-                                            if a > 0.0 {
+                                            if a > 0.1 {
                                                 let r = pixmap.pixels[idx + 1] as f32 / 255.0;
                                                 let g = pixmap.pixels[idx + 2] as f32 / 255.0;
                                                 let b = pixmap.pixels[idx + 3] as f32 / 255.0;
+                                                total_brightness += (r + g + b) / 3.0;
+                                                visible_pixel_count += 1;
+                                            }
+                                        }
+                                    }
+                                }
+                                
+                                let avg_brightness = if visible_pixel_count > 0 {
+                                    total_brightness / visible_pixel_count as f32
+                                } else {
+                                    0.5
+                                };
+                                                               // If the average brightness is dark, recolor it to be light
+                                let recolor_light = avg_brightness < 0.35;
+ 
+                                // Downsample to 16x16 quads to optimize rendering
+                                let draw_w = 16;
+                                let draw_h = 16;
+                                let pixel_w = icon_size / draw_w as f32;
+                                let pixel_h = icon_size / draw_h as f32;
+                                let mut pushed_pixels = 0;
+                                for row in 0..draw_h {
+                                    for col in 0..draw_w {
+                                        let src_row = row * pixmap.height / draw_h;
+                                        let src_col = col * pixmap.width / draw_w;
+                                        let idx = ((src_row * pixmap.width + src_col) * 4) as usize;
+                                        if idx + 3 < pixmap.pixels.len() {
+                                            let a = pixmap.pixels[idx] as f32 / 255.0;
+                                            if a > 0.0 {
+                                                let mut r = pixmap.pixels[idx + 1] as f32 / 255.0;
+                                                let mut g = pixmap.pixels[idx + 2] as f32 / 255.0;
+                                                let mut b = pixmap.pixels[idx + 3] as f32 / 255.0;
+                                                
+                                                if recolor_light {
+                                                    let l = (r + g + b) / 3.0;
+                                                    // Map 0.0 (black) to 0.85 (light grey), 1.0 stays 1.0
+                                                    let new_l = 0.85 + (1.0 - 0.85) * l;
+                                                    r = new_l;
+                                                    g = new_l;
+                                                    b = new_l;
+                                                }
+                                                
                                                 self.rects.push(RectWidget {
                                                     x: x + col as f32 * pixel_w,
                                                     y: y + row as f32 * pixel_h,
@@ -550,16 +597,20 @@ impl StatusApp {
                                                     h: pixel_h,
                                                     color: [r, g, b, a],
                                                 });
+                                                pushed_pixels += 1;
                                             }
                                         }
                                     }
                                 }
+                                println!("[status-tray-render] Item '{}' drawing downsampled pixmap width={}, height={}, icon_size={}, x={}, y={}, pixel_size={}x{}, pushed_rects={}", 
+                                    item.id, pixmap.width, pixmap.height, icon_size, x, y, pixel_w, pixel_h, pushed_pixels);
                                 drawn_pixmap = true;
                             }
                         }
                     }
                 }
 
+                println!("[status-tray-render] Item '{}' drawn_pixmap: {}", item.id, drawn_pixmap);
                 // Fallback to text icon symbol
                 if !drawn_pixmap {
                     let symbol = if let Some(ref name) = item.icon_name {
@@ -578,6 +629,8 @@ impl StatusApp {
                             "💬"
                         } else if name_lower.contains("steam") || name_lower.contains("game") {
                             "🎮"
+                        } else if name_lower.contains("dropbox") {
+                            "📦"
                         } else {
                             "âš™"
                         }
@@ -910,55 +963,474 @@ async fn spawn_system_stats(proxy: EventLoopProxy<CustomEvent>) {
     }
 }
 
-async fn spawn_status_tray(
-    proxy: EventLoopProxy<CustomEvent>,
-    cmd_rx: tokio::sync::mpsc::Receiver<stray::message::NotifierItemCommand>,
-) {
-    let watcher = match StatusNotifierWatcher::new(cmd_rx).await {
-        Ok(w) => w,
+#[derive(Debug, Clone)]
+pub struct NotifierAddress {
+    pub destination: String,
+    pub path: String,
+}
+
+impl NotifierAddress {
+    pub fn from_notifier_service(service: &str, sender: &str) -> Result<Self, String> {
+        if service.starts_with('/') {
+            Ok(NotifierAddress {
+                destination: sender.to_string(),
+                path: service.to_string(),
+            })
+        } else if let Some((destination, path)) = service.split_once('/') {
+            Ok(NotifierAddress {
+                destination: destination.to_string(),
+                path: format!("/{}", path),
+            })
+        } else if service.contains(':') {
+            let split = service.split(':').collect::<Vec<&str>>();
+            Ok(NotifierAddress {
+                destination: format!(":{}", split[1]),
+                path: "/StatusNotifierItem".to_string(),
+            })
+        } else {
+            Ok(NotifierAddress {
+                destination: service.to_string(),
+                path: "/StatusNotifierItem".to_string(),
+            })
+        }
+    }
+}
+
+#[zbus::proxy(
+    interface = "org.kde.StatusNotifierItem",
+    default_path = "/StatusNotifierItem"
+)]
+trait StatusNotifierItem {
+    #[zbus(property)]
+    fn id(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn category(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn status(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn title(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn icon_name(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn icon_theme_path(&self) -> zbus::Result<String>;
+
+    #[zbus(property)]
+    fn icon_pixmap(&self) -> zbus::Result<Vec<(i32, i32, Vec<u8>)>>;
+
+    #[zbus(signal)]
+    fn new_icon(&self) -> zbus::Result<()>;
+    #[zbus(signal)]
+    fn new_title(&self) -> zbus::Result<()>;
+
+    #[zbus(signal)]
+    fn new_status(&self) -> zbus::Result<()>;
+}
+
+fn find_icon_file(dir: &std::path::Path, icon_name: &str) -> Option<std::path::PathBuf> {
+    if let Ok(entries) = std::fs::read_dir(dir) {
+        for entry in entries.filter_map(Result::ok) {
+            if let Ok(file_type) = entry.file_type() {
+                let path = entry.path();
+                if file_type.is_dir() {
+                    if !file_type.is_symlink() {
+                        if let Some(found) = find_icon_file(&path, icon_name) {
+                            return Some(found);
+                        }
+                    }
+                } else if file_type.is_file() {
+                    if let Some(file_name) = path.file_name().and_then(|f| f.to_str()) {
+                        if file_name == format!("{}.png", icon_name) {
+                            return Some(path);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    None
+}
+
+fn load_png_as_pixmap(path: &std::path::Path) -> Option<TrayPixmap> {
+    let file = std::fs::File::open(path).ok()?;
+    let mut decoder = png::Decoder::new(file);
+    decoder.set_transformations(png::Transformations::EXPAND);
+    let mut reader = decoder.read_info().ok()?;
+    let mut buf = vec![0; reader.output_buffer_size()];
+    let info = reader.next_frame(&mut buf).ok()?;
+    
+    let width = info.width as i32;
+    let height = info.height as i32;
+    println!("[status-tray] PNG info: width={}, height={}, color_type={:?}, buffer_size={}", width, height, info.color_type, info.buffer_size());
+    let mut argb_pixels = Vec::with_capacity((width * height * 4) as usize);
+    
+    let actual_bytes = &buf[..info.buffer_size()];
+    let mut printed = 0;
+    match info.color_type {
+        png::ColorType::Rgba => {
+            for (i, chunk) in actual_bytes.chunks_exact(4).enumerate() {
+                if chunk[3] > 10 && printed < 5 {
+                    println!("[status-tray] Pixel {}: original RGBA=[{}, {}, {}, {}]", i, chunk[0], chunk[1], chunk[2], chunk[3]);
+                    printed += 1;
+                }
+                argb_pixels.push(chunk[3]); // A
+                argb_pixels.push(chunk[0]); // R
+                argb_pixels.push(chunk[1]); // G
+                argb_pixels.push(chunk[2]); // B
+            }
+        }
+        png::ColorType::Rgb => {
+            for chunk in actual_bytes.chunks_exact(3) {
+                argb_pixels.push(255);      // A
+                argb_pixels.push(chunk[0]); // R
+                argb_pixels.push(chunk[1]); // G
+                argb_pixels.push(chunk[2]); // B
+            }
+        }
+        png::ColorType::Grayscale => {
+            for &g in actual_bytes {
+                argb_pixels.push(255); // A
+                argb_pixels.push(g);   // R
+                argb_pixels.push(g);   // G
+                argb_pixels.push(g);   // B
+            }
+        }
+        png::ColorType::GrayscaleAlpha => {
+            for chunk in actual_bytes.chunks_exact(2) {
+                argb_pixels.push(chunk[1]); // A
+                argb_pixels.push(chunk[0]); // R
+                argb_pixels.push(chunk[0]); // G
+                argb_pixels.push(chunk[0]); // B
+            }
+        }
+        _ => return None,
+    }
+    
+    Some(TrayPixmap {
+        width,
+        height,
+        pixels: argb_pixels,
+    })
+}
+
+fn resolve_icon_path(theme_path: Option<&str>, icon_name: &str) -> Option<std::path::PathBuf> {
+    if icon_name.is_empty() {
+        return None;
+    }
+
+    let icon_name = if icon_name == "dropbox" { "dropboxstatus-idle" } else { icon_name };
+
+    if let Some(path_str) = theme_path {
+        if !path_str.is_empty() {
+            let path = std::path::Path::new(path_str);
+            if path.exists() {
+                if let Some(found) = find_icon_file(path, icon_name) {
+                    return Some(found);
+                }
+            }
+        }
+    }
+
+    let mut search_dirs = Vec::new();
+    if let Ok(home) = std::env::var("HOME") {
+        search_dirs.push(format!("{}/.local/share/icons", home));
+        search_dirs.push(format!("{}/.icons", home));
+    }
+    search_dirs.push("/usr/share/icons".to_string());
+    search_dirs.push("/usr/share/pixmaps".to_string());
+
+    let sub_paths = [
+        "hicolor/16x16/status",
+        "hicolor/22x22/status",
+        "hicolor/24x24/status",
+        "hicolor/32x32/status",
+        "hicolor/48x48/status",
+        "hicolor/16x16/apps",
+        "hicolor/22x22/apps",
+        "hicolor/24x24/apps",
+        "hicolor/32x32/apps",
+        "hicolor/48x48/apps",
+        "gnome/16x16/status",
+        "gnome/22x22/status",
+        "gnome/24x24/status",
+        "gnome/32x32/status",
+        "gnome/48x48/status",
+        "gnome/16x16/apps",
+        "gnome/22x22/apps",
+        "gnome/24x24/apps",
+        "gnome/32x32/apps",
+        "gnome/48x48/apps",
+    ];
+
+    for base in &search_dirs {
+        for sub in &sub_paths {
+            let path = std::path::Path::new(base).join(sub).join(format!("{}.png", icon_name));
+            if path.exists() && path.is_file() {
+                return Some(path);
+            }
+        }
+        let base_path = std::path::Path::new(base);
+        if base_path.exists() {
+            if let Some(found) = find_icon_file(base_path, icon_name) {
+                return Some(found);
+            }
+        }
+    }
+
+    None
+}
+
+async fn fetch_tray_item(conn: &zbus::Connection, addr: &NotifierAddress) -> Result<TrayItem, zbus::Error> {
+    let proxy = StatusNotifierItemProxy::builder(conn)
+        .destination(addr.destination.clone())?
+        .path(addr.path.clone())?
+        .build()
+        .await?;
+
+    let id = format!("{}/{}", addr.destination, addr.path.trim_start_matches('/'));
+    let icon_name = proxy.icon_name().await.ok();
+    let icon_theme_path = proxy.icon_theme_path().await.ok();
+    let title = proxy.title().await.ok();
+
+    let mut pixmaps = proxy.icon_pixmap().await.ok().and_then(|v| {
+        if v.is_empty() || (v.len() == 1 && v[0].0 == 0 && v[0].1 == 0) {
+            None
+        } else {
+            Some(v.into_iter()
+                .map(|(w, h, pixels)| TrayPixmap {
+                    width: w,
+                    height: h,
+                    pixels,
+                })
+                .collect::<Vec<_>>())
+        }
+    });
+
+    if pixmaps.is_none() {
+        if let Some(ref name) = icon_name {
+            println!("[status-tray] Trying to resolve theme icon for '{}' (theme path: {:?})", name, icon_theme_path);
+            if let Some(icon_path) = resolve_icon_path(icon_theme_path.as_deref(), name) {
+                println!("[status-tray] Found icon file at {:?}", icon_path);
+                if let Some(pixmap) = load_png_as_pixmap(&icon_path) {
+                    println!("[status-tray] Successfully decoded icon file to pixmap (size: {}x{})", pixmap.width, pixmap.height);
+                    pixmaps = Some(vec![pixmap]);
+                } else {
+                    println!("[status-tray] Failed to decode icon file");
+                }
+            } else {
+                println!("[status-tray] Could not find icon file on system or theme path");
+            }
+        }
+    } else {
+        println!("[status-tray] Loaded raw D-Bus pixmap for '{}'", id);
+    }
+
+    Ok(TrayItem {
+        id,
+        icon_name,
+        icon_theme_path,
+        pixmaps,
+        title,
+    })
+}
+
+struct Watcher {
+    registered_items: Arc<tokio::sync::Mutex<HashMap<String, NotifierAddress>>>,
+    proxy_events: EventLoopProxy<CustomEvent>,
+    tokio_handle: tokio::runtime::Handle,
+}
+
+#[zbus::interface(name = "org.kde.StatusNotifierWatcher")]
+impl Watcher {
+    async fn register_status_notifier_item(
+        &self,
+        service: &str,
+        #[zbus(header)] header: zbus::MessageHeader<'_>,
+        #[zbus(connection)] conn: &zbus::Connection,
+    ) {
+        let sender = header
+            .sender()
+            .map(|s| s.to_string())
+            .unwrap_or_else(|| service.to_string());
+        
+        if let Ok(addr) = NotifierAddress::from_notifier_service(service, &sender) {
+            let mut items = self.registered_items.lock().await;
+            let full_address = format!("{}/{}", addr.destination, addr.path.trim_start_matches('/'));
+            if !items.contains_key(&full_address) {
+                items.insert(full_address.clone(), addr.clone());
+                
+                let conn = conn.clone();
+                let addr_clone = addr.clone();
+                let proxy_events_clone = self.proxy_events.clone();
+                
+                self.tokio_handle.spawn(async move {
+                    if let Ok(item) = fetch_tray_item(&conn, &addr_clone).await {
+                        let _ = proxy_events_clone.send_event(CustomEvent::TrayUpdated(item));
+                    }
+                    
+                    // Listen for updates
+                    if let Ok(proxy) = StatusNotifierItemProxy::builder(&conn)
+                        .destination(addr_clone.destination.clone())
+                        .unwrap()
+                        .path(addr_clone.path.clone())
+                        .unwrap()
+                        .build()
+                        .await
+                    {
+                        let mut new_icon_stream = proxy.receive_new_icon().await.ok();
+                        let mut new_title_stream = proxy.receive_new_title().await.ok();
+                        let mut new_status_stream = proxy.receive_new_status().await.ok();
+                        
+                        use tokio_stream::StreamExt;
+                        loop {
+                            tokio::select! {
+                                Some(_) = async {
+                                    if let Some(ref mut s) = new_icon_stream {
+                                        s.next().await
+                                    } else {
+                                        std::future::pending().await
+                                    }
+                                } => {
+                                    if let Ok(item) = fetch_tray_item(&conn, &addr_clone).await {
+                                        let _ = proxy_events_clone.send_event(CustomEvent::TrayUpdated(item));
+                                    }
+                                }
+                                Some(_) = async {
+                                    if let Some(ref mut s) = new_title_stream {
+                                        s.next().await
+                                    } else {
+                                        std::future::pending().await
+                                    }
+                                } => {
+                                    if let Ok(item) = fetch_tray_item(&conn, &addr_clone).await {
+                                        let _ = proxy_events_clone.send_event(CustomEvent::TrayUpdated(item));
+                                    }
+                                }
+                                Some(_) = async {
+                                    if let Some(ref mut s) = new_status_stream {
+                                        s.next().await
+                                    } else {
+                                        std::future::pending().await
+                                    }
+                                } => {
+                                    if let Ok(item) = fetch_tray_item(&conn, &addr_clone).await {
+                                        let _ = proxy_events_clone.send_event(CustomEvent::TrayUpdated(item));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    async fn register_status_notifier_host(&self, _service: &str) {}
+
+    #[zbus(property)]
+    async fn protocol_version(&self) -> i32 {
+        0
+    }
+
+    #[zbus(property)]
+    async fn is_status_notifier_host_registered(&self) -> bool {
+        true
+    }
+
+    #[zbus(property)]
+    async fn registered_status_notifier_items(&self) -> Vec<String> {
+        let items = self.registered_items.lock().await;
+        items.keys().cloned().collect()
+    }
+}
+
+async fn spawn_status_tray(proxy: EventLoopProxy<CustomEvent>) {
+    let registered_items = Arc::new(tokio::sync::Mutex::new(HashMap::new()));
+    let tokio_handle = tokio::runtime::Handle::current();
+
+    let watcher = Watcher {
+        registered_items: registered_items.clone(),
+        proxy_events: proxy.clone(),
+        tokio_handle,
+    };
+
+    let conn = match zbus::ConnectionBuilder::session() {
+        Ok(builder) => {
+            match builder
+                .name("org.kde.StatusNotifierWatcher")
+                .unwrap()
+                .serve_at("/StatusNotifierWatcher", watcher)
+                .unwrap()
+                .build()
+                .await
+            {
+                Ok(c) => c,
+                Err(e) => {
+                    eprintln!("Failed to build D-Bus connection: {:?}", e);
+                    return;
+                }
+            }
+        }
         Err(e) => {
-            eprintln!("Failed to create StatusNotifierWatcher: {:?}", e);
+            eprintln!("Failed to initialize D-Bus session: {:?}", e);
             return;
         }
     };
-    let mut host = match watcher.create_notifier_host("clear-status-bar").await {
-        Ok(h) => h,
+
+    println!("StatusNotifierWatcher running successfully on D-Bus!");
+
+    // Start NameOwnerChanged listener to detect when tray apps disconnect
+    let dbus_proxy = match zbus::fdo::DBusProxy::new(&conn).await {
+        Ok(p) => p,
         Err(e) => {
-            eprintln!("Failed to create NotifierHost: {:?}", e);
+            eprintln!("Failed to create DBusProxy: {:?}", e);
             return;
         }
     };
-    loop {
-        match host.recv().await {
-            Ok(msg) => match msg {
-                NotifierItemMessage::Update { address, item, menu: _ } => {
-                    let pixmaps = item.icon_pixmap.map(|v| {
-                        v.into_iter()
-                            .map(|p| TrayPixmap {
-                                width: p.width,
-                                height: p.height,
-                                pixels: p.pixels,
-                            })
-                            .collect()
-                    });
-                    let tray_item = TrayItem {
-                        id: address.clone(),
-                        icon_name: item.icon_name,
-                        icon_theme_path: item.icon_theme_path,
-                        pixmaps,
-                        title: item.title,
-                    };
-                    let _ = proxy.send_event(CustomEvent::TrayUpdated(tray_item));
-                }
-                NotifierItemMessage::Remove { address } => {
-                    let _ = proxy.send_event(CustomEvent::TrayRemoved(address));
+    let mut owner_changes = match dbus_proxy.receive_name_owner_changed().await {
+        Ok(oc) => oc,
+        Err(e) => {
+            eprintln!("Failed to receive name owner changed: {:?}", e);
+            return;
+        }
+    };
+
+    let registered_items_clone = registered_items.clone();
+    let proxy_events_clone = proxy.clone();
+    
+    tokio::spawn(async move {
+        use tokio_stream::StreamExt;
+        while let Some(signal) = owner_changes.next().await {
+            if let Ok(args) = signal.args() {
+                let old = args.old_owner;
+                let new = args.new_owner;
+                let old_opt: &Option<_> = &*old;
+                if let Some(ref old_owner) = old_opt {
+                    if new.is_none() {
+                        let mut items = registered_items_clone.lock().await;
+                        let mut to_remove = Vec::new();
+                        for (key, addr) in items.iter() {
+                            if addr.destination == old_owner.as_str() {
+                                to_remove.push(key.clone());
+                            }
+                        }
+                        for key in to_remove {
+                            items.remove(&key);
+                            let _ = proxy_events_clone.send_event(CustomEvent::TrayRemoved(key));
+                        }
+                    }
                 }
-            },
-            Err(e) => {
-                eprintln!("Tray host recv error: {:?}", e);
-                tokio::time::sleep(std::time::Duration::from_secs(2)).await;
             }
         }
+    });
+
+    // Keep the task alive
+    loop {
+        tokio::time::sleep(std::time::Duration::from_secs(3600)).await;
     }
 }
 
@@ -972,8 +1444,6 @@ fn main() {
     let proxy_stats = event_loop.create_proxy();
     let proxy_tray = event_loop.create_proxy();
 
-    let (_cmd_tx, cmd_rx) = tokio::sync::mpsc::channel(32);
-
     // Spawn Tokio Runtime for async listeners
     std::thread::spawn(move || {
         let rt = tokio::runtime::Runtime::new().unwrap();
@@ -982,7 +1452,7 @@ fn main() {
             tokio::spawn(spawn_status_listener("layout", proxy_layout));
             tokio::spawn(spawn_status_listener("title", proxy_title));
             tokio::spawn(spawn_system_stats(proxy_stats));
-            tokio::spawn(spawn_status_tray(proxy_tray, cmd_rx));
+            tokio::spawn(spawn_status_tray(proxy_tray));
             
             // Keep the runtime thread alive
             loop {
@@ -1013,4 +1483,5 @@ fn main() {
 
 
 
+