Clean up X Window configuration and add more options

factor out some x specific logic cleanly

factor out more code into backend specific sections

Minor refactor to enum parsing

fix build on wayland

make default of wm-ignore depend on type and reserve, and add documentation
This commit is contained in:
elkowar 2021-07-15 15:03:58 +02:00
parent 4f59424e0e
commit db9e673b81
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
11 changed files with 454 additions and 466 deletions

334
Cargo.lock generated
View file

@ -10,9 +10,9 @@ checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
[[package]]
name = "aho-corasick"
version = "0.7.18"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
@ -37,15 +37,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.40"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
[[package]]
name = "anymap"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344"
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
[[package]]
name = "arrayvec"
@ -55,9 +49,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "async-stream"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a26cb53174ddd320edfff199a853f93d571f48eeb4dde75e67a9a3dbb7b7e5e"
checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625"
dependencies = [
"async-stream-impl",
"futures-core",
@ -65,13 +59,13 @@ dependencies = [
[[package]]
name = "async-stream-impl"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db134ba52475c060f3329a8ef0f8786d6b872ed01515d4b79c162e5798da1340"
checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -190,9 +184,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.67"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
[[package]]
name = "cfg-if"
@ -256,9 +250,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.4"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94"
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
dependencies = [
"cfg-if",
"crossbeam-utils",
@ -269,11 +263,10 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.4"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
@ -285,7 +278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d"
dependencies = [
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -300,14 +293,15 @@ dependencies = [
[[package]]
name = "derive_more"
version = "0.99.13"
version = "0.99.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b1b72f1263f214c0f823371768776c4f5841b942c9883aa8e5ec584fd0ba6"
checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df"
dependencies = [
"convert_case",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"rustc_version",
"syn 1.0.73",
]
[[package]]
@ -371,7 +365,7 @@ dependencies = [
"gtk",
"gtk-layer-shell",
"gtk-layer-shell-sys",
"itertools 0.10.0",
"itertools 0.10.1",
"lazy_static",
"libc",
"log",
@ -389,8 +383,6 @@ dependencies = [
"simple-signal",
"smart-default",
"structopt",
"strum 0.20.0",
"strum_macros 0.20.1",
"sysinfo",
"tokio",
"tokio-stream",
@ -402,14 +394,14 @@ dependencies = [
[[package]]
name = "extend"
version = "1.0.1"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2feaa8e332f0db2f08788707dc550075aab8e6d20ffc85958e1174e22887d11"
checksum = "f5c89e2933a4ec753dc007a4d6a7f9b6dc8e89b8fe89cabc252ccddf39c08bb1"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -424,21 +416,11 @@ dependencies = [
"winapi",
]
[[package]]
name = "fsevent"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97f347202c95c98805c216f9e1df210e8ebaec9fdb2365700a43c10797a35e63"
dependencies = [
"bitflags",
"fsevent-sys",
]
[[package]]
name = "fsevent-sys"
version = "3.0.2"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a29c77f1ca394c3e73a9a5d24cfcabb734682d9634fc398f2204a63c994120"
checksum = "5c0e564d24da983c053beff1bb7178e237501206840a3e6bf4e267b9e8ae734a"
dependencies = [
"libc",
]
@ -451,9 +433,9 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
[[package]]
name = "futures"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
dependencies = [
"futures-channel",
"futures-core",
@ -466,9 +448,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
dependencies = [
"futures-core",
"futures-sink",
@ -476,15 +458,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
[[package]]
name = "futures-executor"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
dependencies = [
"futures-core",
"futures-task",
@ -493,40 +475,42 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
[[package]]
name = "futures-macro"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
dependencies = [
"autocfg",
"proc-macro-hack",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
name = "futures-sink"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
[[package]]
name = "futures-task"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
[[package]]
name = "futures-util"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
dependencies = [
"autocfg",
"futures-channel",
"futures-core",
"futures-io",
@ -732,7 +716,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -758,9 +742,9 @@ dependencies = [
[[package]]
name = "grass"
version = "0.10.4"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8209e6832a1f93e15adca845b43af12ead0cb8221fb2ef615ca84c75e54af1a"
checksum = "352df9cd46a5538323ba016fdbff8baee4a55011a7349120b0d7280992276fa7"
dependencies = [
"beef",
"clap",
@ -862,24 +846,24 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.9.1"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.18"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
@ -895,19 +879,19 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.6.2"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [
"autocfg",
"hashbrown 0.9.1",
"hashbrown 0.11.2",
]
[[package]]
name = "inotify"
version = "0.9.2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d19f57db1baad9d09e43a3cd76dcf82ebdafd37d75c9498b87762dba77c93f15"
checksum = "b031475cb1b103ee221afb806a23d35e0570bf7271d7588762ceba8127ed43b3"
dependencies = [
"bitflags",
"inotify-sys",
@ -925,9 +909,9 @@ dependencies = [
[[package]]
name = "instant"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
dependencies = [
"cfg-if",
]
@ -943,9 +927,9 @@ dependencies = [
[[package]]
name = "itertools"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]
@ -986,9 +970,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.94"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "lock_api"
@ -1016,24 +1000,24 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "memchr"
version = "2.4.0"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "memoffset"
version = "0.6.3"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]]
name = "mio"
version = "0.7.11"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
dependencies = [
"libc",
"log",
@ -1065,9 +1049,9 @@ dependencies = [
[[package]]
name = "nom"
version = "6.1.2"
version = "6.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6"
dependencies = [
"bitvec",
"funty",
@ -1078,15 +1062,13 @@ dependencies = [
[[package]]
name = "notify"
version = "5.0.0-pre.7"
version = "5.0.0-pre.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebe7699a0f8c5759450716ee03d231685c22b4fe8f406c42c22e0ad94d40ce7"
checksum = "51f18203a26893ca1d3526cf58084025d5639f91c44f8b70ab3b724f60e819a0"
dependencies = [
"anymap",
"bitflags",
"crossbeam-channel",
"filetime",
"fsevent",
"fsevent-sys",
"inotify",
"libc",
@ -1215,9 +1197,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.7.2"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "output_vt100"
@ -1289,6 +1271,15 @@ dependencies = [
"smallvec",
]
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "phf"
version = "0.8.0"
@ -1321,7 +1312,7 @@ dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -1335,9 +1326,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pin-utils"
@ -1397,7 +1388,7 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
"version_check",
]
@ -1426,9 +1417,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]]
name = "proc-macro2"
version = "1.0.26"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [
"unicode-xid 0.2.2",
]
@ -1513,9 +1504,9 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.5.0"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
@ -1525,9 +1516,9 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.9.0"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
@ -1538,18 +1529,18 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.4"
version = "1.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
dependencies = [
"aho-corasick",
"memchr",
@ -1571,6 +1562,15 @@ dependencies = [
"xmlparser",
]
[[package]]
name = "rustc_version"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.5"
@ -1593,23 +1593,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.125"
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
[[package]]
name = "serde"
version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.125"
version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -1625,9 +1643,9 @@ dependencies = [
[[package]]
name = "signal-hook-registry"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
@ -1668,7 +1686,7 @@ checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -1685,9 +1703,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.21"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71"
dependencies = [
"clap",
"lazy_static",
@ -1696,15 +1714,15 @@ dependencies = [
[[package]]
name = "structopt-derive"
version = "0.4.14"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -1713,12 +1731,6 @@ version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
[[package]]
name = "strum"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c"
[[package]]
name = "strum_macros"
version = "0.18.0"
@ -1728,19 +1740,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
]
[[package]]
name = "strum_macros"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149"
dependencies = [
"heck",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
@ -1756,9 +1756,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.72"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
dependencies = [
"proc-macro2",
"quote 1.0.9",
@ -1798,8 +1798,8 @@ checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
dependencies = [
"heck",
"pkg-config",
"strum 0.18.0",
"strum_macros 0.18.0",
"strum",
"strum_macros",
"thiserror",
"toml",
"version-compare",
@ -1831,29 +1831,29 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.24"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.24"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
name = "tokio"
version = "1.5.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5"
checksum = "98c8b05dc14c75ea83d63dd391100353789f5f24b8b3866542a5e85c8be8e985"
dependencies = [
"autocfg",
"bytes",
@ -1871,20 +1871,20 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "1.1.0"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.72",
"syn 1.0.73",
]
[[package]]
name = "tokio-stream"
version = "0.1.5"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e177a5d8c3bf36de9ebe6d58537d8879e964332f93fb3339e43f618c81361af0"
checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f"
dependencies = [
"futures-core",
"pin-project-lite",
@ -1893,9 +1893,9 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.6.6"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
@ -1914,6 +1914,12 @@ dependencies = [
"serde",
]
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "unescape"
version = "0.1.0"
@ -1922,9 +1928,9 @@ checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e"
[[package]]
name = "unicode-segmentation"
version = "1.7.1"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"

View file

@ -206,7 +206,7 @@ The `<windows>` config should look something like this:
```xml
<windows>
<window name="main_window" stacking="fg" focusable="false" screen="1">
<window name="main_window" stacking="fg" screen="1" windowtype="dock">
<geometry anchor="top left" x="300px" y="50%" width="25%" height="20px"/>
<reserve side="left" distance="50px"/>
<widget>
@ -220,7 +220,7 @@ For Wayland users the `<reserve/>` block is replaced by the exclusive field in `
The previous `<window>` block would look like this.
```xml
<window name="main_window" stacking="fg" focusable="false" screen="1" exclusive="true" windowtype="normal">
<window name="main_window" stacking="fg" focusable="false" screen="1" exclusive="true">
<geometry anchor="top left" x="300px" y="50%" width="25%" height="20px"/>
<widget>
<main/>
@ -237,9 +237,6 @@ There are a couple things you can optionally configure on the window itself:
- `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.
@ -247,10 +244,34 @@ There are a couple things you can optionally configure on the window itself:
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"`
- `focusable`: (Wayland only) whether the window should be able to capture keyboard input.
Possible values: `"true"`, `"false"`. Default: `"false"`
- `wm-ignore`: (X11 only) wether the window should be managed by the window manager.
For a centered widget setup this is recommended to be set to true. For a bar, set the windowtype to `dock` instead.
Note that setting `wm-ignore` will make some other options not work, as those rely on the window manager.
Possible values: `"true"`, `"false"`. Default: `"true"` except if `<reserve>` is set.
- `windowtype`: (X11 only) Can be used in determining the decoration, stacking position and other behavior of the window.
Possible values:
Window managers tend to interpret these differently, so play around with which one works for your usecase!
Possible values:
- `"normal"`: indicates that this is a normal, top-level window
- `"dock"`: indicates a dock or panel feature
- `"dock"`: indicates a bar, dock, or panel window
- `"utility"`: indicates a pinned utility window
- `"toolbar"`: toolbars "torn off" from the main application
- `"dialog"`: indicates that this is a dialog window
- Default: `"dock"` if reserve is set, else `"normal"`
- Default: `"dock"`
- `sticky`: (X11 only) If the window should show up on all workspaces. Note that this may not have any effect, depending on your window manager and the window type.
Possible values: `"true"`, `"false"`. Default: `"true"`
- `resizable`: (X11 only) If the window should be resizable. Note that this may not have any effect, depending on your window manager and the window type.
Possible values: `"true"`, `"false"`. Default: `"true"`
### Recommendations for different use-cases on X
Window positioning is... weird on X11. Different window-managers handle things differently, and some things are just not compatible.
Thus, the following setups are recommendations that will _probably_ work. If they don't try to play around with different settings for any of the X11 only properties.
- For a bar:
- Set `windowtype` to `dock`, and provide a `reserve` configuration to match your window geometry to make the WM reserve space.
- Set `wm-ignore` to `false`.
- For a centered, full-screen widget setup:
- Set `wm-ignore` to `true`.

View file

@ -3,7 +3,7 @@ use crate::{
config::{window_definition::WindowName, AnchorPoint},
display_backend, eww_state,
script_var_handler::*,
value::{Coords, NumWithUnit, PrimVal, VarName},
value::{Coords, PrimVal, VarName},
EwwPaths,
};
use anyhow::*;
@ -231,7 +231,7 @@ impl App {
log::info!("Opening window {}", window_name);
let mut window_def = self.eww_config.get_window(window_name)?.clone();
window_def.geometry = window_def.geometry.override_if_given(anchor, pos, size);
window_def.geometry = window_def.geometry.map(|x| x.override_if_given(anchor, pos, size));
let root_widget =
window_def.widget.render(&mut self.eww_state, window_name, &self.eww_config.get_widget_definitions())?;
@ -245,8 +245,7 @@ impl App {
// initialize script var handlers for variables that where not used before opening this window.
// TODO somehow make this less shit
for newly_used_var in
self.variables_only_used_in(window_name).filter_map(|var| self.eww_config.get_script_var(var).ok())
for newly_used_var in self.variables_only_used_in(window_name).filter_map(|var| self.eww_config.get_script_var(var).ok())
{
self.script_var_handler.add(newly_used_var.clone());
}
@ -306,55 +305,53 @@ fn initialize_window(
root_widget: gtk::Widget,
window_def: config::EwwWindowDefinition,
) -> Result<EwwWindow> {
let actual_window_rect = window_def.geometry.get_window_rectangle(monitor_geometry);
if let Some(window) = display_backend::initialize_window(&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);
window.set_position(gtk::WindowPosition::Center);
let window = display_backend::initialize_window(&window_def, monitor_geometry)
.with_context(|| format!("monitor {} is unavailable", window_def.screen_number.unwrap()))?;
window.set_title(&format!("Eww - {}", window_def.name));
window.set_position(gtk::WindowPosition::None);
window.set_gravity(gdk::Gravity::Center);
if let Some(geometry) = window_def.geometry {
let actual_window_rect = geometry.get_window_rectangle(monitor_geometry);
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);
// run on_screen_changed to set the visual correctly initially.
on_screen_changed(&window, None);
window.connect_screen_changed(on_screen_changed);
window.add(&root_widget);
window.show_all();
apply_window_position(window_def.clone(), monitor_geometry, &window)?;
let gdk_window = window.get_window().context("couldn't get gdk window from gtk window")?;
gdk_window.set_override_redirect(!window_def.focusable);
#[cfg(feature = "x11")]
display_backend::set_xprops(&window, monitor_geometry, &window_def)?;
// this should only be required on x11, as waylands layershell should manage the margins properly anways.
#[cfg(feature = "x11")]
window.connect_configure_event({
let window_def = window_def.clone();
move |window, _evt| {
let _ = apply_window_position(window_def.clone(), monitor_geometry, &window);
false
}
});
Ok(EwwWindow { name: window_def.name.clone(), definition: window_def, gtk_window: window })
} else {
Err(anyhow!("monitor {} is unavailable", window_def.screen_number.unwrap()))
}
window.set_decorated(false);
window.set_skip_taskbar_hint(true);
window.set_skip_pager_hint(true);
// run on_screen_changed to set the visual correctly initially.
on_screen_changed(&window, None);
window.connect_screen_changed(on_screen_changed);
window.add(&root_widget);
window.show_all();
#[cfg(feature = "x11")]
{
if let Some(geometry) = window_def.geometry {
let _ = apply_window_position(geometry, monitor_geometry, &window);
window.connect_configure_event(move |window, _| {
let _ = apply_window_position(geometry, monitor_geometry, &window);
false
});
}
display_backend::set_xprops(&window, monitor_geometry, &window_def)?;
}
Ok(EwwWindow { name: window_def.name.clone(), definition: window_def, gtk_window: window })
}
/// Apply the provided window-positioning rules to the window.
fn apply_window_position(
mut window_def: config::EwwWindowDefinition,
mut window_geometry: config::EwwWindowGeometry,
monitor_geometry: gdk::Rectangle,
window: &gtk::Window,
) -> Result<()> {
let (gtk_window_width, gtk_window_height) = window.get_size();
window_def.geometry.size = Coords { x: NumWithUnit::Pixels(gtk_window_width), y: NumWithUnit::Pixels(gtk_window_height) };
let gdk_window = window.get_window().context("Failed to get gdk window from gtk window")?;
let actual_window_rect = window_def.geometry.get_window_rectangle(monitor_geometry);
window_geometry.size = Coords::from_pixels(window.get_size());
let actual_window_rect = window_geometry.get_window_rectangle(monitor_geometry);
gdk_window.move_(actual_window_rect.x, actual_window_rect.y);
Ok(())
}
@ -367,11 +364,13 @@ fn on_screen_changed(window: &gtk::Window, _old_screen: Option<&gdk::Screen>) {
}
fn get_default_monitor_index() -> i32 {
#[allow(deprecated)]
gdk::Display::get_default().expect("could not get default display").get_default_screen().get_primary_monitor()
}
/// Get the monitor geometry of a given monitor number
fn get_monitor_geometry(n: i32) -> gdk::Rectangle {
#[allow(deprecated)]
gdk::Display::get_default().expect("could not get default display").get_default_screen().get_monitor_geometry(n)
}

View file

@ -0,0 +1,69 @@
use crate::config::xml_ext::XmlElement;
use anyhow::*;
pub use backend::*;
#[cfg(feature = "x11")]
mod backend {
use super::*;
use crate::config::{EwwWindowType, StrutDefinition};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BackendWindowOptions {
pub wm_ignore: bool,
pub sticky: bool,
pub window_type: EwwWindowType,
pub struts: StrutDefinition,
}
impl BackendWindowOptions {
pub fn from_xml_element(xml: &XmlElement) -> Result<Self> {
let struts: Option<StrutDefinition> = xml
.child("reserve")
.ok()
.map(StrutDefinition::from_xml_element)
.transpose()
.context("Failed to parse <reserve>")?;
let window_type = xml.parse_optional_attr("windowtype")?;
Ok(BackendWindowOptions {
wm_ignore: xml.parse_optional_attr("wm-ignore")?.unwrap_or(window_type.is_none() && struts.is_none()),
window_type: window_type.unwrap_or_default(),
sticky: xml.parse_optional_attr("sticky")?.unwrap_or(true),
struts: struts.unwrap_or_default(),
})
}
}
}
#[cfg(feature = "wayland")]
mod backend {
use super::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BackendWindowOptions {
pub exclusive: bool,
pub focusable: bool,
}
impl BackendWindowOptions {
pub fn from_xml_element(xml: &XmlElement) -> Result<Self> {
Ok(BackendWindowOptions {
exclusive: xml.parse_optional_attr("exclusive")?.unwrap_or(false),
focusable: xml.parse_optional_attr("focusable")?.unwrap_or(false),
})
}
}
}
#[cfg(feature = "no-x11-wayland")]
mod backend {
use super::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BackendWindowOptions;
impl BackendWindowOptions {
pub fn from_xml_element(xml: &XmlElement) -> Result<Self> {
Ok(BackendWindowOptions)
}
}
}

View file

@ -8,6 +8,7 @@ use anyhow::*;
use element::*;
use xml_ext::*;
pub mod backend_window_options;
pub mod element;
pub mod eww_config;
pub mod inbuilt;

View file

@ -1,57 +1,22 @@
use super::*;
use crate::{ensure_xml_tag_is, value::NumWithUnit, widgets::widget_node};
use super::{backend_window_options::*, *};
use crate::{ensure_xml_tag_is, enum_parse, value::NumWithUnit, widgets::widget_node};
use derive_more::*;
use serde::{Deserialize, Serialize};
use smart_default::SmartDefault;
use std::{collections::HashMap, str::FromStr};
#[derive(Debug, Clone, PartialEq)]
pub enum EwwWindowType {
Dock,
Dialog,
Toolbar,
Normal,
}
impl FromStr for EwwWindowType {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"dock" => Ok(Self::Dock),
"toolbar" => Ok(Self::Toolbar),
"dialog" => Ok(Self::Dialog),
"normal" => Ok(Self::Normal),
x => Err(anyhow!("Unknown windowtype provided '{}'. Possible values are: dock, toolbar, dialog, normal", x)),
}
}
}
impl Default for EwwWindowType {
fn default() -> Self {
Self::Normal
}
}
/// Full window-definition containing the fully expanded widget tree.
/// **Use this** rather than `[RawEwwWindowDefinition]`.
/// **Use this** rather than [RawEwwWindowDefinition].
#[derive(Debug, Clone)]
pub struct EwwWindowDefinition {
pub name: WindowName,
pub geometry: EwwWindowGeometry,
pub geometry: Option<EwwWindowGeometry>,
pub stacking: WindowStacking,
pub screen_number: Option<i32>,
pub widget: Box<dyn widget_node::WidgetNode>,
pub focusable: bool,
#[cfg(feature = "x11")]
pub window_type: EwwWindowType,
#[cfg(feature = "x11")]
pub struts: StrutDefinition,
#[cfg(feature = "wayland")]
pub exclusive: bool,
pub resizable: bool,
pub backend_options: BackendWindowOptions,
}
impl EwwWindowDefinition {
@ -61,14 +26,9 @@ impl EwwWindowDefinition {
geometry: window.geometry,
stacking: window.stacking,
screen_number: window.screen_number,
resizable: window.resizable,
widget: widget_node::generate_generic_widget_node(defs, &HashMap::new(), window.widget)?,
focusable: window.focusable,
#[cfg(feature = "x11")]
window_type: window.window_type,
#[cfg(feature = "x11")]
struts: window.struts,
#[cfg(feature = "wayland")]
exclusive: window.exclusive,
backend_options: window.backend_options,
})
}
}
@ -77,61 +37,58 @@ impl EwwWindowDefinition {
#[derive(Debug, Clone, PartialEq)]
pub struct RawEwwWindowDefinition {
pub name: WindowName,
pub geometry: EwwWindowGeometry,
pub geometry: Option<EwwWindowGeometry>,
pub stacking: WindowStacking,
pub screen_number: Option<i32>,
pub widget: WidgetUse,
pub focusable: bool,
#[cfg(feature = "x11")]
pub window_type: EwwWindowType,
#[cfg(feature = "x11")]
pub struts: StrutDefinition,
#[cfg(feature = "wayland")]
pub exclusive: bool,
pub resizable: bool,
pub backend_options: BackendWindowOptions,
pub screen_number: Option<i32>,
}
impl RawEwwWindowDefinition {
pub fn from_xml_element(xml: &XmlElement) -> Result<Self> {
ensure_xml_tag_is!(xml, "window");
let stacking: WindowStacking = xml.parse_optional_attr("stacking")?.unwrap_or_default();
// TODO maybe rename this to monitor?
let focusable = xml.parse_optional_attr("focusable")?;
let screen_number = xml.parse_optional_attr("screen")?;
#[cfg(feature = "x11")]
let struts: Option<StrutDefinition> =
xml.child("reserve").ok().map(StrutDefinition::from_xml_element).transpose().context("Failed to parse <reserve>")?;
let geometry = match xml.child("geometry") {
Ok(node) => Some(EwwWindowGeometry::from_xml_element(node)?),
Err(_) => None,
};
Ok(RawEwwWindowDefinition {
name: WindowName(xml.attr("name")?),
geometry: match xml.child("geometry") {
Ok(node) => EwwWindowGeometry::from_xml_element(node)?,
Err(_) => EwwWindowGeometry::default(),
},
#[cfg(feature = "x11")]
window_type: match xml.attr("windowtype") {
Ok(v) => EwwWindowType::from_str(&v)?,
Err(_) => match struts {
Some(_) => EwwWindowType::Dock,
None => Default::default(),
},
},
geometry,
widget: WidgetUse::from_xml_node(xml.child("widget")?.only_child()?)?,
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(),
stacking: xml.parse_optional_attr("stacking")?.unwrap_or_default(),
// TODO maybe rename this to monitor?
screen_number: xml.parse_optional_attr("screen")?,
resizable: xml.parse_optional_attr("resizable")?.unwrap_or(true),
backend_options: BackendWindowOptions::from_xml_element(xml)?,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, SmartDefault)]
pub enum EwwWindowType {
#[default]
Dock,
Dialog,
Toolbar,
Normal,
Utility,
}
impl FromStr for EwwWindowType {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
enum_parse! { "window type", s,
"dock" => Self::Dock,
"toolbar" => Self::Toolbar,
"dialog" => Self::Dialog,
"normal" => Self::Normal,
"utility" => Self::Utility,
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, smart_default::SmartDefault)]
pub enum Side {
#[default]
@ -145,12 +102,11 @@ impl std::str::FromStr for Side {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Side> {
match s {
"l" | "left" => Ok(Side::Left),
"r" | "right" => Ok(Side::Right),
"t" | "top" => Ok(Side::Top),
"b" | "bottom" => Ok(Side::Bottom),
_ => Err(anyhow!("Failed to parse {} as valid side. Must be one of \"left\", \"right\", \"top\", \"bottom\"", s)),
enum_parse! { "side", s,
"l" | "left" => Side::Left,
"r" | "right" => Side::Right,
"t" | "top" => Side::Top,
"b" | "bottom" => Side::Bottom,
}
}
}
@ -182,27 +138,19 @@ impl std::str::FromStr for WindowStacking {
#[cfg(not(feature = "wayland"))]
fn from_str(s: &str) -> Result<Self> {
let s = s.to_lowercase();
match s.as_str() {
"foreground" | "fg" | "f" => Ok(WindowStacking::Foreground),
"background" | "bg" | "b" => Ok(WindowStacking::Background),
_ => Err(anyhow!("Couldn't parse '{}' as window stacking, must be either foreground, fg, background or bg", s)),
enum_parse! { "WindowStacking", s,
"foreground" | "fg" | "f" => WindowStacking::Foreground,
"background" | "bg" | "b" => WindowStacking::Background,
}
}
#[cfg(feature = "wayland")]
fn from_str(s: &str) -> Result<Self> {
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
)),
enum_parse! { "WindowStacking", s,
"foreground" | "fg" => WindowStacking::Foreground,
"background" | "bg" => WindowStacking::Background,
"bottom" | "bt" => WindowStacking::Bottom,
"overlay" | "ov" => WindowStacking::Overlay,
}
}
}

View file

@ -9,12 +9,12 @@ use super::xml_ext::XmlElement;
#[derive(Debug, derive_more::Display, Clone, Copy, Eq, PartialEq, SmartDefault, Serialize, Deserialize)]
pub enum AnchorAlignment {
#[display("start")]
#[display(fmt = "start")]
#[default]
START,
#[display("center")]
#[display(fmt = "center")]
CENTER,
#[display("end")]
#[display(fmt = "end")]
END,
}
@ -117,7 +117,7 @@ impl EwwWindowGeometry {
})
}
pub fn override_if_given(&mut self, anchor_point: Option<AnchorPoint>, offset: Option<Coords>, size: Option<Coords>) -> Self {
pub fn override_if_given(&self, anchor_point: Option<AnchorPoint>, offset: Option<Coords>, size: Option<Coords>) -> Self {
EwwWindowGeometry {
anchor_point: anchor_point.unwrap_or(self.anchor_point),
offset: offset.unwrap_or(self.offset),

View file

@ -7,32 +7,13 @@ mod platform {
use gtk::{self, prelude::*};
pub fn initialize_window(window_def: &EwwWindowDefinition, _monitor: gdk::Rectangle) -> Option<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);
}
Some(window)
}
pub fn reserve_space_for(_window: &gtk::Window, _monitor: gdk::Rectangle, _strut_def: StrutDefinition) -> Result<()> {
Err(anyhow!("Cannot reserve space on non X11 or and wayland backends"))
Some(gtk::Window::new(gtk::WindowType::Toplevel))
}
}
#[cfg(feature = "wayland")]
mod platform {
use crate::config::{AnchorAlignment, EwwWindowDefinition, Side, WindowStacking};
use anyhow::*;
use crate::config::{AnchorAlignment, EwwWindowDefinition, WindowStacking};
use gdk;
use gtk::prelude::*;
@ -46,12 +27,12 @@ mod platform {
if let Some(monitor) = gdk::Display::get_default().expect("could not get default display").get_monitor(index) {
gtk_layer_shell::set_monitor(&window, &monitor);
} else {
return None
return None;
}
}
None => {},
None => {}
};
window.set_resizable(true);
window.set_resizable(window_def.resizable);
// Sets the layer where the layer shell surface will spawn
match window_def.stacking {
@ -62,44 +43,46 @@ mod platform {
}
// 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;
gtk_layer_shell::set_keyboard_interactivity(&window, window_def.backend_options.focusable);
match window_def.geometry.anchor_point.x {
AnchorAlignment::START => left = true,
AnchorAlignment::CENTER => {}
AnchorAlignment::END => right = true,
if let Some(geometry) = window_def.geometry {
// Positioning surface
let mut top = false;
let mut left = false;
let mut right = false;
let mut bottom = false;
match geometry.anchor_point.x {
AnchorAlignment::START => left = true,
AnchorAlignment::CENTER => {}
AnchorAlignment::END => right = true,
}
match 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 = geometry.offset.x.relative_to(monitor.width);
let yoffset = 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);
}
}
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 {
if window_def.backend_options.exclusive {
gtk_layer_shell::auto_exclusive_zone_enable(&window);
}
Some(window)
@ -122,19 +105,18 @@ mod platform {
};
pub fn initialize_window(window_def: &EwwWindowDefinition, _monitor: gdk::Rectangle) -> Option<gtk::Window> {
let window = if window_def.focusable {
gtk::Window::new(gtk::WindowType::Toplevel)
let window_type = if window_def.backend_options.wm_ignore { gtk::WindowType::Popup } else { gtk::WindowType::Toplevel };
let window = gtk::Window::new(window_type);
let wm_class_name = format!("eww-{}", window_def.name);
#[allow(deprecated)]
window.set_wmclass(&wm_class_name, &wm_class_name);
window.set_resizable(window_def.resizable);
window.set_keep_above(window_def.stacking == WindowStacking::Foreground);
window.set_keep_below(window_def.stacking == WindowStacking::Background);
if window_def.backend_options.sticky {
window.stick();
} 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.unstick();
}
Some(window)
}
@ -172,7 +154,7 @@ mod platform {
.ok()
.context("Failed to get x11 window for gtk window")?
.get_xid() as u32;
let strut_def = window_def.struts;
let strut_def = window_def.backend_options.struts;
let root_window_geometry = self.conn.get_geometry(self.root_window)?.reply()?;
let mon_end_x = (monitor_rect.x + monitor_rect.width) as u32 - 1u32;
@ -225,11 +207,12 @@ mod platform {
win_id,
self.atoms._NET_WM_WINDOW_TYPE,
self.atoms.ATOM,
&[match window_def.window_type {
&[match window_def.backend_options.window_type {
EwwWindowType::Dock => self.atoms._NET_WM_WINDOW_TYPE_DOCK,
EwwWindowType::Normal => self.atoms._NET_WM_WINDOW_TYPE_NORMAL,
EwwWindowType::Dialog => self.atoms._NET_WM_WINDOW_TYPE_DIALOG,
EwwWindowType::Toolbar => self.atoms._NET_WM_WINDOW_TYPE_TOOLBAR,
EwwWindowType::Utility => self.atoms._NET_WM_WINDOW_TYPE_UTILITY,
}],
)?
.check()?;
@ -245,6 +228,7 @@ mod platform {
_NET_WM_WINDOW_TYPE_DOCK,
_NET_WM_WINDOW_TYPE_DIALOG,
_NET_WM_WINDOW_TYPE_TOOLBAR,
_NET_WM_WINDOW_TYPE_UTILITY,
_NET_WM_STATE,
_NET_WM_STATE_STICKY,
_NET_WM_STATE_ABOVE,

View file

@ -3,23 +3,6 @@ use extend::ext;
use itertools::Itertools;
use std::path::Path;
#[macro_export]
macro_rules! impl_try_from {
($typ:ty {
$(
for $for:ty => |$arg:ident| $code:expr
);*;
}) => {
$(impl TryFrom<$typ> for $for {
type Error = anyhow::Error;
fn try_from($arg: $typ) -> Result<Self> {
$code
}
})*
};
}
#[macro_export]
macro_rules! try_logging_errors {
($context:expr => $code:block) => {{
@ -62,8 +45,8 @@ macro_rules! loop_select {
#[macro_export]
macro_rules! enum_parse {
($name:literal, $input:expr, $($($s:literal)|* => $val:expr),* $(,)?) => {
let input = $input;
match input {
let input = $input.to_lowercase();
match input.as_str() {
$( $( $s )|* => Ok($val) ),*,
_ => Err(anyhow!(concat!("Couldn't parse ", $name, ": '{}'. Possible values are ", $($($s),*),*), input))
}

View file

@ -68,7 +68,7 @@ impl fmt::Debug for Coords {
}
impl Coords {
pub fn from_pixels(x: i32, y: i32) -> Self {
pub fn from_pixels((x, y): (i32, i32)) -> Self {
Coords { x: NumWithUnit::Pixels(x), y: NumWithUnit::Pixels(y) }
}

View file

@ -3,8 +3,6 @@ use itertools::Itertools;
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, fmt, iter::FromIterator};
use crate::impl_try_from;
#[derive(Clone, Deserialize, Serialize, derive_more::From, Default)]
pub struct PrimVal(pub String);
@ -46,53 +44,32 @@ impl std::str::FromStr for PrimVal {
}
}
impl_try_from!(PrimVal {
macro_rules! impl_try_from {
(impl From<$typ:ty> {
$(for $for:ty => |$arg:ident| $code:expr);*;
}) => {
$(impl TryFrom<$typ> for $for {
type Error = anyhow::Error;
fn try_from($arg: $typ) -> Result<Self> { $code }
})*
};
}
macro_rules! impl_primval_from {
($($t:ty),*) => {
$(impl From<$t> for PrimVal {
fn from(x: $t) -> Self { PrimVal(x.to_string()) }
})*
};
}
impl_try_from!(impl From<PrimVal> {
for String => |x| x.as_string();
for f64 => |x| x.as_f64();
for bool => |x| x.as_bool();
for Vec<String> => |x| x.as_vec();
});
impl From<bool> for PrimVal {
fn from(x: bool) -> Self {
PrimVal(x.to_string())
}
}
impl From<i32> for PrimVal {
fn from(s: i32) -> Self {
PrimVal(s.to_string())
}
}
impl From<u32> for PrimVal {
fn from(s: u32) -> Self {
PrimVal(s.to_string())
}
}
impl From<f32> for PrimVal {
fn from(s: f32) -> Self {
PrimVal(s.to_string())
}
}
impl From<u8> for PrimVal {
fn from(s: u8) -> Self {
PrimVal(s.to_string())
}
}
impl From<f64> for PrimVal {
fn from(s: f64) -> Self {
PrimVal(s.to_string())
}
}
impl From<&str> for PrimVal {
fn from(s: &str) -> Self {
PrimVal(s.to_string())
}
}
impl_primval_from!(bool, i32, u32, f32, u8, f64, &str);
impl From<&serde_json::Value> for PrimVal {
fn from(v: &serde_json::Value) -> Self {