mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 13:52:55 +03:00
upgrade to latest smithay client toolkit
This version greatly improves the client side decoration handling under Wayland and allows rendering the window title in the titlebar (shocker!).
This commit is contained in:
parent
fa32457656
commit
d3cb27129c
180
Cargo.lock
generated
180
Cargo.lock
generated
@ -15,6 +15,12 @@ dependencies = [
|
|||||||
"const-random",
|
"const-random",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35b909d1c126f78ace756fc337133356c499eebeefcce930fa5fb018823f2b2d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.10"
|
version = "0.7.10"
|
||||||
@ -317,6 +323,16 @@ version = "0.5.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
|
checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "calloop"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e9e85e9184ff1f5129d751a87500ac57069e28086da57da858b78f0f1530973"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"nix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cassowary"
|
name = "cassowary"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -726,6 +742,15 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dlv-list"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b391911b9a786312a10cb9d2b3d0735adfd5a8113eb3648de26a75e91b0826c"
|
||||||
|
dependencies = [
|
||||||
|
"rand 0.7.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "downcast-rs"
|
name = "downcast-rs"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
@ -1126,10 +1151,20 @@ version = "0.6.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
|
checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.2.18",
|
||||||
"autocfg 0.1.7",
|
"autocfg 0.1.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf"
|
||||||
|
dependencies = [
|
||||||
|
"ahash 0.3.3",
|
||||||
|
"autocfg 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hdrhistogram"
|
name = "hdrhistogram"
|
||||||
version = "6.3.4"
|
version = "6.3.4"
|
||||||
@ -1688,9 +1723,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.14.1"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.2.1",
|
"bitflags 1.2.1",
|
||||||
"cc",
|
"cc",
|
||||||
@ -1705,6 +1740,12 @@ version = "0.1.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "1.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "4.2.3"
|
version = "4.2.3"
|
||||||
@ -1957,6 +1998,16 @@ dependencies = [
|
|||||||
"num-traits 0.2.11",
|
"num-traits 0.2.11",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-multimap"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e88f947c6799d5eff50e6cf8a2365c17ac4aa8f8f43aceeedc29b616d872a358"
|
||||||
|
dependencies = [
|
||||||
|
"dlv-list",
|
||||||
|
"hashbrown 0.7.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "output_vt100"
|
name = "output_vt100"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@ -2508,6 +2559,16 @@ dependencies = [
|
|||||||
"crossbeam-utils 0.7.2",
|
"crossbeam-utils 0.7.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-ini"
|
||||||
|
version = "0.15.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c609fa8151080b18c38d39e09d1e55d6301d5610428ff804d0d59c4bac15cf7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"ordered-multimap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
@ -2558,6 +2619,12 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scoped_threadpool"
|
name = "scoped_threadpool"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@ -2743,17 +2810,20 @@ checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-client-toolkit"
|
name = "smithay-client-toolkit"
|
||||||
version = "0.6.6"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/wez/client-toolkit.git?branch=title_tunc#a178efdd19113228d02ce711602bb9ab78f66084"
|
||||||
checksum = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"andrew",
|
"andrew",
|
||||||
"bitflags 1.2.1",
|
"bitflags 1.2.1",
|
||||||
|
"byteorder",
|
||||||
|
"calloop",
|
||||||
"dlib",
|
"dlib",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"log",
|
||||||
"memmap",
|
"memmap",
|
||||||
"nix",
|
"nix",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
|
"wayland-cursor",
|
||||||
"wayland-protocols",
|
"wayland-protocols",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3374,14 +3444,15 @@ checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-client"
|
name = "wayland-client"
|
||||||
version = "0.23.6"
|
version = "0.26.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda"
|
checksum = "b1d7a5dfc26df8b651cebffeda272b0e444a7485cc83009be2aaffee249d9ea6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.2.1",
|
"bitflags 1.2.1",
|
||||||
"downcast-rs",
|
"downcast-rs",
|
||||||
"libc",
|
"libc",
|
||||||
"nix",
|
"nix",
|
||||||
|
"scoped-tls",
|
||||||
"wayland-commons",
|
"wayland-commons",
|
||||||
"wayland-scanner",
|
"wayland-scanner",
|
||||||
"wayland-sys",
|
"wayland-sys",
|
||||||
@ -3389,19 +3460,43 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-commons"
|
name = "wayland-commons"
|
||||||
version = "0.23.6"
|
version = "0.26.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb"
|
checksum = "3b0ad6f753185c9ad9c7d6daa588b5c42b2531c58a4ba2f2268f81f1aafb0580"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nix",
|
"nix",
|
||||||
|
"once_cell",
|
||||||
|
"smallvec 1.4.0",
|
||||||
|
"wayland-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-cursor"
|
||||||
|
version = "0.26.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b823dded13083b2874710af9a7d258a90d44d8501e2c34bb43568b4cc427f47b"
|
||||||
|
dependencies = [
|
||||||
|
"nix",
|
||||||
|
"wayland-client",
|
||||||
|
"xcur",
|
||||||
|
"xcursor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-egl"
|
||||||
|
version = "0.26.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73ba50703dbdb6d4b5524b593519547b45b69bf1bb3692c191647325faa50371"
|
||||||
|
dependencies = [
|
||||||
|
"wayland-client",
|
||||||
"wayland-sys",
|
"wayland-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-protocols"
|
name = "wayland-protocols"
|
||||||
version = "0.23.6"
|
version = "0.26.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9"
|
checksum = "d3458a4a34c37220130cce717aa4e4766a6ee8c19a8db1a565e19dc54d666c68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.2.1",
|
"bitflags 1.2.1",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
@ -3411,20 +3506,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-scanner"
|
name = "wayland-scanner"
|
||||||
version = "0.23.6"
|
version = "0.26.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d"
|
checksum = "e794b09da468acaeee5f21feb6148ff61a79a6614f6540fe513b060bbb03f1e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.30",
|
"proc-macro2 1.0.12",
|
||||||
"quote 0.6.13",
|
"quote 1.0.4",
|
||||||
"xml-rs 0.8.3",
|
"xml-rs 0.8.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-sys"
|
name = "wayland-sys"
|
||||||
version = "0.23.6"
|
version = "0.26.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4"
|
checksum = "26d91fd1620a38a2815091741e6e75e104d7c135f2239d464d319d63f872d906"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dlib",
|
"dlib",
|
||||||
]
|
]
|
||||||
@ -3594,10 +3689,11 @@ dependencies = [
|
|||||||
"smithay-client-toolkit",
|
"smithay-client-toolkit",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
|
"wayland-egl",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.8",
|
||||||
"winreg",
|
"winreg",
|
||||||
"x11",
|
"x11",
|
||||||
"xcb",
|
"xcb 0.9.0",
|
||||||
"xcb-util",
|
"xcb-util",
|
||||||
"xkbcommon",
|
"xkbcommon",
|
||||||
]
|
]
|
||||||
@ -3659,7 +3755,7 @@ version = "0.3.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea"
|
checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"xcb",
|
"xcb 0.8.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3673,13 +3769,41 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xcb-util"
|
name = "xcb"
|
||||||
version = "0.2.1"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d35fc0bbe4349a46322f30a670f61f4da2c2896f64cef53fe54e6c5ec48d8ab"
|
checksum = "62056f63138b39116f82a540c983cc11f1c90cd70b3d492a70c25eaa50bd22a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"xcb",
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xcb-util"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43893e47f27bf7d81d489feef3a0e34a457e90bc314b7e74ad9bb3980e4c1c48"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"xcb 0.9.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xcur"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af1879006e82c8f58cf3d1a260434a39c210964e9665fa2f826dc53619201e8b"
|
||||||
|
dependencies = [
|
||||||
|
"nom 1.2.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xcursor"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad3ff3b2f6870f8bf3472cdb4aac8063d8bc2c2ef4d71746e307f5cca592d8a1"
|
||||||
|
dependencies = [
|
||||||
|
"rust-ini",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3696,12 +3820,12 @@ checksum = "7395cdb9d0a6219fa0ea77d08c946adf9c1984c72fcd443ace30365f3daadef7"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xkbcommon"
|
name = "xkbcommon"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/wez/xkbcommon-rs.git?rev=01a0a0cd5663405e6e4abb1ad3add9add1496f58#01a0a0cd5663405e6e4abb1ad3add9add1496f58"
|
||||||
checksum = "fda0ea5f7ddabd51deeeda7799bee06274112f577da7dd3d954b8eda731b2fce"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"xcb",
|
"memmap",
|
||||||
|
"xcb 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -33,7 +33,7 @@ glium = { version = "0.26.0-alpha3", optional=true, default-features = false}
|
|||||||
[features]
|
[features]
|
||||||
async_await = []
|
async_await = []
|
||||||
opengl = ["cgl", "glium", "gl_generator", "libloading"]
|
opengl = ["cgl", "glium", "gl_generator", "libloading"]
|
||||||
wayland = ["smithay-client-toolkit", "memmap", "wayland-client"]
|
wayland = ["smithay-client-toolkit", "memmap", "wayland-client", "wayland-egl"]
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies]
|
[target."cfg(windows)".dependencies]
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
@ -52,16 +52,16 @@ clipboard-win = "2.2"
|
|||||||
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
|
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
|
||||||
filedescriptor = { version="0.7", path = "../filedescriptor" }
|
filedescriptor = { version="0.7", path = "../filedescriptor" }
|
||||||
x11 = {version ="2.18", features = ["xlib_xcb"]}
|
x11 = {version ="2.18", features = ["xlib_xcb"]}
|
||||||
xcb = "0.8"
|
xcb = {version="0.9", features=["shm", "xkb"]}
|
||||||
# See: https://github.com/meh/rust-xcb-util/issues/12
|
xcb-util = { features = [ "icccm", "ewmh", "keysyms", "shm"], version = "0.3" }
|
||||||
xcb-util = { features = [ "icccm", "ewmh", "keysyms", "shm"], version = "=0.2.1" }
|
xkbcommon = { version = "0.5", features = ["x11", "wayland"], git="https://github.com/wez/xkbcommon-rs.git", rev="01a0a0cd5663405e6e4abb1ad3add9add1496f58"}
|
||||||
xkbcommon = { version = "0.4", features = ["x11"] }
|
|
||||||
mio = "0.6"
|
mio = "0.6"
|
||||||
mio-extras = "2.0"
|
mio-extras = "2.0"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
smithay-client-toolkit = {version = "0.6", optional = true}
|
smithay-client-toolkit = {version = "0.9", optional = true, features=["calloop"], git="https://github.com/wez/client-toolkit.git", branch="title_tunc"}
|
||||||
memmap = {version="0.7", optional=true}
|
memmap = {version="0.7", optional=true}
|
||||||
wayland-client = {version="0.23", optional=true, features=["egl"]}
|
wayland-client = {version="0.26", optional=true}
|
||||||
|
wayland-egl = {version="0.26", optional=true}
|
||||||
|
|
||||||
[target.'cfg(target_os="macos")'.dependencies]
|
[target.'cfg(target_os="macos")'.dependencies]
|
||||||
cocoa = "0.20"
|
cocoa = "0.20"
|
||||||
|
@ -238,7 +238,7 @@ impl GlState {
|
|||||||
#[cfg(all(unix, feature = "wayland", not(target_os = "macos")))]
|
#[cfg(all(unix, feature = "wayland", not(target_os = "macos")))]
|
||||||
pub fn create_wayland(
|
pub fn create_wayland(
|
||||||
display: Option<ffi::EGLNativeDisplayType>,
|
display: Option<ffi::EGLNativeDisplayType>,
|
||||||
wegl_surface: &wayland_client::egl::WlEglSurface,
|
wegl_surface: &wayland_egl::WlEglSurface,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
Self::with_egl_lib(move |egl| {
|
Self::with_egl_lib(move |egl| {
|
||||||
let egl_display = egl.get_display(display)?;
|
let egl_display = egl.get_display(display)?;
|
||||||
|
@ -6,18 +6,19 @@ use crate::connection::ConnectionOps;
|
|||||||
use crate::spawn::*;
|
use crate::spawn::*;
|
||||||
use crate::timerlist::{TimerEntry, TimerList};
|
use crate::timerlist::{TimerEntry, TimerList};
|
||||||
use crate::Connection;
|
use crate::Connection;
|
||||||
use anyhow::{bail, Context};
|
use anyhow::{anyhow, bail, Context};
|
||||||
use mio::unix::EventedFd;
|
|
||||||
use mio::{Evented, Events, Poll, PollOpt, Ready, Token};
|
|
||||||
use smithay_client_toolkit as toolkit;
|
use smithay_client_toolkit as toolkit;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use toolkit::reexports::client::protocol::wl_seat::{Event as SeatEvent, WlSeat};
|
use toolkit::environment::Environment;
|
||||||
use toolkit::reexports::client::{Display, EventQueue};
|
use toolkit::reexports::calloop::{EventLoop, EventSource, Interest, Mode, Poll, Readiness, Token};
|
||||||
use toolkit::Environment;
|
use toolkit::reexports::client::Display;
|
||||||
|
use toolkit::WaylandSource;
|
||||||
|
|
||||||
|
toolkit::default_environment!(MyEnvironment, desktop);
|
||||||
|
|
||||||
pub struct WaylandConnection {
|
pub struct WaylandConnection {
|
||||||
should_terminate: RefCell<bool>,
|
should_terminate: RefCell<bool>,
|
||||||
@ -34,77 +35,55 @@ pub struct WaylandConnection {
|
|||||||
// bottom of this list.
|
// bottom of this list.
|
||||||
pub(crate) pointer: PointerDispatcher,
|
pub(crate) pointer: PointerDispatcher,
|
||||||
pub(crate) keyboard: KeyboardDispatcher,
|
pub(crate) keyboard: KeyboardDispatcher,
|
||||||
pub(crate) seat: WlSeat,
|
pub(crate) environment: RefCell<Environment<MyEnvironment>>,
|
||||||
pub(crate) environment: RefCell<Environment>,
|
event_q: RefCell<EventLoop<()>>,
|
||||||
event_q: RefCell<EventQueue>,
|
|
||||||
pub(crate) display: RefCell<Display>,
|
pub(crate) display: RefCell<Display>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evented for WaylandConnection {
|
|
||||||
fn register(
|
|
||||||
&self,
|
|
||||||
poll: &Poll,
|
|
||||||
token: Token,
|
|
||||||
interest: Ready,
|
|
||||||
opts: PollOpt,
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
EventedFd(&self.event_q.borrow().get_connection_fd()).register(poll, token, interest, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reregister(
|
|
||||||
&self,
|
|
||||||
poll: &Poll,
|
|
||||||
token: Token,
|
|
||||||
interest: Ready,
|
|
||||||
opts: PollOpt,
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
EventedFd(&self.event_q.borrow().get_connection_fd())
|
|
||||||
.reregister(poll, token, interest, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deregister(&self, poll: &Poll) -> std::io::Result<()> {
|
|
||||||
EventedFd(&self.event_q.borrow().get_connection_fd()).deregister(poll)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WaylandConnection {
|
impl WaylandConnection {
|
||||||
pub fn create_new() -> anyhow::Result<Self> {
|
pub fn create_new() -> anyhow::Result<Self> {
|
||||||
let (display, mut event_q) = Display::connect_to_env()?;
|
let (environment, display, event_q) =
|
||||||
let environment = Environment::from_display(&*display, &mut event_q)?;
|
toolkit::init_default_environment!(MyEnvironment, desktop)?;
|
||||||
|
let event_loop = toolkit::reexports::calloop::EventLoop::<()>::new()?;
|
||||||
|
|
||||||
let seat = environment
|
let keyboard = KeyboardDispatcher::new();
|
||||||
.manager
|
let mut pointer = None;
|
||||||
.instantiate_range(1, 6, move |seat| {
|
|
||||||
seat.implement_closure(
|
for seat in environment.get_all_seats() {
|
||||||
move |event, _seat| {
|
if let Some((has_kbd, has_ptr)) = toolkit::seat::with_seat_data(&seat, |seat_data| {
|
||||||
if let SeatEvent::Name { name } = event {
|
(
|
||||||
log::info!("seat name is {}", name);
|
seat_data.has_keyboard && !seat_data.defunct,
|
||||||
}
|
seat_data.has_pointer && !seat_data.defunct,
|
||||||
},
|
|
||||||
(),
|
|
||||||
)
|
)
|
||||||
})
|
}) {
|
||||||
.context("Failed to create seat")?;
|
if has_kbd {
|
||||||
let keyboard = KeyboardDispatcher::register(&seat)?;
|
keyboard.register(event_loop.handle(), &seat)?;
|
||||||
|
}
|
||||||
|
if has_ptr {
|
||||||
|
pointer.replace(PointerDispatcher::register(
|
||||||
|
&seat,
|
||||||
|
environment.require_global(),
|
||||||
|
environment.require_global(),
|
||||||
|
environment.require_global(),
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let pointer = PointerDispatcher::register(
|
WaylandSource::new(event_q)
|
||||||
&seat,
|
.quick_insert(event_loop.handle())
|
||||||
environment.compositor.clone(),
|
.map_err(|e| anyhow!("failed to setup WaylandSource: {:?}", e))?;
|
||||||
&environment.shm,
|
|
||||||
&environment.data_device_manager,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
display: RefCell::new(display),
|
display: RefCell::new(display),
|
||||||
event_q: RefCell::new(event_q),
|
event_q: RefCell::new(event_loop),
|
||||||
environment: RefCell::new(environment),
|
environment: RefCell::new(environment),
|
||||||
should_terminate: RefCell::new(false),
|
should_terminate: RefCell::new(false),
|
||||||
timers: RefCell::new(TimerList::new()),
|
timers: RefCell::new(TimerList::new()),
|
||||||
next_window_id: AtomicUsize::new(1),
|
next_window_id: AtomicUsize::new(1),
|
||||||
windows: RefCell::new(HashMap::new()),
|
windows: RefCell::new(HashMap::new()),
|
||||||
seat,
|
|
||||||
keyboard,
|
keyboard,
|
||||||
pointer,
|
pointer: pointer.unwrap(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,22 +103,6 @@ impl WaylandConnection {
|
|||||||
|
|
||||||
fn do_paint(&self) {}
|
fn do_paint(&self) {}
|
||||||
|
|
||||||
fn process_queued_events(&self) -> anyhow::Result<()> {
|
|
||||||
{
|
|
||||||
let mut event_q = self.event_q.borrow_mut();
|
|
||||||
if let Some(guard) = event_q.prepare_read() {
|
|
||||||
if let Err(e) = guard.read_events() {
|
|
||||||
if e.kind() != ::std::io::ErrorKind::WouldBlock {
|
|
||||||
bail!("Error while reading events: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event_q.dispatch_pending()?;
|
|
||||||
}
|
|
||||||
self.flush()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn window_by_id(&self, window_id: usize) -> Option<Rc<RefCell<WaylandWindowInner>>> {
|
pub(crate) fn window_by_id(&self, window_id: usize) -> Option<Rc<RefCell<WaylandWindowInner>>> {
|
||||||
self.windows.borrow().get(&window_id).map(Rc::clone)
|
self.windows.borrow().get(&window_id).map(Rc::clone)
|
||||||
}
|
}
|
||||||
@ -168,6 +131,38 @@ impl WaylandConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SpawnQueueSource {}
|
||||||
|
impl EventSource for SpawnQueueSource {
|
||||||
|
type Event = ();
|
||||||
|
type Metadata = ();
|
||||||
|
type Ret = ();
|
||||||
|
|
||||||
|
fn process_events<F>(
|
||||||
|
&mut self,
|
||||||
|
_readiness: Readiness,
|
||||||
|
_token: Token,
|
||||||
|
mut callback: F,
|
||||||
|
) -> std::io::Result<()>
|
||||||
|
where
|
||||||
|
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
|
||||||
|
{
|
||||||
|
callback((), &mut ());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
|
poll.register(SPAWN_QUEUE.raw_fd(), Interest::Readable, Mode::Level, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
|
poll.register(SPAWN_QUEUE.raw_fd(), Interest::Readable, Mode::Level, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
||||||
|
poll.unregister(SPAWN_QUEUE.raw_fd())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ConnectionOps for WaylandConnection {
|
impl ConnectionOps for WaylandConnection {
|
||||||
fn terminate_message_loop(&self) {
|
fn terminate_message_loop(&self) {
|
||||||
*self.should_terminate.borrow_mut() = true;
|
*self.should_terminate.borrow_mut() = true;
|
||||||
@ -176,20 +171,16 @@ impl ConnectionOps for WaylandConnection {
|
|||||||
fn run_message_loop(&self) -> anyhow::Result<()> {
|
fn run_message_loop(&self) -> anyhow::Result<()> {
|
||||||
self.flush()?;
|
self.flush()?;
|
||||||
|
|
||||||
const TOK_WAYLAND: usize = 0xffff_fffc;
|
self.event_q
|
||||||
const TOK_SPAWN: usize = 0xffff_fffd;
|
.borrow_mut()
|
||||||
let tok_wayland = Token(TOK_WAYLAND);
|
.handle()
|
||||||
let tok_spawn = Token(TOK_SPAWN);
|
.insert_source(SpawnQueueSource {}, move |_, _, _| {
|
||||||
|
// In theory, we'd SPAWN_QUEUE.run() here but we
|
||||||
let poll = Poll::new()?;
|
// prefer to defer that to the loop below where we
|
||||||
let mut events = Events::with_capacity(8);
|
// can have better control over the event_q borrow,
|
||||||
poll.register(self, tok_wayland, Ready::readable(), PollOpt::level())?;
|
// and so that we can inspect its return code.
|
||||||
poll.register(
|
})
|
||||||
&*SPAWN_QUEUE,
|
.map_err(|e| anyhow!("failed to insert SpawnQueueSource: {:?}", e))?;
|
||||||
tok_spawn,
|
|
||||||
Ready::readable(),
|
|
||||||
PollOpt::level(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let paint_interval = Duration::from_millis(25);
|
let paint_interval = Duration::from_millis(25);
|
||||||
let mut last_interval = Instant::now();
|
let mut last_interval = Instant::now();
|
||||||
@ -207,13 +198,6 @@ impl ConnectionOps for WaylandConnection {
|
|||||||
paint_interval - diff
|
paint_interval - diff
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process any events that might have accumulated in the local
|
|
||||||
// buffer (eg: due to a flush) before we potentially go to sleep.
|
|
||||||
// The locally queued events won't mark the fd as ready, so we
|
|
||||||
// could potentially sleep when there is work to be done if we
|
|
||||||
// relied solely on that.
|
|
||||||
self.process_queued_events()?;
|
|
||||||
|
|
||||||
// Check the spawn queue before we try to sleep; there may
|
// Check the spawn queue before we try to sleep; there may
|
||||||
// be work pending and we don't guarantee that there is a
|
// be work pending and we don't guarantee that there is a
|
||||||
// 1:1 wakeup to queued function, so we need to be assertive
|
// 1:1 wakeup to queued function, so we need to be assertive
|
||||||
@ -230,15 +214,16 @@ impl ConnectionOps for WaylandConnection {
|
|||||||
.unwrap_or(period)
|
.unwrap_or(period)
|
||||||
};
|
};
|
||||||
|
|
||||||
match poll.poll(&mut events, Some(period)) {
|
self.flush()?;
|
||||||
Ok(_) => {
|
|
||||||
// We process both event sources unconditionally
|
|
||||||
// in the loop above anyway; we're just using
|
|
||||||
// this to get woken up.
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(err) => {
|
{
|
||||||
bail!("polling for events: {:?}", err);
|
let mut event_q = self.event_q.borrow_mut();
|
||||||
|
if let Err(err) = event_q.dispatch(Some(period), &mut ()) {
|
||||||
|
if err.kind() != std::io::ErrorKind::WouldBlock
|
||||||
|
&& err.kind() != std::io::ErrorKind::Interrupted
|
||||||
|
{
|
||||||
|
return Err(err).context("error during event_q.dispatch");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use std::os::unix::io::AsRawFd;
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use toolkit::reexports::client::protocol::wl_data_offer::{Event as DataOfferEvent, WlDataOffer};
|
use toolkit::reexports::client::protocol::wl_data_offer::{Event as DataOfferEvent, WlDataOffer};
|
||||||
use toolkit::reexports::client::protocol::wl_data_source::WlDataSource;
|
use toolkit::reexports::client::protocol::wl_data_source::WlDataSource;
|
||||||
|
use wayland_client::Attached;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CopyAndPaste {
|
pub struct CopyAndPaste {
|
||||||
@ -69,7 +70,7 @@ impl CopyAndPaste {
|
|||||||
self.data_offer.replace(offer);
|
self.data_offer.replace(offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_selection(&mut self, source: WlDataSource) {
|
pub fn set_selection(&mut self, source: &Attached<WlDataSource>) {
|
||||||
use crate::connection::ConnectionOps;
|
use crate::connection::ConnectionOps;
|
||||||
crate::Connection::get()
|
crate::Connection::get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -4,12 +4,13 @@ use anyhow::anyhow;
|
|||||||
use smithay_client_toolkit as toolkit;
|
use smithay_client_toolkit as toolkit;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use toolkit::keyboard::{
|
use toolkit::reexports::calloop::LoopHandle;
|
||||||
map_keyboard_auto_with_repeat, Event as KbEvent, KeyRepeatEvent, KeyRepeatKind, KeyState,
|
use toolkit::seat::keyboard::{
|
||||||
ModifiersState,
|
map_keyboard_repeat, Event as KbEvent, KeyState, ModifiersState, RepeatKind,
|
||||||
};
|
};
|
||||||
use wayland_client::protocol::wl_seat::WlSeat;
|
use wayland_client::protocol::wl_seat::WlSeat;
|
||||||
use wayland_client::protocol::wl_surface::WlSurface;
|
use wayland_client::protocol::wl_surface::WlSurface;
|
||||||
|
use wayland_client::Attached;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Inner {
|
struct Inner {
|
||||||
@ -37,16 +38,6 @@ impl Inner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_repeat(&mut self, rawkey: u32, keysym: u32, utf8: Option<String>) {
|
|
||||||
self.dispatch_to_window(KeyboardEvent::Key {
|
|
||||||
serial: 0,
|
|
||||||
rawkey,
|
|
||||||
keysym,
|
|
||||||
is_down: true,
|
|
||||||
utf8,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dispatch_to_window(&mut self, evt: KeyboardEvent) {
|
fn dispatch_to_window(&mut self, evt: KeyboardEvent) {
|
||||||
if let Some(window_id) = self.surface_to_window_id.get(&self.active_surface_id) {
|
if let Some(window_id) = self.surface_to_window_id.get(&self.active_surface_id) {
|
||||||
let mut evt = Some(evt);
|
let mut evt = Some(evt);
|
||||||
@ -64,31 +55,29 @@ pub struct KeyboardDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeyboardDispatcher {
|
impl KeyboardDispatcher {
|
||||||
pub fn register(seat: &WlSeat) -> anyhow::Result<Self> {
|
pub fn new() -> Self {
|
||||||
let inner = Arc::new(Mutex::new(Inner::default()));
|
let inner = Arc::new(Mutex::new(Inner::default()));
|
||||||
|
Self { inner }
|
||||||
|
}
|
||||||
|
|
||||||
map_keyboard_auto_with_repeat(
|
pub fn register(
|
||||||
|
&self,
|
||||||
|
loop_handle: LoopHandle<()>,
|
||||||
|
seat: &Attached<WlSeat>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let inner = Arc::clone(&self.inner);
|
||||||
|
let (_kbd, _source) = map_keyboard_repeat(
|
||||||
|
loop_handle,
|
||||||
&seat,
|
&seat,
|
||||||
KeyRepeatKind::System,
|
None,
|
||||||
{
|
RepeatKind::System,
|
||||||
let inner = Arc::clone(&inner);
|
move |evt: KbEvent, _, _| {
|
||||||
move |evt: KbEvent, _| {
|
inner.lock().unwrap().handle_event(evt);
|
||||||
inner.lock().unwrap().handle_event(evt);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
let inner = Arc::clone(&inner);
|
|
||||||
move |evt: KeyRepeatEvent, _| {
|
|
||||||
inner
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.handle_repeat(evt.rawkey, evt.keysym, evt.utf8);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.map_err(|e| anyhow!("Failed to configure keyboard callback: {:?}", e))?;
|
.map_err(|e| anyhow!("Failed to configure keyboard callback: {:?}", e))?;
|
||||||
|
|
||||||
Ok(Self { inner })
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_window(&self, window_id: usize, surface: &WlSurface) {
|
pub fn add_window(&self, window_id: usize, surface: &WlSurface) {
|
||||||
@ -138,10 +127,21 @@ impl KeyboardEvent {
|
|||||||
serial,
|
serial,
|
||||||
utf8,
|
utf8,
|
||||||
},
|
},
|
||||||
|
KbEvent::Repeat {
|
||||||
|
rawkey,
|
||||||
|
keysym,
|
||||||
|
utf8,
|
||||||
|
..
|
||||||
|
} => KeyboardEvent::Key {
|
||||||
|
rawkey,
|
||||||
|
keysym,
|
||||||
|
is_down: true,
|
||||||
|
serial: 0,
|
||||||
|
utf8,
|
||||||
|
},
|
||||||
KbEvent::Modifiers { modifiers } => KeyboardEvent::Modifiers {
|
KbEvent::Modifiers { modifiers } => KeyboardEvent::Modifiers {
|
||||||
modifiers: modifier_keys(modifiers),
|
modifiers: modifier_keys(modifiers),
|
||||||
},
|
},
|
||||||
_ => return None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
use super::copy_and_paste::*;
|
use super::copy_and_paste::*;
|
||||||
use crate::input::*;
|
use crate::input::*;
|
||||||
use crate::os::wayland::connection::WaylandConnection;
|
use crate::os::wayland::connection::WaylandConnection;
|
||||||
use anyhow::anyhow;
|
|
||||||
use smithay_client_toolkit as toolkit;
|
use smithay_client_toolkit as toolkit;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use toolkit::pointer::{AutoPointer, AutoThemer};
|
|
||||||
use toolkit::reexports::client::protocol::wl_data_device::{
|
use toolkit::reexports::client::protocol::wl_data_device::{
|
||||||
Event as DataDeviceEvent, WlDataDevice,
|
Event as DataDeviceEvent, WlDataDevice,
|
||||||
};
|
};
|
||||||
@ -14,10 +12,12 @@ use toolkit::reexports::client::protocol::wl_pointer::{
|
|||||||
self, Axis, AxisSource, Event as PointerEvent,
|
self, Axis, AxisSource, Event as PointerEvent,
|
||||||
};
|
};
|
||||||
use toolkit::reexports::client::protocol::wl_surface::WlSurface;
|
use toolkit::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
|
use toolkit::seat::pointer::{ThemeManager, ThemeSpec, ThemedPointer};
|
||||||
use wayland_client::protocol::wl_compositor::WlCompositor;
|
use wayland_client::protocol::wl_compositor::WlCompositor;
|
||||||
use wayland_client::protocol::wl_data_device_manager::WlDataDeviceManager;
|
use wayland_client::protocol::wl_data_device_manager::WlDataDeviceManager;
|
||||||
use wayland_client::protocol::wl_seat::WlSeat;
|
use wayland_client::protocol::wl_seat::WlSeat;
|
||||||
use wayland_client::protocol::wl_shm::WlShm;
|
use wayland_client::protocol::wl_shm::WlShm;
|
||||||
|
use wayland_client::{Attached, Main};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Inner {
|
struct Inner {
|
||||||
@ -66,16 +66,13 @@ impl Inner {
|
|||||||
fn handle_data_event(&mut self, event: DataDeviceEvent, inner: &Arc<Mutex<Self>>) {
|
fn handle_data_event(&mut self, event: DataDeviceEvent, inner: &Arc<Mutex<Self>>) {
|
||||||
match event {
|
match event {
|
||||||
DataDeviceEvent::DataOffer { id } => {
|
DataDeviceEvent::DataOffer { id } => {
|
||||||
id.implement_closure(
|
id.quick_assign({
|
||||||
{
|
let inner = Arc::clone(inner);
|
||||||
let inner = Arc::clone(inner);
|
move |offer, event, _dispatch_data| {
|
||||||
move |event, offer| {
|
let mut inner = inner.lock().unwrap();
|
||||||
let mut inner = inner.lock().unwrap();
|
inner.route_data_offer(event, offer.detach());
|
||||||
inner.route_data_offer(event, offer);
|
}
|
||||||
}
|
});
|
||||||
},
|
|
||||||
(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
DataDeviceEvent::Enter { .. }
|
DataDeviceEvent::Enter { .. }
|
||||||
| DataDeviceEvent::Leave { .. }
|
| DataDeviceEvent::Leave { .. }
|
||||||
@ -96,10 +93,10 @@ impl Inner {
|
|||||||
|
|
||||||
pub struct PointerDispatcher {
|
pub struct PointerDispatcher {
|
||||||
inner: Arc<Mutex<Inner>>,
|
inner: Arc<Mutex<Inner>>,
|
||||||
pub(crate) data_device: WlDataDevice,
|
pub(crate) data_device: Main<WlDataDevice>,
|
||||||
auto_pointer: AutoPointer,
|
auto_pointer: ThemedPointer,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
themer: AutoThemer,
|
themer: ThemeManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -214,47 +211,29 @@ impl PendingMouse {
|
|||||||
impl PointerDispatcher {
|
impl PointerDispatcher {
|
||||||
pub fn register(
|
pub fn register(
|
||||||
seat: &WlSeat,
|
seat: &WlSeat,
|
||||||
compositor: WlCompositor,
|
compositor: Attached<WlCompositor>,
|
||||||
shm: &WlShm,
|
shm: Attached<WlShm>,
|
||||||
dev_mgr: &WlDataDeviceManager,
|
dev_mgr: Attached<WlDataDeviceManager>,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let inner = Arc::new(Mutex::new(Inner::default()));
|
let inner = Arc::new(Mutex::new(Inner::default()));
|
||||||
let pointer = seat
|
let pointer = seat.get_pointer();
|
||||||
.get_pointer({
|
pointer.quick_assign({
|
||||||
let inner = Arc::clone(&inner);
|
let inner = Arc::clone(&inner);
|
||||||
move |ptr| {
|
move |_, evt, _| {
|
||||||
ptr.implement_closure(
|
inner.lock().unwrap().handle_event(evt);
|
||||||
{
|
}
|
||||||
let inner = Arc::clone(&inner);
|
});
|
||||||
move |evt, _| {
|
|
||||||
inner.lock().unwrap().handle_event(evt);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map_err(|()| anyhow!("Failed to configure pointer callback"))?;
|
|
||||||
|
|
||||||
let themer = AutoThemer::init(None, compositor, shm);
|
let themer = ThemeManager::init(ThemeSpec::System, compositor, shm);
|
||||||
let auto_pointer = themer.theme_pointer(pointer);
|
let auto_pointer = themer.theme_pointer(pointer.detach());
|
||||||
|
|
||||||
let data_device = dev_mgr
|
let data_device = dev_mgr.get_data_device(seat);
|
||||||
.get_data_device(seat, {
|
data_device.quick_assign({
|
||||||
let inner = Arc::clone(&inner);
|
let inner = Arc::clone(&inner);
|
||||||
move |device| {
|
move |_device, event, _| {
|
||||||
device.implement_closure(
|
inner.lock().unwrap().handle_data_event(event, &inner);
|
||||||
{
|
}
|
||||||
let inner = Arc::clone(&inner);
|
});
|
||||||
move |event, _device| {
|
|
||||||
inner.lock().unwrap().handle_data_event(event, &inner);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map_err(|()| anyhow!("Failed to configure data_device"))?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner,
|
inner,
|
||||||
|
@ -22,61 +22,62 @@ use std::io::{Read, Write};
|
|||||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use toolkit::get_surface_scale_factor;
|
||||||
use toolkit::reexports::client::protocol::wl_data_source::Event as DataSourceEvent;
|
use toolkit::reexports::client::protocol::wl_data_source::Event as DataSourceEvent;
|
||||||
use toolkit::reexports::client::protocol::wl_surface::WlSurface;
|
use toolkit::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
use toolkit::utils::MemPool;
|
use toolkit::shm::MemPool;
|
||||||
use toolkit::window::Event;
|
use toolkit::window::{ButtonColorSpec, ColorSpec, ConceptConfig, ConceptFrame, Event};
|
||||||
|
use wayland_client::protocol::wl_data_device_manager::WlDataDeviceManager;
|
||||||
#[cfg(feature = "opengl")]
|
#[cfg(feature = "opengl")]
|
||||||
use wayland_client::egl::{is_available as egl_is_available, WlEglSurface};
|
use wayland_egl::{is_available as egl_is_available, WlEglSurface};
|
||||||
|
|
||||||
struct MyTheme;
|
|
||||||
use toolkit::window::ButtonState;
|
|
||||||
|
|
||||||
const DARK_GRAY: [u8; 4] = [0xff, 0x35, 0x35, 0x35];
|
const DARK_GRAY: [u8; 4] = [0xff, 0x35, 0x35, 0x35];
|
||||||
const DARK_PURPLE: [u8; 4] = [0xff, 0x2b, 0x20, 0x42];
|
const DARK_PURPLE: [u8; 4] = [0xff, 0x2b, 0x20, 0x42];
|
||||||
const PURPLE: [u8; 4] = [0xff, 0x3b, 0x30, 0x52];
|
const PURPLE: [u8; 4] = [0xff, 0x3b, 0x30, 0x52];
|
||||||
const WHITE: [u8; 4] = [0xff, 0xff, 0xff, 0xff];
|
const WHITE: [u8; 4] = [0xff, 0xff, 0xff, 0xff];
|
||||||
const GRAY: [u8; 4] = [0x80, 0x80, 0x80, 0x80];
|
const SILVER: [u8; 4] = [0xcc, 0xcc, 0xcc, 0xcc];
|
||||||
|
|
||||||
impl toolkit::window::Theme for MyTheme {
|
fn frame_config() -> ConceptConfig {
|
||||||
fn get_primary_color(&self, active: bool) -> [u8; 4] {
|
let icon = ButtonColorSpec {
|
||||||
if active {
|
hovered: ColorSpec::identical(WHITE.into()),
|
||||||
DARK_PURPLE
|
idle: ColorSpec {
|
||||||
} else {
|
active: PURPLE.into(),
|
||||||
DARK_GRAY
|
inactive: SILVER.into(),
|
||||||
}
|
},
|
||||||
}
|
disabled: ColorSpec::invisible(),
|
||||||
|
};
|
||||||
|
|
||||||
fn get_secondary_color(&self, active: bool) -> [u8; 4] {
|
let close = Some((
|
||||||
self.get_primary_color(active)
|
icon,
|
||||||
}
|
ButtonColorSpec {
|
||||||
|
hovered: ColorSpec::identical(PURPLE.into()),
|
||||||
|
idle: ColorSpec {
|
||||||
|
active: DARK_PURPLE.into(),
|
||||||
|
inactive: DARK_GRAY.into(),
|
||||||
|
},
|
||||||
|
disabled: ColorSpec::invisible(),
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
fn get_close_button_color(&self, status: ButtonState) -> [u8; 4] {
|
ConceptConfig {
|
||||||
match status {
|
primary_color: ColorSpec {
|
||||||
ButtonState::Hovered => PURPLE,
|
active: DARK_PURPLE.into(),
|
||||||
ButtonState::Idle => DARK_PURPLE,
|
inactive: DARK_GRAY.into(),
|
||||||
ButtonState::Disabled => DARK_GRAY,
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
fn get_maximize_button_color(&self, status: ButtonState) -> [u8; 4] {
|
|
||||||
self.get_close_button_color(status)
|
|
||||||
}
|
|
||||||
fn get_minimize_button_color(&self, status: ButtonState) -> [u8; 4] {
|
|
||||||
self.get_close_button_color(status)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_close_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
|
secondary_color: ColorSpec {
|
||||||
match status {
|
active: DARK_PURPLE.into(),
|
||||||
ButtonState::Hovered => WHITE,
|
inactive: DARK_GRAY.into(),
|
||||||
ButtonState::Idle => GRAY,
|
},
|
||||||
ButtonState::Disabled => DARK_GRAY,
|
|
||||||
}
|
close_button: close,
|
||||||
}
|
maximize_button: close,
|
||||||
fn get_maximize_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
|
minimize_button: close,
|
||||||
self.get_close_button_icon_color(status)
|
title_font: Some(("sans".into(), 17.0)),
|
||||||
}
|
title_color: ColorSpec {
|
||||||
fn get_minimize_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
|
active: WHITE.into(),
|
||||||
self.get_close_button_icon_color(status)
|
inactive: SILVER.into(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ pub struct WaylandWindowInner {
|
|||||||
callbacks: Box<dyn WindowCallbacks>,
|
callbacks: Box<dyn WindowCallbacks>,
|
||||||
surface: WlSurface,
|
surface: WlSurface,
|
||||||
copy_and_paste: Arc<Mutex<CopyAndPaste>>,
|
copy_and_paste: Arc<Mutex<CopyAndPaste>>,
|
||||||
window: Option<toolkit::window::Window<toolkit::window::ConceptFrame>>,
|
window: Option<toolkit::window::Window<ConceptFrame>>,
|
||||||
pool: MemPool,
|
pool: MemPool,
|
||||||
dimensions: Dimensions,
|
dimensions: Dimensions,
|
||||||
need_paint: bool,
|
need_paint: bool,
|
||||||
@ -167,21 +168,24 @@ impl WaylandWindow {
|
|||||||
let window_id = conn.next_window_id();
|
let window_id = conn.next_window_id();
|
||||||
let pending_event = Arc::new(Mutex::new(PendingEvent::default()));
|
let pending_event = Arc::new(Mutex::new(PendingEvent::default()));
|
||||||
|
|
||||||
let surface = conn.environment.borrow_mut().create_surface({
|
let surface = conn
|
||||||
let pending_event = Arc::clone(&pending_event);
|
.environment
|
||||||
move |dpi, surface| {
|
.borrow_mut()
|
||||||
pending_event.lock().unwrap().dpi.replace(dpi);
|
.create_surface_with_scale_callback({
|
||||||
log::debug!(
|
let pending_event = Arc::clone(&pending_event);
|
||||||
"surface id={} dpi scale changed to {}",
|
move |dpi, surface, _dispatch_data| {
|
||||||
surface.as_ref().id(),
|
pending_event.lock().unwrap().dpi.replace(dpi);
|
||||||
dpi
|
log::debug!(
|
||||||
);
|
"surface id={} dpi scale changed to {}",
|
||||||
WaylandConnection::with_window_inner(window_id, move |inner| {
|
surface.as_ref().id(),
|
||||||
inner.dispatch_pending_event();
|
dpi
|
||||||
Ok(())
|
);
|
||||||
});
|
WaylandConnection::with_window_inner(window_id, move |inner| {
|
||||||
}
|
inner.dispatch_pending_event();
|
||||||
});
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let dimensions = Dimensions {
|
let dimensions = Dimensions {
|
||||||
pixel_width: width,
|
pixel_width: width,
|
||||||
@ -189,36 +193,37 @@ impl WaylandWindow {
|
|||||||
dpi: 96,
|
dpi: 96,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut window = toolkit::window::Window::<toolkit::window::ConceptFrame>::init_from_env(
|
let mut window = conn
|
||||||
&*conn.environment.borrow(),
|
.environment
|
||||||
surface.clone(),
|
.borrow()
|
||||||
(
|
.create_window::<ConceptFrame, _>(
|
||||||
dimensions.pixel_width as u32,
|
surface.clone(),
|
||||||
dimensions.pixel_height as u32,
|
(
|
||||||
),
|
dimensions.pixel_width as u32,
|
||||||
{
|
dimensions.pixel_height as u32,
|
||||||
let pending_event = Arc::clone(&pending_event);
|
),
|
||||||
move |evt| {
|
{
|
||||||
if pending_event.lock().unwrap().queue(evt) {
|
let pending_event = Arc::clone(&pending_event);
|
||||||
WaylandConnection::with_window_inner(window_id, move |inner| {
|
move |evt, mut _dispatch_data| {
|
||||||
inner.dispatch_pending_event();
|
if pending_event.lock().unwrap().queue(evt) {
|
||||||
Ok(())
|
WaylandConnection::with_window_inner(window_id, move |inner| {
|
||||||
});
|
inner.dispatch_pending_event();
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
)
|
||||||
)
|
.context("Failed to create window")?;
|
||||||
.context("Failed to create window")?;
|
|
||||||
|
|
||||||
window.set_app_id(class_name.to_string());
|
window.set_app_id(class_name.to_string());
|
||||||
window.set_decorate(true);
|
|
||||||
window.set_resizable(true);
|
window.set_resizable(true);
|
||||||
window.set_title(name.to_string());
|
window.set_title(name.to_string());
|
||||||
window.set_theme(MyTheme {});
|
window.set_frame_config(frame_config());
|
||||||
|
|
||||||
let pool = MemPool::new(&conn.environment.borrow().shm, || {})?;
|
let pool = MemPool::new(conn.environment.borrow().require_global(), |_| {})?;
|
||||||
|
|
||||||
window.new_seat(&conn.seat);
|
// window.new_seat(&conn.seat);
|
||||||
conn.keyboard.add_window(window_id, &surface);
|
conn.keyboard.add_window(window_id, &surface);
|
||||||
|
|
||||||
let copy_and_paste = CopyAndPaste::create();
|
let copy_and_paste = CopyAndPaste::create();
|
||||||
@ -437,7 +442,7 @@ impl WaylandWindowInner {
|
|||||||
|
|
||||||
if let Some((w, h)) = pending.configure.take() {
|
if let Some((w, h)) = pending.configure.take() {
|
||||||
if self.window.is_some() {
|
if self.window.is_some() {
|
||||||
let factor = toolkit::surface::get_dpi_factor(&self.surface);
|
let factor = get_surface_scale_factor(&self.surface);
|
||||||
|
|
||||||
let pixel_width = self.surface_to_pixels(w.try_into().unwrap());
|
let pixel_width = self.surface_to_pixels(w.try_into().unwrap());
|
||||||
let pixel_height = self.surface_to_pixels(h.try_into().unwrap());
|
let pixel_height = self.surface_to_pixels(h.try_into().unwrap());
|
||||||
@ -472,6 +477,7 @@ impl WaylandWindowInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.refresh_frame();
|
self.refresh_frame();
|
||||||
|
self.need_paint = true;
|
||||||
self.do_paint().unwrap();
|
self.do_paint().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,6 +489,7 @@ impl WaylandWindowInner {
|
|||||||
fn refresh_frame(&mut self) {
|
fn refresh_frame(&mut self) {
|
||||||
if let Some(window) = self.window.as_mut() {
|
if let Some(window) = self.window.as_mut() {
|
||||||
window.refresh();
|
window.refresh();
|
||||||
|
self.surface.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +509,6 @@ impl WaylandWindowInner {
|
|||||||
frame.finish()?;
|
frame.finish()?;
|
||||||
// self.damage();
|
// self.damage();
|
||||||
self.refresh_frame();
|
self.refresh_frame();
|
||||||
self.surface.commit();
|
|
||||||
self.need_paint = false;
|
self.need_paint = false;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -783,26 +789,22 @@ impl WindowOps for WaylandWindow {
|
|||||||
WaylandConnection::with_window_inner(self.0, move |inner| {
|
WaylandConnection::with_window_inner(self.0, move |inner| {
|
||||||
let text = text.clone();
|
let text = text.clone();
|
||||||
let conn = Connection::get().unwrap().wayland();
|
let conn = Connection::get().unwrap().wayland();
|
||||||
|
|
||||||
let source = conn
|
let source = conn
|
||||||
.environment
|
.environment
|
||||||
.borrow()
|
.borrow()
|
||||||
.data_device_manager
|
.require_global::<WlDataDeviceManager>()
|
||||||
.create_data_source(move |source| {
|
.create_data_source();
|
||||||
source.implement_closure(
|
source.quick_assign(move |_source, event, _dispatch_data| {
|
||||||
move |event, _source| {
|
if let DataSourceEvent::Send { fd, .. } = event {
|
||||||
if let DataSourceEvent::Send { fd, .. } = event {
|
let fd = unsafe { FileDescriptor::from_raw_fd(fd) };
|
||||||
let fd = unsafe { FileDescriptor::from_raw_fd(fd) };
|
if let Err(e) = write_pipe_with_timeout(fd, text.as_bytes()) {
|
||||||
if let Err(e) = write_pipe_with_timeout(fd, text.as_bytes()) {
|
log::error!("while sending paste to pipe: {}", e);
|
||||||
log::error!("while sending paste to pipe: {}", e);
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
|
||||||
(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.map_err(|()| anyhow!("failed to create data source"))?;
|
|
||||||
source.offer(TEXT_MIME_TYPE.to_string());
|
source.offer(TEXT_MIME_TYPE.to_string());
|
||||||
inner.copy_and_paste.lock().unwrap().set_selection(source);
|
inner.copy_and_paste.lock().unwrap().set_selection(&source);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -887,7 +889,13 @@ impl WindowOpsMut for WaylandWindowInner {
|
|||||||
}
|
}
|
||||||
let conn = Connection::get().unwrap().wayland();
|
let conn = Connection::get().unwrap().wayland();
|
||||||
|
|
||||||
if !conn.environment.borrow().shell.needs_configure() {
|
if !conn
|
||||||
|
.environment
|
||||||
|
.borrow()
|
||||||
|
.get_shell()
|
||||||
|
.unwrap()
|
||||||
|
.needs_configure()
|
||||||
|
{
|
||||||
self.do_paint().unwrap();
|
self.do_paint().unwrap();
|
||||||
} else {
|
} else {
|
||||||
self.refresh_frame();
|
self.refresh_frame();
|
||||||
|
@ -51,7 +51,7 @@ impl Keyboard {
|
|||||||
device_id,
|
device_id,
|
||||||
xkb::KEYMAP_COMPILE_NO_FLAGS,
|
xkb::KEYMAP_COMPILE_NO_FLAGS,
|
||||||
);
|
);
|
||||||
let state = xkb::x11::state_new_from_device(&keymap, &connection, device_id);
|
let state = xkb::x11::state_new_from_device(&keymap, connection, device_id);
|
||||||
|
|
||||||
let locale = query_lc_ctype()?;
|
let locale = query_lc_ctype()?;
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ impl Keyboard {
|
|||||||
"problem with new keymap"
|
"problem with new keymap"
|
||||||
);
|
);
|
||||||
|
|
||||||
let new_state = xkb::x11::state_new_from_device(&new_keymap, &connection, self.device_id);
|
let new_state = xkb::x11::state_new_from_device(&new_keymap, connection, self.device_id);
|
||||||
ensure!(!new_state.get_raw_ptr().is_null(), "problem with new state");
|
ensure!(!new_state.get_raw_ptr().is_null(), "problem with new state");
|
||||||
|
|
||||||
self.state.replace(new_state);
|
self.state.replace(new_state);
|
||||||
|
@ -169,6 +169,10 @@ impl SpawnQueue {
|
|||||||
|
|
||||||
self.has_any_queued()
|
self.has_any_queued()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn raw_fd(&self) -> std::os::unix::io::RawFd {
|
||||||
|
self.read.lock().unwrap().as_raw_fd()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "macos")))]
|
#[cfg(all(unix, not(target_os = "macos")))]
|
||||||
@ -180,7 +184,7 @@ impl Evented for SpawnQueue {
|
|||||||
interest: Ready,
|
interest: Ready,
|
||||||
opts: PollOpt,
|
opts: PollOpt,
|
||||||
) -> std::io::Result<()> {
|
) -> std::io::Result<()> {
|
||||||
EventedFd(&self.read.lock().unwrap().as_raw_fd()).register(poll, token, interest, opts)
|
EventedFd(&self.raw_fd()).register(poll, token, interest, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reregister(
|
fn reregister(
|
||||||
@ -190,11 +194,11 @@ impl Evented for SpawnQueue {
|
|||||||
interest: Ready,
|
interest: Ready,
|
||||||
opts: PollOpt,
|
opts: PollOpt,
|
||||||
) -> std::io::Result<()> {
|
) -> std::io::Result<()> {
|
||||||
EventedFd(&self.read.lock().unwrap().as_raw_fd()).reregister(poll, token, interest, opts)
|
EventedFd(&self.raw_fd()).reregister(poll, token, interest, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deregister(&self, poll: &Poll) -> std::io::Result<()> {
|
fn deregister(&self, poll: &Poll) -> std::io::Result<()> {
|
||||||
EventedFd(&self.read.lock().unwrap().as_raw_fd()).deregister(poll)
|
EventedFd(&self.raw_fd()).deregister(poll)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user