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