From 9ea20cd7537bd9637c42e36ba260e360f5d51440 Mon Sep 17 00:00:00 2001 From: snakedye <49378990+snakedye@users.noreply.github.com> Date: Mon, 3 May 2021 15:14:34 -0400 Subject: [PATCH] Proper wayland support (#125) * Initial commit for wayland support * Improvements to Wayland backend, structs and enums * gtk-layer-shell-rs imported * Eww compiles with wayland backend * Full layershell support * Compatibility with x11 backend * updated docs and better compatibily with X config * error in example * "screen" in config works * Updated documentation * bar example for wayland * eww follow focus when screen is undefined * NumWithUnit * Removed SurfaceDefinition for StrutDefinition again... * cargo fmt * fix match statement for screen number * fix focusable / kb interactivity * revision #2 * fix: compile error and example * feat: I fixed the deps X11 doesn't compile because of some x11 fuckery * fix: x11 fuckery PR NOW REEEEEEEEEEEEEEEEEEEEEEEEE * fix conflics and cargo fmt * i can't read * conflicts: a never ending loop... * dammit ptr * conflicts: Cargo.lock * Expression language (#124) * Add AST * add make-shift testing parser, and make stuff ocmpile * add proper expression parser * make string format use ' * Add empty doc page for expressions * add tests * Clean up file structure and add unary operators * Write documentation * make multiple daemons possible and make commands time out * Add EwwPaths struct and refactor path handling in general * Update docs to include * Improve handling of paths and daemon-ids * Add elvis operator * Allow literal-tag content to use user-defined widgets * Add support for overriding monitor in CLI * change formatting config * Improve error messages for non-existant config dir * Added tooltips (#127) * update dependencies * Explicetely states where to look for installing eww (#131) I think this should be added, because we already had a couple of people opening issues because they didn't read the docs on how to install eww. * (Very) Rudimentry gif support (#143) * rudimentry gif support * revert main.rs * Fix variable reference detection, should fix #144 * cleanup TextPos in eww debug * Manually resolve escaped symbols in xml. This shouldn't be necesary. Fixes #154 and fixes #147 * Add JSON support for exprs (fixes #146) * Add docs for json values and make value related names shorter * Add animated icon * Initial commit for wayland support * Improvements to Wayland backend, structs and enums * gtk-layer-shell-rs imported * Eww compiles with wayland backend * Full layershell support * Compatibility with x11 backend * updated docs and better compatibily with X config * "screen" in config works * Updated documentation * eww follow focus when screen is undefined * Removed SurfaceDefinition for StrutDefinition again... * cargo fmt * fix match statement for screen number * fix focusable / kb interactivity * revision #2 * fix: compile error and example * feat: I fixed the deps X11 doesn't compile because of some x11 fuckery * fix conflics and cargo fmt * i can't read * conflicts: a never ending loop... * dammit ptr * conflicts: Cargo.lock * yeeting git syntax * trying to resolve conflicts * yeeting Cargo.lock... * i try * revision: removing duplicates * fix geometry, example and improving docs * clearing up the documentation * I forgot the scss file. I also edited the bar to take advantage of eww expressions. * more yeeting and moved exclusive to window Co-authored-by: Bryan Ndjeutcha Co-authored-by: ElKowar <5300871+elkowar@users.noreply.github.com> Co-authored-by: undefinedDarkness <38278035+undefinedDarkness@users.noreply.github.com> Co-authored-by: legendofmiracles <30902201+legendofmiracles@users.noreply.github.com> --- Cargo.lock | 186 ++++++++++++++++------------- Cargo.toml | 8 +- docs/content/main/configuration.md | 23 +++- examples/eww-bar/eww.scss | 12 +- examples/eww-bar/eww.xml | 2 +- src/app.rs | 19 +-- src/config/window_definition.rs | 89 +++++++++++++- src/config/window_geometry.rs | 4 +- src/display_backend.rs | 109 ++++++++++++++++- src/main.rs | 2 + src/opts.rs | 2 +- src/widgets/widget_definitions.rs | 3 +- 12 files changed, 337 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e51908c..48ae6ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767" +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" [[package]] name = "arrayvec" @@ -49,9 +49,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "async-stream" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3670df70cbc01729f901f94c887814b3c68db038aad1329a418bae178bc5295c" +checksum = "0a26cb53174ddd320edfff199a853f93d571f48eeb4dde75e67a9a3dbb7b7e5e" dependencies = [ "async-stream-impl", "futures-core", @@ -59,13 +59,13 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3548b8efc9f8e8a5a0a2808c5bd8451a9031b9e5b879a79590304ae928b0a70" +checksum = "db134ba52475c060f3329a8ef0f8786d6b872ed01515d4b79c162e5798da1340" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -125,11 +125,10 @@ checksum = "474a626a67200bd107d44179bb3d4fc61891172d11696609264589be6a0e6a43" [[package]] name = "bincode" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "byteorder", "serde", ] @@ -151,12 +150,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - [[package]] name = "bytes" version = "1.0.1" @@ -235,7 +228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" dependencies = [ "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -257,7 +250,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -299,6 +292,7 @@ dependencies = [ "async-stream", "base64", "bincode", + "cairo-sys-rs", "debug_stub_derive", "derive_more", "dyn-clone", @@ -312,6 +306,8 @@ dependencies = [ "glib", "grass", "gtk", + "gtk-layer-shell", + "gtk-layer-shell-sys", "inotify", "itertools 0.10.0", "lazy_static", @@ -347,7 +343,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -358,9 +354,9 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" [[package]] name = "futures" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1" +checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253" dependencies = [ "futures-channel", "futures-core", @@ -373,9 +369,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" +checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25" dependencies = [ "futures-core", "futures-sink", @@ -383,15 +379,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" +checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815" [[package]] name = "futures-executor" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1" +checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d" dependencies = [ "futures-core", "futures-task", @@ -400,39 +396,39 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" +checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04" [[package]] name = "futures-macro" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7" +checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b" dependencies = [ "proc-macro-hack", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] name = "futures-sink" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" +checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23" [[package]] name = "futures-task" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80" +checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc" [[package]] name = "futures-util" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" +checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025" dependencies = [ "futures-channel", "futures-core", @@ -639,7 +635,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -711,6 +707,34 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "gtk-layer-shell" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb41868e4305f14a5b5bc0d5a3fcc0553d3a24f1f176f93c7e136290eaa3b77" +dependencies = [ + "bitflags", + "gdk", + "glib", + "glib-sys", + "gtk", + "gtk-layer-shell-sys", + "libc", +] + +[[package]] +name = "gtk-layer-shell-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3c2ad4c131bf8e6870686615eb9897ad8c02ca0d4354c575f0d74acb429a0b" +dependencies = [ + "gdk-sys", + "glib-sys", + "gtk-sys", + "libc", + "system-deps", +] + [[package]] name = "gtk-sys" version = "0.10.0" @@ -854,9 +878,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lexical-core" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21f866863575d0e1d654fbeeabdc927292fdf862873dc3c96c6f753357e13374" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec", "bitflags", @@ -867,15 +891,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.91" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7" +checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" [[package]] name = "lock_api" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" dependencies = [ "scopeguard", ] @@ -897,9 +921,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "mio" @@ -1174,7 +1198,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -1212,9 +1236,9 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "pretty_assertions" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f297542c27a7df8d45de2b0e620308ab883ad232d06c14b76ac3e144bda50184" +checksum = "1cab0e7c02cf376875e9335e0ba1da535775beb5450d21e1dffca068818ed98b" dependencies = [ "ansi_term 0.12.1", "ctor", @@ -1250,7 +1274,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", "version_check", ] @@ -1279,11 +1303,11 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ - "unicode-xid 0.2.1", + "unicode-xid 0.2.2", ] [[package]] @@ -1366,18 +1390,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +checksum = "85dd92e586f7355c633911e11f77f3d12f04b1b1bd76a198bd34ae3af8341ef2" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.4.5" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" +checksum = "1efb2352a0f4d4b128f734b5c44c79ff80117351138733f12f982fe3e2b13343" dependencies = [ "aho-corasick", "memchr", @@ -1386,15 +1410,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.23" +version = "0.6.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" +checksum = "00efb87459ba4f6fb2169d20f68565555688e1250ee6825cdf6254f8b48fafb2" [[package]] name = "roxmltree" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf58a7d05b28e14b1e8902fa04c4d5d6109f5450ef71a5e6597f66e53f541504" +checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" dependencies = [ "xmlparser", ] @@ -1428,7 +1452,7 @@ checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -1469,9 +1493,9 @@ checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" [[package]] name = "slab" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" [[package]] name = "smallvec" @@ -1487,7 +1511,7 @@ checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -1523,7 +1547,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -1541,7 +1565,7 @@ dependencies = [ "heck", "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -1557,13 +1581,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.64" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" +checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" dependencies = [ "proc-macro2", "quote 1.0.9", - "unicode-xid 0.2.1", + "unicode-xid 0.2.2", ] [[package]] @@ -1631,14 +1655,14 @@ checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] name = "tokio" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722" +checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5" dependencies = [ "autocfg", "bytes", @@ -1662,7 +1686,7 @@ checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.64", + "syn 1.0.71", ] [[package]] @@ -1678,9 +1702,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5143d049e85af7fbc36f5454d990e62c2df705b3589f123b71f441b6b59f443f" +checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e" dependencies = [ "bytes", "futures-core", @@ -1725,9 +1749,9 @@ checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "vec_map" diff --git a/Cargo.toml b/Cargo.toml index 48057b4..3c2ee2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,10 @@ homepage = "https://github.com/elkowar/eww" [features] default = ["x11"] x11 = ["gdkx11", "x11rb"] -no-x11 = [] - +wayland = ["gtk-layer-shell", "gtk-layer-shell-sys"] +no-x11-wayland = [] +[dependencies.cairo-sys-rs] +version = "0.10.0" [dependencies] gtk = { version = "0.9", features = [ "v3_16" ] } @@ -23,6 +25,8 @@ glib = { version = "", features = ["v2_44"] } gdk-pixbuf = "0.9" +gtk-layer-shell = { version="0.2.0", optional=true } +gtk-layer-shell-sys = { version="0.2.0", optional=true } gdkx11 = { version = "0.9", optional = true } x11rb = { version = "0.8", features = ["randr"], optional = true } diff --git a/docs/content/main/configuration.md b/docs/content/main/configuration.md index e4d8ce8..a29808e 100644 --- a/docs/content/main/configuration.md +++ b/docs/content/main/configuration.md @@ -222,17 +222,34 @@ The `` config should look something like this: ``` +For Wayland users the `` block is replaced by the exclusive field in ``. +The previous `` block would look like this. + +```xml + + + +
+ + +``` + The window block contains multiple elements to configure the window. - `` is used to specify the position and size of the window. - `` is used to have eww reserve space at a given side of the screen the widget is on. - `` will contain the widget that is shown in the window. There are a couple things you can optionally configure on the window itself: -- `stacking`: stacking describes if the window will be shown in the foreground (in front of other windows) - or in the background (behind other windows). - Possible values: `"fg"`, `"bg"`. Default: `"fg"` +- `stacking`: stacking describes on what "layer" of the screen the window is shown. + Possible values on the X11 backend: `foreground "fg"`, `background "bg"`. Default: `"fg"` + Possible values on the Wayland backend: `foreground "fg"`, `bottom "bt"`, `background "bg"`, `overlay "ov"`. Default: `"fg"` - `focusable`: whether the window should be focusable by the windowmanager. This is necessary for things like text-input-fields to work properly. Possible values: `"true"`, `"false"`. Default: `"false"` - `screen`: Specifies on which display to show the window in a multi-monitor setup. This can be any number, representing the index of your monitor. +- `exclusive`: Specifies whether or not a surface can be occupied by another. + A surface can be a window, an Eww widget or any layershell surface. + The details on how it is actually implemented are left to the compositor. + This option is only valid on Wayland. + Possible values: `"true"`, `"false"`. Default: `"false"` diff --git a/examples/eww-bar/eww.scss b/examples/eww-bar/eww.scss index 9a009ac..139c3ee 100644 --- a/examples/eww-bar/eww.scss +++ b/examples/eww-bar/eww.scss @@ -4,15 +4,9 @@ //Global Styles window { - background-color: #121212; - color: #ffd5cd; - font-family: Iosevka; -} - -button { - all: unset; - background-color: #121212; - padding: 10px; + background-color: #3a3a3a; + color: #b0b4bc; + font-family: CascadiaCode; } // Styles on classes (see eww.xml for more information) diff --git a/examples/eww-bar/eww.xml b/examples/eww-bar/eww.xml index 47a1a08..2c716f8 100644 --- a/examples/eww-bar/eww.xml +++ b/examples/eww-bar/eww.xml @@ -95,7 +95,7 @@ contain are defined. --> - + diff --git a/src/app.rs b/src/app.rs index 14cb8dc..fdf8918 100644 --- a/src/app.rs +++ b/src/app.rs @@ -303,20 +303,15 @@ fn initialize_window( ) -> Result { let actual_window_rect = window_def.geometry.get_window_rectangle(monitor_geometry); - let window = - if window_def.focusable { gtk::Window::new(gtk::WindowType::Toplevel) } else { gtk::Window::new(gtk::WindowType::Popup) }; + let window = display_backend::initialize_window(&mut window_def, monitor_geometry); window.set_title(&format!("Eww - {}", window_def.name)); let wm_class_name = format!("eww-{}", window_def.name); window.set_wmclass(&wm_class_name, &wm_class_name); - if !window_def.focusable { - window.set_type_hint(gdk::WindowTypeHint::Dock); - } window.set_position(gtk::WindowPosition::Center); - window.set_default_size(actual_window_rect.width, actual_window_rect.height); window.set_size_request(actual_window_rect.width, actual_window_rect.height); + window.set_default_size(actual_window_rect.width, actual_window_rect.height); window.set_decorated(false); - window.set_resizable(false); // run on_screen_changed to set the visual correctly initially. on_screen_changed(&window, None); @@ -337,14 +332,7 @@ fn initialize_window( gdk_window.set_override_redirect(!window_def.focusable); gdk_window.move_(actual_window_rect.x, actual_window_rect.y); - if window_def.stacking == WindowStacking::Foreground { - gdk_window.raise(); - window.set_keep_above(true); - } else { - gdk_window.lower(); - window.set_keep_below(true); - } - + #[cfg(feature = "x11")] display_backend::reserve_space_for(&window, monitor_geometry, window_def.struts)?; Ok(EwwWindow { name: window_def.name.clone(), definition: window_def, gtk_window: window }) @@ -357,7 +345,6 @@ fn on_screen_changed(window: >k::Window, _old_screen: Option<&gdk::Screen>) { window.set_visual(visual.as_ref()); } -/// get the index of the default monitor fn get_default_monitor_index() -> i32 { gdk::Display::get_default().expect("could not get default display").get_default_screen().get_primary_monitor() } diff --git a/src/config/window_definition.rs b/src/config/window_definition.rs index f084226..042d928 100644 --- a/src/config/window_definition.rs +++ b/src/config/window_definition.rs @@ -1,4 +1,8 @@ -use crate::{ensure_xml_tag_is, value::NumWithUnit, widgets::widget_node}; +use crate::{ + ensure_xml_tag_is, + value::{Coords, NumWithUnit}, + widgets::widget_node, +}; use anyhow::*; use derive_more::*; use serde::{Deserialize, Serialize}; @@ -9,6 +13,7 @@ use super::*; /// Full window-definition containing the fully expanded widget tree. /// **Use this** rather than `[RawEwwWindowDefinition]`. +#[cfg(feature = "x11")] #[derive(Debug, Clone)] pub struct EwwWindowDefinition { pub name: WindowName, @@ -20,6 +25,18 @@ pub struct EwwWindowDefinition { pub focusable: bool, } +#[cfg(feature = "wayland")] +#[derive(Debug, Clone)] +pub struct EwwWindowDefinition { + pub name: WindowName, + pub geometry: EwwWindowGeometry, + pub stacking: WindowStacking, + pub screen_number: Option, + pub widget: Box, + pub exclusive: bool, + pub focusable: bool, +} + impl EwwWindowDefinition { pub fn generate(defs: &HashMap, window: RawEwwWindowDefinition) -> Result { Ok(EwwWindowDefinition { @@ -28,13 +45,17 @@ impl EwwWindowDefinition { stacking: window.stacking, screen_number: window.screen_number, widget: widget_node::generate_generic_widget_node(defs, &HashMap::new(), window.widget)?, - struts: window.struts, focusable: window.focusable, + #[cfg(feature = "x11")] + struts: window.struts, + #[cfg(feature = "wayland")] + exclusive: window.exclusive, }) } } /// Window-definition storing the raw WidgetUse, as received directly from parsing. +#[cfg(feature = "x11")] #[derive(Debug, Clone, PartialEq)] pub struct RawEwwWindowDefinition { pub name: WindowName, @@ -46,6 +67,18 @@ pub struct RawEwwWindowDefinition { pub focusable: bool, } +#[cfg(feature = "wayland")] +#[derive(Debug, Clone, PartialEq)] +pub struct RawEwwWindowDefinition { + pub name: WindowName, + pub exclusive: bool, + pub geometry: EwwWindowGeometry, + pub stacking: WindowStacking, + pub screen_number: Option, + pub widget: WidgetUse, + pub focusable: bool, +} + impl RawEwwWindowDefinition { pub fn from_xml_element(xml: &XmlElement) -> Result { ensure_xml_tag_is!(xml, "window"); @@ -55,6 +88,7 @@ impl RawEwwWindowDefinition { let focusable = xml.parse_optional_attr("focusable")?; let screen_number = xml.parse_optional_attr("screen")?; + #[cfg(feature = "x11")] let struts: Option = xml.child("reserve").ok().map(StrutDefinition::from_xml_element).transpose().context("Failed to parse ")?; @@ -68,7 +102,10 @@ impl RawEwwWindowDefinition { stacking, screen_number, focusable: focusable.unwrap_or(false), + #[cfg(feature = "x11")] struts: struts.unwrap_or_default(), + #[cfg(feature = "wayland")] + exclusive: xml.parse_optional_attr("exclusive")?.unwrap_or_default(), }) } } @@ -80,10 +117,17 @@ pub enum Side { Left, Right, Bottom, + Center, + TopLeft, + TopRight, + BottomLeft, + BottomRight, } + impl std::str::FromStr for Side { type Err = anyhow::Error; + #[cfg(feature = "x11")] fn from_str(s: &str) -> Result { match s { "l" | "left" => Ok(Side::Left), @@ -93,14 +137,36 @@ impl std::str::FromStr for Side { _ => Err(anyhow!("Failed to parse {} as valid side. Must be one of \"left\", \"right\", \"top\", \"bottom\"", s)), } } + + #[cfg(feature = "wayland")] + fn from_str(s: &str) -> Result { + match s { + "l" | "left" => Ok(Side::Left), + "r" | "right" => Ok(Side::Right), + "t" | "top" => Ok(Side::Top), + "b" | "bottom" => Ok(Side::Bottom), + "c" | "center" => Ok(Side::Center), + "tl" | "top-left" => Ok(Side::TopLeft), + "tr" | "top-right" => Ok(Side::TopRight), + "bl" | "bottom-left" => Ok(Side::BottomLeft), + "br" | "bottom-right" => Ok(Side::BottomRight), + _ => Err(anyhow!( + r#"Failed to parse {} as valid side. Must be one of "left", "right", "top", "bottom", "top-right", "top-left", "bottom-left", "bottom-right""#, + s + )), + } + } } +// Surface definition if the backend for X11 is enable +#[cfg(feature = "x11")] #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] pub struct StrutDefinition { pub side: Side, pub dist: NumWithUnit, } +#[cfg(feature = "x11")] impl StrutDefinition { pub fn from_xml_element(xml: XmlElement) -> Result { Ok(StrutDefinition { side: xml.attr("side")?.parse()?, dist: xml.attr("distance")?.parse()? }) @@ -112,11 +178,14 @@ pub enum WindowStacking { #[default] Foreground, Background, + Bottom, + Overlay, } impl std::str::FromStr for WindowStacking { type Err = anyhow::Error; + #[cfg(feature = "x11")] fn from_str(s: &str) -> Result { let s = s.to_lowercase(); match s.as_str() { @@ -125,6 +194,22 @@ impl std::str::FromStr for WindowStacking { _ => Err(anyhow!("Couldn't parse '{}' as window stacking, must be either foreground, fg, background or bg", s)), } } + + #[cfg(feature = "wayland")] + fn from_str(s: &str) -> Result { + let s = s.to_lowercase(); + match s.as_str() { + "foreground" | "fg" => Ok(WindowStacking::Foreground), + "background" | "bg" => Ok(WindowStacking::Background), + "bottom" | "bt" => Ok(WindowStacking::Bottom), + "overlay" | "ov" => Ok(WindowStacking::Overlay), + _ => Err(anyhow!( + "Couldn't parse '{}' as window stacking, must be either foreground, fg, background, bg, bottom, bt, overlay or \ + ov", + s + )), + } + } } #[repr(transparent)] diff --git a/src/config/window_geometry.rs b/src/config/window_geometry.rs index 0caa0be..4b68c35 100644 --- a/src/config/window_geometry.rs +++ b/src/config/window_geometry.rs @@ -48,8 +48,8 @@ impl AnchorAlignment { #[derive(Debug, Clone, Copy, Eq, PartialEq, Default, Serialize, Deserialize)] pub struct AnchorPoint { - x: AnchorAlignment, - y: AnchorAlignment, + pub x: AnchorAlignment, + pub y: AnchorAlignment, } impl std::fmt::Display for AnchorPoint { diff --git a/src/display_backend.rs b/src/display_backend.rs index e136008..bd44391 100644 --- a/src/display_backend.rs +++ b/src/display_backend.rs @@ -1,17 +1,96 @@ pub use platform::*; -#[cfg(feature = "no-x11")] +#[cfg(feature = "no-x11-wayland")] mod platform { use crate::config::{Side, StrutDefinition}; use anyhow::*; pub fn reserve_space_for(window: >k::Window, monitor: gdk::Rectangle, strut_def: StrutDefinition) -> Result<()> { - Err(anyhow!("Cannot reserve space on non-X11 backends")) + Err(anyhow!("Cannot reserve space on non X11 or and wayland backends")) + } +} + +#[cfg(feature = "wayland")] +mod platform { + use gdk; + use crate::{ + config::{EwwWindowDefinition, AnchorAlignment, Side, WindowStacking}, + }; + use anyhow::*; + use gtk::prelude::*; + + pub fn initialize_window(window_def: &mut EwwWindowDefinition, monitor: gdk::Rectangle) -> gtk::Window { + let window = gtk::Window::new(gtk::WindowType::Toplevel); + // Initialising a layer shell surface + gtk_layer_shell::init_for_window(&window); + // Sets the monitor where the surface is shown + match window_def.screen_number { + Some(index) => { + if let Some(monitor) = gdk::Display::get_default() + .expect("could not get default display") + .get_monitor(index) { + gtk_layer_shell::set_monitor(&window, &monitor); + }; + } + None => {} + }; + window.set_resizable(true); + + // Sets the layer where the layer shell surface will spawn + match window_def.stacking { + WindowStacking::Foreground => gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Top), + WindowStacking::Background => gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Background), + WindowStacking::Bottom => gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Bottom), + WindowStacking::Overlay => gtk_layer_shell::set_layer(&window, gtk_layer_shell::Layer::Overlay), + } + + // Sets the keyboard interactivity + gtk_layer_shell::set_keyboard_interactivity(&window, window_def.focusable); + // Positioning surface + let mut top = false; + let mut left = false; + let mut right = false; + let mut bottom = false; + + match window_def.geometry.anchor_point.x { + AnchorAlignment::START => left = true, + AnchorAlignment::CENTER => {} + AnchorAlignment::END => right = true, + } + match window_def.geometry.anchor_point.y { + AnchorAlignment::START => top = true, + AnchorAlignment::CENTER => {} + AnchorAlignment::END => bottom = true, + } + + gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Left, left); + gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Right, right); + gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Top, top); + gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Bottom, bottom); + + let xoffset = window_def.geometry.offset.x.relative_to(monitor.width); + let yoffset = window_def.geometry.offset.y.relative_to(monitor.height); + + if left { + gtk_layer_shell::set_margin(&window, gtk_layer_shell::Edge::Left, xoffset); + } else { + gtk_layer_shell::set_margin(&window, gtk_layer_shell::Edge::Right, xoffset); + } + if bottom { + gtk_layer_shell::set_margin(&window, gtk_layer_shell::Edge::Bottom, yoffset); + } else { + gtk_layer_shell::set_margin(&window, gtk_layer_shell::Edge::Top, yoffset); + } + + if window_def.exclusive { + gtk_layer_shell::auto_exclusive_zone_enable(&window); + } + window } } #[cfg(feature = "x11")] mod platform { - use crate::config::{Side, StrutDefinition}; + use crate::config::{EwwWindowDefinition, Side, StrutDefinition, WindowStacking}; use anyhow::*; use gdkx11; use gtk::{self, prelude::*}; @@ -24,6 +103,24 @@ mod platform { rust_connection::{DefaultStream, RustConnection}, }; + pub fn initialize_window(window_def: &mut EwwWindowDefinition, _monitor: gdk::Rectangle) -> gtk::Window { + let window = if window_def.focusable { + gtk::Window::new(gtk::WindowType::Toplevel) + } else { + gtk::Window::new(gtk::WindowType::Popup) + }; + window.set_resizable(true); + if !window_def.focusable { + window.set_type_hint(gdk::WindowTypeHint::Dock); + } + if window_def.stacking == WindowStacking::Foreground { + window.set_keep_above(true); + } else { + window.set_keep_below(true); + } + window + } + pub fn reserve_space_for(window: >k::Window, monitor: gdk::Rectangle, strut_def: StrutDefinition) -> Result<()> { let backend = X11Backend::new()?; backend.reserve_space_for(window, monitor, strut_def)?; @@ -65,6 +162,7 @@ mod platform { let dist = match strut_def.side { Side::Left | Side::Right => strut_def.dist.relative_to(monitor_rect.width) as u32, Side::Top | Side::Bottom => strut_def.dist.relative_to(monitor_rect.height) as u32, + _ => (monitor_rect.height / 2) as u32, }; // don't question it,..... @@ -75,7 +173,10 @@ mod platform { Side::Left => vec![dist + monitor_rect.x as u32, 0, 0, 0, monitor_rect.y as u32, mon_end_y, 0, 0, 0, 0, 0, 0], Side::Right => vec![0, root_window_geometry.width as u32 - mon_end_x + dist, 0, 0, 0, 0, monitor_rect.y as u32, mon_end_y, 0, 0, 0, 0], Side::Top => vec![0, 0, dist + monitor_rect.y as u32, 0, 0, 0, 0, 0, monitor_rect.x as u32, mon_end_x, 0, 0], - Side::Bottom => vec![0, 0, 0, root_window_geometry.height as u32 - mon_end_y + dist, 0, 0, 0, 0, 0, 0, monitor_rect.x as u32, mon_end_x] + Side::Bottom => vec![0, 0, 0, root_window_geometry.height as u32 - mon_end_y + dist, 0, 0, 0, 0, 0, 0, monitor_rect.x as u32, mon_end_x], + // This should never happen but if it does the window will be anchored on the + // right of the screen + _ => vec![0, root_window_geometry.width as u32 - mon_end_x + dist, 0, 0, 0, 0, monitor_rect.y as u32, mon_end_y, 0, 0, 0, 0], }.iter().flat_map(|x| x.to_le_bytes().to_vec()).collect(); self.conn diff --git a/src/main.rs b/src/main.rs index 304b4f9..637f65a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,8 @@ extern crate gio; extern crate gtk; +#[cfg(feature = "wayland")] +extern crate gtk_layer_shell as gtk_layer_shell; use anyhow::*; use std::{ diff --git a/src/opts.rs b/src/opts.rs index ba1f1fe..bd6e3be 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -82,7 +82,7 @@ pub enum ActionWithServer { #[structopt(short, long)] size: Option, - /// Anchorpoint of the window, formatted like "top right" + /// Sidepoint of the window, formatted like "top right" #[structopt(short, long)] anchor: Option, }, diff --git a/src/widgets/widget_definitions.rs b/src/widgets/widget_definitions.rs index b6fc36d..f5143a7 100644 --- a/src/widgets/widget_definitions.rs +++ b/src/widgets/widget_definitions.rs @@ -1,7 +1,8 @@ use super::{run_command, BuilderArgs}; use crate::{config, eww_state, resolve_block, value::AttrVal, widgets::widget_node}; use anyhow::*; -use gtk::{prelude::*, ImageExt}; +use glib; +use gtk::{self, prelude::*, ImageExt}; use std::{cell::RefCell, collections::HashMap, rc::Rc}; // TODO figure out how to