From f6146220e4519e1adadda5c7d0fa7504af0d62e1 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 18 Jul 2024 18:00:23 +0800 Subject: [PATCH] Add WebView (#2) - https://github.com/huacnlee/zed/pull/6 - https://github.com/zed-industries/zed/pull/13730 --- Cargo.lock | 710 +++++++++++++++++++++++++++--- Cargo.toml | 3 +- assets/icons/arrow-left.svg | 4 + assets/icons/arrow-right.svg | 4 + assets/icons/chevron-left.svg | 3 + assets/icons/chevron-right.svg | 3 + crates/app/src/story_workspace.rs | 28 +- crates/story/Cargo.toml | 4 + crates/story/src/lib.rs | 12 +- crates/story/src/webview_story.rs | 105 +++++ crates/ui/Cargo.toml | 8 +- crates/ui/src/icon.rs | 8 + crates/ui/src/lib.rs | 2 + crates/ui/src/webview.rs | 187 ++++++++ 14 files changed, 998 insertions(+), 83 deletions(-) create mode 100644 assets/icons/arrow-left.svg create mode 100644 assets/icons/arrow-right.svg create mode 100644 assets/icons/chevron-left.svg create mode 100644 assets/icons/chevron-right.svg create mode 100644 crates/story/src/webview_story.rs create mode 100644 crates/ui/src/webview.rs diff --git a/Cargo.lock b/Cargo.lock index e5809bc7..e4db30a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,22 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ab_glyph" +version = "0.2.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + [[package]] name = "adler" version = "1.0.2" @@ -28,6 +44,7 @@ checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "const-random", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -54,6 +71,33 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk 0.9.0", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum 0.7.2", + "thiserror", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "anyhow" version = "1.0.86" @@ -117,8 +161,9 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.9.0" -source = "git+https://github.com/bilelmoussaoui/ashpd?rev=29f2e1a#29f2e1a6f4b0911f504658f5f4630c02e01b13f2" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe7e0dd0ac5a401dc116ed9f9119cf9decc625600474cb41f0fc0a0050abc9a" dependencies = [ "async-fs 2.1.2", "async-net 2.0.0", @@ -169,9 +214,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ "async-task", "concurrent-queue", @@ -334,9 +379,9 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" dependencies = [ "async-io 2.3.3", "async-lock 3.4.0", @@ -585,6 +630,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + [[package]] name = "blocking" version = "1.6.1" @@ -911,7 +965,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "rustc-hash", ] @@ -1040,7 +1094,7 @@ dependencies = [ "self_cell", "swash", "sys-locale", - "ttf-parser", + "ttf-parser 0.21.1", "unicode-bidi", "unicode-linebreak", "unicode-script", @@ -1192,6 +1246,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + [[package]] name = "data-url" version = "0.3.1" @@ -1224,7 +1284,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "proc-macro2", "quote", @@ -1289,6 +1349,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + [[package]] name = "dlib" version = "0.5.2" @@ -1357,14 +1423,14 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "embed-resource" -version = "2.4.2" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d" +checksum = "4edcacde9351c33139a41e3c97eb2334351a81a2791bebb0b243df837128f602" dependencies = [ "cc", "memchr", "rustc_version", - "toml 0.8.14", + "toml 0.8.15", "vswhom", "winreg", ] @@ -1665,7 +1731,7 @@ dependencies = [ "memmap2", "slotmap", "tinyvec", - "ttf-parser", + "ttf-parser 0.21.1", ] [[package]] @@ -1675,7 +1741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efe23d02309319171d00d794c9ff48d4f903c0e481375b1b04b017470838af04" dependencies = [ "hashbrown 0.14.5", - "ttf-parser", + "ttf-parser 0.21.1", ] [[package]] @@ -2164,7 +2230,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -2207,6 +2273,7 @@ dependencies = [ "num_cpus", "objc", "oo7", + "open", "parking", "parking_lot", "pathfinder_geometry", @@ -2236,8 +2303,8 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-cursor", - "wayland-protocols", - "wayland-protocols-plasma", + "wayland-protocols 0.31.2", + "wayland-protocols-plasma 0.2.0", "windows", "windows-core", "x11-clipboard", @@ -2262,7 +2329,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "proc-macro2", "quote", @@ -2453,7 +2520,7 @@ dependencies = [ [[package]] name = "http" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "anyhow", "futures", @@ -2528,12 +2595,12 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" dependencies = [ "byteorder-lite", - "thiserror", + "quick-error", ] [[package]] @@ -2609,6 +2676,25 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + [[package]] name = "isahc" version = "1.7.2" @@ -2822,6 +2908,17 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "libredox" version = "0.1.3" @@ -2963,7 +3060,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "anyhow", "bindgen", @@ -3077,12 +3174,27 @@ checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" dependencies = [ "bitflags 1.3.2", "jni-sys", - "ndk-sys", - "num_enum", + "ndk-sys 0.4.1+23.1.7779620", + "num_enum 0.5.11", "raw-window-handle 0.5.2", "thiserror", ] +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum 0.7.2", + "raw-window-handle 0.6.2", + "thiserror", +] + [[package]] name = "ndk-context" version = "0.1.1" @@ -3098,6 +3210,15 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3263,7 +3384,16 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive 0.7.2", ] [[package]] @@ -3278,6 +3408,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.71", +] + [[package]] name = "objc" version = "0.2.7" @@ -3288,6 +3430,209 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -3345,6 +3690,17 @@ dependencies = [ "zvariant", ] +[[package]] +name = "open" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -3363,6 +3719,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "orbclient" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" +dependencies = [ + "libredox 0.0.2", +] + [[package]] name = "ordered-stream" version = "0.2.0" @@ -3379,6 +3744,15 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "owned_ttf_parser" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" +dependencies = [ + "ttf-parser 0.24.0", +] + [[package]] name = "pango" version = "0.18.3" @@ -3428,7 +3802,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.3", "smallvec", "windows-targets 0.52.6", ] @@ -3439,6 +3813,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "pathfinder_geometry" version = "0.5.1" @@ -4034,9 +4414,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ "bitflags 2.6.0", ] @@ -4048,14 +4437,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom 0.2.15", - "libredox", + "libredox 0.1.3", "thiserror", ] [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "derive_refineable", ] @@ -4105,9 +4494,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.44" +version = "0.8.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aee83dc281d5a3200d37b299acd13b81066ea126a7f16f0eae70fc9aed241d9" +checksum = "ade4539f42266ded9e755c605bdddf546242b2c961b03b06a7375260788a0523" dependencies = [ "bytemuck", ] @@ -4205,7 +4594,7 @@ dependencies = [ "bytemuck", "libm", "smallvec", - "ttf-parser", + "ttf-parser 0.21.1", "unicode-bidi-mirroring", "unicode-ccc", "unicode-properties", @@ -4295,6 +4684,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + [[package]] name = "seahash" version = "4.1.0" @@ -4330,7 +4732,7 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "semantic_version" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "anyhow", "serde", @@ -4559,6 +4961,31 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.6.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.34", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols 0.32.3", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + [[package]] name = "smol" version = "1.3.0" @@ -4576,6 +5003,15 @@ dependencies = [ "futures-lite 1.13.0", ] +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + [[package]] name = "snafu" version = "0.8.4" @@ -4685,6 +5121,7 @@ dependencies = [ "serde", "ui", "workspace", + "wry", ] [[package]] @@ -4746,7 +5183,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "arrayvec", "log", @@ -4898,7 +5335,7 @@ dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml 0.8.14", + "toml 0.8.15", "version-compare", ] @@ -4984,18 +5421,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", @@ -5105,14 +5542,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.15", + "toml_edit 0.22.16", ] [[package]] @@ -5159,9 +5596,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.15" +version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ "indexmap 2.2.6", "serde", @@ -5218,6 +5655,12 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" +[[package]] +name = "ttf-parser" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8686b91785aff82828ed725225925b33b4fde44c4bb15876e5f7c832724c420a" + [[package]] name = "typeid" version = "1.0.0" @@ -5246,11 +5689,15 @@ name = "ui" version = "0.1.0" dependencies = [ "anyhow", + "cocoa", "gpui", "image", "log", + "objc", + "objc_id", "once_cell", "paste", + "raw-window-handle 0.6.2", "resvg", "serde", "serde_json", @@ -5259,6 +5706,7 @@ dependencies = [ "unicode-segmentation", "usvg", "windows", + "winit", "wry", ] @@ -5383,7 +5831,7 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed.git#315692d1126659e7f6fe0b377f28843a132d2005" +source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#4df6491cd8ffea43bd1d0258a02a209224869b61" dependencies = [ "anyhow", "async-fs 1.6.0", @@ -5552,6 +6000,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.92" @@ -5583,9 +6043,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wayland-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269c04f203640d0da2092d1b8d89a2d081714ae3ac2f1b53e99f205740517198" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" dependencies = [ "cc", "downcast-rs", @@ -5597,9 +6057,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.4" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bd0f46c069d3382a36c8666c1b9ccef32b8b04f41667ca1fef06a1adcc2982" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" dependencies = [ "bitflags 2.6.0", "rustix 0.38.34", @@ -5608,10 +6068,21 @@ dependencies = [ ] [[package]] -name = "wayland-cursor" -version = "0.31.4" +name = "wayland-csd-frame" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09414bcf0fd8d9577d73e9ac4659ebc45bcc9cff1980a350543ad8e50ee263b2" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" dependencies = [ "rustix 0.38.34", "wayland-client", @@ -5630,6 +6101,18 @@ dependencies = [ "wayland-scanner", ] +[[package]] +name = "wayland-protocols" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + [[package]] name = "wayland-protocols-plasma" version = "0.2.0" @@ -5639,15 +6122,41 @@ dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols", + "wayland-protocols 0.31.2", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.3", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.3", "wayland-scanner", ] [[package]] name = "wayland-scanner" -version = "0.31.3" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edf466fc49a4feb65a511ca403fec3601494d0dee85dbf37fff6fa0dd4eec3b6" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" dependencies = [ "proc-macro2", "quick-xml", @@ -5656,9 +6165,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.3" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6754825230fa5b27bafaa28c30b3c9e72c55530581220cef401fa422c0fae7" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" dependencies = [ "dlib", "log", @@ -5676,6 +6185,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webkit2gtk" version = "2.0.1" @@ -6072,6 +6591,58 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winit" +version = "0.30.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.6.0", + "block2", + "bytemuck", + "calloop", + "cfg_aliases 0.2.1", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk 0.9.0", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle 0.6.2", + "redox_syscall 0.4.1", + "rustix 0.38.34", + "sctk-adwaita", + "smithay-client-toolkit", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.3", + "wayland-protocols-plasma 0.3.3", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.5.40" @@ -6145,9 +6716,9 @@ dependencies = [ "jni", "kuchikiki", "libc", - "ndk", + "ndk 0.7.0", "ndk-context", - "ndk-sys", + "ndk-sys 0.4.1+23.1.7779620", "objc", "objc_id", "once_cell", @@ -6206,6 +6777,8 @@ dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", + "libloading", + "once_cell", "rustix 0.38.34", "x11rb-protocol", ] @@ -6264,7 +6837,7 @@ dependencies = [ [[package]] name = "xkbcommon" version = "0.7.0" -source = "git+https://github.com/ConradIrwin/xkbcommon-rs?rev=2d4c4439160c7846ede0f0ece93bf73b1e613339#2d4c4439160c7846ede0f0ece93bf73b1e613339" +source = "git+https://github.com/ConradIrwin/xkbcommon-rs?rev=fcbb4612185cc129ceeff51d22f7fb51810a03b2#fcbb4612185cc129ceeff51d22f7fb51810a03b2" dependencies = [ "as-raw-xcb-connection", "libc", @@ -6272,6 +6845,19 @@ dependencies = [ "xkeysym", ] +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.6.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + [[package]] name = "xkeysym" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 03e377b3..fb6749a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,7 @@ default-members = ["crates/app"] resolver = "2" [workspace.dependencies] -# gpui = { path = "/Users/jason/github/zed/crates/gpui" } -gpui = { git = "https://github.com/zed-industries/zed.git" } +gpui = { git = "https://github.com/huacnlee/zed.git", branch = "export-platform-window" } ui = { path = "crates/ui" } story = { path = "crates/story" } workspace = { path = "crates/workspace" } diff --git a/assets/icons/arrow-left.svg b/assets/icons/arrow-left.svg new file mode 100644 index 00000000..ed034950 --- /dev/null +++ b/assets/icons/arrow-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/assets/icons/arrow-right.svg b/assets/icons/arrow-right.svg new file mode 100644 index 00000000..519fffdc --- /dev/null +++ b/assets/icons/arrow-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/assets/icons/chevron-left.svg b/assets/icons/chevron-left.svg new file mode 100644 index 00000000..f27e97cd --- /dev/null +++ b/assets/icons/chevron-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/icons/chevron-right.svg b/assets/icons/chevron-right.svg new file mode 100644 index 00000000..c1b76ee4 --- /dev/null +++ b/assets/icons/chevron-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/crates/app/src/story_workspace.rs b/crates/app/src/story_workspace.rs index eb98f36d..7c583a25 100644 --- a/crates/app/src/story_workspace.rs +++ b/crates/app/src/story_workspace.rs @@ -3,7 +3,7 @@ use prelude::FluentBuilder as _; use story::{ ButtonStory, CheckboxStory, DropdownStory, ImageStory, InputStory, ListStory, PickerStory, PopoverStory, ProgressStory, ResizableStory, ScrollableStory, StoryContainer, SwitchStory, - TableStory, TooltipStory, + TableStory, TooltipStory, WebViewStory, }; use workspace::{dock::DockPosition, TitleBar, Workspace}; @@ -50,21 +50,23 @@ impl StoryWorkspace { ) .detach(); - StoryContainer::add_panel( + StoryContainer::add_pane( + "Input", + "A control that allows the user to input text.", InputStory::view(cx).into(), workspace.clone(), - DockPosition::Right, - px(350.0), cx, - ); + ) + .detach(); - StoryContainer::add_panel( + StoryContainer::add_pane( + "Checkbox", + "A control that allows the user to toggle between checked and not checked.", CheckboxStory::view(cx).into(), workspace.clone(), - DockPosition::Bottom, - px(200.), cx, - ); + ) + .detach(); StoryContainer::add_pane( "Switch", @@ -128,6 +130,14 @@ impl StoryWorkspace { ) .detach(); + StoryContainer::add_panel( + WebViewStory::view(cx).into(), + workspace.clone(), + DockPosition::Right, + px(450.), + cx, + ); + StoryContainer::add_pane( "Table", "Powerful table and datagrids built.", diff --git a/crates/story/Cargo.toml b/crates/story/Cargo.toml index 5ad844ef..f464312e 100644 --- a/crates/story/Cargo.toml +++ b/crates/story/Cargo.toml @@ -12,3 +12,7 @@ anyhow = "1" workspace.workspace = true charts-rs = "0.3" image = "0.25.1" +wry = "0" + +[lints] +workspace = true diff --git a/crates/story/src/lib.rs b/crates/story/src/lib.rs index 3895c42e..d248f1ec 100644 --- a/crates/story/src/lib.rs +++ b/crates/story/src/lib.rs @@ -12,6 +12,7 @@ mod scrollable_story; mod switch_story; mod table_story; mod tooltip_story; +mod webview_story; pub use button_story::ButtonStory; pub use checkbox_story::CheckboxStory; @@ -27,6 +28,7 @@ pub use scrollable_story::ScrollableStory; pub use switch_story::SwitchStory; pub use table_story::TableStory; pub use tooltip_story::TooltipStory; +pub use webview_story::WebViewStory; use gpui::{ div, prelude::FluentBuilder as _, px, AnyElement, AnyView, AppContext, Div, EventEmitter, @@ -46,14 +48,6 @@ pub fn init(cx: &mut AppContext) { input_story::init(cx); } -pub fn story_case( - name: &'static str, - description: &'static str, - cx: &mut WindowContext, -) -> StoryContainer { - StoryContainer::new(name, description, cx) -} - pub fn section(title: impl Into, cx: &WindowContext) -> Div { use ui::theme::ActiveTheme; let theme = cx.theme(); @@ -104,7 +98,7 @@ impl Item for StoryContainer { Label::new(self.name.clone()).into_any_element() } - fn deactivated(&mut self, _: &mut ViewContext) { + fn deactivated(&mut self, _cx: &mut ViewContext) { self.active = false; } diff --git a/crates/story/src/webview_story.rs b/crates/story/src/webview_story.rs new file mode 100644 index 00000000..407bef55 --- /dev/null +++ b/crates/story/src/webview_story.rs @@ -0,0 +1,105 @@ +use gpui::{ + div, ClickEvent, FocusHandle, FocusableView, ParentElement as _, Render, Styled as _, View, + ViewContext, VisualContext as _, WindowContext, +}; +use ui::{ + button::Button, + h_flex, + input::{TextEvent, TextInput}, + theme::ActiveTheme, + v_flex, + webview::WebView, + Clickable, IconName, +}; + +pub struct WebViewStory { + focus_handle: FocusHandle, + webview: View, + address_input: View, +} + +impl WebViewStory { + pub fn view(cx: &mut WindowContext) -> View { + let focus_handle = cx.focus_handle(); + + let webview = cx.new_view(|cx| WebView::new(cx)); + + let address_input = cx.new_view(|cx| { + let mut input = TextInput::new(cx); + input.set_text("https://github.com/explore", cx); + input + }); + + let url = address_input.read(cx).text(); + webview.update(cx, |view, _| { + view.load_url(&url); + }); + + cx.new_view(|cx| { + let this = WebViewStory { + focus_handle, + webview, + address_input: address_input.clone(), + }; + + cx.subscribe( + &address_input, + |this: &mut Self, input, event: &TextEvent, cx| match event { + TextEvent::PressEnter => { + let url = input.read(cx).text(); + this.webview.update(cx, |view, _| { + view.load_url(&url); + }); + } + _ => {} + }, + ) + .detach(); + + this + }) + } + + pub fn hide(&self, cx: &mut WindowContext) { + self.webview.update(cx, |webview, _| webview.hide()) + } + + fn go_back(&mut self, _: &ClickEvent, cx: &mut ViewContext) { + self.webview.update(cx, |webview, _| { + webview.back().unwrap(); + }); + } +} + +impl FocusableView for WebViewStory { + fn focus_handle(&self, _cx: &gpui::AppContext) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Render for WebViewStory { + fn render(&mut self, cx: &mut gpui::ViewContext) -> impl gpui::IntoElement { + v_flex() + .p_2() + .gap_3() + .size_full() + .child( + h_flex() + .gap_2() + .items_center() + .child( + Button::new("go-back", cx) + .icon(IconName::ArrowLeft) + .on_click(cx.listener(Self::go_back)), + ) + .child(self.address_input.clone()), + ) + .child( + div() + .size_full() + .border_1() + .border_color(cx.theme().border) + .child(self.webview.clone()), + ) + } +} diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index 0ec2a811..37886823 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -14,7 +14,7 @@ anyhow = "1" log = "0.4" serde = "1.0.203" serde_json = "1" -wry = "0" + smallvec = "1.13.2" windows = "0.57.0" unicode-segmentation = "1.11.0" @@ -24,6 +24,12 @@ usvg = { version = "0.41.0", default-features = false } taffy = "0.4.3" paste = "1" once_cell = "1.19.0" +raw-window-handle = "0.6.2" +winit = "0.30.3" +objc = "0.2" +objc_id = "0.1" +cocoa = "0.25" +wry = "0" [lints] workspace = true diff --git a/crates/ui/src/icon.rs b/crates/ui/src/icon.rs index 45794598..1bb563b7 100644 --- a/crates/ui/src/icon.rs +++ b/crates/ui/src/icon.rs @@ -23,6 +23,10 @@ pub enum IconName { CircleX, Loader, LoaderCircle, + ArrowLeft, + ArrowRight, + ChevronLeft, + ChevronRight, } impl IconName { @@ -45,6 +49,10 @@ impl IconName { IconName::CircleX => "icons/circle-x.svg", IconName::Loader => "icons/loader.svg", IconName::LoaderCircle => "icons/loader-circle.svg", + IconName::ArrowLeft => "icons/arrow-left.svg", + IconName::ArrowRight => "icons/arrow-right.svg", + IconName::ChevronLeft => "icons/chevron-left.svg", + IconName::ChevronRight => "icons/chevron-right.svg", } .into() } diff --git a/crates/ui/src/lib.rs b/crates/ui/src/lib.rs index fff16537..bca9d6aa 100644 --- a/crates/ui/src/lib.rs +++ b/crates/ui/src/lib.rs @@ -31,6 +31,7 @@ pub mod tab; pub mod table; pub mod theme; pub mod tooltip; +pub mod webview; pub use clickable::Clickable; pub use disableable::Disableable; @@ -52,4 +53,5 @@ pub fn init(cx: &mut gpui::AppContext) { popover::init(cx); popup_menu::init(cx); table::init(cx); + webview::init(cx) } diff --git a/crates/ui/src/webview.rs b/crates/ui/src/webview.rs new file mode 100644 index 00000000..95facd68 --- /dev/null +++ b/crates/ui/src/webview.rs @@ -0,0 +1,187 @@ +use std::{ops::Deref, rc::Rc}; + +use wry::{ + dpi::{self, LogicalSize}, + Rect, +}; + +use gpui::{ + div, AppContext, Bounds, ContentMask, DismissEvent, Element, ElementId, EventEmitter, + FocusHandle, FocusableView, GlobalElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, + MouseDownEvent, ParentElement as _, Pixels, Render, Size, Style, Styled as _, View, + WindowContext, +}; + +pub fn init(_cx: &AppContext) {} + +pub struct WebView { + focus_handle: FocusHandle, + webview: Rc, + visable: bool, +} + +impl WebView { + pub fn new(cx: &mut WindowContext) -> Self { + let focus_handle = cx.focus_handle(); + let window_handle = cx.raw_window_handle(); + + let webview = wry::WebView::new_as_child(&window_handle) + .expect("failed to create webview to child window"); + let _ = webview.set_bounds(Rect::default()); + + Self { + focus_handle, + visable: true, + webview: Rc::new(webview), + } + } + + pub fn show(&mut self) { + let _ = self.webview.set_visible(true); + } + + pub fn hide(&mut self) { + let _ = self.webview.set_visible(false); + } + + pub fn visible(&self) -> bool { + self.visable + } + + /// Go back in the webview history. + pub fn back(&mut self) -> anyhow::Result<()> { + Ok(self.webview.evaluate_script("history.back();")?) + } + + pub fn load_url(&mut self, url: &str) { + self.webview.load_url(url).unwrap(); + } +} + +impl Deref for WebView { + type Target = wry::WebView; + + fn deref(&self) -> &Self::Target { + &self.webview + } +} + +impl FocusableView for WebView { + fn focus_handle(&self, _cx: &gpui::AppContext) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl EventEmitter for WebView {} + +impl Render for WebView { + fn render(&mut self, cx: &mut gpui::ViewContext) -> impl IntoElement { + let view = cx.view().clone(); + + div() + .track_focus(&self.focus_handle) + .size_full() + .child(WebViewElement::new(self.webview.clone(), view, cx)) + } +} + +/// A webview element can display a wry webview. +pub struct WebViewElement { + parent: View, + view: Rc, +} + +impl WebViewElement { + /// Create a new webview element from a wry WebView. + pub fn new(view: Rc, parent: View, _: &mut WindowContext) -> Self { + Self { view, parent } + } +} + +impl IntoElement for WebViewElement { + type Element = WebViewElement; + + fn into_element(self) -> Self::Element { + self + } +} + +impl Element for WebViewElement { + type RequestLayoutState = (); + type PrepaintState = Option; + + fn id(&self) -> Option { + None + } + + fn request_layout( + &mut self, + _: Option<&GlobalElementId>, + cx: &mut WindowContext, + ) -> (LayoutId, Self::RequestLayoutState) { + let mut style = Style::default(); + style.flex_grow = 0.0; + style.flex_shrink = 1.; + style.size = Size::full(); + // If the parent view is no longer visible, we don't need to layout the webview + + let id = cx.request_layout(style, []); + (id, ()) + } + + fn prepaint( + &mut self, + _: Option<&GlobalElementId>, + bounds: Bounds, + _: &mut Self::RequestLayoutState, + cx: &mut WindowContext, + ) -> Self::PrepaintState { + if !self.parent.read(cx).visible() { + return None; + } + + self.view + .set_bounds(Rect { + size: dpi::Size::Logical(LogicalSize { + width: (bounds.size.width.0).into(), + height: (bounds.size.height.0).into(), + }), + position: dpi::Position::Logical(dpi::LogicalPosition::new( + bounds.origin.x.into(), + bounds.origin.y.into(), + )), + }) + .unwrap(); + + // Create a hitbox to handle mouse event + Some(cx.insert_hitbox(bounds, false)) + } + + fn paint( + &mut self, + _: Option<&GlobalElementId>, + bounds: Bounds, + _: &mut Self::RequestLayoutState, + hitbox: &mut Self::PrepaintState, + cx: &mut WindowContext, + ) { + let bounds = hitbox.clone().map(|h| h.bounds).unwrap_or(bounds); + cx.with_content_mask(Some(ContentMask { bounds }), |cx| { + let webview = self.view.clone(); + cx.on_mouse_event(move |event: &MouseDownEvent, _, cx| { + if !bounds.contains(&event.position) { + // Click white space to blur the input focus + webview + .evaluate_script( + r#" + document.querySelectorAll("input,textarea").forEach(input => input.blur()); + "#, + ) + .expect("failed to evaluate_script to blur input"); + } else { + cx.blur(); + } + }); + }); + } +}