~kennylevinsen/wldash

d2f3ef222149e5da05d02292f75d44b0ddd66b8f — Kenny Levinsen 15 days ago ee2646f
Bump wayland-rs to 0.28, key repeat
8 files changed, 585 insertions(+), 443 deletions(-)

M Cargo.lock
M Cargo.toml
M src/app.rs
M src/cmd.rs
M src/doublemempool.rs
M src/main.rs
M src/widget.rs
M src/widgets/launcher.rs
M Cargo.lock => Cargo.lock +160 -289
@@ 1,16 1,18 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "ab_glyph_rasterizer"
version = "0.1.2"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b7e4e8cf778db814365e46839949ca74df4efb10e87ba4913e6ec5967ef0285"
checksum = "d9fe5e32de01730eb1f6b7f5b51c17e03e2325bf40a74f754f04f130043affff"

[[package]]
name = "alsa"
version = "0.4.0"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91888c0eee9b75c72c7dfe71247d6bb7da2755420696fc507107c358431610f8"
checksum = "eb213f6b3e4b1480a60931ca2035794aa67b73103d254715b1db7b70dcb3c934"
dependencies = [
 "alsa-sys",
 "bitflags",


@@ 20,48 22,19 @@ dependencies = [

[[package]]
name = "alsa-sys"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e95eaae787b8047ceefb94fd90682b03dd3f82f2d6fcaa83908c3814a8bef36"
checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527"
dependencies = [
 "libc",
 "pkg-config",
]

[[package]]
name = "andrew"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e"
dependencies = [
 "bitflags",
 "line_drawing",
 "rusttype 0.7.9",
 "walkdir",
 "xdg",
 "xml-rs",
]

[[package]]
name = "approx"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
dependencies = [
 "num-traits",
]

[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"

[[package]]
name = "autocfg"
version = "0.1.7"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"

[[package]]
name = "bitflags"


@@ 98,15 71,15 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"

[[package]]
name = "byteorder"
version = "1.3.2"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"

[[package]]
name = "cc"
version = "1.0.48"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"

[[package]]
name = "cfg-if"


@@ 115,14 88,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"

[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "chrono"
version = "0.4.10"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
 "libc",
 "num-integer",
 "num-traits",
 "time",
 "winapi",
]

[[package]]


@@ 152,24 133,24 @@ dependencies = [

[[package]]
name = "dlib"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76"
dependencies = [
 "libloading",
]

[[package]]
name = "downcast-rs"
version = "1.1.1"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ba6eb47c2131e784a38b726eb54c1e1484904f013e576a25354d0124161af6"
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"

[[package]]
name = "dtoa"
version = "0.4.4"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"

[[package]]
name = "fake-simd"


@@ 188,9 169,9 @@ dependencies = [

[[package]]
name = "fuzzy-matcher"
version = "0.3.1"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d860c6f043a7f367ffcbdb5833c36f7dc85fa8bc6e7898e2530f643ec90f9f3"
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
dependencies = [
 "thread_local",
]


@@ 206,9 187,9 @@ dependencies = [

[[package]]
name = "itoa"
version = "0.4.4"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"

[[package]]
name = "lazy_static"


@@ 218,9 199,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"

[[package]]
name = "libc"
version = "0.2.66"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"

[[package]]
name = "libdbus-sys"


@@ 233,19 214,19 @@ dependencies = [

[[package]]
name = "libloading"
version = "0.5.2"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883"
dependencies = [
 "cc",
 "cfg-if 1.0.0",
 "winapi",
]

[[package]]
name = "libpulse-binding"
version = "2.22.0"
version = "2.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce89ab17bd343b08bd4321c674ef1477d34f83be18b1ab2ee47a5e5fbee64a91"
checksum = "b2405f806801527dfb3d2b6d48a282cdebe9a1b41b0652e0d7b5bad81dbc700e"
dependencies = [
 "bitflags",
 "libc",


@@ 257,9 238,9 @@ dependencies = [

[[package]]
name = "libpulse-sys"
version = "1.17.0"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcfb56118765adba111da47e36278b77d00aebf822e4f014a832fbfa183a13b"
checksum = "cf17e9832643c4f320c42b7d78b2c0510f45aa5e823af094413b94e45076ba82"
dependencies = [
 "libc",
 "num-derive",


@@ 269,19 250,10 @@ dependencies = [
]

[[package]]
name = "line_drawing"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9"
dependencies = [
 "num-traits",
]

[[package]]
name = "linked-hash-map"
version = "0.5.2"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"

[[package]]
name = "maplit"


@@ 301,57 273,56 @@ dependencies = [

[[package]]
name = "multimap"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc"
checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333"
dependencies = [
 "serde",
]

[[package]]
name = "nix"
version = "0.14.1"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
dependencies = [
 "bitflags",
 "cc",
 "cfg-if",
 "cfg-if 0.1.10",
 "libc",
 "void",
]

[[package]]
name = "nix"
version = "0.15.0"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb"
dependencies = [
 "bitflags",
 "cc",
 "cfg-if",
 "cfg-if 0.1.10",
 "libc",
 "void",
]

[[package]]
name = "nix"
version = "0.16.1"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb"
checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055"
dependencies = [
 "bitflags",
 "cc",
 "cfg-if",
 "cfg-if 0.1.10",
 "libc",
 "void",
]

[[package]]
name = "num-bigint"
version = "0.2.4"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343b3df15c945a59e72aae31e89a7cfc9e11850e96d4fde6fed5e3c7c8d9c887"
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
dependencies = [
 "autocfg",
 "num-integer",


@@ 360,9 331,9 @@ dependencies = [

[[package]]
name = "num-complex"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc"
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
dependencies = [
 "autocfg",
 "num-traits",


@@ 374,16 345,16 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
dependencies = [
 "proc-macro2 1.0.7",
 "quote 1.0.2",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "num-integer"
version = "0.1.41"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
 "autocfg",
 "num-traits",


@@ 391,9 362,9 @@ dependencies = [

[[package]]
name = "num-rational"
version = "0.2.2"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454"
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
dependencies = [
 "autocfg",
 "num-bigint",


@@ 403,33 374,30 @@ dependencies = [

[[package]]
name = "num-traits"
version = "0.2.10"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
 "autocfg",
]

[[package]]
name = "opaque-debug"
version = "0.2.3"
name = "once_cell"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"

[[package]]
name = "ordered-float"
version = "1.0.2"
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
dependencies = [
 "num-traits",
]
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"

[[package]]
name = "os_pipe"
version = "0.9.1"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db4d06355a7090ce852965b2d08e11426c315438462638c6d721448d0b47aa22"
checksum = "fb233f06c2307e1f5ce2ecad9f8121cffbbee2c95428f44ea85222e460d0d213"
dependencies = [
 "libc",
 "winapi",


@@ 446,9 414,9 @@ dependencies = [

[[package]]
name = "pest"
version = "2.1.2"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e4fb201c5c22a55d8b24fef95f78be52738e5e1361129be1b5e862ecdb6894a"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
 "ucd-trie",
]


@@ 465,22 433,22 @@ dependencies = [

[[package]]
name = "pest_generator"
version = "2.1.1"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b9fcf299b5712d06ee128a556c94709aaa04512c4dffb8ead07c5c998447fc0"
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
dependencies = [
 "pest",
 "pest_meta",
 "proc-macro2 1.0.7",
 "quote 1.0.2",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "pest_meta"
version = "2.1.2"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df43fd99896fd72c485fe47542c7b500e4ac1e8700bf995544d1317a60ded547"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
 "maplit",
 "pest",


@@ 489,44 457,26 @@ dependencies = [

[[package]]
name = "pkg-config"
version = "0.3.17"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"

[[package]]
name = "proc-macro2"
version = "0.4.30"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
 "unicode-xid 0.1.0",
]

[[package]]
name = "proc-macro2"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
dependencies = [
 "unicode-xid 0.2.0",
 "unicode-xid",
]

[[package]]
name = "quote"
version = "0.6.13"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
 "proc-macro2 0.4.30",
]

[[package]]
name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
dependencies = [
 "proc-macro2 1.0.7",
 "proc-macro2",
]

[[package]]


@@ 546,12 496,6 @@ dependencies = [
]

[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"

[[package]]
name = "rust-ini"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 562,27 506,6 @@ dependencies = [

[[package]]
name = "rusttype"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5"
dependencies = [
 "rusttype 0.8.2",
]

[[package]]
name = "rusttype"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14a911032fb5791ccbeec9f28fdcb9bf0983b81f227bafdfd227c658d0731c8a"
dependencies = [
 "approx",
 "arrayvec",
 "ordered-float",
 "stb_truetype",
]

[[package]]
name = "rusttype"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59"


@@ 593,44 516,35 @@ dependencies = [

[[package]]
name = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"

[[package]]
name = "same-file"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
dependencies = [
 "winapi-util",
]
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"

[[package]]
name = "serde"
version = "1.0.104"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
dependencies = [
 "serde_derive",
]

[[package]]
name = "serde_derive"
version = "1.0.104"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
dependencies = [
 "proc-macro2 1.0.7",
 "quote 1.0.2",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_json"
version = "1.0.44"
version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486"
dependencies = [
 "itoa",
 "ryu",


@@ 639,9 553,9 @@ dependencies = [

[[package]]
name = "serde_yaml"
version = "0.8.11"
version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23"
dependencies = [
 "dtoa",
 "linked-hash-map",


@@ 651,9 565,9 @@ dependencies = [

[[package]]
name = "sha-1"
version = "0.8.1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [
 "block-buffer",
 "digest",


@@ 668,105 582,80 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"

[[package]]
name = "smithay-client-toolkit"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93960e8975909fcb14cc755de93af2149d8b8f4eb368315537d40cfd0f324054"
dependencies = [
 "andrew",
 "bitflags",
 "dlib",
 "lazy_static",
 "memmap",
 "nix 0.14.1",
 "wayland-client",
 "wayland-protocols",
]

[[package]]
name = "stb_truetype"
version = "0.3.1"
name = "smallvec"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51"
dependencies = [
 "byteorder",
]
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"

[[package]]
name = "syn"
version = "1.0.12"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddc157159e2a7df58cd67b1cace10b8ed256a404fb0070593f137d8ba6bef4de"
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
dependencies = [
 "proc-macro2 1.0.7",
 "quote 1.0.2",
 "unicode-xid 0.2.0",
 "proc-macro2",
 "quote",
 "unicode-xid",
]

[[package]]
name = "thread_local"
version = "1.0.0"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ddf1ad580c7e3d1efff877d972bcc93f995556b9087a5a259630985c88ceab"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
 "lazy_static",
 "once_cell",
]

[[package]]
name = "time"
version = "0.1.42"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
 "libc",
 "redox_syscall",
 "wasi",
 "winapi",
]

[[package]]
name = "timerfd"
version = "1.0.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c9a7822e546fa39d0b5ae14a93a33903975b62af6597288aea77f0580a6abbe"
checksum = "0bb53e6628675d73224925201a9a41f01c8d31108fdccb983975a1c1449dfc91"
dependencies = [
 "libc",
]

[[package]]
name = "ttf-parser"
version = "0.6.1"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52fbe7769f5af5d7d25aea74b9443b64e544a5ffb4d2b2968295ddea934f1a06"
checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc"

[[package]]
name = "typenum"
version = "1.11.2"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"

[[package]]
name = "ucd-trie"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"

[[package]]
name = "unicode-segmentation"
version = "1.6.0"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"

[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"

[[package]]
name = "unicode-xid"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

[[package]]
name = "void"


@@ 775,26 664,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

[[package]]
name = "walkdir"
version = "2.2.9"
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
dependencies = [
 "same-file",
 "winapi",
 "winapi-util",
]
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"

[[package]]
name = "wayland-client"
version = "0.23.6"
version = "0.28.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda"
checksum = "bdbdbe01d03b2267809f3ed99495b37395387fde789e0f2ebb78e8b43f75b6d7"
dependencies = [
 "bitflags",
 "downcast-rs",
 "libc",
 "nix 0.14.1",
 "nix 0.18.0",
 "wayland-commons",
 "wayland-scanner",
 "wayland-sys",


@@ 802,19 686,21 @@ dependencies = [

[[package]]
name = "wayland-commons"
version = "0.23.6"
version = "0.28.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb"
checksum = "480450f76717edd64ad04a4426280d737fc3d10a236b982df7b1aee19f0e2d56"
dependencies = [
 "nix 0.14.1",
 "nix 0.18.0",
 "once_cell",
 "smallvec",
 "wayland-sys",
]

[[package]]
name = "wayland-protocols"
version = "0.23.6"
version = "0.28.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9"
checksum = "319a82b4d3054dd25acc32d9aee0f84fa95b63bc983fffe4703b6b8d47e01a30"
dependencies = [
 "bitflags",
 "wayland-client",


@@ 824,30 710,29 @@ dependencies = [

[[package]]
name = "wayland-scanner"
version = "0.23.6"
version = "0.28.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d"
checksum = "7010ba5767b3fcd350decc59055390b4ebe6bd1b9279a9feb1f1888987f1133d"
dependencies = [
 "proc-macro2 0.4.30",
 "quote 0.6.13",
 "proc-macro2",
 "quote",
 "xml-rs",
]

[[package]]
name = "wayland-sys"
version = "0.23.6"
version = "0.28.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4"
checksum = "6793834e0c35d11fd96a97297abe03d37be627e1847da52e17d7e0e3b51cc099"
dependencies = [
 "dlib",
 "lazy_static",
 "pkg-config",
]

[[package]]
name = "winapi"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
 "winapi-i686-pc-windows-gnu",
 "winapi-x86_64-pc-windows-gnu",


@@ 860,15 745,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"

[[package]]
name = "winapi-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
dependencies = [
 "winapi",
]

[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 879,9 755,11 @@ name = "wldash"
version = "0.2.0"
dependencies = [
 "alsa",
 "bitflags",
 "byteorder",
 "chrono",
 "dbus",
 "dlib",
 "fontconfig",
 "fuzzy-matcher",
 "lazy_static",


@@ 891,12 769,11 @@ dependencies = [
 "os_pipe",
 "rcalc_lib",
 "rust-ini",
 "rusttype 0.9.2",
 "rusttype",
 "serde",
 "serde_json",
 "serde_yaml",
 "shlex",
 "smithay-client-toolkit",
 "timerfd",
 "unicode-segmentation",
 "wayland-client",


@@ 904,22 781,16 @@ dependencies = [
]

[[package]]
name = "xdg"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"

[[package]]
name = "xml-rs"
version = "0.8.0"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"
checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a"

[[package]]
name = "yaml-rust"
version = "0.4.3"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
 "linked-hash-map",
]

M Cargo.toml => Cargo.toml +4 -3
@@ 20,15 20,16 @@ alsa-widget = ["alsa"]
pulseaudio-widget = ["libpulse-binding"]

[dependencies]
smithay-client-toolkit = "0.6.4"
byteorder = "1.3"
bitflags = "1.0"
dlib = "0.4"
rusttype = "^0.9"
chrono = "0.4"
nix = "0.16"
memmap = "0.7"
os_pipe = "0.9"
wayland-client = { version = "0.23", features = ["dlopen"] }
wayland-protocols = { version = "0.23", features = ["client", "unstable_protocols"] }
wayland-client = { version = "0.28"}
wayland-protocols = { version = "0.28", features = ["client", "unstable_protocols"] }
dbus = "0.6"
fuzzy-matcher = "0.3"
lazy_static = "1.4"

M src/app.rs => src/app.rs +168 -140
@@ 3,21 3,21 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};

use chrono::Local;
use chrono::{Duration, Local, NaiveDateTime};

use smithay_client_toolkit::keyboard::{
    keysyms, map_keyboard_auto, Event as KbEvent, KeyState, ModifiersState,
use crate::keyboard::{
    keysyms, map_keyboard, Event as KbEvent, KeyState, ModifiersState,
};

use wayland_client::protocol::{wl_compositor, wl_output, wl_pointer, wl_shm, wl_surface};
use wayland_client::{Display, EventQueue, GlobalEvent, GlobalManager, NewProxy};
use wayland_client::protocol::{wl_compositor, wl_output, wl_pointer, wl_shm, wl_surface, wl_seat};
use wayland_client::{Display, EventQueue, GlobalEvent, GlobalManager, Main};
use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
    zwlr_layer_shell_v1, zwlr_layer_surface_v1,
};

use crate::buffer::Buffer;
use crate::color::Color;
use crate::widget::{DrawContext, Widget};
use crate::widget::{WaitContext, DrawContext, Widget};

use crate::cmd::Cmd;
use crate::doublemempool::DoubleMemPool;


@@ 29,12 29,12 @@ pub enum OutputMode {
}

struct AppInner {
    compositor: Option<wl_compositor::WlCompositor>,
    surfaces: Vec<wl_surface::WlSurface>,
    shell_surfaces: Vec<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>,
    compositor: Option<Main<wl_compositor::WlCompositor>>,
    surfaces: Vec<Main<wl_surface::WlSurface>>,
    shell_surfaces: Vec<Main<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>>,
    configured_surfaces: Arc<Mutex<usize>>,
    outputs: Vec<(u32, wl_output::WlOutput)>,
    shell: Option<zwlr_layer_shell_v1::ZwlrLayerShellV1>,
    outputs: Vec<(u32, Main<wl_output::WlOutput>)>,
    shell: Option<Main<zwlr_layer_shell_v1::ZwlrLayerShellV1>>,
    draw_tx: Sender<Cmd>,
    output_mode: OutputMode,
    visible: bool,


@@ 65,12 65,11 @@ impl AppInner {
        tx: Sender<Cmd>,
        output: Option<&wl_output::WlOutput>,
    ) -> (
        wl_surface::WlSurface,
        zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
        Main<wl_surface::WlSurface>,
        Main<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>,
    ) {
        let surface = compositor
            .create_surface(NewProxy::implement_dummy)
            .unwrap();
            .create_surface();

        let this_is_stupid = AtomicBool::new(false);



@@ 79,24 78,18 @@ impl AppInner {
                &surface,
                output,
                zwlr_layer_shell_v1::Layer::Overlay,
                "".to_string(),
                move |layer| {
                    layer.implement_closure(
                        move |evt, layer| match evt {
                            zwlr_layer_surface_v1::Event::Configure { serial, .. } => {
                                if !this_is_stupid.compare_and_swap(false, true, Ordering::SeqCst) {
                                    *(configured_surfaces.lock().unwrap()) += 1;
                                    layer.ack_configure(serial);
                                    tx.send(Cmd::ForceDraw).unwrap();
                                }
                            }
                            _ => unreachable!(),
                        },
                        (),
                    )
                },
            )
            .unwrap();
                "".to_string());
        shell_surface.quick_assign(move |layer, event, _| match event {
                zwlr_layer_surface_v1::Event::Configure { serial, .. } => {
                    if !this_is_stupid.compare_and_swap(false, true, Ordering::SeqCst) {
                        *(configured_surfaces.lock().unwrap()) += 1;
                        layer.ack_configure(serial);
                        tx.send(Cmd::ForceDraw).unwrap();
                    }
                }
                _ => unreachable!(),
            },
        );

        shell_surface.set_keyboard_interactivity(1);
        shell_surface.set_size(1, 1);


@@ 169,7 162,7 @@ impl AppInner {
        self.draw_tx.send(Cmd::ForceDraw).unwrap();
    }

    fn add_output(&mut self, id: u32, output: wl_output::WlOutput) {
    fn add_output(&mut self, id: u32, output: Main<wl_output::WlOutput>) {
        self.outputs.push((id, output));
        self.outputs_changed();
    }


@@ 191,15 184,22 @@ impl AppInner {
        }
    }

    fn set_compositor(&mut self, compositor: Option<wl_compositor::WlCompositor>) {
    fn set_compositor(&mut self, compositor: Option<Main<wl_compositor::WlCompositor>>) {
        self.compositor = compositor
    }

    fn set_shell(&mut self, shell: Option<zwlr_layer_shell_v1::ZwlrLayerShellV1>) {
    fn set_shell(&mut self, shell: Option<Main<zwlr_layer_shell_v1::ZwlrLayerShellV1>>) {
        self.shell = shell
    }
}

struct AppKeyboard {
    current: Option<Cmd>,
    delay: i32,
    rate: i32,
    next: Option<NaiveDateTime>,
}

pub struct App<'a> {
    pools: DoubleMemPool,
    display: Display,


@@ 210,6 210,7 @@ pub struct App<'a> {
    inner: Arc<Mutex<AppInner>>,
    last_damage: Option<Vec<(i32, i32, i32, i32)>>,
    last_dim: (u32, u32),
    keyboard: Arc<Mutex<AppKeyboard>>,
}

impl<'a> App<'a> {


@@ 355,6 356,26 @@ impl<'a> App<'a> {
        self.redraw(true)
    }

    pub fn set_keyboard_repeat(&mut self, ctx: &mut WaitContext) {
        let kbd = self.keyboard.lock().unwrap();
        if let Some(t) = kbd.next {
            ctx.set_time(t);
        }
    }

    pub fn key_repeat(&mut self) -> Option<Cmd> {
        let time = Local::now().naive_local();
        let mut kbd = self.keyboard.lock().unwrap();
        if let Some(target) = kbd.next {
            if time >= target {
                let cmd = kbd.current.as_ref().unwrap().clone();
                kbd.next = Some(time + Duration::milliseconds(kbd.rate.into()));
                return Some(cmd);
            }
        }
        None
    }

    pub fn new(tx: Sender<Cmd>, output_mode: OutputMode, bg: Color, scale: u32) -> App<'a> {
        let inner = Arc::new(Mutex::new(AppInner::new(tx, output_mode, scale)));



@@ 364,19 385,16 @@ impl<'a> App<'a> {

        let cmd_queue = Arc::new(Mutex::new(VecDeque::new()));

        let (display, mut event_queue) = Display::connect_to_env().unwrap();

        let display_wrapper = display
            .as_ref()
            .make_wrapper(&event_queue.get_token())
            .unwrap();
        let display = Display::connect_to_env().unwrap();
        let mut event_queue = display.create_event_queue();
        let display_wrapper = (*display).clone().attach(event_queue.token());

        //
        // Set up global manager
        //
        let inner_global = inner.clone();
        let manager =
            GlobalManager::new_with_cb(&display_wrapper, move |event, registry| match event {
            GlobalManager::new_with_cb(&display_wrapper, move |event, registry, _| match event {
                GlobalEvent::New {
                    id,
                    ref interface,


@@ 384,10 402,7 @@ impl<'a> App<'a> {
                } => {
                    if let "wl_output" = &interface[..] {
                        let output = registry
                            .bind(version, id, move |output| {
                                output.implement_closure(move |_, _| {}, ())
                            })
                            .unwrap();
                            .bind(version, id);
                        inner_global.lock().unwrap().add_output(id, output);
                    }
                }


@@ 400,39 415,30 @@ impl<'a> App<'a> {

        // double sync to retrieve the global list
        // and the globals metadata
        event_queue.sync_roundtrip().unwrap();
        event_queue.sync_roundtrip().unwrap();
        event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();
        event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();

        // wl_compositor
        let compositor: wl_compositor::WlCompositor = manager
            .instantiate_range(1, 4, NewProxy::implement_dummy)
        let compositor = manager
            .instantiate_range(1, 4)
            .expect("server didn't advertise `wl_compositor`");

        inner.lock().unwrap().set_compositor(Some(compositor));

        // wl_shm
        let shm_formats = Arc::new(Mutex::new(Vec::new()));
        let shm = manager
            .instantiate_range(1, 1, |shm| {
                shm.implement_closure(
                    move |evt, _| {
                        if let wl_shm::Event::Format { format } = evt {
                            shm_formats.lock().unwrap().push(format);
                        }
                    },
                    (),
                )
            })
        let shm: Main<wl_shm::WlShm> = manager
            .instantiate_range(1, 1)
            .expect("server didn't advertise `wl_shm`");

        let pools = DoubleMemPool::new(&shm).expect("Failed to create a memory pool !");
        let pools = DoubleMemPool::new(shm).expect("Failed to create a memory pool !");

        //
        // Get our seat
        //
        let seat = manager
            .instantiate_range(1, 6, NewProxy::implement_dummy)
        let seat: Main<wl_seat::WlSeat> = manager
            .instantiate_range(1, 6)
            .unwrap();
        event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();

        //
        // Keyboard processing


@@ 446,7 452,17 @@ impl<'a> App<'a> {
            logo: false,
            num_lock: false,
        }));
        map_keyboard_auto(&seat, move |event: KbEvent, _| match event {

        let keyboard = Arc::new(Mutex::new(AppKeyboard{
            current: None,
            delay: 0,
            rate: 0,
            next: None,
        }));

        let kb2 = keyboard.clone();

        map_keyboard(&seat, None, move |event: KbEvent, _, _| match event {
            KbEvent::Key {
                keysym,
                utf8,


@@ 459,101 475,112 @@ impl<'a> App<'a> {
                        keysyms::XKB_KEY_c if modifiers_state.lock().unwrap().ctrl => {
                            kbd_clone.lock().unwrap().push_back(Cmd::Exit)
                        }
                        v => kbd_clone.lock().unwrap().push_back(Cmd::Keyboard {
                            key: v,
                            key_state: state,
                            modifiers_state: *modifiers_state.lock().unwrap(),
                            interpreted: utf8,
                        }),
                        v => {
                            let ev = Cmd::Keyboard {
                                key: v,
                                key_state: state,
                                modifiers_state: *modifiers_state.lock().unwrap(),
                                interpreted: utf8,
                            };
                            let mut kbd = kb2.lock().unwrap();
                            kbd.current = Some(ev.clone());
                            kbd.next = if kbd.delay > 0 {
                                Some(Local::now().naive_local() + Duration::milliseconds(kbd.delay.into()))
                            } else {
                                None
                            };
                            drop(kbd);
                            kbd_clone.lock().unwrap().push_back(ev);
                        }
                    }
                } else {
                    kb2.lock().unwrap().next = None;
                }
            },
            KbEvent::Leave { .. } => {
                kb2.lock().unwrap().next = None;
            },
            KbEvent::RepeatInfo { delay, rate } => {
                let mut kbd = kb2.lock().unwrap();
                kbd.delay = delay;
                kbd.rate = rate;
            }
            KbEvent::Modifiers { modifiers } => *modifiers_state.lock().unwrap() = modifiers,
            _ => (),
        })
        .expect("Failed to map keyboard");
        .expect("could not map keyboard");

        //
        // Prepare shell so that we can create our shell surface
        //
        inner.lock().unwrap().set_shell(Some(
            if let Ok(layer) = manager.instantiate_exact(
                1,
                |layer: NewProxy<zwlr_layer_shell_v1::ZwlrLayerShellV1>| {
                    layer.implement_closure(|_, _| {}, ())
                },
            ) {
            if let Ok(layer) = manager.instantiate_exact(1) {
                layer
            } else {
                panic!("server didn't advertise `zwlr_layer_shell_v1`");
            },
        ));

        event_queue.sync_roundtrip().unwrap();
        event_queue.sync_roundtrip(&mut(), |_, _, _|{}).unwrap();

        //
        // Cursor processing
        //
        let pointer_clone = cmd_queue.clone();
        seat.get_pointer(move |ptr| {
            let mut pos: (u32, u32) = (0, 0);
            let mut vert_scroll: f64 = 0.0;
            let mut horiz_scroll: f64 = 0.0;
            let mut btn: u32 = 0;
            let mut btn_clicked = false;
            ptr.implement_closure(
                move |evt, _| match evt {
                    wl_pointer::Event::Enter {
                        surface_x,
                        surface_y,
                        ..
                    } => {
                        pos = (surface_x as u32, surface_y as u32);
                    }
                    wl_pointer::Event::Leave { .. } => {
                        pos = (0, 0);
                    }
                    wl_pointer::Event::Motion {
                        surface_x,
                        surface_y,
                        ..
                    } => {
                        pos = (surface_x as u32 * scale, surface_y as u32 * scale);
                    }
                    wl_pointer::Event::Axis { axis, value, .. } => {
                        if axis == wl_pointer::Axis::VerticalScroll {
                            vert_scroll += value;
                        }
                    }
                    wl_pointer::Event::Button { button, state, .. } => {
                        if let wl_pointer::ButtonState::Released = state {
                            btn = button;
                            btn_clicked = true;
                        }
                    }
                    wl_pointer::Event::Frame => {
                        if vert_scroll != 0.0 || horiz_scroll != 0.0 {
                            pointer_clone.lock().unwrap().push_back(Cmd::MouseScroll {
                                scroll: (horiz_scroll, vert_scroll),
                                pos,
                            });
                            vert_scroll = 0.0;
                            horiz_scroll = 0.0;
                        }
                        if btn_clicked {
                            pointer_clone
                                .lock()
                                .unwrap()
                                .push_back(Cmd::MouseClick { btn, pos });
                            btn_clicked = false;
                        }
                    }
                    _ => {}
                },
                (),
            )
        })
        .unwrap();
        let pointer = seat.get_pointer();
        let mut pos: (u32, u32) = (0, 0);
        let mut vert_scroll: f64 = 0.0;
        let mut horiz_scroll: f64 = 0.0;
        let mut btn: u32 = 0;
        let mut btn_clicked = false;
        pointer.quick_assign(move |_, event, _| match event {
            wl_pointer::Event::Enter {
                surface_x,
                surface_y,
                ..
            } => {
                pos = (surface_x as u32, surface_y as u32);
            }
            wl_pointer::Event::Leave { .. } => {
                pos = (0, 0);
            }
            wl_pointer::Event::Motion {
                surface_x,
                surface_y,
                ..
            } => {
                pos = (surface_x as u32 * scale, surface_y as u32 * scale);
            }
            wl_pointer::Event::Axis { axis, value, .. } => {
                if axis == wl_pointer::Axis::VerticalScroll {
                    vert_scroll += value;
                }
            }
            wl_pointer::Event::Button { button, state, .. } => {
                if let wl_pointer::ButtonState::Released = state {
                    btn = button;
                    btn_clicked = true;
                }
            }
            wl_pointer::Event::Frame => {
                if vert_scroll != 0.0 || horiz_scroll != 0.0 {
                    pointer_clone.lock().unwrap().push_back(Cmd::MouseScroll {
                        scroll: (horiz_scroll, vert_scroll),
                        pos,
                    });
                    vert_scroll = 0.0;
                    horiz_scroll = 0.0;
                }
                if btn_clicked {
                    pointer_clone
                        .lock()
                        .unwrap()
                        .push_back(Cmd::MouseClick { btn, pos });
                    btn_clicked = false;
                }
            }
            _ => {}
        });

        display.flush().unwrap();



@@ 567,6 594,7 @@ impl<'a> App<'a> {
            inner,
            last_damage: None,
            last_dim: (0, 0),
            keyboard,
        }
    }
}

M src/cmd.rs => src/cmd.rs +3 -1
@@ 1,5 1,6 @@
use smithay_client_toolkit::keyboard::{KeyState, ModifiersState};
use crate::keyboard::{KeyState, ModifiersState};

#[derive(Clone)]
pub enum Cmd {
    Exit,
    Draw,


@@ 13,6 14,7 @@ pub enum Cmd {
        scroll: (f64, f64),
        pos: (u32, u32),
    },
    KeyboardTest,
    Keyboard {
        key: u32,
        key_state: KeyState,

M src/doublemempool.rs => src/doublemempool.rs +233 -5
@@ 1,5 1,233 @@
use smithay_client_toolkit::utils::MemPool;
use wayland_client::protocol::wl_shm;
use std::{
    cell::RefCell,
    ffi::CStr,
    fs::File,
    io,
    os::unix::io::{FromRawFd, RawFd},
    rc::Rc,
    time::SystemTime,
    time::UNIX_EPOCH,
};

#[cfg(target_os = "linux")]
use nix::sys::memfd;
use nix::{
    errno::Errno,
    fcntl,
    sys::{mman, stat},
    unistd,
};

use memmap::MmapMut;

use wayland_client::{
    protocol::{wl_buffer, wl_shm, wl_shm_pool},
    Main,
};

/// A wrapper handling an SHM memory pool backed by a shared memory file
///
/// This wrapper handles for you the creation of the shared memory file and its synchronization
/// with the protocol.
///
/// Mempool internally tracks the release of the buffers by the compositor. As such, creating a buffer
/// that is not commited to a surface (and then never released by the server) would cause the Mempool
/// to be stuck believing it is still in use.
///
/// Mempool will also handle the destruction of buffers and as such the `destroy()` method should not
/// be used on buffers created from Mempool.
///
/// Overwriting the contents of the memory pool before it is completely freed may cause graphical
/// glitches due to the possible corruption of data while the compositor is reading it.
///
/// Mempool requires a callback that will be called when the pool becomes free, this
/// happens when all the pools buffers are released by the server.
pub struct MemPool {
    file: File,
    len: usize,
    pool: Main<wl_shm_pool::WlShmPool>,
    buffer_count: Rc<RefCell<u32>>,
    mmap: MmapMut,
    callback: Rc<RefCell<dyn FnMut(wayland_client::DispatchData)>>,
}

impl MemPool {
    /// Create a new memory pool associated with given shm
    pub fn new<F>(shm: Main<wl_shm::WlShm>, callback: F) -> io::Result<MemPool>
    where
        F: FnMut(wayland_client::DispatchData) + 'static,
    {
        let mem_fd = create_shm_fd()?;
        let mem_file = unsafe { File::from_raw_fd(mem_fd) };
        mem_file.set_len(128)?;

        let pool = shm.create_pool(mem_fd, 128);

        let mmap = unsafe { MmapMut::map_mut(&mem_file).unwrap() };

        Ok(MemPool {
            file: mem_file,
            len: 128,
            pool,
            buffer_count: Rc::new(RefCell::new(0)),
            mmap,
            callback: Rc::new(RefCell::new(callback)),
        })
    }

    /// Resize the memory pool
    ///
    /// This affect the size as it is seen by the wayland server. Even
    /// if you extend the temporary file size by writing to it, you need to
    /// call this method otherwise the server won't see the new size.
    ///
    /// Memory pools can only be extented, as such this method will do nothing
    /// if the requested new size is smaller than the current size.
    ///
    /// This method allows you to ensure the underlying pool is large enough to
    /// hold what you want to write to it.
    pub fn resize(&mut self, newsize: usize) -> io::Result<()> {
        if newsize > self.len {
            self.file.set_len(newsize as u64)?;
            self.pool.resize(newsize as i32);
            self.len = newsize;
            self.mmap = unsafe { MmapMut::map_mut(&self.file).unwrap() };
        }
        Ok(())
    }

    /// Create a new buffer to this pool
    ///
    /// The parameters are:
    ///
    /// - `offset`: the offset (in bytes) from the beginning of the pool at which this
    ///   buffer starts
    /// - `width`: the width of this buffer (in pixels)
    /// - `height`: the height of this buffer (in pixels)
    /// - `stride`: distance (in bytes) between the beginning of a row and the next one
    /// - `format`: the encoding format of the pixels. Using a format that was not
    ///   advertised to the `wl_shm` global by the server is a protocol error and will
    ///   terminate your connection
    pub fn buffer(
        &self,
        offset: i32,
        width: i32,
        height: i32,
        stride: i32,
        format: wl_shm::Format,
    ) -> wl_buffer::WlBuffer {
        *self.buffer_count.borrow_mut() += 1;
        let my_buffer_count = self.buffer_count.clone();
        let my_callback = self.callback.clone();
        let buffer = self
            .pool
            .create_buffer(offset, width, height, stride, format);
        buffer.quick_assign(move |buffer, event, dispatch_data| match event {
            wl_buffer::Event::Release => {
                buffer.destroy();
                let new_count = {
                    // borrow the buffer_count for as short as possible, in case
                    // the user wants to create a new buffer from the callback
                    let mut my_buffer_count = my_buffer_count.borrow_mut();
                    *my_buffer_count -= 1;
                    *my_buffer_count
                };
                if new_count == 0 {
                    (&mut *my_callback.borrow_mut())(dispatch_data);
                }
            }
            _ => unreachable!(),
        });
        (*buffer).clone().detach()
    }

    /// Uses the memmap crate to map the underlying shared memory file
    pub fn mmap(&mut self) -> &mut MmapMut {
        &mut self.mmap
    }

    /// Returns true if the pool contains buffers that are currently in use by the server
    pub fn is_used(&self) -> bool {
        *self.buffer_count.borrow() != 0
    }
}

impl Drop for MemPool {
    fn drop(&mut self) {
        self.pool.destroy();
    }
}

impl io::Write for MemPool {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        io::Write::write(&mut self.file, buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        io::Write::flush(&mut self.file)
    }
}

impl io::Seek for MemPool {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        io::Seek::seek(&mut self.file, pos)
    }
}

fn create_shm_fd() -> io::Result<RawFd> {
    // Only try memfd on linux
    #[cfg(target_os = "linux")]
    loop {
        match memfd::memfd_create(
            CStr::from_bytes_with_nul(b"smithay-client-toolkit\0").unwrap(),
            memfd::MemFdCreateFlag::MFD_CLOEXEC,
        ) {
            Ok(fd) => return Ok(fd),
            Err(nix::Error::Sys(Errno::EINTR)) => continue,
            Err(nix::Error::Sys(Errno::ENOSYS)) => break,
            Err(nix::Error::Sys(errno)) => return Err(io::Error::from(errno)),
            Err(err) => unreachable!(err),
        }
    }

    // Fallback to using shm_open
    let sys_time = SystemTime::now();
    let mut mem_file_handle = format!(
        "/smithay-client-toolkit-{}",
        sys_time.duration_since(UNIX_EPOCH).unwrap().subsec_nanos()
    );
    loop {
        match mman::shm_open(
            mem_file_handle.as_str(),
            fcntl::OFlag::O_CREAT
                | fcntl::OFlag::O_EXCL
                | fcntl::OFlag::O_RDWR
                | fcntl::OFlag::O_CLOEXEC,
            stat::Mode::S_IRUSR | stat::Mode::S_IWUSR,
        ) {
            Ok(fd) => match mman::shm_unlink(mem_file_handle.as_str()) {
                Ok(_) => return Ok(fd),
                Err(nix::Error::Sys(errno)) => match unistd::close(fd) {
                    Ok(_) => return Err(io::Error::from(errno)),
                    Err(nix::Error::Sys(errno)) => return Err(io::Error::from(errno)),
                    Err(err) => panic!(err),
                },
                Err(err) => panic!(err),
            },
            Err(nix::Error::Sys(Errno::EEXIST)) => {
                // If a file with that handle exists then change the handle
                mem_file_handle = format!(
                    "/smithay-client-toolkit-{}",
                    sys_time.duration_since(UNIX_EPOCH).unwrap().subsec_nanos()
                );
                continue;
            }
            Err(nix::Error::Sys(Errno::EINTR)) => continue,
            Err(nix::Error::Sys(errno)) => return Err(io::Error::from(errno)),
            Err(err) => unreachable!(err),
        }
    }
}


pub struct DoubleMemPool {
    pool1: MemPool,


@@ 8,10 236,10 @@ pub struct DoubleMemPool {
}

impl DoubleMemPool {
    pub fn new(shm: &wl_shm::WlShm) -> ::std::io::Result<DoubleMemPool> {
    pub fn new(shm: Main<wl_shm::WlShm>) -> ::std::io::Result<DoubleMemPool> {
        Ok(DoubleMemPool {
            pool1: MemPool::new(shm, move || {})?,
            pool2: MemPool::new(shm, move || {})?,
            pool1: MemPool::new(shm.clone(), move |_| {})?,
            pool2: MemPool::new(shm.clone(), move |_| {})?,
            switch: false,
        })
    }

M src/main.rs => src/main.rs +15 -3
@@ 12,6 12,7 @@ use timerfd::{SetTimeFlags, TimerFd, TimerState};

mod app;
mod buffer;
mod keyboard;
mod cmd;
mod color;
mod config;


@@ 23,6 24,9 @@ mod fonts;
mod widget;
mod widgets;

#[macro_use]
extern crate dlib;

use app::{App, OutputMode};
use cmd::Cmd;
use config::Config;


@@ 202,7 206,7 @@ fn main() {
        });

    let mut timer = TimerFd::new().unwrap();
    let ev_fd = PollFd::new(app.event_queue().get_connection_fd(), PollFlags::POLLIN);
    let ev_fd = PollFd::new(app.event_queue().display().get_connection_fd(), PollFlags::POLLIN);
    let rx_fd = PollFd::new(rx_pipe.as_raw_fd(), PollFlags::POLLIN);
    let tm_fd = PollFd::new(timer.as_raw_fd(), PollFlags::POLLIN);
    let ipc_fd = PollFd::new(listener.as_raw_fd(), PollFlags::POLLIN);


@@ 224,6 228,11 @@ fn main() {
                    app.redraw(false).expect("Failed to draw");
                    app.flush_display();
                }
                Cmd::KeyboardTest => {
                    if let Some(cmd) = app.key_repeat() {
                        q.lock().unwrap().push_back(cmd);
                    }
                }
                Cmd::ForceDraw => {
                    app.redraw(true).expect("Failed to draw");
                    app.flush_display();


@@ 279,6 288,7 @@ fn main() {
                wait_ctx.target_time = None;

                app.get_widget().wait(&mut wait_ctx);
                app.set_keyboard_repeat(&mut wait_ctx);

                if let Some(target_time) = wait_ctx.target_time {
                    let n = Local::now().naive_local();


@@ 313,7 323,7 @@ fn main() {
                    }

                    app.event_queue()
                        .dispatch_pending()
                        .dispatch_pending(&mut (), |_, _, _|{})
                        .expect("Failed to dispatch all messages.");
                }



@@ 365,7 375,9 @@ fn main() {
                        .contains(PollFlags::POLLIN)
                {
                    timer.read();
                    q.lock().unwrap().push_back(Cmd::Draw);
                    let mut qq = q.lock().unwrap();
                    qq.push_back(Cmd::KeyboardTest);
                    qq.push_back(Cmd::Draw);
                }
            }
        }

M src/widget.rs => src/widget.rs +1 -1
@@ 2,7 2,7 @@ use crate::buffer::Buffer;
use crate::color::Color;
use chrono::NaiveDateTime;
use nix::poll::PollFd;
pub use smithay_client_toolkit::keyboard::{KeyState, ModifiersState};
pub use crate::keyboard::{KeyState, ModifiersState};

pub struct DrawContext<'a> {
    pub buf: &'a mut Buffer<'a>,

M src/widgets/launcher.rs => src/widgets/launcher.rs +1 -1
@@ 15,7 15,7 @@ use std::process::Command;
use std::sync::mpsc::Sender;

use fuzzy_matcher::skim::{fuzzy_indices, fuzzy_match};
use smithay_client_toolkit::keyboard::keysyms;
use crate::keyboard::keysyms;
use unicode_segmentation::UnicodeSegmentation;

pub struct Launcher<'a> {