diff --git a/Cargo.lock b/Cargo.lock index 35312379c..b73a669a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,7 +101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" dependencies = [ "atk-sys", - "glib", + "glib 0.18.5", "libc", ] @@ -111,10 +111,10 @@ version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -226,22 +226,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ "bitflags 2.8.0", - "cairo-sys-rs", - "glib", + "cairo-sys-rs 0.18.2", + "glib 0.18.5", "libc", "once_cell", "thiserror 1.0.69", ] +[[package]] +name = "cairo-rs" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae50b5510d86cf96ac2370e66d8dc960882f3df179d6a5a1e52bd94a1416c0f7" +dependencies = [ + "bitflags 2.8.0", + "cairo-sys-rs 0.20.7", + "glib 0.20.9", + "libc", +] + [[package]] name = "cairo-sys-rs" version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" dependencies = [ - "glib-sys", + "glib-sys 0.18.1", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18b6bb8e43c7eb0f2aac7976afe0c61b6f5fc2ab7bc4c139537ea56c92290df" +dependencies = [ + "glib-sys 0.20.9", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -297,6 +320,16 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cfg-expr" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d4ba6e40bd1184518716a6e1a781bf9160e286d219ccdb8ab2612e74cfe4789" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -789,13 +822,13 @@ version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" dependencies = [ - "cairo-rs", - "gdk-pixbuf", + "cairo-rs 0.18.5", + "gdk-pixbuf 0.18.5", "gdk-sys", - "gio", - "glib", + "gio 0.18.4", + "glib 0.18.5", "libc", - "pango", + "pango 0.18.3", ] [[package]] @@ -804,24 +837,49 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" dependencies = [ - "gdk-pixbuf-sys", - "gio", - "glib", + "gdk-pixbuf-sys 0.18.0", + "gio 0.18.4", + "glib 0.18.5", "libc", "once_cell", ] +[[package]] +name = "gdk-pixbuf" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7563afd6ff0a221edfbb70a78add5075b8d9cb48e637a40a24c3ece3fea414d0" +dependencies = [ + "gdk-pixbuf-sys 0.20.7", + "gio 0.20.9", + "glib 0.20.9", + "libc", +] + [[package]] name = "gdk-pixbuf-sys" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.18.1", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67f2587c9202bf997476bbba6aaed4f78a11538a2567df002a5f57f5331d0b5c" +dependencies = [ + "gio-sys 0.20.9", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -830,43 +888,61 @@ version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", + "cairo-sys-rs 0.18.2", + "gdk-pixbuf-sys 0.18.0", + "gio-sys 0.18.1", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", "libc", - "pango-sys", + "pango-sys 0.18.0", "pkg-config", - "system-deps", + "system-deps 6.2.2", ] [[package]] -name = "gdkwayland-sys" -version = "0.18.2" +name = "gdk4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +checksum = "4850c9d9c1aecd1a3eb14fadc1cdb0ac0a2298037e116264c7473e1740a32d60" dependencies = [ - "gdk-sys", - "glib-sys", - "gobject-sys", + "cairo-rs 0.20.7", + "gdk-pixbuf 0.20.9", + "gdk4-sys", + "gio 0.20.9", + "glib 0.20.9", "libc", + "pango 0.20.9", +] + +[[package]] +name = "gdk4-sys" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6eb95798e2b46f279cf59005daf297d5b69555428f185650d71974a910473a" +dependencies = [ + "cairo-sys-rs 0.20.7", + "gdk-pixbuf-sys 0.20.7", + "gio-sys 0.20.9", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", + "libc", + "pango-sys 0.20.9", "pkg-config", - "system-deps", + "system-deps 7.0.3", ] [[package]] -name = "gdkx11" +name = "gdkwayland-sys" version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" dependencies = [ - "gdk", - "gdkx11-sys", - "gio", - "glib", + "gdk-sys", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", "libc", - "x11", + "pkg-config", + "system-deps 6.2.2", ] [[package]] @@ -876,9 +952,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" dependencies = [ "gdk-sys", - "glib-sys", + "glib-sys 0.18.1", "libc", - "system-deps", + "system-deps 6.2.2", "x11", ] @@ -946,8 +1022,8 @@ dependencies = [ "futures-core", "futures-io", "futures-util", - "gio-sys", - "glib", + "gio-sys 0.18.1", + "glib 0.18.5", "libc", "once_cell", "pin-project-lite", @@ -955,19 +1031,49 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "gio" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f00c70f8029d84ea7572dd0e1aaa79e5329667b4c17f329d79ffb1e6277487" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys 0.20.9", + "glib 0.20.9", + "libc", + "pin-project-lite", + "smallvec", +] + [[package]] name = "gio-sys" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", "libc", - "system-deps", + "system-deps 6.2.2", "winapi", ] +[[package]] +name = "gio-sys" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "160eb5250a26998c3e1b54e6a3d4ea15c6c7762a6062a19a7b63eff6e2b33f9e" +dependencies = [ + "glib-sys 0.20.9", + "gobject-sys 0.20.9", + "libc", + "system-deps 7.0.3", + "windows-sys 0.59.0", +] + [[package]] name = "gl_generator" version = "0.14.0" @@ -991,10 +1097,10 @@ dependencies = [ "futures-executor", "futures-task", "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", + "gio-sys 0.18.1", + "glib-macros 0.18.5", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", "libc", "memchr", "once_cell", @@ -1002,6 +1108,27 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "glib" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b819af8059ee5395a2de9f2317d87a53dbad8846a2f089f0bb44703f37686" +dependencies = [ + "bitflags 2.8.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys 0.20.9", + "glib-macros 0.20.7", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", + "libc", + "memchr", + "smallvec", +] + [[package]] name = "glib-macros" version = "0.18.5" @@ -1009,13 +1136,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" dependencies = [ "heck 0.4.1", - "proc-macro-crate 2.0.2", + "proc-macro-crate 2.0.0", "proc-macro-error", "proc-macro2", "quote", "syn 2.0.98", ] +[[package]] +name = "glib-macros" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715601f8f02e71baef9c1f94a657a9a77c192aea6097cf9ae7e5e177cd8cde68" +dependencies = [ + "heck 0.5.0", + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "glib-sys" version = "0.18.1" @@ -1023,7 +1163,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" dependencies = [ "libc", - "system-deps", + "system-deps 6.2.2", +] + +[[package]] +name = "glib-sys" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8928869a44cfdd1fccb17d6746e4ff82c8f82e41ce705aa026a52ca8dc3aefb" +dependencies = [ + "libc", + "system-deps 7.0.3", ] [[package]] @@ -1053,9 +1203,20 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" dependencies = [ - "glib-sys", + "glib-sys 0.18.1", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gobject-sys" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c773a3cb38a419ad9c26c81d177d96b4b08980e8bdbbf32dace883e96e96e7e3" +dependencies = [ + "glib-sys 0.20.9", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -1109,6 +1270,60 @@ dependencies = [ "bitflags 2.8.0", ] +[[package]] +name = "graphene-rs" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc5911bfb32d68dcfa92c9510c462696c2f715548fcd7f3f1be424c739de19" +dependencies = [ + "glib 0.20.9", + "graphene-sys", + "libc", +] + +[[package]] +name = "graphene-sys" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11a68d39515bf340e879b72cecd4a25c1332557757ada6e8aba8654b4b81d23a" +dependencies = [ + "glib-sys 0.20.9", + "libc", + "pkg-config", + "system-deps 7.0.3", +] + +[[package]] +name = "gsk4" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f5e72f931c8c9f65fbfc89fe0ddc7746f147f822f127a53a9854666ac1f855" +dependencies = [ + "cairo-rs 0.20.7", + "gdk4", + "glib 0.20.9", + "graphene-rs", + "gsk4-sys", + "libc", + "pango 0.20.9", +] + +[[package]] +name = "gsk4-sys" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "755059de55fa6f85a46bde8caf03e2184c96bfda1f6206163c72fb0ea12436dc" +dependencies = [ + "cairo-sys-rs 0.20.7", + "gdk4-sys", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", + "graphene-sys", + "libc", + "pango-sys 0.20.9", + "system-deps 7.0.3", +] + [[package]] name = "gtk" version = "0.18.2" @@ -1116,17 +1331,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" dependencies = [ "atk", - "cairo-rs", + "cairo-rs 0.18.5", "field-offset", "futures-channel", "gdk", - "gdk-pixbuf", - "gio", - "glib", + "gdk-pixbuf 0.18.5", + "gio 0.18.4", + "glib 0.18.5", "gtk-sys", "gtk3-macros", "libc", - "pango", + "pango 0.18.3", "pkg-config", ] @@ -1137,15 +1352,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" dependencies = [ "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", + "cairo-sys-rs 0.18.2", + "gdk-pixbuf-sys 0.18.0", "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.18.1", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", "libc", - "pango-sys", - "system-deps", + "pango-sys 0.18.0", + "system-deps 6.2.2", ] [[package]] @@ -1161,6 +1376,58 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "gtk4" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1c491051f030994fd0cde6f3c44f3f5640210308cff1298c7673c47408091d" +dependencies = [ + "cairo-rs 0.20.7", + "field-offset", + "futures-channel", + "gdk-pixbuf 0.20.9", + "gdk4", + "gio 0.20.9", + "glib 0.20.9", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango 0.20.9", +] + +[[package]] +name = "gtk4-macros" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed1786c4703dd196baf7e103525ce0cf579b3a63a0570fe653b7ee6bac33999" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.98", +] + +[[package]] +name = "gtk4-sys" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e03b01e54d77c310e1d98647d73f996d04b2f29b9121fe493ea525a7ec03d6" +dependencies = [ + "cairo-sys-rs 0.20.7", + "gdk-pixbuf-sys 0.20.7", + "gdk4-sys", + "gio-sys 0.20.9", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys 0.20.9", + "system-deps 7.0.3", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1403,26 +1670,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] -name = "javascriptcore-rs" -version = "1.1.2" +name = "javascriptcore6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +checksum = "03b28ed9c7c08f906b2a51bc2365eae2ba5e7db1249b89892f7ae4cbd602d1f4" dependencies = [ - "bitflags 1.3.2", - "glib", - "javascriptcore-rs-sys", + "glib 0.20.9", + "javascriptcore6-sys", + "libc", ] [[package]] -name = "javascriptcore-rs-sys" -version = "1.1.1" +name = "javascriptcore6-sys" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +checksum = "4741e2a31c2145050dd4971f8dd51e92c840d5839a7124cc68a33c7325523a12" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -1730,7 +1997,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 2.0.2", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.98", @@ -2056,11 +2323,23 @@ version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" dependencies = [ - "gio", - "glib", + "gio 0.18.4", + "glib 0.18.5", "libc", "once_cell", - "pango-sys", + "pango-sys 0.18.0", +] + +[[package]] +name = "pango" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1f5dc1b8cf9bc08bfc0843a04ee0fa2e78f1e1fa4b126844a383af4f25f0ec" +dependencies = [ + "gio 0.20.9", + "glib 0.20.9", + "libc", + "pango-sys 0.20.9", ] [[package]] @@ -2069,10 +2348,22 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.18.1", + "gobject-sys 0.18.0", "libc", - "system-deps", + "system-deps 6.2.2", +] + +[[package]] +name = "pango-sys" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dbb9b751673bd8fe49eb78620547973a1e719ed431372122b20abd12445bab5" +dependencies = [ + "glib-sys 0.20.9", + "gobject-sys 0.20.9", + "libc", + "system-deps 7.0.3", ] [[package]] @@ -2319,14 +2610,22 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_datetime", "toml_edit 0.20.2", ] +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit 0.22.24", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -2729,28 +3028,28 @@ dependencies = [ [[package]] name = "soup3" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +checksum = "b84ccd1f4aee0854a16b0b489ba843798e2eb4cdcddd4a61248f7db9ce8b6df1" dependencies = [ "futures-channel", - "gio", - "glib", + "gio 0.20.9", + "glib 0.20.9", "libc", "soup3-sys", ] [[package]] name = "soup3-sys" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +checksum = "8869997193d52a61a1db48627bdaa57343f76e2c5132ee6d351245a6ab30631e" dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.20.9", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", "libc", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -2844,7 +3143,20 @@ version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ - "cfg-expr", + "cfg-expr 0.15.8", + "heck 0.5.0", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "system-deps" +version = "7.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d23aaf9f331227789a99e8de4c91bf46703add012bdfd45fdecdfb2975a005" +dependencies = [ + "cfg-expr 0.17.2", "heck 0.5.0", "pkg-config", "toml", @@ -3053,9 +3365,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -3068,7 +3380,7 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.7.1", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] @@ -3081,7 +3393,18 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +dependencies = [ + "indexmap 2.7.1", + "toml_datetime", + "winnow 0.7.4", ] [[package]] @@ -3424,47 +3747,36 @@ dependencies = [ ] [[package]] -name = "webkit2gtk" -version = "2.0.1" +name = "webkit6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +checksum = "8c359ef247305dcade3363c281c505b943e0e6162a42eac76ff76ed8e7cebfbd" dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "gdk", - "gdk-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "gtk", - "gtk-sys", - "javascriptcore-rs", + "gdk4", + "gio 0.20.9", + "glib 0.20.9", + "gtk4", + "javascriptcore6", "libc", - "once_cell", "soup3", - "webkit2gtk-sys", + "webkit6-sys", ] [[package]] -name = "webkit2gtk-sys" -version = "2.0.1" +name = "webkit6-sys" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +checksum = "96284c5280af5984dbdae8dae3cfeea11b44b214f9bd42b35c0ca75903bccce2" dependencies = [ - "bitflags 1.3.2", - "cairo-sys-rs", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "gtk-sys", - "javascriptcore-rs-sys", + "gdk4-sys", + "gio-sys 0.20.9", + "glib-sys 0.20.9", + "gobject-sys 0.20.9", + "gtk4-sys", + "javascriptcore6-sys", "libc", - "pkg-config", "soup3-sys", - "system-deps", + "system-deps 7.0.3", ] [[package]] @@ -4155,6 +4467,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen-rt" version = "0.33.0" @@ -4186,13 +4507,11 @@ dependencies = [ "crossbeam-channel", "dpi", "dunce", - "gdkx11", "getrandom 0.3.1", - "gtk", + "gtk4", "html5ever", "http", "http-range", - "javascriptcore-rs", "jni", "kuchikiki", "libc", @@ -4214,8 +4533,7 @@ dependencies = [ "thiserror 2.0.11", "tracing", "url", - "webkit2gtk", - "webkit2gtk-sys", + "webkit6", "webview2-com", "wgpu", "windows 0.61.1", diff --git a/Cargo.toml b/Cargo.toml index 54786878a..eabd305dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,17 +33,9 @@ protocol = [] devtools = [] transparent = [] fullscreen = [] -linux-body = ["webkit2gtk/v2_40", "os-webview"] +linux-body = ["os-webview"] mac-proxy = [] -os-webview = [ - "javascriptcore-rs", - "webkit2gtk", - "webkit2gtk-sys", - "dep:gtk", - "soup3", - "x11-dl", - "gdkx11", -] +os-webview = ["soup3", "webkit", "dep:gtk"] tracing = ["dep:tracing"] [dependencies] @@ -56,16 +48,10 @@ dpi = "0.1" cookie = "0.18" [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] -javascriptcore-rs = { version = "=1.1.2", features = [ - "v2_28", -], optional = true } -webkit2gtk = { version = "=2.0.1", features = ["v2_38"], optional = true } -webkit2gtk-sys = { version = "=2.0.1", optional = true } -gtk = { version = "0.18", optional = true } -soup3 = { version = "0.5", optional = true } -x11-dl = { version = "2.21", optional = true } -gdkx11 = { version = "0.18", optional = true } +soup3 = { version = "0.7", optional = true } percent-encoding = "2.3" +webkit = { package = "webkit6", version = "0.4", optional = true, features = ["v2_42"]} +gtk = { package = "gtk4", version = "0.9", optional = true, features = ["v4_6"] } [target."cfg(target_os = \"windows\")".dependencies] webview2-com = "0.37" @@ -207,6 +193,9 @@ getrandom = "0.3" http-range = "0.1" percent-encoding = "2.3" +[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dev-dependencies] +x11-dl = { version = "2.21" } + [lints.rust.unexpected_cfgs] level = "warn" check-cfg = ["cfg(linux)", "cfg(gtk)"] diff --git a/README.md b/README.md index bb0052c60..e1ae9943d 100644 --- a/README.md +++ b/README.md @@ -172,19 +172,19 @@ event_loop.run_app(&mut app).unwrap(); ###### Arch Linux / Manjaro: ```bash -sudo pacman -S webkit2gtk-4.1 +sudo pacman -S webkitgtk-6.0 ``` ###### Debian / Ubuntu: ```bash -sudo apt install libwebkit2gtk-4.1-dev +sudo apt install libwebkitgtk-6.0-dev ``` ###### Fedora ```bash -sudo dnf install gtk3-devel webkit2gtk4.1-devel +sudo dnf install webkitgtk6.0-devel ``` ###### Nix & NixOS @@ -197,7 +197,7 @@ let pkgs = import (fetchTarball("channel:nixpkgs-unstable")) { }; packages = with pkgs; [ pkg-config - webkitgtk_4_1 + webkitgtk_6_0 ]; in pkgs.mkShell { @@ -288,7 +288,7 @@ Wry uses a set of feature flags to toggle several advanced features. Avoid this in release build if your app needs to publish to App Store. libraries and prevent from building documentation on doc.rs fails. - `linux-body`: Enables body support of custom protocol request on Linux. Requires - webkit2gtk v2.40 or above. + webkitgtk6 v2.42 or above. - `tracing`: enables [`tracing`] for `evaluate_script`, `ipc_handler` and `custom_protocols. ### Partners diff --git a/examples/custom_titlebar.rs b/examples/custom_titlebar.rs index 226207ac8..eb25a1866 100644 --- a/examples/custom_titlebar.rs +++ b/examples/custom_titlebar.rs @@ -72,6 +72,9 @@ fn hit_test(window_size: PhysicalSize, x: i32, y: i32, scale: f64) -> HitTe let bottom = top + window_size.height as i32; let right = left + window_size.width as i32; + let x = x * scale as i32; + let y = y * scale as i32; + let inset = (BORDERLESS_RESIZE_INSET * scale) as i32; #[rustfmt::skip] @@ -266,7 +269,7 @@ fn main() -> wry::Result<()> { builder.build_gtk(vbox)? }; - let mut webview = Some(webview); + let mut webview: Option = Some(webview); event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; diff --git a/examples/gtk_multiwebview.rs b/examples/gtk_multiwebview.rs index 3e47efd4e..eb620b847 100644 --- a/examples/gtk_multiwebview.rs +++ b/examples/gtk_multiwebview.rs @@ -27,8 +27,7 @@ fn main() -> wry::Result<()> { use tao::platform::unix::WindowExtUnix; let fixed = gtk::Fixed::new(); let vbox = window.default_vbox().unwrap(); - vbox.pack_start(&fixed, true, true, 0); - fixed.show_all(); + vbox.prepend(&fixed); fixed }; diff --git a/examples/multiwebview.rs b/examples/multiwebview.rs index 6540c1541..257dc1339 100644 --- a/examples/multiwebview.rs +++ b/examples/multiwebview.rs @@ -131,8 +131,9 @@ impl ApplicationHandler for State { target_os = "openbsd", ))] { - while gtk::events_pending() { - gtk::main_iteration_do(false); + let context = gtk::glib::MainContext::default(); + while context.pending() { + context.iteration(false); } } } diff --git a/examples/reparent.rs b/examples/reparent.rs index 1b5476508..ddc5c812e 100644 --- a/examples/reparent.rs +++ b/examples/reparent.rs @@ -52,7 +52,7 @@ fn main() -> wry::Result<()> { target_os = "ios", target_os = "android" )))] - let webview = { + let mut webview = { use tao::platform::unix::WindowExtUnix; let vbox = window.default_vbox().unwrap(); builder.build_gtk(vbox)? diff --git a/examples/wgpu.rs b/examples/wgpu.rs index cc261f024..e57af2081 100644 --- a/examples/wgpu.rs +++ b/examples/wgpu.rs @@ -239,8 +239,9 @@ impl ApplicationHandler for State { target_os = "openbsd", ))] { - while gtk::events_pending() { - gtk::main_iteration_do(false); + let context = gtk::glib::MainContext::default(); + while context.pending() { + context.iteration(false); } } } diff --git a/examples/winit.rs b/examples/winit.rs index 729948700..c1424b1e8 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -63,8 +63,9 @@ impl ApplicationHandler for State { target_os = "openbsd", ))] { - while gtk::events_pending() { - gtk::main_iteration_do(false); + let context = gtk::glib::MainContext::default(); + while context.pending() { + context.iteration(false); } } } diff --git a/src/error.rs b/src/error.rs index ddeb73cdd..47485af1a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -12,14 +12,14 @@ pub enum Error { #[error(transparent)] GlibBoolError(#[from] gtk::glib::BoolError), #[cfg(gtk)] + #[error("{0} is not a supported webview parent widget.")] + UnsupportedParentWidget(String), + #[cfg(gtk)] #[error("Fail to fetch security manager")] MissingManager, #[cfg(gtk)] #[error("Couldn't find X11 Display")] X11DisplayNotFound, - #[cfg(gtk)] - #[error(transparent)] - XlibError(#[from] x11_dl::error::OpenError), #[error("Failed to initialize the script")] InitScriptError, #[error("Bad RPC request: {0} ((1))")] diff --git a/src/lib.rs b/src/lib.rs index 020f8df94..07215d657 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -194,19 +194,19 @@ //! ##### Arch Linux / Manjaro: //! //! ```bash -//! sudo pacman -S webkit2gtk-4.1 +//! sudo pacman -S webkitgtk-6.0 //! ``` //! //! ##### Debian / Ubuntu: //! //! ```bash -//! sudo apt install libwebkit2gtk-4.1-dev +//! sudo apt install libwebkitgtk-6.0-dev //! ``` //! //! ##### Fedora //! //! ```bash -//! sudo dnf install gtk3-devel webkit2gtk4.1-devel +//! sudo dnf install gtk3-devel webkitgtk6.0-devel //! ``` //! //! ##### Nix & NixOS @@ -219,7 +219,7 @@ //! pkgs = import (fetchTarball("channel:nixpkgs-unstable")) { }; //! packages = with pkgs; [ //! pkg-config -//! webkitgtk_4_1 +//! webkitgtk_6_0 //! ]; //! in //! pkgs.mkShell { @@ -1701,7 +1701,7 @@ pub trait WebViewBuilderExtUnix<'a> { /// - Panics if [`gtk::init`] was not called in this thread. fn build_gtk(self, widget: &'a W) -> Result where - W: gtk::prelude::IsA; + W: gtk::prelude::IsA; /// Set the path from which to load extensions from. fn with_extensions_path(self, path: impl Into) -> Self; @@ -1717,7 +1717,7 @@ pub trait WebViewBuilderExtUnix<'a> { impl<'a> WebViewBuilderExtUnix<'a> for WebViewBuilder<'a> { fn build_gtk(self, widget: &'a W) -> Result where - W: gtk::prelude::IsA, + W: gtk::prelude::IsA, { let parts = self.inner?; @@ -2067,33 +2067,33 @@ pub trait WebViewExtUnix: Sized { /// - Panics if [`gtk::init`] was not called in this thread. fn new_gtk(widget: &W) -> Result where - W: gtk::prelude::IsA; + W: gtk::prelude::IsA; - /// Returns Webkit2gtk Webview handle - fn webview(&self) -> webkit2gtk::WebView; + /// Returns Webkitgtk Webview handle + fn webview(&self) -> webkit::WebView; /// Attaches this webview to the given Widget and removes it from the current one. - fn reparent(&self, widget: &W) -> Result<()> + fn reparent(&mut self, widget: &W) -> Result<()> where - W: gtk::prelude::IsA; + W: gtk::prelude::IsA; } #[cfg(gtk)] impl WebViewExtUnix for WebView { fn new_gtk(widget: &W) -> Result where - W: gtk::prelude::IsA, + W: gtk::prelude::IsA, { WebViewBuilder::new().build_gtk(widget) } - fn webview(&self) -> webkit2gtk::WebView { + fn webview(&self) -> webkit::WebView { self.webview.webview.clone() } - fn reparent(&self, widget: &W) -> Result<()> + fn reparent(&mut self, widget: &W) -> Result<()> where - W: gtk::prelude::IsA, + W: gtk::prelude::IsA, { self.webview.reparent(widget) } diff --git a/src/webkitgtk/drag_drop.rs b/src/webkitgtk/drag_drop.rs index 513371330..c0b144c98 100644 --- a/src/webkitgtk/drag_drop.rs +++ b/src/webkitgtk/drag_drop.rs @@ -8,8 +8,13 @@ use std::{ rc::Rc, }; -use gtk::{glib::GString, prelude::*}; -use webkit2gtk::WebView; +use gtk::{ + gdk::{DragAction, FileList}, + gio::Cancellable, + prelude::*, + DropTargetAsync, +}; +use webkit::WebView; use crate::DragDropEvent; @@ -72,45 +77,63 @@ impl DragDropController { pub(crate) fn connect_drag_event(webview: &WebView, handler: Box bool>) { let controller = Rc::new(DragDropController::new(handler)); + let drop_target = DropTargetAsync::new(None, DragAction::all()); { - let controller = controller.clone(); - webview.connect_drag_data_received(move |_, _, _, _, data, info, _| { - if info == 2 { - let uris = data.uris(); - let paths = uris.iter().map(path_buf_from_uri).collect::>(); - controller.enter(); - controller.call(DragDropEvent::Enter { - paths: paths.clone(), - position: controller.position.get(), - }); - controller.store_paths(paths); - } + let controller: Rc = controller.clone(); + drop_target.connect_accept(move |_, drop| { + let controller = controller.clone(); + drop.read_value_async( + FileList::static_type(), + gtk::glib::Priority::DEFAULT, + Cancellable::NONE, + move |result| { + if let Ok(value) = result { + if let Ok(files) = value.get::() { + let paths = files + .files() + .iter() + .filter_map(|gfile| gfile.path()) + .collect::>(); + + controller.enter(); + controller.call(DragDropEvent::Enter { + paths: paths.clone(), + position: controller.position.get(), + }); + controller.store_paths(paths); + } + } + }, + ); + true }); } { let controller = controller.clone(); - webview.connect_drag_motion(move |_, _, x, y, _| { + drop_target.connect_drag_motion(move |_, _, x, y| { if controller.state() == DragControllerState::Entered { - controller.call(DragDropEvent::Over { position: (x, y) }); + controller.call(DragDropEvent::Over { + position: (x.round() as _, y.round() as _), + }); } else { - controller.store_position((x, y)); + controller.store_position((x.round() as _, y.round() as _)); } - false + DragAction::COPY }); } { let controller = controller.clone(); - webview.connect_drag_drop(move |_, ctx, x, y, time| { - if controller.state() == DragControllerState::Leaving { + drop_target.connect_drop(move |_, drop, x, y| { + if controller.state() == DragControllerState::Entered { if let Some(paths) = controller.take_paths() { - ctx.drop_finish(true, time); + drop.finish(DragAction::COPY); controller.leave(); return controller.call(DragDropEvent::Drop { paths, - position: (x, y), + position: (x.round() as _, y.round() as _), }); } } @@ -119,7 +142,7 @@ pub(crate) fn connect_drag_event(webview: &WebView, handler: Box PathBuf { - let path = gstr.as_str(); - let path = path.strip_prefix("file://").unwrap_or(path); - let path = percent_encoding::percent_decode(path.as_bytes()) - .decode_utf8_lossy() - .to_string(); - PathBuf::from(path) + webview.add_controller(drop_target); } diff --git a/src/webkitgtk/mod.rs b/src/webkitgtk/mod.rs index f72170b6a..209853fa9 100644 --- a/src/webkitgtk/mod.rs +++ b/src/webkitgtk/mod.rs @@ -2,42 +2,22 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use dpi::{LogicalPosition, LogicalSize}; -use ffi::CookieManageExt; -use gdkx11::{ - ffi::{gdk_x11_window_foreign_new_for_display, GdkX11Display}, - X11Display, -}; +use dpi::LogicalSize; use gtk::{ - gdk::{self}, gio::Cancellable, - glib::{self, translate::FromGlibPtrFull}, + glib::{self}, prelude::*, }; use http::Request; -use javascriptcore::ValueExt; -use raw_window_handle::{HasWindowHandle, RawWindowHandle}; +use raw_window_handle::HasWindowHandle; #[cfg(any(debug_assertions, feature = "devtools"))] use std::sync::atomic::{AtomicBool, Ordering}; -use std::{ - ffi::c_ulong, - sync::{Arc, Mutex}, -}; -#[cfg(any(debug_assertions, feature = "devtools"))] -use webkit2gtk::WebInspectorExt; -use webkit2gtk::{ - AutoplayPolicy, CookieManagerExt, InputMethodContextExt, LoadEvent, NavigationPolicyDecision, - NavigationPolicyDecisionExt, NetworkProxyMode, NetworkProxySettings, PolicyDecisionType, - PrintOperationExt, SettingsExt, URIRequest, URIRequestExt, UserContentInjectedFrames, - UserContentManager, UserContentManagerExt, UserScript, UserScriptInjectionTime, - WebContextExt as Webkit2gtkWeContextExt, WebView, WebViewExt, WebsiteDataManagerExt, - WebsiteDataManagerExtManual, WebsitePolicies, +use std::sync::{Arc, Mutex}; +use webkit::{ + prelude::*, AutoplayPolicy, LoadEvent, NavigationPolicyDecision, NetworkProxyMode, + NetworkProxySettings, PolicyDecisionType, URIRequest, UserContentInjectedFrames, + UserContentManager, UserScript, UserScriptInjectionTime, WebView, WebsitePolicies, }; -use webkit2gtk_sys::{ - webkit_get_major_version, webkit_get_micro_version, webkit_get_minor_version, - webkit_policy_decision_ignore, webkit_policy_decision_use, -}; -use x11_dl::xlib::*; pub use web_context::WebContextImpl; @@ -54,21 +34,6 @@ mod drag_drop; mod synthetic_mouse_events; mod web_context; -struct X11Data { - is_child: bool, - xlib: Xlib, - x11_display: *mut std::ffi::c_void, - x11_window: c_ulong, - gtk_window: gtk::Window, -} - -impl Drop for X11Data { - fn drop(&mut self) { - unsafe { (self.xlib.XDestroyWindow)(self.x11_display as _, self.x11_window) }; - self.gtk_window.close(); - } -} - pub(crate) struct InnerWebView { id: String, pub webview: WebView, @@ -76,58 +41,16 @@ pub(crate) struct InnerWebView { is_inspector_open: Arc, pending_scripts: Arc>>>, is_in_fixed_parent: bool, - - x11: Option, -} - -impl Drop for InnerWebView { - fn drop(&mut self) { - unsafe { self.webview.destroy() } - } + gtk_window: Option, } impl InnerWebView { - pub fn new( - window: &W, + pub fn new( + _window: &impl HasWindowHandle, attributes: WebViewAttributes, pl_attrs: super::PlatformSpecificWebViewAttributes, ) -> Result { - Self::new_x11(window, attributes, pl_attrs, false) - } - - pub fn new_as_child( - parent: &W, - attributes: WebViewAttributes, - pl_attrs: super::PlatformSpecificWebViewAttributes, - ) -> Result { - Self::new_x11(parent, attributes, pl_attrs, true) - } - - fn new_x11( - window: &W, - attributes: WebViewAttributes, - pl_attrs: super::PlatformSpecificWebViewAttributes, - is_child: bool, - ) -> Result { - let parent = match window.window_handle()?.as_raw() { - RawWindowHandle::Xlib(w) => w.window, - _ => return Err(Error::UnsupportedWindowHandle), - }; - - let xlib = Xlib::open()?; - - let gdk_display = gdk::Display::default().ok_or(crate::Error::X11DisplayNotFound)?; - let gx11_display: &X11Display = gdk_display.downcast_ref().unwrap(); - let raw = gx11_display.as_ptr(); - - let x11_display = unsafe { gdkx11::ffi::gdk_x11_display_get_xdisplay(raw) }; - - let x11_window = match is_child { - true => Self::create_container_x11_window(&xlib, x11_display as _, parent, &attributes), - false => parent, - }; - - let (gtk_window, vbox) = Self::create_gtk_window(raw, x11_window); + let (gtk_window, vbox) = Self::create_gtk_window(); let visible = attributes.visible; @@ -137,71 +60,32 @@ impl InnerWebView { // with alternating value. // calling gtk_window.show_all() then hiding it again // seems to fix the issue. - gtk_window.show_all(); + gtk_window.present(); if !visible { let _ = w.set_visible(false); } - w.x11.replace(X11Data { - is_child, - xlib, - x11_display: x11_display as _, - x11_window, - gtk_window, - }); + w.gtk_window = Some(gtk_window); w }) } - fn create_container_x11_window( - xlib: &Xlib, - display: *mut _XDisplay, - parent: c_ulong, - attributes: &WebViewAttributes, - ) -> c_ulong { - let scale_factor = scale_factor_from_x11(xlib, display, parent); - let (x, y) = attributes - .bounds - .map(|b| b.position.to_physical::(scale_factor)) - .map(Into::into) - .unwrap_or((0, 0)); - let (width, height) = attributes - .bounds - .map(|b| b.size.to_physical::(scale_factor)) - .map(Into::into) - // it is unlikey that bounds are not set because - // we have a default for it, but anyways we need to have a fallback - // and we need to use 1 not 0 here otherwise xlib will crash - .unwrap_or((1, 1)); - - let window = - unsafe { (xlib.XCreateSimpleWindow)(display, parent, x, y, width, height, 0, 0, 0) }; - - if attributes.visible { - unsafe { (xlib.XMapWindow)(display, window) }; - } - - window + pub fn new_as_child( + _window: &impl HasWindowHandle, + attributes: WebViewAttributes, + pl_attrs: super::PlatformSpecificWebViewAttributes, + ) -> Result { + Self::new(_window, attributes, pl_attrs) } - pub fn create_gtk_window( - raw: *mut GdkX11Display, - x11_window: c_ulong, - ) -> (gtk::Window, gtk::Box) { - // Gdk.Window - let gdk_window = unsafe { gdk_x11_window_foreign_new_for_display(raw, x11_window) }; - let gdk_window = unsafe { gdk::Window::from_glib_full(gdk_window) }; - + pub fn create_gtk_window() -> (gtk::Window, gtk::Box) { // Gtk.Window - let window = gtk::Window::new(gtk::WindowType::Toplevel); - window.connect_realize(glib::clone!(@weak gdk_window as wd => move |w| w.set_window(wd))); - window.set_has_window(true); - window.realize(); + let window = gtk::Window::new(); // Gtk.Box (vertical) let vbox = gtk::Box::new(gtk::Orientation::Vertical, 0); - window.add(&vbox); + window.set_child(Some(&vbox)); (window, vbox) } @@ -212,7 +96,7 @@ impl InnerWebView { pl_attrs: super::PlatformSpecificWebViewAttributes, ) -> Result where - W: IsA, + W: gtk::prelude::IsA, { // default_context allows us to create a scoped context on-demand let mut default_context; @@ -228,6 +112,16 @@ impl InnerWebView { } } }; + + web_context + .context() + .connect_initialize_web_process_extensions(move |context| { + // Extension loading + if let Some(extension_path) = &pl_attrs.extension_path { + context.set_web_process_extensions_directory(&extension_path.to_string_lossy()); + } + }); + if let Some(proxy_setting) = &attributes.proxy_config { let proxy_uri = match proxy_setting { ProxyConfig::Http(endpoint) => format!("http://{}:{}", endpoint.host, endpoint.port), @@ -235,19 +129,15 @@ impl InnerWebView { format!("socks5://{}:{}", endpoint.host, endpoint.port) } }; - if let Some(website_data_manager) = web_context.context().website_data_manager() { - let mut settings = NetworkProxySettings::new(Some(proxy_uri.as_str()), &[]); - website_data_manager - .set_network_proxy_settings(NetworkProxyMode::Custom, Some(&mut settings)); - } - } - - // Extension loading - if let Some(extension_path) = pl_attrs.extension_path { - web_context.os.set_web_extensions_directory(&extension_path); + let network_session = web_context.network_session(); + let settings = NetworkProxySettings::new(Some(proxy_uri.as_str()), &[]); + network_session.set_proxy_settings(NetworkProxyMode::Custom, Some(&settings)); } let webview = Self::create_webview(web_context, &attributes); + // Webview will forever be invisible if we don't set vexpand before rendering. + // Webkit bug maybe?? + webview.set_vexpand(true); // Transparent if attributes.transparent { @@ -277,7 +167,7 @@ impl InnerWebView { web_context.register_automation(webview.clone()); - let is_in_fixed_parent = Self::add_to_container(&webview, container, &attributes); + let is_in_fixed_parent = Self::add_to_container(&webview, container, attributes.bounds)?; #[cfg(any(debug_assertions, feature = "devtools"))] let is_inspector_open = Self::attach_inspector_handlers(&webview); @@ -292,12 +182,10 @@ impl InnerWebView { id, webview, pending_scripts: Arc::new(Mutex::new(Some(Vec::new()))), - is_in_fixed_parent, - x11: None, - #[cfg(any(debug_assertions, feature = "devtools"))] is_inspector_open, + gtk_window: None, }; // Initialize message handler @@ -316,7 +204,7 @@ impl InnerWebView { if let Some(pending_scripts) = pending_scripts_.take() { let cancellable: Option<&Cancellable> = None; for script in pending_scripts { - webview.run_javascript(&script, cancellable, |_| ()); + webview.evaluate_javascript(&script, None, None, cancellable, |_| ()); } } } @@ -335,8 +223,8 @@ impl InnerWebView { w.webview.load_html(&html, None); } - if attributes.visible { - w.webview.show_all(); + if !attributes.visible { + w.webview.set_visible(false); } if attributes.focused { @@ -350,6 +238,7 @@ impl InnerWebView { let mut builder = WebView::builder() .user_content_manager(&UserContentManager::new()) .web_context(web_context.context()) + .network_session(web_context.network_session()) .is_controlled_by_automation(web_context.allows_automation()); if attributes.autoplay { @@ -369,11 +258,6 @@ impl InnerWebView { input_context.set_enable_preedit(false); } - // use system scrollbars - if let Some(context) = webview.context() { - context.set_use_system_appearance_for_scrollbars(false); - } - if let Some(settings) = WebViewExt::settings(webview) { // Enable webgl, webaudio, canvas features as default. settings.set_enable_webgl(true); @@ -408,9 +292,6 @@ impl InnerWebView { web_context: &mut WebContext, attributes: &mut WebViewAttributes, ) { - // window.close() - webview.connect_close(move |webview| unsafe { webview.destroy() }); - // Synthetic mouse events synthetic_mouse_events::setup(webview); @@ -449,19 +330,15 @@ impl InnerWebView { if let Some(handler) = handler { if let Some(policy) = policy_decision.dynamic_cast_ref::() { - if let Some(nav_action) = policy.navigation_action() { + if let Some(mut nav_action) = policy.navigation_action() { if let Some(uri_req) = nav_action.request() { if let Some(uri) = uri_req.uri() { let allow = handler(uri.to_string()); - let pointer = policy_decision.as_ptr(); - unsafe { - if allow { - webkit_policy_decision_use(pointer) - } else { - webkit_policy_decision_ignore(pointer) - } + if allow { + policy_decision.use_(); + } else { + policy_decision.ignore(); } - return true; } } @@ -484,46 +361,6 @@ impl InnerWebView { } } - fn add_to_container(webview: &WebView, container: &W, attributes: &WebViewAttributes) -> bool - where - W: IsA, - { - let mut is_in_fixed_parent = false; - - let container_type = container.type_().name(); - if container_type == "GtkBox" { - container - .dynamic_cast_ref::() - .unwrap() - .pack_start(webview, true, true, 0); - } else if container_type == "GtkFixed" { - let scale_factor = webview.scale_factor() as f64; - let (width, height) = attributes - .bounds - .map(|b| b.size.to_logical::(scale_factor)) - .map(Into::into) - .unwrap_or((1, 1)); - let (x, y) = attributes - .bounds - .map(|b| b.position.to_logical::(scale_factor)) - .map(Into::into) - .unwrap_or((0, 0)); - - webview.set_size_request(width, height); - - container - .dynamic_cast_ref::() - .unwrap() - .put(webview, x, y); - - is_in_fixed_parent = true; - } else { - container.add(webview); - } - - is_in_fixed_parent - } - fn attach_ipc_handler(webview: WebView, attributes: &mut WebViewAttributes) { // Message handler let ipc_handler = attributes.ipc_handler.take(); @@ -536,20 +373,18 @@ impl InnerWebView { #[cfg(feature = "tracing")] let _span = tracing::info_span!(parent: None, "wry::ipc::handle").entered(); - if let Some(js) = msg.js_value() { - if let Some(ipc_handler) = &ipc_handler { - ipc_handler( - Request::builder() - .uri(webview.uri().unwrap().to_string()) - .body(js.to_string()) - .unwrap(), - ); - } + if let Some(ipc_handler) = &ipc_handler { + ipc_handler( + Request::builder() + .uri(webview.uri().unwrap().to_string()) + .body(msg.to_string()) + .unwrap(), + ); } }); // Register the handler we just connected - manager.register_script_message_handler("ipc"); + manager.register_script_message_handler("ipc", None); } #[cfg(any(debug_assertions, feature = "devtools"))] @@ -574,8 +409,8 @@ impl InnerWebView { } pub fn print(&self) -> Result<()> { - let print = webkit2gtk::PrintOperation::new(&self.webview); - print.run_dialog(None::<>k::Window>); + let print = webkit::PrintOperation::new(&self.webview); + print.run_dialog(gtk::Window::NONE); Ok(()) } @@ -596,20 +431,22 @@ impl InnerWebView { #[cfg(feature = "tracing")] let span = SendEnteredSpan(tracing::debug_span!("wry::eval").entered()); - self.webview.run_javascript(js, cancellable, |result| { - #[cfg(feature = "tracing")] - drop(span); - - if let Some(callback) = callback { - let result = result - .map(|r| r.js_value().and_then(|js| js.to_json(0))) - .unwrap_or_default() - .unwrap_or_default() - .to_string(); - - callback(result); - } - }); + self + .webview + .evaluate_javascript(js, None, None, cancellable, |result| { + #[cfg(feature = "tracing")] + drop(span); + + if let Some(callback) = callback { + let result = result + .map(|r| r.to_json(0)) + .unwrap_or_default() + .unwrap_or_default() + .to_string(); + + callback(result); + } + }); } Ok(()) @@ -674,7 +511,7 @@ impl InnerWebView { } pub fn load_url_with_headers(&self, url: &str, headers: http::HeaderMap) -> Result<()> { - let req = URIRequest::builder().uri(url).build(); + let req = URIRequest::new(url); if let Some(ref mut req_headers) = req.http_headers() { for (header, value) in headers.iter() { @@ -701,12 +538,12 @@ impl InnerWebView { } pub fn clear_all_browsing_data(&self) -> Result<()> { - if let Some(context) = self.webview.context() { - if let Some(data_manger) = context.website_data_manager() { + if let Some(network_session) = self.webview.network_session() { + if let Some(data_manger) = network_session.website_data_manager() { data_manger.clear( - webkit2gtk::WebsiteDataTypes::ALL, + webkit::WebsiteDataTypes::ALL, gtk::glib::TimeSpan::from_seconds(0), - None::<&Cancellable>, + Cancellable::NONE, |_| {}, ); } @@ -716,28 +553,10 @@ impl InnerWebView { } pub fn bounds(&self) -> Result { - let mut bounds = Rect::default(); - - if let Some(x11_data) = &self.x11 { - unsafe { - let attributes: XWindowAttributes = std::mem::zeroed(); - let mut attributes = std::mem::MaybeUninit::new(attributes).assume_init(); - - let ok = (x11_data.xlib.XGetWindowAttributes)( - x11_data.x11_display as _, - x11_data.x11_window, - &mut attributes, - ); - - if ok != 0 { - bounds.position = LogicalPosition::new(attributes.x, attributes.y).into(); - bounds.size = LogicalSize::new(attributes.width, attributes.height).into(); - } - } - } else { - let (size, _) = self.webview.allocated_size(); - bounds.size = LogicalSize::new(size.width(), size.height()).into(); - } + let bounds = Rect { + size: LogicalSize::new(self.webview.width(), self.webview.height()).into(), + ..Default::default() + }; Ok(bounds) } @@ -747,56 +566,28 @@ impl InnerWebView { let (width, height) = bounds.size.to_logical::(scale_factor).into(); let (x, y) = bounds.position.to_logical::(scale_factor).into(); - if let Some(x11_data) = &self.x11 { - let window = &x11_data.gtk_window; - window.move_(x, y); - if let Some(window) = window.window() { - window.resize(width, height); - } - window.size_allocate(>k::Allocation::new(0, 0, width, height)); + if let Some(gtk_window) = &self.gtk_window { + gtk_window.set_default_width(width); + gtk_window.set_default_height(height); } if self.is_in_fixed_parent { self .webview - .size_allocate(>k::Allocation::new(x, y, width, height)); + .size_allocate(>k::Allocation::new(x, y, width, height), -1); } Ok(()) } - fn set_visible_x11(&self, visible: bool) { - if let Some(x11_data) = &self.x11 { - if x11_data.is_child { - if visible { - unsafe { (x11_data.xlib.XMapWindow)(x11_data.x11_display as _, x11_data.x11_window) }; - } else { - unsafe { (x11_data.xlib.XUnmapWindow)(x11_data.x11_display as _, x11_data.x11_window) }; - } - } - } - } - fn set_visible_gtk(&self, visible: bool) { - if let Some(x11_data) = &self.x11 { - if x11_data.is_child { - if visible { - x11_data.gtk_window.show_all(); - } else { - x11_data.gtk_window.hide(); - } - } + if let Some(gtk_window) = &self.gtk_window { + gtk_window.set_visible(visible); } } pub fn set_visible(&self, visible: bool) -> Result<()> { - self.set_visible_x11(visible); - - if visible { - self.webview.show_all(); - } else { - self.webview.hide(); - } + self.webview.set_visible(visible); self.set_visible_gtk(visible); @@ -809,8 +600,13 @@ impl InnerWebView { } pub fn focus_parent(&self) -> Result<()> { - if let Some(window) = self.webview.parent_window() { - window.focus(gdk::ffi::GDK_CURRENT_TIME.try_into().unwrap_or(0)); + if let Some(window) = self.webview.root() { + if let Some(t) = window + .surface() + .and_then(|s| s.downcast::().ok()) + { + t.focus(gtk::gdk::ffi::GDK_CURRENT_TIME as _) + } } Ok(()) @@ -861,24 +657,26 @@ impl InnerWebView { pub fn cookies_for_url(&self, url: &str) -> Result>> { let (tx, rx) = std::sync::mpsc::channel(); - self + if let Some(cookies_manager) = self .webview - .website_data_manager() - .and_then(|manager| manager.cookie_manager()) - .map(|cookies_manager| { - cookies_manager.cookies(url, None::<&Cancellable>, move |cookies| { - let cookies = cookies.map(|cookies| { - cookies - .into_iter() - .map(Self::cookie_from_soup_cookie) - .collect() - }); - let _ = tx.send(cookies); - }) - }); + .network_session() + .and_then(|network_session| network_session.cookie_manager()) + { + cookies_manager.cookies(url, Cancellable::NONE, move |cookies| { + let cookies = cookies.map(|cookies| { + cookies + .into_iter() + .map(Self::cookie_from_soup_cookie) + .collect() + }); + let _ = tx.send(cookies); + }) + } + + let main_context = glib::MainContext::default(); loop { - gtk::main_iteration(); + main_context.iteration(true); if let Ok(response) = rx.try_recv() { return response.map_err(Into::into); @@ -888,24 +686,26 @@ impl InnerWebView { pub fn cookies(&self) -> Result>> { let (tx, rx) = std::sync::mpsc::channel(); - self + if let Some(cookies_manager) = self .webview - .website_data_manager() - .and_then(|manager| manager.cookie_manager()) - .map(|cookies_manager| { - cookies_manager.all_cookies(None::<&Cancellable>, move |cookies| { - let cookies = cookies.map(|cookies| { - cookies - .into_iter() - .map(Self::cookie_from_soup_cookie) - .collect() - }); - let _ = tx.send(cookies); - }) - }); + .network_session() + .and_then(|network_session| network_session.cookie_manager()) + { + cookies_manager.all_cookies(Cancellable::NONE, move |cookies| { + let cookies = cookies.map(|cookies| { + cookies + .into_iter() + .map(Self::cookie_from_soup_cookie) + .collect() + }); + let _ = tx.send(cookies); + }) + } + + let main_context = glib::MainContext::default(); loop { - gtk::main_iteration(); + main_context.iteration(true); if let Ok(response) = rx.try_recv() { return response.map_err(Into::into); @@ -913,45 +713,68 @@ impl InnerWebView { } } - pub fn reparent(&self, container: &W) -> Result<()> + fn add_to_container(webview: &WebView, container: &W, bounds: Option) -> Result where - W: gtk::prelude::IsA, + W: IsA, { - if let Some(parent) = self - .webview - .parent() - .and_then(|p| p.dynamic_cast::().ok()) - { - parent.remove(&self.webview); - - let container_type = container.type_().name(); - if container_type == "GtkBox" { - container - .dynamic_cast_ref::() - .unwrap() - .pack_start(&self.webview, true, true, 0); - } else if container_type == "GtkFixed" { - container - .dynamic_cast_ref::() - .unwrap() - .put(&self.webview, 0, 0); + let mut is_in_fixed_parent = false; + if let Some(c) = container.dynamic_cast_ref::() { + c.set_child(Some(webview)); + } else if let Some(c) = container.dynamic_cast_ref::() { + c.append(webview); + } else if let Some(c) = container.dynamic_cast_ref::() { + let scale_factor = webview.scale_factor() as f64; + let (width, height) = bounds + .map(|b| b.size.to_logical::(scale_factor)) + .map(Into::into) + .unwrap_or((1, 1)); + let (x, y) = bounds + .map(|b| b.position.to_logical::(scale_factor)) + .map(Into::into) + .unwrap_or((0., 0.)); + + // This seems to be the same bug where the webview is invisible without vexpand + // GtkFixed ignores vexpand though so we need this here. + webview.set_size_request(1, 1); + webview.size_allocate(>k::Allocation::new(x as _, y as _, width, height), -1); + c.put(webview, x, y); + + is_in_fixed_parent = true; + } else { + return Err(Error::UnsupportedParentWidget( + container.type_().to_string(), + )); + } + Ok(is_in_fixed_parent) + } + + pub fn reparent(&mut self, container: &W) -> Result<()> + where + W: IsA, + { + if let Some(parent) = self.webview.parent() { + if let Some(p) = parent.dynamic_cast_ref::() { + p.set_child(gtk::Widget::NONE); + } else if let Some(p) = parent.dynamic_cast_ref::() { + p.remove(&self.webview); + } else if let Some(p) = parent.dynamic_cast_ref::() { + p.remove(&self.webview); } else { - container.add(&self.webview); + return Err(Error::UnsupportedParentWidget(parent.type_().to_string())); } } + self.is_in_fixed_parent = Self::add_to_container(&self.webview, container, self.bounds().ok())?; Ok(()) } } pub fn platform_webview_version() -> Result { - let (major, minor, patch) = unsafe { - ( - webkit_get_major_version(), - webkit_get_minor_version(), - webkit_get_micro_version(), - ) - }; + let (major, minor, patch) = ( + webkit::functions::major_version(), + webkit::functions::minor_version(), + webkit::functions::micro_version(), + ); Ok(format!("{major}.{minor}.{patch}")) } @@ -961,96 +784,3 @@ struct SendEnteredSpan(tracing::span::EnteredSpan); #[cfg(feature = "tracing")] unsafe impl Send for SendEnteredSpan {} - -const BASE_DPI: f64 = 96.0; -fn scale_factor_from_x11(xlib: &Xlib, display: *mut _XDisplay, parent: c_ulong) -> f64 { - let mut attrs = unsafe { std::mem::zeroed() }; - unsafe { (xlib.XGetWindowAttributes)(display, parent, &mut attrs) }; - let scale_factor = unsafe { (*attrs.screen).width as f64 * 25.4 / (*attrs.screen).mwidth as f64 }; - scale_factor / BASE_DPI -} - -mod ffi { - use gtk::{ - gdk, - gio::{ - self, - ffi::{GAsyncReadyCallback, GCancellable}, - prelude::*, - Cancellable, - }, - glib::{ - self, - translate::{FromGlibPtrContainer, ToGlibPtr}, - }, - }; - use webkit2gtk::CookieManager; - use webkit2gtk_sys::WebKitCookieManager; - - pub trait CookieManageExt: IsA + 'static { - fn all_cookies, glib::Error>) + 'static>( - &self, - cancellable: Option<&impl IsA>, - callback: P, - ) { - let main_context = glib::MainContext::ref_thread_default(); - let is_main_context_owner = main_context.is_owner(); - let has_acquired_main_context = (!is_main_context_owner) - .then(|| main_context.acquire().ok()) - .flatten(); - assert!( - is_main_context_owner || has_acquired_main_context.is_some(), - "Async operations only allowed if the thread is owning the MainContext" - ); - - let user_data: Box> = - Box::new(glib::thread_guard::ThreadGuard::new(callback)); - unsafe extern "C" fn cookies_trampoline< - P: FnOnce(std::result::Result, glib::Error>) + 'static, - >( - _source_object: *mut glib::gobject_ffi::GObject, - res: *mut gdk::gio::ffi::GAsyncResult, - user_data: glib::ffi::gpointer, - ) { - let mut error = std::ptr::null_mut(); - let ret = - webkit_cookie_manager_get_all_cookies_finish(_source_object as *mut _, res, &mut error); - let result = if error.is_null() { - Ok(FromGlibPtrContainer::from_glib_full(ret)) - } else { - Err(glib::translate::from_glib_full(error)) - }; - let callback: Box> = Box::from_raw(user_data as *mut _); - let callback: P = callback.into_inner(); - callback(result); - } - let callback = cookies_trampoline::

; - - unsafe { - webkit_cookie_manager_get_all_cookies( - self.as_ref().to_glib_none().0, - cancellable.map(|p| p.as_ref()).to_glib_none().0, - Some(callback), - Box::into_raw(user_data) as *mut _, - ); - } - } - } - - impl CookieManageExt for CookieManager {} - - extern "C" { - pub fn webkit_cookie_manager_get_all_cookies( - cookie_manager: *mut webkit2gtk_sys::WebKitCookieManager, - cancellable: *mut GCancellable, - callback: GAsyncReadyCallback, - user_data: glib::ffi::gpointer, - ); - - pub fn webkit_cookie_manager_get_all_cookies_finish( - cookie_manager: *mut WebKitCookieManager, - result: *mut gio::ffi::GAsyncResult, - error: *mut *mut glib::ffi::GError, - ) -> *mut glib::ffi::GList; - } -} diff --git a/src/webkitgtk/synthetic_mouse_events.rs b/src/webkitgtk/synthetic_mouse_events.rs index 5c1d24fcb..7b08f551f 100644 --- a/src/webkitgtk/synthetic_mouse_events.rs +++ b/src/webkitgtk/synthetic_mouse_events.rs @@ -1,102 +1,88 @@ use std::{cell::RefCell, rc::Rc}; -use gtk::{ - gdk::{EventButton, EventMask, ModifierType}, - prelude::*, -}; -use webkit2gtk::{WebView, WebViewExt}; +use gtk::{gdk::ModifierType, prelude::*, GestureClick}; +use webkit::{prelude::WebViewExt, WebView}; pub fn setup(webview: &WebView) { - webview.add_events(EventMask::BUTTON1_MOTION_MASK | EventMask::BUTTON_PRESS_MASK); + let gesture = gtk::GestureClick::new(); let bf_state = BackForwardState(Rc::new(RefCell::new(0))); let bf_state_c = bf_state.clone(); - webview.connect_button_press_event(move |webview, event| { - let mut inhibit = false; - match event.button() { - // back button - 8 => { - inhibit = true; - bf_state_c.set(BACK); - webview.run_javascript( - &create_js_mouse_event(event, true, &bf_state_c), - None::<>k::gio::Cancellable>, - |_| {}, - ); - } - // forward button - 9 => { - inhibit = true; - bf_state_c.set(FORWARD); - webview.run_javascript( - &create_js_mouse_event(event, true, &bf_state_c), - None::<>k::gio::Cancellable>, - |_| {}, - ); - } - _ => {} + gesture.connect_pressed(move |event, n_press, x, y| match event.button() { + // back button + 8 => { + bf_state_c.set(BACK); + on_gesture_click(event, false, n_press, x, y, &bf_state_c); } - - if inhibit { - gtk::glib::Propagation::Stop - } else { - gtk::glib::Propagation::Proceed + // forward button + 9 => { + bf_state_c.set(FORWARD); + on_gesture_click(event, false, n_press, x, y, &bf_state_c); } + _ => {} }); let bf_state_c = bf_state.clone(); - webview.connect_button_release_event(move |webview, event| { - let mut inhibit = false; - match event.button() { - // back button - 8 => { - inhibit = true; - bf_state_c.remove(BACK); - webview.run_javascript( - &create_js_mouse_event(event, false, &bf_state_c), - None::<>k::gio::Cancellable>, - |_| {}, - ); - } - // forward button - 9 => { - inhibit = true; - bf_state_c.remove(FORWARD); - webview.run_javascript( - &create_js_mouse_event(event, false, &bf_state_c), - None::<>k::gio::Cancellable>, - |_| {}, - ); - } - _ => {} + gesture.connect_released(move |event, n_press, x, y| match event.current_button() { + // back button + 8 => { + bf_state_c.remove(BACK); + on_gesture_click(event, false, n_press, x, y, &bf_state_c); } - if inhibit { - gtk::glib::Propagation::Stop - } else { - gtk::glib::Propagation::Proceed + // forward button + 9 => { + bf_state_c.remove(FORWARD); + on_gesture_click(event, false, n_press, x, y, &bf_state_c); } + _ => {} }); + + webview.add_controller(gesture); +} + +fn on_gesture_click( + event: &GestureClick, + pressed: bool, + n_press: i32, + x: f64, + y: f64, + state: &BackForwardState, +) { + if let Ok(webview) = event.widget().and_dynamic_cast::() { + webview.evaluate_javascript( + &create_js_mouse_event(event, n_press, x, y, pressed, state), + None, + None, + gtk::gio::Cancellable::NONE, + |_| {}, + ); + } + event.reset(); } -fn create_js_mouse_event(event: &EventButton, pressed: bool, state: &BackForwardState) -> String { - let event_name = if pressed { "mousedown" } else { "mouseup" }; +fn create_js_mouse_event( + event: &GestureClick, + n_press: i32, + x: f64, + y: f64, + pressed: bool, + state: &BackForwardState, +) -> String { + let modifier_state = event.current_event_state(); + let event_name: &str = if pressed { "mousedown" } else { "mouseup" }; // js equivalent https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button - let button = if event.button() == 8 { 3 } else { 4 }; - let (x, y) = event.position(); - let (x, y) = (x as i32, y as i32); - let modifers_state = event.state(); let mut buttons = 0; // left button - if modifers_state.contains(ModifierType::BUTTON1_MASK) { + if modifier_state.contains(ModifierType::BUTTON1_MASK) { buttons += 1; } // right button - if modifers_state.contains(ModifierType::BUTTON3_MASK) { + if modifier_state.contains(ModifierType::BUTTON3_MASK) { buttons += 2; } // middle button - if modifers_state.contains(ModifierType::BUTTON2_MASK) { + if modifier_state.contains(ModifierType::BUTTON2_MASK) { buttons += 4; } // back button @@ -153,12 +139,12 @@ fn create_js_mouse_event(event: &EventButton, pressed: bool, state: &BackForward event_name = event_name, x = x, y = y, - detail = event.click_count().unwrap_or(1), - ctrl_key = modifers_state.contains(ModifierType::CONTROL_MASK), - alt_key = modifers_state.contains(ModifierType::MOD1_MASK), - shift_key = modifers_state.contains(ModifierType::SHIFT_MASK), - meta_key = modifers_state.contains(ModifierType::SUPER_MASK), - button = button, + detail = n_press, + ctrl_key = modifier_state.contains(ModifierType::CONTROL_MASK), + alt_key = modifier_state.contains(ModifierType::ALT_MASK), + shift_key = modifier_state.contains(ModifierType::SHIFT_MASK), + meta_key = modifier_state.contains(ModifierType::SUPER_MASK), + button = event.current_button(), buttons = buttons, ) } diff --git a/src/webkitgtk/web_context.rs b/src/webkitgtk/web_context.rs index 7cd942ad1..683794587 100644 --- a/src/webkitgtk/web_context.rs +++ b/src/webkitgtk/web_context.rs @@ -5,7 +5,10 @@ //! Unix platform extensions for [`WebContext`](super::WebContext). use crate::{Error, RequestAsyncResponder}; -use gtk::glib::{self, MainContext, ObjectExt}; +use gtk::{ + glib::{self, MainContext}, + prelude::ObjectExt, +}; use http::{header::CONTENT_TYPE, HeaderName, HeaderValue, Request, Response as HttpResponse}; use soup::{MessageHeaders, MessageHeadersType}; use std::{ @@ -19,16 +22,15 @@ use std::{ Mutex, }, }; -use webkit2gtk::{ - ApplicationInfo, AutomationSessionExt, CookiePersistentStorage, DownloadExt, LoadEvent, - SecurityManagerExt, URIRequest, URIRequestExt, URISchemeRequest, URISchemeRequestExt, - URISchemeResponse, URISchemeResponseExt, WebContext, WebContextExt as Webkit2gtkContextExt, - WebView, WebViewExt, +use webkit::{ + prelude::WebViewExt, ApplicationInfo, CookiePersistentStorage, LoadEvent, NetworkSession, + URIRequest, URISchemeRequest, URISchemeResponse, WebContext, WebView, }; #[derive(Debug)] pub struct WebContextImpl { context: WebContext, + network_session: NetworkSession, webview_uri_loader: Rc, automation: bool, app_info: Option, @@ -36,33 +38,35 @@ pub struct WebContextImpl { impl WebContextImpl { pub fn new(data_directory: Option<&Path>) -> Self { - use webkit2gtk::{CookieManagerExt, WebsiteDataManager, WebsiteDataManagerExt}; - let mut context_builder = WebContext::builder(); - if let Some(data_directory) = data_directory { - let data_manager = WebsiteDataManager::builder() - .base_data_directory(data_directory.to_string_lossy()) - .build(); - if let Some(cookie_manager) = data_manager.cookie_manager() { - cookie_manager.set_persistent_storage( - &data_directory.join("cookies").to_string_lossy(), - CookiePersistentStorage::Text, - ); + let network_session = match data_directory { + Some(data_directory) => { + let network_session = NetworkSession::builder() + .data_directory(data_directory.to_string_lossy()) + .build(); + + if let Some(cookie_manager) = network_session.cookie_manager() { + cookie_manager.set_persistent_storage( + &data_directory.join("cookies").to_string_lossy(), + CookiePersistentStorage::Text, + ); + } + network_session } - context_builder = context_builder.website_data_manager(&data_manager); - } - let context = context_builder.build(); + None => NetworkSession::builder().build(), + }; - Self::create_context(context) + Self::create_context(network_session) } pub fn new_ephemeral() -> Self { - let context = WebContext::new_ephemeral(); + let network_session = NetworkSession::new_ephemeral(); - Self::create_context(context) + Self::create_context(network_session) } - pub fn create_context(context: WebContext) -> Self { + pub fn create_context(network_session: NetworkSession) -> Self { let automation = false; + let context = WebContext::new(); context.set_automation_allowed(automation); // e.g. wry 0.9.4 @@ -82,6 +86,7 @@ impl WebContextImpl { Self { context, + network_session, automation, webview_uri_loader: Rc::default(), app_info: Some(app_info), @@ -92,12 +97,6 @@ impl WebContextImpl { self.automation = flag; self.context.set_automation_allowed(flag); } - - pub fn set_web_extensions_directory(&mut self, path: &Path) { - self - .context - .set_web_extensions_directory(&path.to_string_lossy()); - } } /// [`WebContext`](super::WebContext) items that only matter on unix. @@ -105,6 +104,9 @@ pub trait WebContextExt { /// The GTK [`WebContext`] of all webviews in the context. fn context(&self) -> &WebContext; + /// The GTK [`NetworkSession`] of all webviews in the context. + fn network_session(&self) -> &NetworkSession; + /// Register a custom protocol to the web context. fn register_uri_scheme(&mut self, name: &str, handler: F) -> crate::Result<()> where @@ -122,7 +124,7 @@ pub trait WebContextExt { /// If the context allows automation. /// - /// **Note:** `libwebkit2gtk` only allows 1 automation context at a time. + /// **Note:** `libwebkitgtk` only allows 1 automation context at a time. fn allows_automation(&self) -> bool; fn register_automation(&mut self, webview: WebView); @@ -139,6 +141,10 @@ impl WebContextExt for super::WebContext { &self.os.context } + fn network_session(&self) -> &NetworkSession { + &self.os.network_session + } + fn register_uri_scheme(&mut self, name: &str, handler: F) -> crate::Result<()> where F: Fn(crate::WebViewId, Request>, RequestAsyncResponder) + 'static, @@ -308,12 +314,12 @@ impl WebContextExt for super::WebContext { download_started_handler: Option bool>>, download_completed_handler: Option, bool) + 'static>>, ) { - let context = &self.os.context; + let network_session = &self.os.network_session; let download_started_handler = RefCell::new(download_started_handler); let failed = Rc::new(RefCell::new(false)); - context.connect_download_started(move |_context, download| { + network_session.connect_download_started(move |_network_session, download| { if let Some(uri) = download.request().and_then(|req| req.uri()) { let uri = uri.to_string(); let mut download_location = download @@ -379,7 +385,7 @@ struct WebviewUriRequest { headers: Option, } -/// Prevents an unknown concurrency bug with loading multiple URIs at the same time on webkit2gtk. +/// Prevents an unknown concurrency bug with loading multiple URIs at the same time on webkitgtk. /// /// Using the queue prevents data race issues with loading uris for multiple [`WebView`]s in the /// same context at the same time. Occasionally, the one of the [`WebView`]s will be clobbered @@ -404,7 +410,7 @@ struct WebviewUriRequest { /// because it was triggered twice even through only started once. The content injected will not /// be sequential, and often is interjected in the middle of one of the other contents. /// -/// FIXME: We think this may be an underlying concurrency bug in webkit2gtk as the usual ways of +/// FIXME: We think this may be an underlying concurrency bug in webkitgtk as the usual ways of /// fixing threading issues are not working. Ideally, the locks are not needed if we can understand /// the true cause of the bug. #[derive(Debug, Default)] @@ -458,7 +464,7 @@ impl WebViewUriLoader { }); if let Some(headers) = headers { - let req = URIRequest::builder().uri(&uri).build(); + let req = URIRequest::new(&uri); if let Some(ref mut req_headers) = req.http_headers() { for (header, value) in headers.iter() {