From 25787c42b258aed20fa12ea4892c116dcc8f350b Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Wed, 4 Feb 2026 14:39:12 +0100 Subject: [PATCH 1/9] app: Allow app to build on MacOS This adds code and dependency needed for MacOS, using conditional compilation. --- Cargo.lock | 745 ++++++++++++++++++++++---- reflection-app/Cargo.toml | 18 +- reflection-app/src/secret.rs | 47 +- reflection-app/src/system_settings.rs | 13 + 4 files changed, 710 insertions(+), 113 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efdad07f..af38e068 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures 0.2.17", +] + [[package]] name = "ahash" version = "0.8.12" @@ -149,7 +160,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "618a409b91d5265798a99e3d1d0b226911605e581c4e7255e83c1e397b172bce" dependencies = [ - "async-fs", + "async-fs 2.2.0", "async-net", "enumflags2", "futures-channel", @@ -159,7 +170,17 @@ dependencies = [ "serde_repr", "tracing", "url", - "zbus", + "zbus 5.13.2", +] + +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", ] [[package]] @@ -168,7 +189,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ - "event-listener", + "event-listener 5.4.1", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -207,21 +228,53 @@ checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue", - "fastrand", - "futures-lite", + "fastrand 2.3.0", + "futures-lite 2.6.1", "pin-project-lite", "slab", ] +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + [[package]] name = "async-fs" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ - "async-lock", + "async-lock 3.4.2", "blocking", - "futures-lite", + "futures-lite 2.6.1", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.28", + "slab", + "socket2 0.4.10", + "waker-fn", ] [[package]] @@ -234,21 +287,30 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite", + "futures-lite 2.6.1", "parking", - "polling", - "rustix", + "polling 3.11.0", + "rustix 1.1.3", "slab", "windows-sys 0.61.2", ] +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + [[package]] name = "async-lock" version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "event-listener", + "event-listener 5.4.1", "event-listener-strategy", "pin-project-lite", ] @@ -259,9 +321,26 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ - "async-io", + "async-io 2.6.0", + "blocking", + "futures-lite 2.6.1", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", "blocking", - "futures-lite", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.44", + "windows-sys 0.48.0", ] [[package]] @@ -271,15 +350,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel", - "async-io", - "async-lock", + "async-io 2.6.0", + "async-lock 3.4.2", "async-signal", "async-task", "blocking", "cfg-if", - "event-listener", - "futures-lite", - "rustix", + "event-listener 5.4.1", + "futures-lite 2.6.1", + "rustix 1.1.3", ] [[package]] @@ -299,13 +378,13 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ - "async-io", - "async-lock", + "async-io 2.6.0", + "async-lock 3.4.2", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix", + "rustix 1.1.3", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -369,7 +448,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e2cdb6d5ed835199484bb92bb8b3edd526effe995c61732580439c1a67e2e9" dependencies = [ - "base64", + "base64 0.22.1", "http", "log", "url", @@ -387,7 +466,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" dependencies = [ - "fastrand", + "fastrand 2.3.0", "gloo-timers", "tokio", ] @@ -398,6 +477,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -410,6 +495,12 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.10.0" @@ -466,6 +557,15 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + [[package]] name = "block2" version = "0.6.2" @@ -484,7 +584,7 @@ dependencies = [ "async-channel", "async-task", "futures-io", - "futures-lite", + "futures-lite 2.6.1", "piper", ] @@ -538,7 +638,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b01fe135c0bd16afe262b6dea349bd5ea30e6de50708cec639aae7c5c14cc7e4" dependencies = [ - "bitflags", + "bitflags 2.10.0", "cairo-sys-rs", "glib", "libc", @@ -555,6 +655,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.2.55" @@ -639,6 +748,16 @@ dependencies = [ "half", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common 0.1.7", + "inout", +] + [[package]] name = "cobs" version = "0.3.0" @@ -700,6 +819,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -934,6 +1063,17 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.4.2" @@ -1040,7 +1180,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags", + "bitflags 2.10.0", "block2", "libc", "objc2", @@ -1290,6 +1430,23 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "event-listener" version = "5.4.1" @@ -1307,7 +1464,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener", + "event-listener 5.4.1", "pin-project-lite", ] @@ -1323,6 +1480,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -1347,7 +1513,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" dependencies = [ - "memoffset", + "memoffset 0.9.1", "rustc_version", ] @@ -1468,7 +1634,7 @@ checksum = "175cd8cca9e1d45b87f18ffa75088f2099e3c4fe5e2f83e42de112560bea8ea6" dependencies = [ "fixedbitset", "futures-core", - "futures-lite", + "futures-lite 2.6.1", "pin-project", "smallvec", ] @@ -1507,13 +1673,28 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-lite" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand", + "fastrand 2.3.0", "futures-core", "futures-io", "parking", @@ -1754,7 +1935,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16de123c2e6c90ce3b573b7330de19be649080ec612033d397d72da265f1bd8b" dependencies = [ - "bitflags", + "bitflags 2.10.0", "futures-channel", "futures-core", "futures-executor", @@ -1776,7 +1957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf59b675301228a696fe01c3073974643365080a76cc3ed5bc2cbc466ad87f17" dependencies = [ "heck 0.5.0", - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.114", @@ -1896,7 +2077,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ccfb5a14a3d941244815d5f8101fa12d4577b59cc47245778d8d907b0003e42" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.114", @@ -2052,6 +2233,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hermit-abi" version = "0.5.2" @@ -2247,7 +2434,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -2456,6 +2643,36 @@ dependencies = [ "serde_core", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipconfig" version = "0.3.2" @@ -2570,7 +2787,7 @@ dependencies = [ "derive_more", "ed25519-dalek 3.0.0-pre.1", "futures-concurrency", - "futures-lite", + "futures-lite 2.6.1", "futures-util", "hex", "indexmap", @@ -2789,6 +3006,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keyring" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363387f0019d714aa60cc30ab4fe501a747f4c08fc58f069dd14be971bd495a0" +dependencies = [ + "byteorder", + "lazy_static", + "linux-keyutils", + "secret-service", + "security-framework", + "windows-sys 0.52.0", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -2859,7 +3090,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags", + "bitflags 2.10.0", "libc", "redox_syscall 0.7.0", ] @@ -2904,6 +3135,28 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-keyutils" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" +dependencies = [ + "bitflags 2.10.0", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -3166,6 +3419,15 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -3234,7 +3496,7 @@ dependencies = [ "cfg_aliases", "derive_more", "futures-buffered", - "futures-lite", + "futures-lite 2.6.1", "futures-util", "js-sys", "pin-project", @@ -3294,7 +3556,7 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ec2f5b6839be2a19d7fa5aab5bc444380f6311c2b693551cb80f45caaa7b5ef" dependencies = [ - "bitflags", + "bitflags 2.10.0", "libc", "log", "netlink-packet-core", @@ -3306,7 +3568,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ce3636fa715e988114552619582b530481fd5ef176a1e5c1bf024077c2c9445" dependencies = [ - "bitflags", + "bitflags 2.10.0", "libc", "log", "netlink-packet-core", @@ -3375,6 +3637,18 @@ dependencies = [ "wmi", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", +] + [[package]] name = "nonmax" version = "0.5.5" @@ -3518,7 +3792,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.114", @@ -3568,7 +3842,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags", + "bitflags 2.10.0", "block2", "dispatch2", "libc", @@ -3587,7 +3861,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" dependencies = [ - "bitflags", + "bitflags 2.10.0", "objc2", "objc2-core-foundation", ] @@ -3598,7 +3872,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7216bd11cbda54ccabcab84d523dc93b858ec75ecfb3a7d89513fa22464da396" dependencies = [ - "bitflags", + "bitflags 2.10.0", "dispatch2", "libc", "objc2", @@ -3638,12 +3912,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3299dd401feaf1d45afd8fd1c0586f10fcfb22f244bb9afa942cec73503b89d" dependencies = [ "ashpd", - "async-fs", - "async-io", - "async-lock", + "async-fs 2.2.0", + "async-io 2.6.0", + "async-lock 3.4.2", "blocking", "endi", - "futures-lite", + "futures-lite 2.6.1", "futures-util", "getrandom 0.3.4", "num", @@ -3652,10 +3926,10 @@ dependencies = [ "rand 0.9.2", "serde", "tracing", - "zbus", - "zbus_macros", + "zbus 5.13.2", + "zbus_macros 5.13.2", "zeroize", - "zvariant", + "zvariant 5.9.2", ] [[package]] @@ -3664,7 +3938,7 @@ version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ - "bitflags", + "bitflags 2.10.0", "cfg-if", "foreign-types", "libc", @@ -3992,7 +4266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand", + "fastrand 2.3.0", "futures-io", ] @@ -4010,7 +4284,7 @@ dependencies = [ "dyn-clone", "ed25519-dalek 3.0.0-pre.1", "futures-buffered", - "futures-lite", + "futures-lite 2.6.1", "getrandom 0.3.4", "log", "lru", @@ -4070,13 +4344,29 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ - "base64", + "base64 0.22.1", "indexmap", "quick-xml", "serde", "time", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "polling" version = "3.11.0" @@ -4085,9 +4375,9 @@ checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", + "hermit-abi 0.5.2", "pin-project-lite", - "rustix", + "rustix 1.1.3", "windows-sys 0.61.2", ] @@ -4103,10 +4393,10 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d2a8825353ace3285138da3378b1e21860d60351942f7aa3b99b13b41f80318" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "derive_more", - "futures-lite", + "futures-lite 2.6.1", "futures-util", "hyper-util", "igd-next", @@ -4196,13 +4486,23 @@ dependencies = [ "syn 2.0.114", ] +[[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.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit", + "toml_edit 0.23.10+spec-1.0.0", ] [[package]] @@ -4426,7 +4726,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.10.0", ] [[package]] @@ -4435,7 +4735,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ - "bitflags", + "bitflags 2.10.0", ] [[package]] @@ -4443,10 +4743,12 @@ name = "reflection" version = "0.2.0" dependencies = [ "ashpd", + "base64 0.21.7", "formatx", "futures-util", "gettext-rs", "gtk4", + "keyring", "libadwaita", "libspelling", "oo7", @@ -4535,7 +4837,7 @@ version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-core", "futures-util", @@ -4625,16 +4927,43 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.11.0", "windows-sys 0.61.2", ] @@ -4698,6 +5027,48 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "secret-service" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5204d39df37f06d1944935232fd2dfe05008def7ca599bf28c0800366c8a8f9" +dependencies = [ + "aes", + "cbc", + "futures-util", + "generic-array", + "hkdf", + "num", + "once_cell", + "rand 0.8.5", + "serde", + "sha2 0.10.9", + "zbus 3.15.2", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.10.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "seize" version = "0.5.1" @@ -4928,7 +5299,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dee851d0e5e7af3721faea1843e8015e820a234f81fda3dea9247e15bac9a86a" dependencies = [ - "bitflags", + "bitflags 2.10.0", ] [[package]] @@ -4968,6 +5339,16 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.10" @@ -5094,13 +5475,13 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "chrono", "crc", "crossbeam-queue", "either", - "event-listener", + "event-listener 5.4.1", "futures-core", "futures-intrusive", "futures-io", @@ -5168,8 +5549,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", - "base64", - "bitflags", + "base64 0.22.1", + "bitflags 2.10.0", "byteorder", "bytes", "chrono", @@ -5211,8 +5592,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", - "base64", - "bitflags", + "base64 0.22.1", + "bitflags 2.10.0", "byteorder", "chrono", "crc", @@ -5273,6 +5654,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stringprep" version = "0.1.5" @@ -5433,10 +5820,10 @@ version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ - "fastrand", + "fastrand 2.3.0", "getrandom 0.3.4", "once_cell", - "rustix", + "rustix 1.1.3", "windows-sys 0.61.2", ] @@ -5641,7 +6028,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1b6348ebfaaecd771cecb69e832961d277f59845d4220a584701f72728152b7" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-core", "futures-sink", @@ -5690,12 +6077,18 @@ dependencies = [ "indexmap", "serde_core", "serde_spanned", - "toml_datetime", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.14", ] +[[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 = "0.7.5+spec-1.1.0" @@ -5705,6 +6098,17 @@ 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.23.10+spec-1.0.0" @@ -5712,9 +6116,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", - "toml_datetime", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", - "winnow", + "winnow 0.7.14", ] [[package]] @@ -5723,7 +6127,7 @@ version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ - "winnow", + "winnow 0.7.14", ] [[package]] @@ -5753,7 +6157,7 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags", + "bitflags 2.10.0", "bytes", "futures-util", "http", @@ -5880,7 +6284,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset", + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -6039,6 +6443,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "want" version = "0.3.1" @@ -6178,7 +6588,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags", + "bitflags 2.10.0", "hashbrown 0.15.5", "indexmap", "semver", @@ -6592,6 +7002,15 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[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 = "0.7.14" @@ -6669,7 +7088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags", + "bitflags 2.10.0", "indexmap", "log", "serde", @@ -6739,6 +7158,16 @@ dependencies = [ "web-sys", ] +[[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 = "xml-rs" version = "0.8.28" @@ -6795,39 +7224,94 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2164e798d9e3d84ee2c91139ace54638059a3b23e361f5c11781c2c6459bde0f" +[[package]] +name = "zbus" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +dependencies = [ + "async-broadcast 0.5.1", + "async-executor", + "async-fs 1.6.0", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process 1.8.1", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "byteorder", + "derivative", + "enumflags2", + "event-listener 2.5.3", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "once_cell", + "ordered-stream", + "rand 0.8.5", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros 3.15.2", + "zbus_names 2.6.1", + "zvariant 3.15.2", +] + [[package]] name = "zbus" version = "5.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfeff997a0aaa3eb20c4652baf788d2dfa6d2839a0ead0b3ff69ce2f9c4bdd1" dependencies = [ - "async-broadcast", + "async-broadcast 0.7.2", "async-executor", - "async-io", - "async-lock", - "async-process", + "async-io 2.6.0", + "async-lock 3.4.2", + "async-process 2.5.0", "async-recursion", "async-task", "async-trait", "blocking", "enumflags2", - "event-listener", + "event-listener 5.4.1", "futures-core", - "futures-lite", + "futures-lite 2.6.1", "hex", "libc", "ordered-stream", - "rustix", + "rustix 1.1.3", "serde", "serde_repr", "tracing", "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow", - "zbus_macros", - "zbus_names", - "zvariant", + "winnow 0.7.14", + "zbus_macros 5.13.2", + "zbus_names 4.3.1", + "zvariant 5.9.2", +] + +[[package]] +name = "zbus_macros" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -6836,13 +7320,24 @@ version = "5.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bbd5a90dbe8feee5b13def448427ae314ccd26a49cac47905cafefb9ff846f1" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.114", - "zbus_names", - "zvariant", - "zvariant_utils", + "zbus_names 4.3.1", + "zvariant 5.9.2", + "zvariant_utils 3.3.0", +] + +[[package]] +name = "zbus_names" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +dependencies = [ + "serde", + "static_assertions", + "zvariant 3.15.2", ] [[package]] @@ -6852,8 +7347,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" dependencies = [ "serde", - "winnow", - "zvariant", + "winnow 0.7.14", + "zvariant 5.9.2", ] [[package]] @@ -6956,6 +7451,20 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" +[[package]] +name = "zvariant" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive 3.15.2", +] + [[package]] name = "zvariant" version = "5.9.2" @@ -6966,9 +7475,22 @@ dependencies = [ "enumflags2", "serde", "url", - "winnow", - "zvariant_derive", - "zvariant_utils", + "winnow 0.7.14", + "zvariant_derive 5.9.2", + "zvariant_utils 3.3.0", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -6977,11 +7499,22 @@ version = "5.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "484d5d975eb7afb52cc6b929c13d3719a20ad650fea4120e6310de3fc55e415c" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.114", - "zvariant_utils", + "zvariant_utils 3.3.0", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -6994,5 +7527,5 @@ dependencies = [ "quote", "serde", "syn 2.0.114", - "winnow", + "winnow 0.7.14", ] diff --git a/reflection-app/Cargo.toml b/reflection-app/Cargo.toml index 62c670ea..3a3f5365 100644 --- a/reflection-app/Cargo.toml +++ b/reflection-app/Cargo.toml @@ -15,14 +15,8 @@ gtk = { version = "0.10", package = "gtk4", features = ["gnome_48", "v4_20", "bl sourceview = { package = "sourceview5", version = "0.10" } tracing = "0.1" tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } -ashpd = { version = "0.12", default-features = false, features = ["tracing", "async-std"] } thiserror = { version = "2.0" } futures-util = "0.3" -oo7 = { version = "0.5", default-features = false, features = [ - "openssl_crypto", - "async-std", - "tracing", -] } libspelling = "0.4.1" formatx = "0.2.4" @@ -30,3 +24,15 @@ formatx = "0.2.4" package = "libadwaita" version = "0.8" features = ["v1_7"] + +[target.'cfg(target_os = "linux")'.dependencies] +oo7 = { version = "0.5", default-features = false, features = [ + "openssl_crypto", + "async-std", + "tracing", +] } +ashpd = { version = "0.12", default-features = false, features = ["tracing", "async-std"] } + +[target.'cfg(target_os = "macos")'.dependencies] +keyring = "2.0" +base64 = "0.21" diff --git a/reflection-app/src/secret.rs b/reflection-app/src/secret.rs index 6fc4edce..6ea956a7 100644 --- a/reflection-app/src/secret.rs +++ b/reflection-app/src/secret.rs @@ -16,27 +16,42 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +#[cfg(target_os = "linux")] use std::collections::HashMap; use thiserror::Error; use tracing::info; +#[cfg(target_os = "linux")] use crate::APP_ID; use reflection_doc::identity::{IdentityError, PrivateKey}; -const XDG_SCHEMA: &str = "xdg:schema"; +#[cfg(target_os = "linux")] +const XDG_SCHEMA: &'static str = "xdg:schema"; +#[cfg(target_os = "linux")] fn attributes() -> HashMap<&'static str, String> { HashMap::from([(XDG_SCHEMA, APP_ID.to_owned())]) } +#[cfg(target_os = "macos")] +use base64::engine::general_purpose::STANDARD as Base64Engine; + +#[cfg(target_os = "macos")] +use base64::Engine as _; + #[derive(Debug, Error)] pub enum Error { + #[cfg(target_os = "linux")] #[error(transparent)] Service(#[from] oo7::Error), + #[cfg(target_os = "macos")] + #[error(transparent)] + Service(#[from] keyring::Error), #[error(transparent)] Format(#[from] IdentityError), } +#[cfg(target_os = "linux")] pub async fn get_or_create_identity() -> Result { let keyring = oo7::Keyring::new().await?; @@ -64,3 +79,33 @@ pub async fn get_or_create_identity() -> Result { Ok(private_key) } + +#[cfg(target_os = "macos")] +pub async fn get_or_create_identity() -> Result { + let entry = keyring::Entry::new("Reflection Identity", "default user")?; + + let private_key: PrivateKey = match entry.get_password() { + Ok(password) => { + let private_key = PrivateKey::try_from( + Base64Engine + .decode(password) + .expect("Failed to decode base64 secret from keyring") + .as_slice(), + )?; + info!("Found existing identity: {}", private_key.public_key()); + private_key + } + Err(keyring::Error::NoEntry) => { + let private_key = PrivateKey::new(); + entry.set_password(&Base64Engine.encode(private_key.as_bytes()))?; + info!( + "No existing identity found. Create new identity: {}", + private_key.public_key() + ); + private_key + } + Err(e) => return Err(Error::Service(e)), + }; + + Ok(private_key) +} diff --git a/reflection-app/src/system_settings.rs b/reflection-app/src/system_settings.rs index bbe8f9d3..3183283f 100644 --- a/reflection-app/src/system_settings.rs +++ b/reflection-app/src/system_settings.rs @@ -20,14 +20,21 @@ use adw::prelude::*; use adw::subclass::prelude::*; +#[cfg(target_os = "linux")] use ashpd::{desktop::settings::Settings as SettingsProxy, zvariant}; +#[cfg(target_os = "linux")] use futures_util::stream::StreamExt; use gtk::{glib, glib::Properties, glib::clone, pango}; use std::cell::{Cell, RefCell}; use tracing::error; +#[cfg(target_os = "linux")] const GNOME_DESKTOP_NAMESPACE: &str = "org.gnome.desktop.interface"; + +#[cfg(target_os = "linux")] const CLOCK_FORMAT_KEY: &str = "clock-format"; + +#[cfg(target_os = "linux")] const MONOSPACE_FONT_NAME_KEY: &str = "monospace-font-name"; /// The clock format setting. @@ -84,6 +91,7 @@ mod imp { fn constructed(&self) { self.parent_constructed(); + #[cfg(target_os = "linux")] glib::spawn_future_local(clone!( #[weak(rename_to = this)] self, @@ -97,6 +105,7 @@ mod imp { } impl SystemSettings { + #[cfg(target_os = "linux")] async fn init(&self) -> Result<(), ashpd::Error> { let proxy = SettingsProxy::new().await?; let settings = proxy.read_all(&[GNOME_DESKTOP_NAMESPACE]).await?; @@ -173,6 +182,7 @@ mod imp { Ok(()) } + #[cfg(target_os = "linux")] fn set_clock_format(&self, clock_format: ClockFormat) { if self.obj().clock_format() == clock_format { return; @@ -182,6 +192,7 @@ mod imp { self.obj().notify_clock_format(); } + #[cfg(target_os = "linux")] fn set_monospace_font_name(&self, font_name: Option) { if self.obj().monospace_font_name() == font_name { return; @@ -209,6 +220,7 @@ impl Default for SystemSettings { } } +#[cfg(target_os = "linux")] impl TryFrom<&zvariant::OwnedValue> for ClockFormat { type Error = zvariant::Error; @@ -227,6 +239,7 @@ impl TryFrom<&zvariant::OwnedValue> for ClockFormat { } } +#[cfg(target_os = "linux")] impl TryFrom for ClockFormat { type Error = zvariant::Error; From cef91a80d071283f28da77ecd1a187d76752edcd Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Sun, 29 Mar 2026 00:05:23 +0100 Subject: [PATCH 2/9] data: Run svgo over all svgs This makes svg files smaller and cleaner, and fixes an issue with rendering some svgs on mac. --- .../icons/scalable/actions/about-symbolic.svg | 3 +- .../actions/add-document-symbolic.svg | 5 +- .../scalable/actions/bluetooth-symbolic.svg | 5 +- .../actions/down-smaller-symbolic.svg | 3 +- .../actions/join-document-symbolic.svg | 3 +- .../scalable/actions/network-symbolic.svg | 60 +------------------ .../scalable/actions/offline-symbolic.svg | 21 +------ .../scalable/status/call-missed-symbolic.svg | 6 +- .../status/document-text-symbolic.svg | 3 +- .../icons/scalable/status/folder-symbolic.svg | 8 +-- .../icons/scalable/status/key-symbolic.svg | 3 +- .../status/network-computer-symbolic.svg | 3 +- .../scalable/status/no-network-symbolic.svg | 20 +------ .../scalable/status/no-wifi-symbolic.svg | 3 +- 14 files changed, 14 insertions(+), 132 deletions(-) diff --git a/reflection-app/data/resources/icons/scalable/actions/about-symbolic.svg b/reflection-app/data/resources/icons/scalable/actions/about-symbolic.svg index 254e7e83..90ac29ed 100644 --- a/reflection-app/data/resources/icons/scalable/actions/about-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/actions/about-symbolic.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/actions/add-document-symbolic.svg b/reflection-app/data/resources/icons/scalable/actions/add-document-symbolic.svg index cf686224..e7cc9da1 100644 --- a/reflection-app/data/resources/icons/scalable/actions/add-document-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/actions/add-document-symbolic.svg @@ -1,4 +1 @@ - - - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/actions/bluetooth-symbolic.svg b/reflection-app/data/resources/icons/scalable/actions/bluetooth-symbolic.svg index f086eb3e..d6ee578f 100644 --- a/reflection-app/data/resources/icons/scalable/actions/bluetooth-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/actions/bluetooth-symbolic.svg @@ -1,4 +1 @@ - - - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/actions/down-smaller-symbolic.svg b/reflection-app/data/resources/icons/scalable/actions/down-smaller-symbolic.svg index 0d073be9..9a377685 100644 --- a/reflection-app/data/resources/icons/scalable/actions/down-smaller-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/actions/down-smaller-symbolic.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/actions/join-document-symbolic.svg b/reflection-app/data/resources/icons/scalable/actions/join-document-symbolic.svg index 975067b2..5e2ebd1b 100644 --- a/reflection-app/data/resources/icons/scalable/actions/join-document-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/actions/join-document-symbolic.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/actions/network-symbolic.svg b/reflection-app/data/resources/icons/scalable/actions/network-symbolic.svg index dc9b93b0..a544602e 100644 --- a/reflection-app/data/resources/icons/scalable/actions/network-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/actions/network-symbolic.svg @@ -1,59 +1 @@ - - - - - - - - - - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/actions/offline-symbolic.svg b/reflection-app/data/resources/icons/scalable/actions/offline-symbolic.svg index fc55f8af..252fee61 100644 --- a/reflection-app/data/resources/icons/scalable/actions/offline-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/actions/offline-symbolic.svg @@ -1,20 +1 @@ - - - - - - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/status/call-missed-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/call-missed-symbolic.svg index 54a11040..3f49379a 100644 --- a/reflection-app/data/resources/icons/scalable/status/call-missed-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/status/call-missed-symbolic.svg @@ -1,5 +1 @@ - - - - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/status/document-text-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/document-text-symbolic.svg index b00046d6..86d59782 100644 --- a/reflection-app/data/resources/icons/scalable/status/document-text-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/status/document-text-symbolic.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/status/folder-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/folder-symbolic.svg index 9ab3c04c..e0024267 100644 --- a/reflection-app/data/resources/icons/scalable/status/folder-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/status/folder-symbolic.svg @@ -1,7 +1 @@ - - - - - - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/status/key-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/key-symbolic.svg index b67f8df2..7e6349ae 100644 --- a/reflection-app/data/resources/icons/scalable/status/key-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/status/key-symbolic.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/status/network-computer-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/network-computer-symbolic.svg index 005d9cfe..013499a0 100644 --- a/reflection-app/data/resources/icons/scalable/status/network-computer-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/status/network-computer-symbolic.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/status/no-network-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/no-network-symbolic.svg index e6689d9c..65555423 100644 --- a/reflection-app/data/resources/icons/scalable/status/no-network-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/status/no-network-symbolic.svg @@ -1,19 +1 @@ - - - - - + \ No newline at end of file diff --git a/reflection-app/data/resources/icons/scalable/status/no-wifi-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/no-wifi-symbolic.svg index 7cde2cdc..c79c22fc 100644 --- a/reflection-app/data/resources/icons/scalable/status/no-wifi-symbolic.svg +++ b/reflection-app/data/resources/icons/scalable/status/no-wifi-symbolic.svg @@ -1,2 +1 @@ - - + \ No newline at end of file From 9cc1325dcbdd3f5ff311363358dc09f8e19cf77c Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Sun, 29 Mar 2026 00:07:11 +0100 Subject: [PATCH 3/9] landing-page: Add symbolic for the empty landing page On mac the app icon symbolic doesn't exist so don't use that on the landing page. --- .../resources/icons/scalable/status/landing-page-symbolic.svg | 1 + reflection-app/data/resources/resources.gresource.xml | 1 + reflection-app/src/landing_view/landing_view.blp | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 reflection-app/data/resources/icons/scalable/status/landing-page-symbolic.svg diff --git a/reflection-app/data/resources/icons/scalable/status/landing-page-symbolic.svg b/reflection-app/data/resources/icons/scalable/status/landing-page-symbolic.svg new file mode 100644 index 00000000..54745619 --- /dev/null +++ b/reflection-app/data/resources/icons/scalable/status/landing-page-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/reflection-app/data/resources/resources.gresource.xml b/reflection-app/data/resources/resources.gresource.xml index 0e54d276..a320dd04 100644 --- a/reflection-app/data/resources/resources.gresource.xml +++ b/reflection-app/data/resources/resources.gresource.xml @@ -9,6 +9,7 @@ icons/scalable/actions/join-document-symbolic.svg icons/scalable/status/key-symbolic.svg icons/scalable/status/network-computer-symbolic.svg + icons/scalable/status/landing-page-symbolic.svg icons/scalable/actions/network-symbolic.svg icons/scalable/status/no-network-symbolic.svg icons/scalable/status/no-wifi-symbolic.svg diff --git a/reflection-app/src/landing_view/landing_view.blp b/reflection-app/src/landing_view/landing_view.blp index 68241aa8..fd1c380c 100644 --- a/reflection-app/src/landing_view/landing_view.blp +++ b/reflection-app/src/landing_view/landing_view.blp @@ -49,7 +49,7 @@ template $ReflectionLandingView: Adw.NavigationPage { StackPage { name: "no-documents"; child: Adw.StatusPage no-document-page { - icon-name: "cx.modal.Reflection-symbolic"; + icon-name: "landing-page-symbolic"; title: _("Take Notes, Together"); child: Box { orientation: vertical; @@ -182,4 +182,4 @@ menu primary_menu { action: "app.about"; } } -} \ No newline at end of file +} From f22f6cd4d471295fc13c3c6bd8923c56e2d10f20 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Sun, 29 Mar 2026 00:08:11 +0100 Subject: [PATCH 4/9] connection-popover: Never use a horizontal scrollbar --- reflection-app/src/connection_popover/connection_popover.blp | 1 + 1 file changed, 1 insertion(+) diff --git a/reflection-app/src/connection_popover/connection_popover.blp b/reflection-app/src/connection_popover/connection_popover.blp index 06f09c70..c749d0ae 100644 --- a/reflection-app/src/connection_popover/connection_popover.blp +++ b/reflection-app/src/connection_popover/connection_popover.blp @@ -169,6 +169,7 @@ template $ReflectionConnectionPopover: Adw.Bin { propagate-natural-height: true; max-content-height: 300; margin-top: 12; + hscrollbar-policy: never; child: $ReflectionAuthorList author_list {}; styles [ From 1744520864298199937840b5a820a549f6ef920b Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Wed, 4 Feb 2026 14:42:28 +0100 Subject: [PATCH 5/9] build: Add script to build app for MacOS --- .gitignore | 4 + build-aux/Brewfile | 33 ++++ build-aux/build_macos.sh | 241 ++++++++++++++++++++++++++++++ build-aux/x86_64-darwin-cross.txt | 11 ++ 4 files changed, 289 insertions(+) create mode 100644 build-aux/Brewfile create mode 100755 build-aux/build_macos.sh create mode 100644 build-aux/x86_64-darwin-cross.txt diff --git a/.gitignore b/.gitignore index f38fe0aa..ef1b0249 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,7 @@ target reflection-app/src/config.rs /subprojects/blueprint-compiler + +# Build artifacts +Reflection.app/ +reflection*.dmg diff --git a/build-aux/Brewfile b/build-aux/Brewfile new file mode 100644 index 00000000..a5d2b3bf --- /dev/null +++ b/build-aux/Brewfile @@ -0,0 +1,33 @@ +# Build tools +brew "meson" +brew "ninja" +brew "pkg-config" + +# Rust toolchain (if not already installed) +brew "rustup-init" + +# Core GTK4 and GNOME dependencies +brew "gtk4" +brew "libadwaita" +brew "gtksourceview5" +brew "glib" + +# Graphics and text rendering +brew "cairo" +brew "pango" +brew "gdk-pixbuf" +brew "graphene" +brew "libspelling" +brew "blueprint-compiler" + +# Accessibility +brew "at-spi2-core" + +# Desktop file utilities (for update-desktop-database) +brew "desktop-file-utils" + +# App bundling for macOS +brew "dylibbundler" + +# Optional: For creating DMG files +brew "create-dmg" \ No newline at end of file diff --git a/build-aux/build_macos.sh b/build-aux/build_macos.sh new file mode 100755 index 00000000..55344989 --- /dev/null +++ b/build-aux/build_macos.sh @@ -0,0 +1,241 @@ +#!/bin/bash + +# Copyright 2024 The Reflection Developers +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# FIXME: Do as much as possible in meson see: https://mesonbuild.com/Creating-OSX-packages.html + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${GREEN}๐Ÿ—๏ธ Reflection Build Script${NC}" + +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Initialize flags +CREATE_APP_BUNDLE=false +CREATE_DMG=false +CREATE_CLEAN=false +BUILD_TYPE="debug" +ARCH=$(uname -m) +# Parse command line arguments +while [[ "$#" -gt 0 ]]; do + case $1 in + --help|-h) + echo "Usage: $0 [options]" + echo "Options:" + echo " --app-bundle Create macOS .app bundle" + echo " --dmg Create DMG installer" + echo " --clean Clean build directory before building" + echo " --release Build in release mode" + echo " --arch ARCH Target architecture (default: $(uname -m))" + echo " --help, -h Show this help message" + exit 0 + ;; + --app-bundle) CREATE_APP_BUNDLE=true ;; + --dmg) CREATE_DMG=true ;; + --clean) CREATE_CLEAN=true ;; + --release) BUILD_TYPE="release" ;; + --arch) ARCH="$2"; shift ;; + *) echo "Unknown parameter passed: $1"; exit 1 ;; + esac + shift +done + +# Determine if we need to cross-compile based on target architecture +if [ "$ARCH" != "$(uname -m)" ]; then + CROSS_COMPILE=true + echo -e "${YELLOW}๐Ÿ‘ฝ Cross-compiling for $ARCH architecture${NC}" +else + CROSS_COMPILE=false +fi + + +# Ask before installing dependencies unless in CI +if [ -z "$CI" ]; then + read -p "Please confirm you want to install dependencies, build and install Reflection (y/n) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo -e "${RED}โŒ Aborting...${NC}" + exit 1 + fi +fi + +# Check if Homebrew is installed +if ! command_exists brew; then + echo -e "${RED}โŒ Homebrew not found. Please install it first.${NC}" + exit 1 +fi + +if [ "$CROSS_COMPILE" = true ]; then + BREW_ARCH_CMD="arch -$ARCH brew" +else + BREW_ARCH_CMD="brew" +fi + +# Install dependencies +echo -e "${BLUE}๐Ÿ“ฆ Installing/updating dependencies...${NC}" +if ! $BREW_ARCH_CMD bundle --file=$(pwd)/build-aux/Brewfile; then + echo -e "${YELLOW}โš ๏ธ brew bundle failed, attempting to resolve Python linking conflicts...${NC}" + + # Try to force link python if it exists but isn't linked + if brew list python@3.13 &> /dev/null; then + echo -e "${YELLOW}๐Ÿ”— Force linking Python...${NC}" + $BREW_ARCH_CMD link --overwrite python@3.13 || true + fi + + # Retry brew bundle + echo -e "${YELLOW}๐Ÿ”„ Retrying brew bundle...${NC}" + if ! $BREW_ARCH_CMD bundle --file=$(pwd)/build-aux/Brewfile; then + echo -e "${RED}โŒ brew bundle failed again. Please check the dependencies.${NC}" + exit 1 + fi +fi + +# Set up environment for system libraries +export PKG_CONFIG_PATH="$HOMEBREW_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH" +export GETTEXT_SYSTEM=1 +export GETTEXT_DIR="$HOMEBREW_PREFIX" +export GETTEXT_LIB_DIR="$HOMEBREW_PREFIX/lib" +export GETTEXT_INCLUDE_DIR="$HOMEBREW_PREFIX/include" + +echo -e "${BLUE}โš™๏ธ Configuring build with Meson...${NC}" + +# Only remove builddir if explicitly requested +if [ "$CREATE_CLEAN" = true ]; then + echo -e "${YELLOW}๐Ÿงน Clean build requested, removing builddir...${NC}" + rm -rf builddir +fi + +if [ ! -d "builddir" ]; then + BUILD_ARGS=( + --buildtype=$BUILD_TYPE \ + --prefix="/Applications/Reflection.app" \ + --bindir="Contents/MacOS" \ + --datadir="Contents/Resources" \ + --localedir="Contents/Resources/locale" + ) + if [ "$CROSS_COMPILE" = true ]; then + BUILD_ARGS+=(--cross-file="$(pwd)/build-aux/$ARCH-darwin-cross.txt") + fi + meson setup builddir "${BUILD_ARGS[@]}" +else + echo -e "${YELLOW}๐Ÿ“ Using existing builddir (use --clean for clean build)${NC}" +fi + +# Build the project +echo -e "${BLUE}๐Ÿ”จ Building Reflection...${NC}" +meson compile -C builddir + +# Install to local directory +echo -e "${BLUE}๐Ÿ“ฆ Installing to local directory...${NC}" +meson install -C builddir + +echo -e "${GREEN}โœ… Build completed successfully!${NC}" + +echo -e "${GREEN}๐Ÿ“‹ Built for: $ARCH${NC}" + +# Optional: Create macOS app bundle +if [ "$CREATE_APP_BUNDLE" = true ]; then + echo -e "${BLUE}๐Ÿ“ฑ Creating app bundle...${NC}" + + # Create app bundle structure + #mkdir -p Reflection.app/Contents/Frameworks + + # FIXME: We should add the Info.plist file using meson + # Create Info.plist + cat > /Applications/Reflection.app/Contents/Info.plist << 'EOF' + + + + + CFBundleExecutable + reflection + CFBundleIdentifier + cx.modal.Reflection + CFBundleName + Reflection + CFBundleDisplayName + Reflection + CFBundlePackageType + APPL + CFBundleShortVersionString + 0.1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + 10.15 + CFBundleSupportedPlatforms + + MacOSX + + NSHighResolutionCapable + + + +EOF + + # Bundle dependencies + echo -e "${BLUE}๐Ÿ”— Bundling dependencies...${NC}" + dylibbundler -od -b -x /Applications/Reflection.app/Contents/MacOS/reflection \ + -d /Applications/Reflection.app/Contents/Frameworks/ \ + -p @executable_path/../Frameworks/ #> /dev/null 2>&1 || echo -e "${YELLOW}โš ๏ธ Some libraries may not be bundled${NC}" + + echo -e "${GREEN}โœ… App bundle created: Reflection.app${NC}" + + # Optional: Create DMG + if [ "$CREATE_DMG" = true ]; then + if command_exists create-dmg; then + echo -e "${BLUE}๐Ÿ’ฟ Creating DMG...${NC}" + rm -f "reflection-$ARCH.dmg" + create-dmg \ + --volname "Reflection" \ + --window-pos 200 120 \ + --window-size 600 400 \ + --icon-size 100 \ + --icon "Reflection.app" 175 120 \ + --hide-extension "Reflection.app" \ + --app-drop-link 425 120 \ + "reflection-$ARCH.dmg" \ + "/Applications/Reflection.app" + echo -e "${GREEN}โœ… DMG created: reflection-$ARCH.dmg${NC}" + else + echo -e "${YELLOW}โš ๏ธ create-dmg command not found. Skipping DMG creation.${NC}" + fi + fi +fi + +echo -e " Direct: ${BLUE}/Applications/Reflection.app/bin/reflection${NC}" + +if [ "$CREATE_APP_BUNDLE" = true ]; then + if [ -d "Reflection.app" ]; then + echo -e " App bundle: ${BLUE}open Reflection.app${NC}" + fi +fi + +if [ "$CREATE_DMG" = true ]; then + if [ -f "reflection-$ARCH.dmg" ]; then + echo -e " DMG: ${BLUE}open \"reflection-$ARCH.dmg\"${NC}" + fi +fi diff --git a/build-aux/x86_64-darwin-cross.txt b/build-aux/x86_64-darwin-cross.txt new file mode 100644 index 00000000..86ab85eb --- /dev/null +++ b/build-aux/x86_64-darwin-cross.txt @@ -0,0 +1,11 @@ +[binaries] +c = ['clang', '-target', 'x86_64-apple-darwin'] +cpp = ['clang++', '-target', 'x86_64-apple-darwin'] +rust = ['rustc', '--target', 'x86_64-apple-darwin'] +pkgconfig = 'pkg-config' + +[host_machine] +system = 'darwin' +cpu_family = 'x86_64' +cpu = 'x86_64' +endian = 'little' From 6a75dd70dc02ca1dbb963e6689db5bce0b16ca9d Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Wed, 4 Feb 2026 14:43:07 +0100 Subject: [PATCH 6/9] CI: Build MacOS bundle in CI --- .github/workflows/build.yml | 196 ++++++++---------------------------- 1 file changed, 40 insertions(+), 156 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 691ac1ea..af836095 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,20 +39,25 @@ jobs: # flatpak run cx.modal.Reflection macos: - if: false # This disable macos for now. - name: macOS - runs-on: macos-latest + name: macOS (${{ matrix.variant.arch }}) + runs-on: ${{ matrix.variant.runner }} strategy: fail-fast: false matrix: - include: - - target: x86_64-apple-darwin - arch: x86_64 - - target: aarch64-apple-darwin - arch: arm64 + variant: + - arch: x86_64 + target: x86_64-apple-darwin + runner: macos-15-intel + - arch: arm64 + target: aarch64-apple-darwin + runner: macos-latest steps: - uses: actions/checkout@v4 - uses: moonrepo/setup-rust@v1 + with: + targets: ${{ matrix.variant.target }} + channel: nightly + cache-target: release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -63,168 +68,47 @@ jobs: ~/Library/Caches/Homebrew /usr/local/Homebrew /opt/homebrew - key: ${{ runner.os }}-${{ matrix.arch }}-brew-${{ hashFiles('.github/workflows/build.yml') }} + key: ${{ runner.os }}-${{ matrix.variant.arch }}-brew-${{ hashFiles('**/Brewfile', '.github/workflows/build.yml') }} restore-keys: | - ${{ runner.os }}-${{ matrix.arch }}-brew- - - - name: Setup x86_64 Homebrew - if: matrix.arch == 'x86_64' - run: | - HOMEBREW_PREFIX="/usr/local" - sudo mkdir -p /usr/local - sudo chown -R $(whoami) /usr/local - arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - eval "$(/usr/local/bin/brew shellenv)" - echo "PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/opt/pango/lib/pkgconfig:/usr/local/opt/cairo/lib/pkgconfig:/usr/local/opt/gdk-pixbuf/lib/pkgconfig:/usr/local/opt/graphene/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig:/usr/local/opt/gtk4/lib/pkgconfig:/usr/local/opt/libadwaita/lib/pkgconfig" >> $GITHUB_ENV - - - name: Install pkg-config (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install pkg-config || echo ERROR - - - name: Install GDK-Pixbuf (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install gdk-pixbuf || echo ERROR - - - name: Install Cairo (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install cairo || echo ERROR - - - name: Install Pango (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install pango || echo ERROR - - - name: Install AT-SPI2-Core (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install at-spi2-core || echo ERROR - - - name: Install Graphene (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install graphene || echo ERROR - - - name: Install GTK4 (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install gtk4 || echo ERROR - - - name: Install GtkSourceView5 (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install gtksourceview5 || echo ERROR - - - name: Install Libadwaita (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install -v libadwaita - - - name: Install dylibbundler (x86_64) - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install -v dylibbundler - - - name: Install dylibbundler ARM64 - if: matrix.arch == 'arm64' - run: brew install -v dylibbundler - - - name: Verify and link x86_64 packages - if: matrix.arch == 'x86_64' - run: | - # Verify installations - arch -x86_64 /usr/local/bin/brew list pango - arch -x86_64 /usr/local/bin/brew list cairo - arch -x86_64 /usr/local/bin/brew list gdk-pixbuf - arch -x86_64 /usr/local/bin/brew list gtk4 - arch -x86_64 /usr/local/bin/brew list gtksourceview5 - arch -x86_64 /usr/local/bin/brew list libadwaita + ${{ runner.os }}-${{ matrix.variant.arch }}-brew- - # Link packages individually with error handling - for package in pango cairo gdk-pixbuf gtk4 gtksourceview5 libadwaita; do - arch -x86_64 /usr/local/bin/brew link --force $package || true - done - - - name: Install ARM64 dependencies - if: matrix.arch == 'arm64' - run: | - brew install pkg-config gtk4 pango cairo gdk-pixbuf at-spi2-core graphene libadwaita gtksourceview5 || true - brew upgrade pkg-config gtk4 pango cairo gdk-pixbuf at-spi2-core graphene libadwaita gtksourceview5 || true - - - name: Finalize ARM64 setup - if: matrix.arch == 'arm64' + - name: Run macOS Build Script run: | - echo "PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig" >> $GITHUB_ENV - echo "PKG_CONFIG_ALLOW_CROSS=1" >> $GITHUB_ENV - - name: Add target ${{ matrix.target }} - run: rustup target add ${{ matrix.target }} - - name: Build + chmod +x build-aux/build_macos.sh + ./build-aux/build_macos.sh --release --app-bundle --dmg env: - PKG_CONFIG_ALLOW_CROSS: "1" - CFLAGS: "-I/usr/local/include -I/usr/local/include/gtk-4.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include" - LDFLAGS: "-L/usr/local/lib -framework Cocoa -framework Security" MACOSX_DEPLOYMENT_TARGET: "10.15" - PKG_CONFIG_SYSROOT_DIR: "" - PKG_CONFIG_PATH: "${{ env.PKG_CONFIG_PATH }}" - run: cargo build --release --target ${{ matrix.target }} - - name: Install glib-compile-resources - if: matrix.arch == 'x86_64' - run: arch -x86_64 /usr/local/bin/brew install glib || echo ERROR - - name: Install glib-compile-resources ARM64 - if: matrix.arch == 'arm64' - run: brew install glib || echo ERROR - - - name: Compile GResource - run: | - mkdir -p target/${{ matrix.target }}/release/ - glib-compile-resources --sourcedir reflection-app/src --target target/${{ matrix.target }}/release/reflection.gresource reflection-app/src/reflection.gresource.xml + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + # Build script creates artifacts in the current directory + name: reflection-macos-${{ matrix.variant.arch }} + path: reflection-${{ matrix.variant.arch }}.dmg - - name: Create App Bundle + - name: Smoke test the build + env: + RUST_BACKTRACE: "full" + RUST_LOG: "debug" + G_MESSAGES_DEBUG: "all" run: | - mkdir -p Reflection.app/Contents/{MacOS,Resources}/share/reflection - cp target/${{ matrix.target }}/release/reflection Reflection.app/Contents/MacOS/ - cp target/${{ matrix.target }}/release/reflection.gresource Reflection.app/Contents/Resources/share/reflection/ - - # Create Info.plist - cat > Reflection.app/Contents/Info.plist << EOF - - - - - CFBundleExecutable - reflection - CFBundleIdentifier - cx.modal.Reflection - CFBundleName - Reflection - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.1.0 - LSMinimumSystemVersion - 10.15 - CFBundleSupportedPlatforms - - MacOSX - - - - EOF + /Applications/Reflection.app/Contents/MacOS/reflection & + PID=$! + sleep 5 + echo Killing reflection + kill $PID || true - # Bundle dependencies - - name: Bundle dependencies - run: | - dylibbundler -od -b -x Reflection.app/Contents/MacOS/reflection \ - -d Reflection.app/Contents/Frameworks/ \ - -p @executable_path/../Frameworks/ - # Create DMG - - name: Create DMG - run: hdiutil create -volname "Reflection" -srcfolder Reflection.app -ov -format UDZO reflection-${{ matrix.arch }}.dmg - - name: Upload Artifact - uses: actions/upload-artifact@v3 - with: - name: reflection-macos-${{ matrix.arch }} - path: reflection-${{ matrix.arch }}.dmg - - name: Smoke test the artifact + - name: Smoke test the bundle env: RUST_BACKTRACE: "full" RUST_LOG: "debug" G_MESSAGES_DEBUG: "all" run: | - ./Reflection.app/Contents/MacOS/reflection & + hdiutil attach reflection-${{ matrix.variant.arch }}.dmg + cp -R /Volumes/Reflection/Reflection.app /Applications + hdiutil unmount /Volumes/Reflection + ls -R /Applications/Reflection.app + /Applications/Reflection.app/Contents/MacOS/reflection & PID=$! sleep 5 echo Killing reflection From 50ef0c7fb560cf7151eeafd2ebf31a7f03d900a6 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Sun, 29 Mar 2026 00:19:56 +0100 Subject: [PATCH 7/9] fixup! app: Allow app to build on MacOS --- reflection-app/src/secret.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflection-app/src/secret.rs b/reflection-app/src/secret.rs index 6ea956a7..26b6222a 100644 --- a/reflection-app/src/secret.rs +++ b/reflection-app/src/secret.rs @@ -26,7 +26,7 @@ use crate::APP_ID; use reflection_doc::identity::{IdentityError, PrivateKey}; #[cfg(target_os = "linux")] -const XDG_SCHEMA: &'static str = "xdg:schema"; +const XDG_SCHEMA: &str = "xdg:schema"; #[cfg(target_os = "linux")] fn attributes() -> HashMap<&'static str, String> { From 714a7b6bc0c501e165d482e400d2f6ad02886cd7 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Sun, 29 Mar 2026 00:22:02 +0100 Subject: [PATCH 8/9] fixup! build: Add script to build app for MacOS --- build-aux/build_macos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/build_macos.sh b/build-aux/build_macos.sh index 55344989..d50aa11c 100755 --- a/build-aux/build_macos.sh +++ b/build-aux/build_macos.sh @@ -200,7 +200,7 @@ EOF echo -e "${BLUE}๐Ÿ”— Bundling dependencies...${NC}" dylibbundler -od -b -x /Applications/Reflection.app/Contents/MacOS/reflection \ -d /Applications/Reflection.app/Contents/Frameworks/ \ - -p @executable_path/../Frameworks/ #> /dev/null 2>&1 || echo -e "${YELLOW}โš ๏ธ Some libraries may not be bundled${NC}" + -p @executable_path/../Frameworks/ > /dev/null 2>&1 || echo -e "${YELLOW}โš ๏ธ Some libraries may not be bundled${NC}" echo -e "${GREEN}โœ… App bundle created: Reflection.app${NC}" From 9f12c371a1c9a0ba493ad62535ae900053c9de90 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Sun, 29 Mar 2026 00:57:42 +0100 Subject: [PATCH 9/9] mac: Add stylesheet for mac --- reflection-app/src/config.rs.in | 4 +++- reflection-app/src/mac-resources.gresource.xml | 6 ++++++ reflection-app/src/mac-style.css | 5 +++++ reflection-app/src/main.rs | 7 +++++++ reflection-app/src/meson.build | 12 +++++++++++- 5 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 reflection-app/src/mac-resources.gresource.xml create mode 100644 reflection-app/src/mac-style.css diff --git a/reflection-app/src/config.rs.in b/reflection-app/src/config.rs.in index 0e057e17..4dcfc313 100644 --- a/reflection-app/src/config.rs.in +++ b/reflection-app/src/config.rs.in @@ -4,4 +4,6 @@ pub const GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@; pub const LOCALEDIR: &str = @LOCALEDIR@; pub const PKGDATADIR: &str = @PKGDATADIR@; pub const RESOURCES_FILE: &str = concat!(@PKGDATADIR@, "/resources.gresource"); -pub const UI_RESOURCES_FILE: &str = concat!(@PKGDATADIR@, "/ui-resources.gresource"); \ No newline at end of file +pub const UI_RESOURCES_FILE: &str = concat!(@PKGDATADIR@, "/ui-resources.gresource"); +#[cfg(target_os = "macos")] +pub const MAC_RESOURCES_FILE: &str = concat!(@PKGDATADIR@, "/mac-resources.gresource"); diff --git a/reflection-app/src/mac-resources.gresource.xml b/reflection-app/src/mac-resources.gresource.xml new file mode 100644 index 00000000..bb5720b9 --- /dev/null +++ b/reflection-app/src/mac-resources.gresource.xml @@ -0,0 +1,6 @@ + + + + style.css + + diff --git a/reflection-app/src/mac-style.css b/reflection-app/src/mac-style.css new file mode 100644 index 00000000..d33a55d2 --- /dev/null +++ b/reflection-app/src/mac-style.css @@ -0,0 +1,5 @@ +.avatar > label { + font-size: 0.7em; + margin-left: -0.2em; + margin-top: -0.05em; +} \ No newline at end of file diff --git a/reflection-app/src/main.rs b/reflection-app/src/main.rs index 05751dad..49c8af57 100644 --- a/reflection-app/src/main.rs +++ b/reflection-app/src/main.rs @@ -62,6 +62,13 @@ fn main() -> glib::ExitCode { let ui_res = gio::Resource::load(UI_RESOURCES_FILE).expect("Could not load UI gresource file"); gio::resources_register(&ui_res); + #[cfg(target_os = "macos")] + { + let mac_res = + gio::Resource::load(MAC_RESOURCES_FILE).expect("Could not load MacOS gresource file"); + gio::resources_register(&mac_res); + } + gtk::glib::set_application_name("Reflection"); gtk::init().expect("Could not start GTK4"); diff --git a/reflection-app/src/meson.build b/reflection-app/src/meson.build index 3b51cbc0..54eb28d8 100644 --- a/reflection-app/src/meson.build +++ b/reflection-app/src/meson.build @@ -14,6 +14,16 @@ gnome.compile_resources('ui-resources', install_dir: pkgdatadir, ) +# Resources specifc for MacOS +if build_machine.system() == 'darwin' + gnome.compile_resources('mac-resources', + 'mac-resources.gresource.xml', + gresource_bundle: true, + install: true, + install_dir: pkgdatadir, + ) +endif + conf = configuration_data() conf.set_quoted('APP_ID', application_id) conf.set_quoted('VERSION', meson.project_version()) @@ -73,4 +83,4 @@ test( ], is_parallel: false, timeout: 1800, -) \ No newline at end of file +)