From 50cefb3f0d63df293440bc38cdc9081e0ae0d304 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Fri, 4 Sep 2026 23:54:13 -0400 Subject: [PATCH 01/24] fix(gpui): align the Kit with the published web IME repair --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 14 +++++++------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f05194594..f176379407 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1388,7 +1388,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "gpui_util", "indexmap", @@ -2086,7 +2086,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "proc-macro2", "quote", @@ -3376,7 +3376,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "accesskit", "anyhow", @@ -3728,7 +3728,7 @@ dependencies = [ [[package]] name = "gpui_apple" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "block", @@ -3751,7 +3751,7 @@ dependencies = [ [[package]] name = "gpui_linux" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "accesskit", "accesskit_unix", @@ -3797,7 +3797,7 @@ dependencies = [ [[package]] name = "gpui_macos" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "accesskit", "accesskit_macos", @@ -3843,7 +3843,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "gpui_platform" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "console_error_panic_hook", "gpui", @@ -3867,7 +3867,7 @@ dependencies = [ [[package]] name = "gpui_shared_string" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "schemars", "serde", @@ -3877,7 +3877,7 @@ dependencies = [ [[package]] name = "gpui_util" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "log", @@ -3887,7 +3887,7 @@ dependencies = [ [[package]] name = "gpui_web" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "async-channel", @@ -3912,7 +3912,7 @@ dependencies = [ [[package]] name = "gpui_wgpu" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "bytemuck", @@ -3938,7 +3938,7 @@ dependencies = [ [[package]] name = "gpui_windows" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "accesskit", "accesskit_windows", @@ -4300,7 +4300,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "async-compression", @@ -4320,7 +4320,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "log", "rustls", @@ -5676,7 +5676,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "bindgen", @@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "collections", "serde", @@ -7828,7 +7828,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "derive_refineable", ] @@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "bytes", @@ -8398,7 +8398,7 @@ dependencies = [ [[package]] name = "scheduler" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "async-task", "backtrace", @@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "heapless", "log", @@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "perf", "quote", @@ -12639,7 +12639,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "anyhow", "chrono", @@ -12684,7 +12684,7 @@ dependencies = [ [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" dependencies = [ "tracing", "tracing-subscriber", @@ -12695,7 +12695,7 @@ dependencies = [ [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" [[package]] name = "zune-core" diff --git a/Cargo.toml b/Cargo.toml index 527d355a3a..922d40aa22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } story = { path = "crates/story" } -gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } -gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } -gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } -gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } -reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } -sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } +gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ "charset", "http2", @@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] [workspace.metadata.theorem-fork] upstream = "https://github.com/longbridge/gpui-kit" upstream_tag = "v0.6.0" -zed_rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" +zed_rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" From 30705bd9bea6c09681bade6e0d64f95b7a96144a Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Fri, 4 Sep 2026 23:54:14 -0400 Subject: [PATCH 02/24] chore(gpui): record the web integration pin in the ordered series --- .../0012-gpui-web-ime-integration-pin.patch | 271 ++++++++++++++++++ patches/README.md | 4 + patches/series | 1 + 3 files changed, 276 insertions(+) create mode 100644 patches/0012-gpui-web-ime-integration-pin.patch diff --git a/patches/0012-gpui-web-ime-integration-pin.patch b/patches/0012-gpui-web-ime-integration-pin.patch new file mode 100644 index 0000000000..fa355c578e --- /dev/null +++ b/patches/0012-gpui-web-ime-integration-pin.patch @@ -0,0 +1,271 @@ +From 50cefb3f0d63df293440bc38cdc9081e0ae0d304 Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Fri, 4 Sep 2026 23:54:13 -0400 +Subject: [PATCH] fix(gpui): align the Kit with the published web IME repair + +--- + Cargo.lock | 50 +++++++++++++++++++++++++------------------------- + Cargo.toml | 14 +++++++------- + 2 files changed, 32 insertions(+), 32 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index 6f051945..f1763794 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -1388,7 +1388,7 @@ dependencies = [ + [[package]] + name = "collections" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "gpui_util", + "indexmap", +@@ -2086,7 +2086,7 @@ dependencies = [ + [[package]] + name = "derive_refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "proc-macro2", + "quote", +@@ -3376,7 +3376,7 @@ dependencies = [ + [[package]] + name = "gpui" + version = "0.2.2" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "accesskit", + "anyhow", +@@ -3728,7 +3728,7 @@ dependencies = [ + [[package]] + name = "gpui_apple" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "block", +@@ -3751,7 +3751,7 @@ dependencies = [ + [[package]] + name = "gpui_linux" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "accesskit", + "accesskit_unix", +@@ -3797,7 +3797,7 @@ dependencies = [ + [[package]] + name = "gpui_macos" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "accesskit", + "accesskit_macos", +@@ -3843,7 +3843,7 @@ dependencies = [ + [[package]] + name = "gpui_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "heck 0.5.0", + "proc-macro2", +@@ -3854,7 +3854,7 @@ dependencies = [ + [[package]] + name = "gpui_platform" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "console_error_panic_hook", + "gpui", +@@ -3867,7 +3867,7 @@ dependencies = [ + [[package]] + name = "gpui_shared_string" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "schemars", + "serde", +@@ -3877,7 +3877,7 @@ dependencies = [ + [[package]] + name = "gpui_util" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "log", +@@ -3887,7 +3887,7 @@ dependencies = [ + [[package]] + name = "gpui_web" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "async-channel", +@@ -3912,7 +3912,7 @@ dependencies = [ + [[package]] + name = "gpui_wgpu" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "bytemuck", +@@ -3938,7 +3938,7 @@ dependencies = [ + [[package]] + name = "gpui_windows" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "accesskit", + "accesskit_windows", +@@ -4300,7 +4300,7 @@ dependencies = [ + [[package]] + name = "http_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "async-compression", +@@ -4320,7 +4320,7 @@ dependencies = [ + [[package]] + name = "http_client_tls" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "log", + "rustls", +@@ -5676,7 +5676,7 @@ dependencies = [ + [[package]] + name = "media" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "bindgen", +@@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] + name = "perf" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "collections", + "serde", +@@ -7828,7 +7828,7 @@ dependencies = [ + [[package]] + name = "refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "derive_refineable", + ] +@@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + [[package]] + name = "reqwest_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "bytes", +@@ -8398,7 +8398,7 @@ dependencies = [ + [[package]] + name = "scheduler" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "async-task", + "backtrace", +@@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] + name = "sum_tree" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "heapless", + "log", +@@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] + name = "util_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "perf", + "quote", +@@ -12639,7 +12639,7 @@ dependencies = [ + [[package]] + name = "zlog" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "anyhow", + "chrono", +@@ -12684,7 +12684,7 @@ dependencies = [ + [[package]] + name = "ztracing" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + dependencies = [ + "tracing", + "tracing-subscriber", +@@ -12695,7 +12695,7 @@ dependencies = [ + [[package]] + name = "ztracing_macro" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=0a3e29a42a1646cb9f50df076e2aa6c9fda85868#0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" + + [[package]] + name = "zune-core" +diff --git a/Cargo.toml b/Cargo.toml +index 527d355a..922d40aa 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } + gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } + story = { path = "crates/story" } + +-gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } +-gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +-gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } +-gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } +-reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } +-sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" } ++gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } ++gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } ++gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } ++gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } ++reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } ++sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } + reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ + "charset", + "http2", +@@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] + [workspace.metadata.theorem-fork] + upstream = "https://github.com/longbridge/gpui-kit" + upstream_tag = "v0.6.0" +-zed_rev = "0a3e29a42a1646cb9f50df076e2aa6c9fda85868" ++zed_rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 815515b0fb..517c08f1cb 100644 --- a/patches/README.md +++ b/patches/README.md @@ -28,3 +28,7 @@ used by Rust 1.90. The third replaces post-1.90 standard-library profiling and UTF-8 boundary helpers with equivalent local implementations. The final patch uses the stable atomic update primitive for text-selection scope allocation, then advances the Zed pin to include action-profiler compatibility as well. + +The web integration pin selects the published textarea IME/accessibility repair +and its corrected workspace lock edge. Every GPUI family dependency continues +to resolve from the same immutable Theorem Zed revision. diff --git a/patches/series b/patches/series index 425180c6c6..8de318f07a 100644 --- a/patches/series +++ b/patches/series @@ -9,3 +9,4 @@ 0009-rust-1.90-atomics.patch 0010-rust-1.90-final-zed-pin.patch 0011-feat-settings-add-controlled-navigation-state.patch +0012-gpui-web-ime-integration-pin.patch From 83e668cdea5c095a917d762752dc8f261c5f4a99 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 00:04:00 -0400 Subject: [PATCH 03/24] fix(gpui): carry the compatible Linux portal dependency with the web pin --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 14 +++++++------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f176379407..60b1ebd05e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1388,7 +1388,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "gpui_util", "indexmap", @@ -2086,7 +2086,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "proc-macro2", "quote", @@ -3376,7 +3376,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "accesskit", "anyhow", @@ -3728,7 +3728,7 @@ dependencies = [ [[package]] name = "gpui_apple" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "block", @@ -3751,7 +3751,7 @@ dependencies = [ [[package]] name = "gpui_linux" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "accesskit", "accesskit_unix", @@ -3797,7 +3797,7 @@ dependencies = [ [[package]] name = "gpui_macos" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "accesskit", "accesskit_macos", @@ -3843,7 +3843,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "gpui_platform" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "console_error_panic_hook", "gpui", @@ -3867,7 +3867,7 @@ dependencies = [ [[package]] name = "gpui_shared_string" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "schemars", "serde", @@ -3877,7 +3877,7 @@ dependencies = [ [[package]] name = "gpui_util" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "log", @@ -3887,7 +3887,7 @@ dependencies = [ [[package]] name = "gpui_web" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "async-channel", @@ -3912,7 +3912,7 @@ dependencies = [ [[package]] name = "gpui_wgpu" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "bytemuck", @@ -3938,7 +3938,7 @@ dependencies = [ [[package]] name = "gpui_windows" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "accesskit", "accesskit_windows", @@ -4300,7 +4300,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "async-compression", @@ -4320,7 +4320,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "log", "rustls", @@ -5676,7 +5676,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "bindgen", @@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "collections", "serde", @@ -7828,7 +7828,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "derive_refineable", ] @@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "bytes", @@ -8398,7 +8398,7 @@ dependencies = [ [[package]] name = "scheduler" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "async-task", "backtrace", @@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "heapless", "log", @@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "perf", "quote", @@ -12639,7 +12639,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "anyhow", "chrono", @@ -12684,7 +12684,7 @@ dependencies = [ [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" dependencies = [ "tracing", "tracing-subscriber", @@ -12695,7 +12695,7 @@ dependencies = [ [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" +source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" [[package]] name = "zune-core" diff --git a/Cargo.toml b/Cargo.toml index 922d40aa22..7ea05b4ea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } story = { path = "crates/story" } -gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } -gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } -gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } -gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } -reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } -sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ "charset", "http2", @@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] [workspace.metadata.theorem-fork] upstream = "https://github.com/longbridge/gpui-kit" upstream_tag = "v0.6.0" -zed_rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" +zed_rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" From 9d4173c8eafcaa9474c3e1bc0f0ded166547f3ea Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 00:04:00 -0400 Subject: [PATCH 04/24] chore(gpui): record the Linux portal pin follow-up --- ...013-gpui-linux-portal-compatible-pin.patch | 272 ++++++++++++++++++ patches/README.md | 3 + patches/series | 1 + 3 files changed, 276 insertions(+) create mode 100644 patches/0013-gpui-linux-portal-compatible-pin.patch diff --git a/patches/0013-gpui-linux-portal-compatible-pin.patch b/patches/0013-gpui-linux-portal-compatible-pin.patch new file mode 100644 index 0000000000..707659aeb4 --- /dev/null +++ b/patches/0013-gpui-linux-portal-compatible-pin.patch @@ -0,0 +1,272 @@ +From 83e668cdea5c095a917d762752dc8f261c5f4a99 Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Sat, 5 Sep 2026 00:04:00 -0400 +Subject: [PATCH] fix(gpui): carry the compatible Linux portal dependency with + the web pin + +--- + Cargo.lock | 50 +++++++++++++++++++++++++------------------------- + Cargo.toml | 14 +++++++------- + 2 files changed, 32 insertions(+), 32 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index f1763794..60b1ebd0 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -1388,7 +1388,7 @@ dependencies = [ + [[package]] + name = "collections" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "gpui_util", + "indexmap", +@@ -2086,7 +2086,7 @@ dependencies = [ + [[package]] + name = "derive_refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "proc-macro2", + "quote", +@@ -3376,7 +3376,7 @@ dependencies = [ + [[package]] + name = "gpui" + version = "0.2.2" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "accesskit", + "anyhow", +@@ -3728,7 +3728,7 @@ dependencies = [ + [[package]] + name = "gpui_apple" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "block", +@@ -3751,7 +3751,7 @@ dependencies = [ + [[package]] + name = "gpui_linux" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "accesskit", + "accesskit_unix", +@@ -3797,7 +3797,7 @@ dependencies = [ + [[package]] + name = "gpui_macos" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "accesskit", + "accesskit_macos", +@@ -3843,7 +3843,7 @@ dependencies = [ + [[package]] + name = "gpui_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "heck 0.5.0", + "proc-macro2", +@@ -3854,7 +3854,7 @@ dependencies = [ + [[package]] + name = "gpui_platform" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "console_error_panic_hook", + "gpui", +@@ -3867,7 +3867,7 @@ dependencies = [ + [[package]] + name = "gpui_shared_string" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "schemars", + "serde", +@@ -3877,7 +3877,7 @@ dependencies = [ + [[package]] + name = "gpui_util" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "log", +@@ -3887,7 +3887,7 @@ dependencies = [ + [[package]] + name = "gpui_web" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "async-channel", +@@ -3912,7 +3912,7 @@ dependencies = [ + [[package]] + name = "gpui_wgpu" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "bytemuck", +@@ -3938,7 +3938,7 @@ dependencies = [ + [[package]] + name = "gpui_windows" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "accesskit", + "accesskit_windows", +@@ -4300,7 +4300,7 @@ dependencies = [ + [[package]] + name = "http_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "async-compression", +@@ -4320,7 +4320,7 @@ dependencies = [ + [[package]] + name = "http_client_tls" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "log", + "rustls", +@@ -5676,7 +5676,7 @@ dependencies = [ + [[package]] + name = "media" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "bindgen", +@@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] + name = "perf" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "collections", + "serde", +@@ -7828,7 +7828,7 @@ dependencies = [ + [[package]] + name = "refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "derive_refineable", + ] +@@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + [[package]] + name = "reqwest_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "bytes", +@@ -8398,7 +8398,7 @@ dependencies = [ + [[package]] + name = "scheduler" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "async-task", + "backtrace", +@@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] + name = "sum_tree" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "heapless", + "log", +@@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] + name = "util_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "perf", + "quote", +@@ -12639,7 +12639,7 @@ dependencies = [ + [[package]] + name = "zlog" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "anyhow", + "chrono", +@@ -12684,7 +12684,7 @@ dependencies = [ + [[package]] + name = "ztracing" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + dependencies = [ + "tracing", + "tracing-subscriber", +@@ -12695,7 +12695,7 @@ dependencies = [ + [[package]] + name = "ztracing_macro" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=3deff0ede14d47839928be8e2f837ba80d0388fd#3deff0ede14d47839928be8e2f837ba80d0388fd" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" + + [[package]] + name = "zune-core" +diff --git a/Cargo.toml b/Cargo.toml +index 922d40aa..7ea05b4e 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } + gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } + story = { path = "crates/story" } + +-gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +-gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +-gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +-gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +-reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } +-sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" } ++gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } ++gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } ++gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } ++gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } ++reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } ++sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } + reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ + "charset", + "http2", +@@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] + [workspace.metadata.theorem-fork] + upstream = "https://github.com/longbridge/gpui-kit" + upstream_tag = "v0.6.0" +-zed_rev = "3deff0ede14d47839928be8e2f837ba80d0388fd" ++zed_rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 517c08f1cb..7be0577904 100644 --- a/patches/README.md +++ b/patches/README.md @@ -32,3 +32,6 @@ then advances the Zed pin to include action-profiler compatibility as well. The web integration pin selects the published textarea IME/accessibility repair and its corrected workspace lock edge. Every GPUI family dependency continues to resolve from the same immutable Theorem Zed revision. + +The Linux portal follow-up also selects ASHPD 0.13.6 in this consumer lockfile, +matching the fork's Rust 1.90-compatible dependency closure. diff --git a/patches/series b/patches/series index 8de318f07a..fe941fff3b 100644 --- a/patches/series +++ b/patches/series @@ -10,3 +10,4 @@ 0010-rust-1.90-final-zed-pin.patch 0011-feat-settings-add-controlled-navigation-state.patch 0012-gpui-web-ime-integration-pin.patch +0013-gpui-linux-portal-compatible-pin.patch From 455751b3c2a2bb7098e4f2c13b57b490d5ec7021 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 00:04:50 -0400 Subject: [PATCH 05/24] docs(gpui): clarify the retained consumer portal dependency --- patches/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/patches/README.md b/patches/README.md index 7be0577904..13acbba790 100644 --- a/patches/README.md +++ b/patches/README.md @@ -33,5 +33,6 @@ The web integration pin selects the published textarea IME/accessibility repair and its corrected workspace lock edge. Every GPUI family dependency continues to resolve from the same immutable Theorem Zed revision. -The Linux portal follow-up also selects ASHPD 0.13.6 in this consumer lockfile, -matching the fork's Rust 1.90-compatible dependency closure. +The Linux portal follow-up advances the Zed source to its compatible ASHPD +patch. This consumer retains its existing ASHPD 0.13.10 lock entry, which +already declares a Rust 1.87 minimum; no consumer registry dependency changes. From 4f50f50b2d8e7a73cdf9e622aba8a68469af1136 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 01:17:54 -0400 Subject: [PATCH 06/24] fix(gpui): carry the desktop keyboard focus prerequisite --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 14 +++++++------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60b1ebd05e..3b939a04ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1388,7 +1388,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "gpui_util", "indexmap", @@ -2086,7 +2086,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "proc-macro2", "quote", @@ -3376,7 +3376,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "accesskit", "anyhow", @@ -3728,7 +3728,7 @@ dependencies = [ [[package]] name = "gpui_apple" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "block", @@ -3751,7 +3751,7 @@ dependencies = [ [[package]] name = "gpui_linux" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "accesskit", "accesskit_unix", @@ -3797,7 +3797,7 @@ dependencies = [ [[package]] name = "gpui_macos" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "accesskit", "accesskit_macos", @@ -3843,7 +3843,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "gpui_platform" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "console_error_panic_hook", "gpui", @@ -3867,7 +3867,7 @@ dependencies = [ [[package]] name = "gpui_shared_string" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "schemars", "serde", @@ -3877,7 +3877,7 @@ dependencies = [ [[package]] name = "gpui_util" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "log", @@ -3887,7 +3887,7 @@ dependencies = [ [[package]] name = "gpui_web" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "async-channel", @@ -3912,7 +3912,7 @@ dependencies = [ [[package]] name = "gpui_wgpu" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "bytemuck", @@ -3938,7 +3938,7 @@ dependencies = [ [[package]] name = "gpui_windows" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "accesskit", "accesskit_windows", @@ -4300,7 +4300,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "async-compression", @@ -4320,7 +4320,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "log", "rustls", @@ -5676,7 +5676,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "bindgen", @@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "collections", "serde", @@ -7828,7 +7828,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "derive_refineable", ] @@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "bytes", @@ -8398,7 +8398,7 @@ dependencies = [ [[package]] name = "scheduler" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "async-task", "backtrace", @@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "heapless", "log", @@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "perf", "quote", @@ -12639,7 +12639,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "anyhow", "chrono", @@ -12684,7 +12684,7 @@ dependencies = [ [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" dependencies = [ "tracing", "tracing-subscriber", @@ -12695,7 +12695,7 @@ dependencies = [ [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" +source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" [[package]] name = "zune-core" diff --git a/Cargo.toml b/Cargo.toml index 7ea05b4ea8..019f9f91fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } story = { path = "crates/story" } -gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } -gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } -gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } -gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } -reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } -sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ "charset", "http2", @@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] [workspace.metadata.theorem-fork] upstream = "https://github.com/longbridge/gpui-kit" upstream_tag = "v0.6.0" -zed_rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" +zed_rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" From 804b6a29c195f1e626df66278c35322eb32f70a0 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 01:18:10 -0400 Subject: [PATCH 07/24] chore(gpui): record the desktop keyboard focus pin --- ...0014-gpui-desktop-keyboard-focus-pin.patch | 271 ++++++++++++++++++ patches/README.md | 6 + patches/series | 1 + 3 files changed, 278 insertions(+) create mode 100644 patches/0014-gpui-desktop-keyboard-focus-pin.patch diff --git a/patches/0014-gpui-desktop-keyboard-focus-pin.patch b/patches/0014-gpui-desktop-keyboard-focus-pin.patch new file mode 100644 index 0000000000..054de913c5 --- /dev/null +++ b/patches/0014-gpui-desktop-keyboard-focus-pin.patch @@ -0,0 +1,271 @@ +From 4f50f50b2d8e7a73cdf9e622aba8a68469af1136 Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Sat, 5 Sep 2026 01:17:54 -0400 +Subject: [PATCH] fix(gpui): carry the desktop keyboard focus prerequisite + +--- + Cargo.lock | 50 +++++++++++++++++++++++++------------------------- + Cargo.toml | 14 +++++++------- + 2 files changed, 32 insertions(+), 32 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index 60b1ebd0..3b939a04 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -1388,7 +1388,7 @@ dependencies = [ + [[package]] + name = "collections" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "gpui_util", + "indexmap", +@@ -2086,7 +2086,7 @@ dependencies = [ + [[package]] + name = "derive_refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "proc-macro2", + "quote", +@@ -3376,7 +3376,7 @@ dependencies = [ + [[package]] + name = "gpui" + version = "0.2.2" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "accesskit", + "anyhow", +@@ -3728,7 +3728,7 @@ dependencies = [ + [[package]] + name = "gpui_apple" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "block", +@@ -3751,7 +3751,7 @@ dependencies = [ + [[package]] + name = "gpui_linux" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "accesskit", + "accesskit_unix", +@@ -3797,7 +3797,7 @@ dependencies = [ + [[package]] + name = "gpui_macos" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "accesskit", + "accesskit_macos", +@@ -3843,7 +3843,7 @@ dependencies = [ + [[package]] + name = "gpui_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "heck 0.5.0", + "proc-macro2", +@@ -3854,7 +3854,7 @@ dependencies = [ + [[package]] + name = "gpui_platform" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "console_error_panic_hook", + "gpui", +@@ -3867,7 +3867,7 @@ dependencies = [ + [[package]] + name = "gpui_shared_string" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "schemars", + "serde", +@@ -3877,7 +3877,7 @@ dependencies = [ + [[package]] + name = "gpui_util" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "log", +@@ -3887,7 +3887,7 @@ dependencies = [ + [[package]] + name = "gpui_web" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "async-channel", +@@ -3912,7 +3912,7 @@ dependencies = [ + [[package]] + name = "gpui_wgpu" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "bytemuck", +@@ -3938,7 +3938,7 @@ dependencies = [ + [[package]] + name = "gpui_windows" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "accesskit", + "accesskit_windows", +@@ -4300,7 +4300,7 @@ dependencies = [ + [[package]] + name = "http_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "async-compression", +@@ -4320,7 +4320,7 @@ dependencies = [ + [[package]] + name = "http_client_tls" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "log", + "rustls", +@@ -5676,7 +5676,7 @@ dependencies = [ + [[package]] + name = "media" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "bindgen", +@@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] + name = "perf" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "collections", + "serde", +@@ -7828,7 +7828,7 @@ dependencies = [ + [[package]] + name = "refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "derive_refineable", + ] +@@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + [[package]] + name = "reqwest_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "bytes", +@@ -8398,7 +8398,7 @@ dependencies = [ + [[package]] + name = "scheduler" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "async-task", + "backtrace", +@@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] + name = "sum_tree" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "heapless", + "log", +@@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] + name = "util_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "perf", + "quote", +@@ -12639,7 +12639,7 @@ dependencies = [ + [[package]] + name = "zlog" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "anyhow", + "chrono", +@@ -12684,7 +12684,7 @@ dependencies = [ + [[package]] + name = "ztracing" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + dependencies = [ + "tracing", + "tracing-subscriber", +@@ -12695,7 +12695,7 @@ dependencies = [ + [[package]] + name = "ztracing_macro" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=4c2af96e84e1cf66696d3542450db75a6dadb8eb#4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" + + [[package]] + name = "zune-core" +diff --git a/Cargo.toml b/Cargo.toml +index 7ea05b4e..019f9f91 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } + gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } + story = { path = "crates/story" } + +-gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +-gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +-gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +-gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +-reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } +-sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" } ++gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } ++gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } ++gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } ++gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } ++reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } ++sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } + reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ + "charset", + "http2", +@@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] + [workspace.metadata.theorem-fork] + upstream = "https://github.com/longbridge/gpui-kit" + upstream_tag = "v0.6.0" +-zed_rev = "4c2af96e84e1cf66696d3542450db75a6dadb8eb" ++zed_rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 13acbba790..30030873f5 100644 --- a/patches/README.md +++ b/patches/README.md @@ -36,3 +36,9 @@ to resolve from the same immutable Theorem Zed revision. The Linux portal follow-up advances the Zed source to its compatible ASHPD patch. This consumer retains its existing ASHPD 0.13.10 lock entry, which already declares a Rust 1.87 minimum; no consumer registry dependency changes. + +The desktop keyboard-focus follow-up moves only the seven GPUI manifest pins +and 25 lock source revisions to Zed `2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4`. +It retains the registry dependency graph, including ASHPD 0.13.10. The pinned +web window keeps desktop shortcuts on its read-only IME event target after +an editor closes while preserving coarse-pointer keyboard dismissal. diff --git a/patches/series b/patches/series index fe941fff3b..533b785554 100644 --- a/patches/series +++ b/patches/series @@ -11,3 +11,4 @@ 0011-feat-settings-add-controlled-navigation-state.patch 0012-gpui-web-ime-integration-pin.patch 0013-gpui-linux-portal-compatible-pin.patch +0014-gpui-desktop-keyboard-focus-pin.patch From 41d78525001d551124010a5766dd305c55e60e57 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 04:50:34 -0400 Subject: [PATCH 08/24] feat(input): forward platform input configuration --- crates/base/src/input/base/state.rs | 80 ++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/crates/base/src/input/base/state.rs b/crates/base/src/input/base/state.rs index ab5397b347..9a1d831b7f 100644 --- a/crates/base/src/input/base/state.rs +++ b/crates/base/src/input/base/state.rs @@ -2,7 +2,6 @@ //! //! Based on the `Input` example from the `gpui` crate. //! https://github.com/zed-industries/zed/blob/main/crates/gpui/examples/input.rs -use gpui::TextAlign; use gpui::{ Action, App, AppContext, Bounds, ClipboardItem, Context, Edges, Entity, EntityInputHandler, EventEmitter, FocusHandle, Focusable, InteractiveElement as _, IntoElement, KeyBinding, @@ -10,6 +9,7 @@ use gpui::{ Pixels, Point, Render, ScrollHandle, ScrollWheelEvent, SharedString, Styled as _, Subscription, UTF16Selection, Window, actions, div, point, prelude::FluentBuilder as _, px, }; +use gpui::{TextAlign, TextInputConfiguration}; use ropey::{Rope, RopeSlice}; use serde::Deserialize; use std::borrow::Cow; @@ -320,6 +320,7 @@ pub struct InputBaseState { pub(super) masked: bool, pub(super) clean_on_escape: bool, pub(super) submit_on_enter: bool, + text_input_configuration: TextInputConfiguration, pub(super) show_whitespaces: bool, /// This flag tells the renderer to prefer the end of the current visual line. pub(crate) cursor_line_end_affinity: bool, @@ -637,6 +638,7 @@ impl InputBaseState { masked: false, clean_on_escape: false, submit_on_enter: false, + text_input_configuration: TextInputConfiguration::default(), show_whitespaces: false, loading: false, pattern: None, @@ -1036,6 +1038,26 @@ impl InputBaseState { cx.notify(); } + /// Configure the focused platform input session's assistance and action key. + /// This only changes platform presentation; Enter keeps its configured + /// input/submit behavior. Defaults remain GPUI's disabled assistance. + pub fn input_configuration(mut self, configuration: TextInputConfiguration) -> Self { + self.text_input_configuration = configuration; + self + } + + /// Update the active input session without replacing its text or selection. + pub fn set_input_configuration( + &mut self, + configuration: TextInputConfiguration, + cx: &mut Context, + ) { + if self.text_input_configuration != configuration { + self.text_input_configuration = configuration; + cx.notify(); + } + } + /// Set whether to show whitespace characters. #[doc(hidden)] pub fn show_whitespaces(mut self, show: bool) -> Self { @@ -2686,6 +2708,14 @@ impl InputBaseState { } impl EntityInputHandler for InputBaseState { + fn text_input_configuration( + &mut self, + _window: &mut Window, + _cx: &mut Context, + ) -> TextInputConfiguration { + self.text_input_configuration.clone() + } + fn text_for_range( &mut self, range_utf16: Range, @@ -3275,6 +3305,54 @@ mod tests { } } + #[gpui::test] + fn platform_input_configuration_preserves_default_and_forwards_changes( + cx: &mut TestAppContext, + ) { + cx.update(crate::init); + let plain = InputView::build(cx, |state| state); + plain + .window_handle + .update(cx, |_, window, cx| { + plain.input.update(cx, |state, cx| { + assert_eq!( + state.text_input_configuration(window, cx), + TextInputConfiguration::default() + ); + }); + }) + .unwrap(); + let search = InputView::build(cx, |state| { + state.input_configuration(TextInputConfiguration { + input_action: gpui::TextInputAction::Search, + ..Default::default() + }) + }); + search + .window_handle + .update(cx, |_, window, cx| { + search.input.update(cx, |state, cx| { + assert_eq!( + state.text_input_configuration(window, cx).input_action, + gpui::TextInputAction::Search + ); + state.set_value("retained draft", window, cx); + state.set_selected_range(2..5, cx); + let changed = TextInputConfiguration { + input_action: gpui::TextInputAction::Send, + autocorrect: true, + suggestions: true, + autocapitalize: gpui::Autocapitalize::Sentences, + }; + state.set_input_configuration(changed.clone(), cx); + assert_eq!(state.text_input_configuration(window, cx), changed); + assert_eq!(state.text().to_string(), "retained draft"); + assert_eq!(state.selected_range(), 2..5); + }); + }) + .unwrap(); + } + #[gpui::test] fn only_a_multi_line_input_paints_scrollbars(cx: &mut TestAppContext) { cx.update(crate::init); From 1636a905607a4130760a0b3225331b34986c40f1 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 04:50:34 -0400 Subject: [PATCH 09/24] chore(patches): record input configuration prerequisite --- .../0015-platform-input-configuration.patch | 145 ++++++++++++++++++ patches/README.md | 14 ++ patches/series | 1 + 3 files changed, 160 insertions(+) create mode 100644 patches/0015-platform-input-configuration.patch diff --git a/patches/0015-platform-input-configuration.patch b/patches/0015-platform-input-configuration.patch new file mode 100644 index 0000000000..a5de8ddfe4 --- /dev/null +++ b/patches/0015-platform-input-configuration.patch @@ -0,0 +1,145 @@ +From 41d78525001d551124010a5766dd305c55e60e57 Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Sat, 5 Sep 2026 04:50:34 -0400 +Subject: [PATCH] feat(input): forward platform input configuration + +--- + crates/base/src/input/base/state.rs | 80 ++++++++++++++++++++++++++++- + 1 file changed, 79 insertions(+), 1 deletion(-) + +diff --git a/crates/base/src/input/base/state.rs b/crates/base/src/input/base/state.rs +index ab5397b3..9a1d831b 100644 +--- a/crates/base/src/input/base/state.rs ++++ b/crates/base/src/input/base/state.rs +@@ -2,7 +2,6 @@ + //! + //! Based on the `Input` example from the `gpui` crate. + //! https://github.com/zed-industries/zed/blob/main/crates/gpui/examples/input.rs +-use gpui::TextAlign; + use gpui::{ + Action, App, AppContext, Bounds, ClipboardItem, Context, Edges, Entity, EntityInputHandler, + EventEmitter, FocusHandle, Focusable, InteractiveElement as _, IntoElement, KeyBinding, +@@ -10,6 +9,7 @@ use gpui::{ + Pixels, Point, Render, ScrollHandle, ScrollWheelEvent, SharedString, Styled as _, Subscription, + UTF16Selection, Window, actions, div, point, prelude::FluentBuilder as _, px, + }; ++use gpui::{TextAlign, TextInputConfiguration}; + use ropey::{Rope, RopeSlice}; + use serde::Deserialize; + use std::borrow::Cow; +@@ -320,6 +320,7 @@ pub struct InputBaseState { + pub(super) masked: bool, + pub(super) clean_on_escape: bool, + pub(super) submit_on_enter: bool, ++ text_input_configuration: TextInputConfiguration, + pub(super) show_whitespaces: bool, + /// This flag tells the renderer to prefer the end of the current visual line. + pub(crate) cursor_line_end_affinity: bool, +@@ -637,6 +638,7 @@ impl InputBaseState { + masked: false, + clean_on_escape: false, + submit_on_enter: false, ++ text_input_configuration: TextInputConfiguration::default(), + show_whitespaces: false, + loading: false, + pattern: None, +@@ -1036,6 +1038,26 @@ impl InputBaseState { + cx.notify(); + } + ++ /// Configure the focused platform input session's assistance and action key. ++ /// This only changes platform presentation; Enter keeps its configured ++ /// input/submit behavior. Defaults remain GPUI's disabled assistance. ++ pub fn input_configuration(mut self, configuration: TextInputConfiguration) -> Self { ++ self.text_input_configuration = configuration; ++ self ++ } ++ ++ /// Update the active input session without replacing its text or selection. ++ pub fn set_input_configuration( ++ &mut self, ++ configuration: TextInputConfiguration, ++ cx: &mut Context, ++ ) { ++ if self.text_input_configuration != configuration { ++ self.text_input_configuration = configuration; ++ cx.notify(); ++ } ++ } ++ + /// Set whether to show whitespace characters. + #[doc(hidden)] + pub fn show_whitespaces(mut self, show: bool) -> Self { +@@ -2686,6 +2708,14 @@ impl InputBaseState { + } + + impl EntityInputHandler for InputBaseState { ++ fn text_input_configuration( ++ &mut self, ++ _window: &mut Window, ++ _cx: &mut Context, ++ ) -> TextInputConfiguration { ++ self.text_input_configuration.clone() ++ } ++ + fn text_for_range( + &mut self, + range_utf16: Range, +@@ -3275,6 +3305,54 @@ mod tests { + } + } + ++ #[gpui::test] ++ fn platform_input_configuration_preserves_default_and_forwards_changes( ++ cx: &mut TestAppContext, ++ ) { ++ cx.update(crate::init); ++ let plain = InputView::build(cx, |state| state); ++ plain ++ .window_handle ++ .update(cx, |_, window, cx| { ++ plain.input.update(cx, |state, cx| { ++ assert_eq!( ++ state.text_input_configuration(window, cx), ++ TextInputConfiguration::default() ++ ); ++ }); ++ }) ++ .unwrap(); ++ let search = InputView::build(cx, |state| { ++ state.input_configuration(TextInputConfiguration { ++ input_action: gpui::TextInputAction::Search, ++ ..Default::default() ++ }) ++ }); ++ search ++ .window_handle ++ .update(cx, |_, window, cx| { ++ search.input.update(cx, |state, cx| { ++ assert_eq!( ++ state.text_input_configuration(window, cx).input_action, ++ gpui::TextInputAction::Search ++ ); ++ state.set_value("retained draft", window, cx); ++ state.set_selected_range(2..5, cx); ++ let changed = TextInputConfiguration { ++ input_action: gpui::TextInputAction::Send, ++ autocorrect: true, ++ suggestions: true, ++ autocapitalize: gpui::Autocapitalize::Sentences, ++ }; ++ state.set_input_configuration(changed.clone(), cx); ++ assert_eq!(state.text_input_configuration(window, cx), changed); ++ assert_eq!(state.text().to_string(), "retained draft"); ++ assert_eq!(state.selected_range(), 2..5); ++ }); ++ }) ++ .unwrap(); ++ } ++ + #[gpui::test] + fn only_a_multi_line_input_paints_scrollbars(cx: &mut TestAppContext) { + cx.update(crate::init); +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 30030873f5..5839a0e75c 100644 --- a/patches/README.md +++ b/patches/README.md @@ -42,3 +42,17 @@ and 25 lock source revisions to Zed `2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4`. It retains the registry dependency graph, including ASHPD 0.13.10. The pinned web window keeps desktop shortcuts on its read-only IME event target after an editor closes while preserving coarse-pointer keyboard dismissal. + +The platform input configuration patch completes the v0.6.0 API migration: +`InputBaseState::input_configuration` and `set_input_configuration` forward +GPUI's actual `TextInputConfiguration` through `EntityInputHandler`. Defaults +remain unchanged. Search fields can request the existing `Search` action key +without restoring the retired text-input-hints API. Changing configuration +retains text and selection. This is a preceding input prerequisite; the +Theorem DATA conversion does not add a private input fork. + +Validation of this addition: locked Wasm `gpui-base --lib` check passes. The +native `platform_input_configuration_preserves_default_and_forwards_changes` +regression covers default, Search builder, and changed Send/assistance settings; +its execution is pending the coordinated native validation slot. This branch +remains a draft requiring review before merge. diff --git a/patches/series b/patches/series index 533b785554..6f2e5c5f95 100644 --- a/patches/series +++ b/patches/series @@ -12,3 +12,4 @@ 0012-gpui-web-ime-integration-pin.patch 0013-gpui-linux-portal-compatible-pin.patch 0014-gpui-desktop-keyboard-focus-pin.patch +0015-platform-input-configuration.patch From a3292163a868b4c81514e658c1d3c06edfd0927b Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 05:10:49 -0400 Subject: [PATCH 10/24] fix(ci): recognize Git patch hashes and capture package names --- _typos.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/_typos.toml b/_typos.toml index 3e996300cc..e9abe5187a 100644 --- a/_typos.toml +++ b/_typos.toml @@ -1,5 +1,11 @@ [default] -extend-ignore-re = ['\\u\{[0-9A-Fa-f]+\}'] +extend-ignore-re = [ + '\\u\{[0-9A-Fa-f]+\}', + # Ordered Git patch object IDs are immutable hex, not prose. + '(?m)^index [0-9a-f]+\.\.[0-9a-f]+(?: [0-7]+)?$', + # The exact screen-capture package identifier in the dependency patches. + '\bzed-scap\b', +] [default.extend-words] # Correct Italian singular of "command". From 7947448f41faac737e9a1ed190c0bc468c4ba411 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 05:10:49 -0400 Subject: [PATCH 11/24] chore(patches): record patch spelling metadata repair --- patches/0016-patch-spelling-identifiers.patch | 29 +++++++++++++++++++ patches/README.md | 4 +++ patches/series | 1 + 3 files changed, 34 insertions(+) create mode 100644 patches/0016-patch-spelling-identifiers.patch diff --git a/patches/0016-patch-spelling-identifiers.patch b/patches/0016-patch-spelling-identifiers.patch new file mode 100644 index 0000000000..dcf716ab05 --- /dev/null +++ b/patches/0016-patch-spelling-identifiers.patch @@ -0,0 +1,29 @@ +From a3292163a868b4c81514e658c1d3c06edfd0927b Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Sat, 5 Sep 2026 05:10:49 -0400 +Subject: [PATCH] fix(ci): recognize Git patch hashes and capture package names + +--- + _typos.toml | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/_typos.toml b/_typos.toml +index 3e996300..e9abe518 100644 +--- a/_typos.toml ++++ b/_typos.toml +@@ -1,5 +1,11 @@ + [default] +-extend-ignore-re = ['\\u\{[0-9A-Fa-f]+\}'] ++extend-ignore-re = [ ++ '\\u\{[0-9A-Fa-f]+\}', ++ # Ordered Git patch object IDs are immutable hex, not prose. ++ '(?m)^index [0-9a-f]+\.\.[0-9a-f]+(?: [0-7]+)?$', ++ # The exact screen-capture package identifier in the dependency patches. ++ '\bzed-scap\b', ++] + + [default.extend-words] + # Correct Italian singular of "command". +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 5839a0e75c..495b17ff62 100644 --- a/patches/README.md +++ b/patches/README.md @@ -56,3 +56,7 @@ native `platform_input_configuration_preserves_default_and_forwards_changes` regression covers default, Search builder, and changed Send/assistance settings; its execution is pending the coordinated native validation slot. This branch remains a draft requiring review before merge. + +The spelling follow-up recognizes only complete Git `index` hash lines and +the exact `zed-scap` package identifier inside the ordered patches. It retains +source and prose spelling checks; no application or runtime code changes. diff --git a/patches/series b/patches/series index 6f2e5c5f95..21c6e2601f 100644 --- a/patches/series +++ b/patches/series @@ -13,3 +13,4 @@ 0013-gpui-linux-portal-compatible-pin.patch 0014-gpui-desktop-keyboard-focus-pin.patch 0015-platform-input-configuration.patch +0016-patch-spelling-identifiers.patch From 3dfc338a2be66a961868f988afd78203e3011af2 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 05:11:47 -0400 Subject: [PATCH 12/24] docs(patches): record the native input configuration proof --- patches/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/patches/README.md b/patches/README.md index 495b17ff62..6989139b18 100644 --- a/patches/README.md +++ b/patches/README.md @@ -53,8 +53,9 @@ Theorem DATA conversion does not add a private input fork. Validation of this addition: locked Wasm `gpui-base --lib` check passes. The native `platform_input_configuration_preserves_default_and_forwards_changes` -regression covers default, Search builder, and changed Send/assistance settings; -its execution is pending the coordinated native validation slot. This branch +regression covers default, Search builder, and changed Send/assistance settings. +It passed in the Linux workspace test job at source head `1636a905`; the +subsequent spelling configuration leaves that source unchanged. This branch remains a draft requiring review before merge. The spelling follow-up recognizes only complete Git `index` hash lines and From bd326291bb967274acd50cd6ece9935b93172463 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 05:23:00 -0400 Subject: [PATCH 13/24] fix(ci): recognize the capture name inside its own patch pattern --- _typos.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_typos.toml b/_typos.toml index e9abe5187a..78a0e7621d 100644 --- a/_typos.toml +++ b/_typos.toml @@ -4,7 +4,7 @@ extend-ignore-re = [ # Ordered Git patch object IDs are immutable hex, not prose. '(?m)^index [0-9a-f]+\.\.[0-9a-f]+(?: [0-7]+)?$', # The exact screen-capture package identifier in the dependency patches. - '\bzed-scap\b', + 'zed-scap', ] [default.extend-words] From fced8e9074063ec5a94f6a1532d0b8dc552974d5 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 05:23:01 -0400 Subject: [PATCH 14/24] chore(patches): record the verified spelling pattern correction --- patches/0017-patch-pattern-spelling.patch | 26 +++++++++++++++++++++++ patches/README.md | 5 +++++ patches/series | 1 + 3 files changed, 32 insertions(+) create mode 100644 patches/0017-patch-pattern-spelling.patch diff --git a/patches/0017-patch-pattern-spelling.patch b/patches/0017-patch-pattern-spelling.patch new file mode 100644 index 0000000000..03e6498535 --- /dev/null +++ b/patches/0017-patch-pattern-spelling.patch @@ -0,0 +1,26 @@ +From bd326291bb967274acd50cd6ece9935b93172463 Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Sat, 5 Sep 2026 05:23:00 -0400 +Subject: [PATCH] fix(ci): recognize the capture name inside its own patch + pattern + +--- + _typos.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/_typos.toml b/_typos.toml +index e9abe518..78a0e762 100644 +--- a/_typos.toml ++++ b/_typos.toml +@@ -4,7 +4,7 @@ extend-ignore-re = [ + # Ordered Git patch object IDs are immutable hex, not prose. + '(?m)^index [0-9a-f]+\.\.[0-9a-f]+(?: [0-7]+)?$', + # The exact screen-capture package identifier in the dependency patches. +- '\bzed-scap\b', ++ 'zed-scap', + ] + + [default.extend-words] +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 6989139b18..0779983cf4 100644 --- a/patches/README.md +++ b/patches/README.md @@ -61,3 +61,8 @@ remains a draft requiring review before merge. The spelling follow-up recognizes only complete Git `index` hash lines and the exact `zed-scap` package identifier inside the ordered patches. It retains source and prose spelling checks; no application or runtime code changes. + +The final spelling follow-up recognizes the exact capture package name even +inside its escaped regex spelling in patch 0016. The exact CI typos-cli 1.50.1 +reproduces that failure before this change and scans the entire final checkout +without errors afterward. Runtime and dependency source remain unchanged. diff --git a/patches/series b/patches/series index 21c6e2601f..8c710c8561 100644 --- a/patches/series +++ b/patches/series @@ -14,3 +14,4 @@ 0014-gpui-desktop-keyboard-focus-pin.patch 0015-platform-input-configuration.patch 0016-patch-spelling-identifiers.patch +0017-patch-pattern-spelling.patch From 8ed45fe12a34d9d6f4d123205db55f6128a35669 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 05:57:19 -0400 Subject: [PATCH 15/24] feat(input): paint retained textarea presentation styles --- crates/base/src/input/base/kind.rs | 6 - crates/base/src/input/editor/decorations.rs | 4 +- crates/base/src/input/editor/mod.rs | 2 +- crates/base/src/input/mod.rs | 2 +- crates/base/src/input/textarea/mod.rs | 102 ++++++++- crates/component/src/status_bar.rs | 2 +- crates/component/src/title_bar.rs | 4 +- .../0018-textarea-presentation-styles.patch | 205 ++++++++++++++++++ patches/README.md | 13 ++ patches/series | 1 + 10 files changed, 326 insertions(+), 15 deletions(-) create mode 100644 patches/0018-textarea-presentation-styles.patch diff --git a/crates/base/src/input/base/kind.rs b/crates/base/src/input/base/kind.rs index 26c28d535f..393b49bda8 100644 --- a/crates/base/src/input/base/kind.rs +++ b/crates/base/src/input/base/kind.rs @@ -313,12 +313,6 @@ impl InputModeKind for InputMode { /// them would cost more in dispatch than it saves. type Extras = (); } -impl InputModeKind for TextareaMode { - const MULTI_LINE: bool = true; - - /// Ordinary multi-line text needs nothing beyond the shared engine. - type Extras = (); -} // `EditorMode`'s implementation lives with the editor code, next to the // language features it dispatches to. diff --git a/crates/base/src/input/editor/decorations.rs b/crates/base/src/input/editor/decorations.rs index dc4b393cce..231546fc2f 100644 --- a/crates/base/src/input/editor/decorations.rs +++ b/crates/base/src/input/editor/decorations.rs @@ -158,7 +158,7 @@ impl DecorationCollections { } } -fn adjust_range_for_edit( +pub(crate) fn adjust_range_for_edit( range: &Range, edited_range: &Range, inserted_len: usize, @@ -204,7 +204,7 @@ fn adjust_range_for_edit( start..end } -fn normalize(text: &Rope, decorations: Vec) -> Vec { +pub(crate) fn normalize(text: &Rope, decorations: Vec) -> Vec { decorations .into_iter() .filter_map(|decoration| { diff --git a/crates/base/src/input/editor/mod.rs b/crates/base/src/input/editor/mod.rs index d4e16e3da3..ce32baaeb2 100644 --- a/crates/base/src/input/editor/mod.rs +++ b/crates/base/src/input/editor/mod.rs @@ -5,7 +5,7 @@ use super::{EditorMode, InputBaseState, InputModeKind}; /// State for source-code editing. /// /// This is the shared editing engine in its code-editor kind. Languages, line -/// numbers, folding, indent guides, diagnostics, decorations, and the LSP +/// numbers, folding, indent guides, diagnostics, and the LSP /// providers exist on this kind only, so an ordinary input or textarea never /// exposes them. pub type EditorState = InputBaseState; diff --git a/crates/base/src/input/mod.rs b/crates/base/src/input/mod.rs index e8d9c2b2fb..0a4ddeb23a 100644 --- a/crates/base/src/input/mod.rs +++ b/crates/base/src/input/mod.rs @@ -96,4 +96,4 @@ pub use rope_ext::{InputEdit, Point, RopeExt, RopeLines}; pub use ropey::Rope; pub use search::{SearchMatcher, SearchSession}; pub use state::*; -pub use textarea::{Textarea, TextareaState}; +pub use textarea::{Textarea, TextareaExtras, TextareaState}; diff --git a/crates/base/src/input/textarea/mod.rs b/crates/base/src/input/textarea/mod.rs index 341d108e06..57e32e58c0 100644 --- a/crates/base/src/input/textarea/mod.rs +++ b/crates/base/src/input/textarea/mod.rs @@ -1,6 +1,6 @@ -use gpui::{App, Entity, IntoElement, RenderOnce, Window}; +use gpui::{App, Context, Entity, IntoElement, RenderOnce, Window}; -use super::{InputBaseState, TextareaMode}; +use super::{InputBaseState, InputExtras, InputModeKind, TextDecoration, TextareaMode}; /// State for editing ordinary multi-line text. /// @@ -28,3 +28,101 @@ impl RenderOnce for Textarea { self.state } } + +/// Presentation-only ranges for ordinary multiline prose. Empty by default; +/// this does not add syntax parsing, diagnostics, folding, or an LSP. +#[derive(Default)] +pub struct TextareaExtras { + decorations: Vec, +} + +impl InputExtras for TextareaExtras { + fn decoration_layers(&self) -> Vec<&[TextDecoration]> { + vec![&self.decorations] + } +} + +impl InputModeKind for TextareaMode { + const MULTI_LINE: bool = true; + type Extras = TextareaExtras; + + fn reset_annotations(state: &mut InputBaseState) { + state.extras.decorations.clear(); + } + + fn adjust_annotations( + state: &mut InputBaseState, + range: &std::ops::Range, + new_len: usize, + ) { + state.extras.decorations.retain_mut(|decoration| { + decoration.range = + super::decorations::adjust_range_for_edit(&decoration.range, range, new_len); + !decoration.range.is_empty() + }); + } +} + +impl TextareaState { + /// Replace presentation styles without replacing text, selection, or IME + /// marked text. UTF-8 ranges use the same clipping and edit adjustment as + /// editor decorations. Applications retain authority over the styles. + pub fn set_text_decorations( + &mut self, + decorations: Vec, + cx: &mut Context, + ) { + let decorations = super::decorations::normalize(&self.text, decorations); + if self.extras.decorations != decorations { + self.extras.decorations = decorations; + cx.notify(); + } + } + + /// The normalized presentation styles currently painted by this textarea. + pub fn text_decorations(&self) -> &[TextDecoration] { + &self.extras.decorations + } +} + +#[cfg(test)] +mod tests { + use super::*; + use gpui::{AppContext as _, EntityInputHandler as _, HighlightStyle, TestAppContext}; + + #[gpui::test] + fn textarea_decorations_preserve_text_selection_and_composition(cx: &mut TestAppContext) { + let window = cx.add_window(|window, cx| TextareaState::new(window, cx)); + window + .update(cx, |state, window, cx| { + assert!(state.text_decorations().is_empty()); + assert!(!state.is_code_editor()); + state.set_value("héllo world", window, cx); + state.set_selected_range(1..4, cx); + let value = state.value(); + let selection = state.selected_range(); + let bold = HighlightStyle { + font_weight: Some(gpui::FontWeight::BOLD), + ..Default::default() + }; + state.set_text_decorations(vec![TextDecoration::new(2..4, bold)], cx); + assert_eq!(state.value(), value); + assert_eq!(state.selected_range(), selection); + assert_eq!(state.text_decorations(), &[TextDecoration::new(1..4, bold)]); + state.set_selected_range(0..0, cx); + state.replace_and_mark_text_in_range(None, "界", Some(1..1), window, cx); + let marked = state.marked_text_range(window, cx); + let value = state.value(); + let selection = state.selected_range(); + assert!(marked.is_some()); + assert_eq!(state.text_decorations()[0].range, 4..7); + state.set_text_decorations(vec![TextDecoration::new(4..7, bold)], cx); + assert_eq!(state.value(), value); + assert_eq!(state.selected_range(), selection); + assert_eq!(state.marked_text_range(window, cx), marked); + state.set_value("replacement", window, cx); + assert!(state.text_decorations().is_empty()); + }) + .expect("textarea remains mounted"); + } +} diff --git a/crates/component/src/status_bar.rs b/crates/component/src/status_bar.rs index 44dff59464..1cfe330665 100644 --- a/crates/component/src/status_bar.rs +++ b/crates/component/src/status_bar.rs @@ -23,7 +23,7 @@ use crate::{ActiveTheme, StyledExt, h_flex}; /// otherwise (only `right`, or neither — like a plain container). /// /// ``` -/// use gpui_kit::component::status_bar::StatusBar; +/// use gpui_component::status_bar::StatusBar; /// /// let _ = StatusBar::new().left("Ln 1, Col 1").right("UTF-8"); /// ``` diff --git a/crates/component/src/title_bar.rs b/crates/component/src/title_bar.rs index 45b091bb37..32254a479f 100644 --- a/crates/component/src/title_bar.rs +++ b/crates/component/src/title_bar.rs @@ -70,8 +70,8 @@ impl TitleBar { /// [`crate::TitleBar`], so the title bar owns dragging and double clicking itself: /// /// ```no_run - /// # use gpui_kit::WindowOptions; - /// # use gpui_kit::component::TitleBar; + /// # use gpui::WindowOptions; + /// # use gpui_component::TitleBar; /// let options = WindowOptions { /// window_min_size: None, /// ..TitleBar::window_options() diff --git a/patches/0018-textarea-presentation-styles.patch b/patches/0018-textarea-presentation-styles.patch new file mode 100644 index 0000000000..e06efc088f --- /dev/null +++ b/patches/0018-textarea-presentation-styles.patch @@ -0,0 +1,205 @@ +diff --git a/crates/base/src/input/base/kind.rs b/crates/base/src/input/base/kind.rs +index 26c28d53..393b49bd 100644 +--- a/crates/base/src/input/base/kind.rs ++++ b/crates/base/src/input/base/kind.rs +@@ -313,12 +313,6 @@ impl InputModeKind for InputMode { + /// them would cost more in dispatch than it saves. + type Extras = (); + } +-impl InputModeKind for TextareaMode { +- const MULTI_LINE: bool = true; +- +- /// Ordinary multi-line text needs nothing beyond the shared engine. +- type Extras = (); +-} + // `EditorMode`'s implementation lives with the editor code, next to the + // language features it dispatches to. + +diff --git a/crates/base/src/input/editor/decorations.rs b/crates/base/src/input/editor/decorations.rs +index dc4b393c..231546fc 100644 +--- a/crates/base/src/input/editor/decorations.rs ++++ b/crates/base/src/input/editor/decorations.rs +@@ -158,7 +158,7 @@ impl DecorationCollections { + } + } + +-fn adjust_range_for_edit( ++pub(crate) fn adjust_range_for_edit( + range: &Range, + edited_range: &Range, + inserted_len: usize, +@@ -204,7 +204,7 @@ fn adjust_range_for_edit( + start..end + } + +-fn normalize(text: &Rope, decorations: Vec) -> Vec { ++pub(crate) fn normalize(text: &Rope, decorations: Vec) -> Vec { + decorations + .into_iter() + .filter_map(|decoration| { +diff --git a/crates/base/src/input/editor/mod.rs b/crates/base/src/input/editor/mod.rs +index d4e16e3d..ce32baae 100644 +--- a/crates/base/src/input/editor/mod.rs ++++ b/crates/base/src/input/editor/mod.rs +@@ -5,7 +5,7 @@ use super::{EditorMode, InputBaseState, InputModeKind}; + /// State for source-code editing. + /// + /// This is the shared editing engine in its code-editor kind. Languages, line +-/// numbers, folding, indent guides, diagnostics, decorations, and the LSP ++/// numbers, folding, indent guides, diagnostics, and the LSP + /// providers exist on this kind only, so an ordinary input or textarea never + /// exposes them. + pub type EditorState = InputBaseState; +diff --git a/crates/base/src/input/mod.rs b/crates/base/src/input/mod.rs +index e8d9c2b2..0a4ddeb2 100644 +--- a/crates/base/src/input/mod.rs ++++ b/crates/base/src/input/mod.rs +@@ -96,4 +96,4 @@ pub use rope_ext::{InputEdit, Point, RopeExt, RopeLines}; + pub use ropey::Rope; + pub use search::{SearchMatcher, SearchSession}; + pub use state::*; +-pub use textarea::{Textarea, TextareaState}; ++pub use textarea::{Textarea, TextareaExtras, TextareaState}; +diff --git a/crates/base/src/input/textarea/mod.rs b/crates/base/src/input/textarea/mod.rs +index 341d108e..57e32e58 100644 +--- a/crates/base/src/input/textarea/mod.rs ++++ b/crates/base/src/input/textarea/mod.rs +@@ -1,6 +1,6 @@ +-use gpui::{App, Entity, IntoElement, RenderOnce, Window}; ++use gpui::{App, Context, Entity, IntoElement, RenderOnce, Window}; + +-use super::{InputBaseState, TextareaMode}; ++use super::{InputBaseState, InputExtras, InputModeKind, TextDecoration, TextareaMode}; + + /// State for editing ordinary multi-line text. + /// +@@ -28,3 +28,101 @@ impl RenderOnce for Textarea { + self.state + } + } ++ ++/// Presentation-only ranges for ordinary multiline prose. Empty by default; ++/// this does not add syntax parsing, diagnostics, folding, or an LSP. ++#[derive(Default)] ++pub struct TextareaExtras { ++ decorations: Vec, ++} ++ ++impl InputExtras for TextareaExtras { ++ fn decoration_layers(&self) -> Vec<&[TextDecoration]> { ++ vec![&self.decorations] ++ } ++} ++ ++impl InputModeKind for TextareaMode { ++ const MULTI_LINE: bool = true; ++ type Extras = TextareaExtras; ++ ++ fn reset_annotations(state: &mut InputBaseState) { ++ state.extras.decorations.clear(); ++ } ++ ++ fn adjust_annotations( ++ state: &mut InputBaseState, ++ range: &std::ops::Range, ++ new_len: usize, ++ ) { ++ state.extras.decorations.retain_mut(|decoration| { ++ decoration.range = ++ super::decorations::adjust_range_for_edit(&decoration.range, range, new_len); ++ !decoration.range.is_empty() ++ }); ++ } ++} ++ ++impl TextareaState { ++ /// Replace presentation styles without replacing text, selection, or IME ++ /// marked text. UTF-8 ranges use the same clipping and edit adjustment as ++ /// editor decorations. Applications retain authority over the styles. ++ pub fn set_text_decorations( ++ &mut self, ++ decorations: Vec, ++ cx: &mut Context, ++ ) { ++ let decorations = super::decorations::normalize(&self.text, decorations); ++ if self.extras.decorations != decorations { ++ self.extras.decorations = decorations; ++ cx.notify(); ++ } ++ } ++ ++ /// The normalized presentation styles currently painted by this textarea. ++ pub fn text_decorations(&self) -> &[TextDecoration] { ++ &self.extras.decorations ++ } ++} ++ ++#[cfg(test)] ++mod tests { ++ use super::*; ++ use gpui::{AppContext as _, EntityInputHandler as _, HighlightStyle, TestAppContext}; ++ ++ #[gpui::test] ++ fn textarea_decorations_preserve_text_selection_and_composition(cx: &mut TestAppContext) { ++ let window = cx.add_window(|window, cx| TextareaState::new(window, cx)); ++ window ++ .update(cx, |state, window, cx| { ++ assert!(state.text_decorations().is_empty()); ++ assert!(!state.is_code_editor()); ++ state.set_value("héllo world", window, cx); ++ state.set_selected_range(1..4, cx); ++ let value = state.value(); ++ let selection = state.selected_range(); ++ let bold = HighlightStyle { ++ font_weight: Some(gpui::FontWeight::BOLD), ++ ..Default::default() ++ }; ++ state.set_text_decorations(vec![TextDecoration::new(2..4, bold)], cx); ++ assert_eq!(state.value(), value); ++ assert_eq!(state.selected_range(), selection); ++ assert_eq!(state.text_decorations(), &[TextDecoration::new(1..4, bold)]); ++ state.set_selected_range(0..0, cx); ++ state.replace_and_mark_text_in_range(None, "界", Some(1..1), window, cx); ++ let marked = state.marked_text_range(window, cx); ++ let value = state.value(); ++ let selection = state.selected_range(); ++ assert!(marked.is_some()); ++ assert_eq!(state.text_decorations()[0].range, 4..7); ++ state.set_text_decorations(vec![TextDecoration::new(4..7, bold)], cx); ++ assert_eq!(state.value(), value); ++ assert_eq!(state.selected_range(), selection); ++ assert_eq!(state.marked_text_range(window, cx), marked); ++ state.set_value("replacement", window, cx); ++ assert!(state.text_decorations().is_empty()); ++ }) ++ .expect("textarea remains mounted"); ++ } ++} +diff --git a/crates/component/src/status_bar.rs b/crates/component/src/status_bar.rs +index 44dff594..1cfe3306 100644 +--- a/crates/component/src/status_bar.rs ++++ b/crates/component/src/status_bar.rs +@@ -23,7 +23,7 @@ use crate::{ActiveTheme, StyledExt, h_flex}; + /// otherwise (only `right`, or neither — like a plain container). + /// + /// ``` +-/// use gpui_kit::component::status_bar::StatusBar; ++/// use gpui_component::status_bar::StatusBar; + /// + /// let _ = StatusBar::new().left("Ln 1, Col 1").right("UTF-8"); + /// ``` +diff --git a/crates/component/src/title_bar.rs b/crates/component/src/title_bar.rs +index 45b091bb..32254a47 100644 +--- a/crates/component/src/title_bar.rs ++++ b/crates/component/src/title_bar.rs +@@ -70,8 +70,8 @@ impl TitleBar { + /// [`crate::TitleBar`], so the title bar owns dragging and double clicking itself: + /// + /// ```no_run +- /// # use gpui_kit::WindowOptions; +- /// # use gpui_kit::component::TitleBar; ++ /// # use gpui::WindowOptions; ++ /// # use gpui_component::TitleBar; + /// let options = WindowOptions { + /// window_min_size: None, + /// ..TitleBar::window_options() diff --git a/patches/README.md b/patches/README.md index 0779983cf4..75904842dc 100644 --- a/patches/README.md +++ b/patches/README.md @@ -66,3 +66,16 @@ The final spelling follow-up recognizes the exact capture package name even inside its escaped regex spelling in patch 0016. The exact CI typos-cli 1.50.1 reproduces that failure before this change and scans the entire final checkout without errors afterward. Runtime and dependency source remain unchanged. + +The textarea presentation patch adds `set_text_decorations` and +`text_decorations` to the ordinary multiline input. It reuses the existing +normalized UTF-8 range and edit adjustment rules, paints through the existing +decoration renderer, and leaves syntax parsing/LSP confined to the code editor. +Its default presentation remains empty. A native regression retains text, +selection, and active IME composition while styles change; native execution +is pending CI for this source. The locked Wasm library check passes. + +Two existing runnable component doctests now import their actual owning crates +(`gpui_component` and `gpui`) instead of the undeclared facade `gpui_kit`. +The original examples and assertions remain executable. This draft still +requires review before merge. diff --git a/patches/series b/patches/series index 8c710c8561..7c4740f717 100644 --- a/patches/series +++ b/patches/series @@ -15,3 +15,4 @@ 0015-platform-input-configuration.patch 0016-patch-spelling-identifiers.patch 0017-patch-pattern-spelling.patch +0018-textarea-presentation-styles.patch From 1d40dad5d87662395eece43cf3d9e206dcd89599 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 06:05:11 -0400 Subject: [PATCH 16/24] test(input): initialize mounted textarea regression --- crates/base/src/input/textarea/mod.rs | 3 ++- patches/0019-textarea-test-initialization.patch | 17 +++++++++++++++++ patches/README.md | 4 ++++ patches/series | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 patches/0019-textarea-test-initialization.patch diff --git a/crates/base/src/input/textarea/mod.rs b/crates/base/src/input/textarea/mod.rs index 57e32e58c0..371d33a2e1 100644 --- a/crates/base/src/input/textarea/mod.rs +++ b/crates/base/src/input/textarea/mod.rs @@ -88,10 +88,11 @@ impl TextareaState { #[cfg(test)] mod tests { use super::*; - use gpui::{AppContext as _, EntityInputHandler as _, HighlightStyle, TestAppContext}; + use gpui::{EntityInputHandler as _, HighlightStyle, TestAppContext}; #[gpui::test] fn textarea_decorations_preserve_text_selection_and_composition(cx: &mut TestAppContext) { + cx.update(crate::init); let window = cx.add_window(|window, cx| TextareaState::new(window, cx)); window .update(cx, |state, window, cx| { diff --git a/patches/0019-textarea-test-initialization.patch b/patches/0019-textarea-test-initialization.patch new file mode 100644 index 0000000000..7d0668403f --- /dev/null +++ b/patches/0019-textarea-test-initialization.patch @@ -0,0 +1,17 @@ +diff --git a/crates/base/src/input/textarea/mod.rs b/crates/base/src/input/textarea/mod.rs +index 57e32e58..371d33a2 100644 +--- a/crates/base/src/input/textarea/mod.rs ++++ b/crates/base/src/input/textarea/mod.rs +@@ -88,10 +88,11 @@ impl TextareaState { + #[cfg(test)] + mod tests { + use super::*; +- use gpui::{AppContext as _, EntityInputHandler as _, HighlightStyle, TestAppContext}; ++ use gpui::{EntityInputHandler as _, HighlightStyle, TestAppContext}; + + #[gpui::test] + fn textarea_decorations_preserve_text_selection_and_composition(cx: &mut TestAppContext) { ++ cx.update(crate::init); + let window = cx.add_window(|window, cx| TextareaState::new(window, cx)); + window + .update(cx, |state, window, cx| { diff --git a/patches/README.md b/patches/README.md index 75904842dc..abb36f1f55 100644 --- a/patches/README.md +++ b/patches/README.md @@ -79,3 +79,7 @@ Two existing runnable component doctests now import their actual owning crates (`gpui_component` and `gpui`) instead of the undeclared facade `gpui_kit`. The original examples and assertions remain executable. This draft still requires review before merge. + +The textarea regression uses the real Kit initializer before mounting the input. +Its test-only unused trait import, rejected by CI's warnings-as-errors gate, is +removed. No runtime behavior or assertions change in this follow-up. diff --git a/patches/series b/patches/series index 7c4740f717..bf1141576b 100644 --- a/patches/series +++ b/patches/series @@ -16,3 +16,4 @@ 0016-patch-spelling-identifiers.patch 0017-patch-pattern-spelling.patch 0018-textarea-presentation-styles.patch +0019-textarea-test-initialization.patch From 901d9f54c17111161848590b95f692a800864e3f Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 06:13:29 -0400 Subject: [PATCH 17/24] fix(input): clear textarea styles on whole-text replacement --- crates/base/src/input/base/kind.rs | 4 ++ crates/base/src/input/base/state.rs | 1 + crates/base/src/input/textarea/mod.rs | 4 ++ ...20-textarea-replacement-presentation.patch | 42 +++++++++++++++++++ patches/README.md | 5 +++ patches/series | 1 + 6 files changed, 57 insertions(+) create mode 100644 patches/0020-textarea-replacement-presentation.patch diff --git a/crates/base/src/input/base/kind.rs b/crates/base/src/input/base/kind.rs index 393b49bda8..6637e80030 100644 --- a/crates/base/src/input/base/kind.rs +++ b/crates/base/src/input/base/kind.rs @@ -185,6 +185,10 @@ pub trait InputModeKind: sealed::Sealed + Sized + 'static { /// Drops decorations and hover state when the text is replaced wholesale. fn reset_annotations(_state: &mut InputBaseState) {} + /// Drops presentation ranges after an authoritative whole-text replacement. + /// Existing mode behavior is unchanged unless a mode opts into this hook. + fn reset_document_presentation(_state: &mut InputBaseState) {} + /// Slides decoration ranges along with an edit. fn adjust_annotations( _state: &mut InputBaseState, diff --git a/crates/base/src/input/base/state.rs b/crates/base/src/input/base/state.rs index 9a1d831b7f..2c776da421 100644 --- a/crates/base/src/input/base/state.rs +++ b/crates/base/src/input/base/state.rs @@ -929,6 +929,7 @@ impl InputBaseState { this.undo_manager.pending_intent = Some(EditIntent::Atomic); let range = 0..this.text.chars().map(|c| c.len_utf16()).sum(); this.replace_text_in_range_silent(Some(range), &text, window, cx); + M::reset_document_presentation(this); this.reset_highlighter(cx); }); } diff --git a/crates/base/src/input/textarea/mod.rs b/crates/base/src/input/textarea/mod.rs index 371d33a2e1..79299b20f3 100644 --- a/crates/base/src/input/textarea/mod.rs +++ b/crates/base/src/input/textarea/mod.rs @@ -50,6 +50,10 @@ impl InputModeKind for TextareaMode { state.extras.decorations.clear(); } + fn reset_document_presentation(state: &mut InputBaseState) { + state.extras.decorations.clear(); + } + fn adjust_annotations( state: &mut InputBaseState, range: &std::ops::Range, diff --git a/patches/0020-textarea-replacement-presentation.patch b/patches/0020-textarea-replacement-presentation.patch new file mode 100644 index 0000000000..3315ea499c --- /dev/null +++ b/patches/0020-textarea-replacement-presentation.patch @@ -0,0 +1,42 @@ +diff --git a/crates/base/src/input/base/kind.rs b/crates/base/src/input/base/kind.rs +index 393b49bd..6637e800 100644 +--- a/crates/base/src/input/base/kind.rs ++++ b/crates/base/src/input/base/kind.rs +@@ -185,6 +185,10 @@ pub trait InputModeKind: sealed::Sealed + Sized + 'static { + /// Drops decorations and hover state when the text is replaced wholesale. + fn reset_annotations(_state: &mut InputBaseState) {} + ++ /// Drops presentation ranges after an authoritative whole-text replacement. ++ /// Existing mode behavior is unchanged unless a mode opts into this hook. ++ fn reset_document_presentation(_state: &mut InputBaseState) {} ++ + /// Slides decoration ranges along with an edit. + fn adjust_annotations( + _state: &mut InputBaseState, +diff --git a/crates/base/src/input/base/state.rs b/crates/base/src/input/base/state.rs +index 9a1d831b..2c776da4 100644 +--- a/crates/base/src/input/base/state.rs ++++ b/crates/base/src/input/base/state.rs +@@ -929,6 +929,7 @@ impl InputBaseState { + this.undo_manager.pending_intent = Some(EditIntent::Atomic); + let range = 0..this.text.chars().map(|c| c.len_utf16()).sum(); + this.replace_text_in_range_silent(Some(range), &text, window, cx); ++ M::reset_document_presentation(this); + this.reset_highlighter(cx); + }); + } +diff --git a/crates/base/src/input/textarea/mod.rs b/crates/base/src/input/textarea/mod.rs +index 371d33a2..79299b20 100644 +--- a/crates/base/src/input/textarea/mod.rs ++++ b/crates/base/src/input/textarea/mod.rs +@@ -50,6 +50,10 @@ impl InputModeKind for TextareaMode { + state.extras.decorations.clear(); + } + ++ fn reset_document_presentation(state: &mut InputBaseState) { ++ state.extras.decorations.clear(); ++ } ++ + fn adjust_annotations( + state: &mut InputBaseState, + range: &std::ops::Range, diff --git a/patches/README.md b/patches/README.md index abb36f1f55..4fe0dd9cb1 100644 --- a/patches/README.md +++ b/patches/README.md @@ -83,3 +83,8 @@ requires review before merge. The textarea regression uses the real Kit initializer before mounting the input. Its test-only unused trait import, rejected by CI's warnings-as-errors gate, is removed. No runtime behavior or assertions change in this follow-up. + +The native textarea test reached all text/selection/IME assertions and exposed +stale styles after `set_value`. The replacement hook clears only the new +textarea presentation ranges; its default is a no-op, preserving existing +editor behavior. The same regression and all its assertions are retained. diff --git a/patches/series b/patches/series index bf1141576b..e55079b045 100644 --- a/patches/series +++ b/patches/series @@ -17,3 +17,4 @@ 0017-patch-pattern-spelling.patch 0018-textarea-presentation-styles.patch 0019-textarea-test-initialization.patch +0020-textarea-replacement-presentation.patch From abf772c47825061b7099ac0d8eb62e4a930d4f8e Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 06:30:03 -0400 Subject: [PATCH 18/24] fix(gpui): pin browser selected replacement repair --- Cargo.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 019f9f91fb..401efdc6a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } story = { path = "crates/story" } -gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } -gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } -gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } -gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } -reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } -sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } +gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } +gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } +reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } +sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ "charset", "http2", @@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] [workspace.metadata.theorem-fork] upstream = "https://github.com/longbridge/gpui-kit" upstream_tag = "v0.6.0" -zed_rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +zed_rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" From b4032637bbca2a9cc899206215c8272eb2602be4 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 06:30:04 -0400 Subject: [PATCH 19/24] chore(gpui): record selected replacement dependency pin --- .../0021-gpui-selected-replacement-pin.patch | 41 +++++++++++++++++++ patches/README.md | 6 +++ patches/series | 1 + 3 files changed, 48 insertions(+) create mode 100644 patches/0021-gpui-selected-replacement-pin.patch diff --git a/patches/0021-gpui-selected-replacement-pin.patch b/patches/0021-gpui-selected-replacement-pin.patch new file mode 100644 index 0000000000..e39b2b55c7 --- /dev/null +++ b/patches/0021-gpui-selected-replacement-pin.patch @@ -0,0 +1,41 @@ +From abf772c47825061b7099ac0d8eb62e4a930d4f8e Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Sat, 5 Sep 2026 06:30:03 -0400 +Subject: [PATCH] fix(gpui): pin browser selected replacement repair + +--- + Cargo.toml | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/Cargo.toml b/Cargo.toml +index 019f9f91..401efdc6 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -48,12 +48,12 @@ gpui-wry = { path = "crates/webview", version = "0.6.0" } + gpui-component-shell = { path = "crates/component-shell", version = "0.6.0" } + story = { path = "crates/story" } + +-gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +-gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } +-gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +-gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +-reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } +-sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" } ++gpui = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } ++gpui_platform = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1", features = ["font-kit", "x11", "wayland", "runtime_shaders"] } ++gpui_web = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } ++gpui_macros = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } ++reqwest_client = { git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } ++sum-tree = { package = "sum_tree", git = "https://github.com/Travis-Gilbert/zed", rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" } + reqwest = { package = "zed-reqwest", git = "https://github.com/zed-industries/reqwest.git", rev = "33bc764aa15ff7b200bf7c93bd96e24878d53e14", version = "0.12.15-zed", default-features = false, features = [ + "charset", + "http2", +@@ -159,4 +159,4 @@ ignored = ["log", "anyhow", "serde"] + [workspace.metadata.theorem-fork] + upstream = "https://github.com/longbridge/gpui-kit" + upstream_tag = "v0.6.0" +-zed_rev = "2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++zed_rev = "de1d65ee70ac21a1ef02a500151a96d96ff937e1" +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 4fe0dd9cb1..220431e577 100644 --- a/patches/README.md +++ b/patches/README.md @@ -88,3 +88,9 @@ The native textarea test reached all text/selection/IME assertions and exposed stale styles after `set_value`. The replacement hook clears only the new textarea presentation ranges; its default is a no-op, preserving existing editor behavior. The same regression and all its assertions are retained. + +The selected-replacement pin follows Zed's actual browser IME repair. It changes +only the seven GPUI manifest revisions and 25 lock source revisions; registry +packages remain unchanged. The replacement diff retains matching text inside +the selected range and fresh editor anchors, with UTF-16 boundary coverage. +The Wikia browser oracle remains the consumer's actual DOM/document gate. diff --git a/patches/series b/patches/series index e55079b045..07427b4758 100644 --- a/patches/series +++ b/patches/series @@ -18,3 +18,4 @@ 0018-textarea-presentation-styles.patch 0019-textarea-test-initialization.patch 0020-textarea-replacement-presentation.patch +0021-gpui-selected-replacement-pin.patch From 2fed4e7bd5192d93de116e8f5701f40671e895e0 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 06:30:38 -0400 Subject: [PATCH 20/24] fix(gpui): synchronize selected replacement lock sources --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b939a04ac..e889dabd5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1388,7 +1388,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "gpui_util", "indexmap", @@ -2086,7 +2086,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "proc-macro2", "quote", @@ -3376,7 +3376,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "accesskit", "anyhow", @@ -3728,7 +3728,7 @@ dependencies = [ [[package]] name = "gpui_apple" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "block", @@ -3751,7 +3751,7 @@ dependencies = [ [[package]] name = "gpui_linux" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "accesskit", "accesskit_unix", @@ -3797,7 +3797,7 @@ dependencies = [ [[package]] name = "gpui_macos" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "accesskit", "accesskit_macos", @@ -3843,7 +3843,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "gpui_platform" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "console_error_panic_hook", "gpui", @@ -3867,7 +3867,7 @@ dependencies = [ [[package]] name = "gpui_shared_string" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "schemars", "serde", @@ -3877,7 +3877,7 @@ dependencies = [ [[package]] name = "gpui_util" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "log", @@ -3887,7 +3887,7 @@ dependencies = [ [[package]] name = "gpui_web" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "async-channel", @@ -3912,7 +3912,7 @@ dependencies = [ [[package]] name = "gpui_wgpu" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "bytemuck", @@ -3938,7 +3938,7 @@ dependencies = [ [[package]] name = "gpui_windows" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "accesskit", "accesskit_windows", @@ -4300,7 +4300,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "async-compression", @@ -4320,7 +4320,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "log", "rustls", @@ -5676,7 +5676,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "bindgen", @@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "collections", "serde", @@ -7828,7 +7828,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "derive_refineable", ] @@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "bytes", @@ -8398,7 +8398,7 @@ dependencies = [ [[package]] name = "scheduler" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "async-task", "backtrace", @@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "heapless", "log", @@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "perf", "quote", @@ -12639,7 +12639,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "anyhow", "chrono", @@ -12684,7 +12684,7 @@ dependencies = [ [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" dependencies = [ "tracing", "tracing-subscriber", @@ -12695,7 +12695,7 @@ dependencies = [ [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" +source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" [[package]] name = "zune-core" From 361d1cc04aee4e7f88b3b2177921cc82d735ed33 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 06:30:38 -0400 Subject: [PATCH 21/24] chore(gpui): record synchronized selected replacement lock --- .../0022-gpui-selected-replacement-lock.patch | 241 ++++++++++++++++++ patches/README.md | 5 + patches/series | 1 + 3 files changed, 247 insertions(+) create mode 100644 patches/0022-gpui-selected-replacement-lock.patch diff --git a/patches/0022-gpui-selected-replacement-lock.patch b/patches/0022-gpui-selected-replacement-lock.patch new file mode 100644 index 0000000000..ff1321e86e --- /dev/null +++ b/patches/0022-gpui-selected-replacement-lock.patch @@ -0,0 +1,241 @@ +From 2fed4e7bd5192d93de116e8f5701f40671e895e0 Mon Sep 17 00:00:00 2001 +From: Travis Gilbert <1travisgilbert@gmail.com> +Date: Sat, 5 Sep 2026 06:30:38 -0400 +Subject: [PATCH] fix(gpui): synchronize selected replacement lock sources + +--- + Cargo.lock | 50 +++++++++++++++++++++++++------------------------- + 1 file changed, 25 insertions(+), 25 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index 3b939a04..e889dabd 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -1388,7 +1388,7 @@ dependencies = [ + [[package]] + name = "collections" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "gpui_util", + "indexmap", +@@ -2086,7 +2086,7 @@ dependencies = [ + [[package]] + name = "derive_refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "proc-macro2", + "quote", +@@ -3376,7 +3376,7 @@ dependencies = [ + [[package]] + name = "gpui" + version = "0.2.2" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "accesskit", + "anyhow", +@@ -3728,7 +3728,7 @@ dependencies = [ + [[package]] + name = "gpui_apple" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "block", +@@ -3751,7 +3751,7 @@ dependencies = [ + [[package]] + name = "gpui_linux" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "accesskit", + "accesskit_unix", +@@ -3797,7 +3797,7 @@ dependencies = [ + [[package]] + name = "gpui_macos" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "accesskit", + "accesskit_macos", +@@ -3843,7 +3843,7 @@ dependencies = [ + [[package]] + name = "gpui_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "heck 0.5.0", + "proc-macro2", +@@ -3854,7 +3854,7 @@ dependencies = [ + [[package]] + name = "gpui_platform" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "console_error_panic_hook", + "gpui", +@@ -3867,7 +3867,7 @@ dependencies = [ + [[package]] + name = "gpui_shared_string" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "schemars", + "serde", +@@ -3877,7 +3877,7 @@ dependencies = [ + [[package]] + name = "gpui_util" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "log", +@@ -3887,7 +3887,7 @@ dependencies = [ + [[package]] + name = "gpui_web" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "async-channel", +@@ -3912,7 +3912,7 @@ dependencies = [ + [[package]] + name = "gpui_wgpu" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "bytemuck", +@@ -3938,7 +3938,7 @@ dependencies = [ + [[package]] + name = "gpui_windows" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "accesskit", + "accesskit_windows", +@@ -4300,7 +4300,7 @@ dependencies = [ + [[package]] + name = "http_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "async-compression", +@@ -4320,7 +4320,7 @@ dependencies = [ + [[package]] + name = "http_client_tls" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "log", + "rustls", +@@ -5676,7 +5676,7 @@ dependencies = [ + [[package]] + name = "media" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "bindgen", +@@ -6746,7 +6746,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] + name = "perf" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "collections", + "serde", +@@ -7828,7 +7828,7 @@ dependencies = [ + [[package]] + name = "refineable" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "derive_refineable", + ] +@@ -7889,7 +7889,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + [[package]] + name = "reqwest_client" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "bytes", +@@ -8398,7 +8398,7 @@ dependencies = [ + [[package]] + name = "scheduler" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "async-task", + "backtrace", +@@ -9082,7 +9082,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] + name = "sum_tree" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "heapless", + "log", +@@ -10610,7 +10610,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] + name = "util_macros" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "perf", + "quote", +@@ -12639,7 +12639,7 @@ dependencies = [ + [[package]] + name = "zlog" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "anyhow", + "chrono", +@@ -12684,7 +12684,7 @@ dependencies = [ + [[package]] + name = "ztracing" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + dependencies = [ + "tracing", + "tracing-subscriber", +@@ -12695,7 +12695,7 @@ dependencies = [ + [[package]] + name = "ztracing_macro" + version = "0.1.0" +-source = "git+https://github.com/Travis-Gilbert/zed?rev=2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4#2f7f1da474f6a8ab0f1f61ce35a1a2278ee31db4" ++source = "git+https://github.com/Travis-Gilbert/zed?rev=de1d65ee70ac21a1ef02a500151a96d96ff937e1#de1d65ee70ac21a1ef02a500151a96d96ff937e1" + + [[package]] + name = "zune-core" +-- +2.53.0 + diff --git a/patches/README.md b/patches/README.md index 220431e577..012d2af5d4 100644 --- a/patches/README.md +++ b/patches/README.md @@ -94,3 +94,8 @@ only the seven GPUI manifest revisions and 25 lock source revisions; registry packages remain unchanged. The replacement diff retains matching text inside the selected range and fresh editor anchors, with UTF-16 boundary coverage. The Wikia browser oracle remains the consumer's actual DOM/document gate. + +The lock follow-up synchronizes the 25 source URLs with that manifest pin. +The initial guard counted URL lines rather than both revision occurrences in +each URL and refused the lock write. Both exact revision occurrences now match; +no package version, checksum, or dependency edge changes. diff --git a/patches/series b/patches/series index 07427b4758..2e56259a8f 100644 --- a/patches/series +++ b/patches/series @@ -19,3 +19,4 @@ 0019-textarea-test-initialization.patch 0020-textarea-replacement-presentation.patch 0021-gpui-selected-replacement-pin.patch +0022-gpui-selected-replacement-lock.patch From 486174b9fb9b9911aa78dfe2b123cd5bdcbca42b Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 09:45:37 -0400 Subject: [PATCH 22/24] feat(sidebar): expose retained row and toggle decoration hooks --- crates/component/src/sidebar/menu.rs | 25 ++++- crates/component/src/sidebar/mod.rs | 13 +++ .../0023-sidebar-semantic-decoration.patch | 105 ++++++++++++++++++ patches/README.md | 11 ++ patches/series | 1 + 5 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 patches/0023-sidebar-semantic-decoration.patch diff --git a/crates/component/src/sidebar/menu.rs b/crates/component/src/sidebar/menu.rs index cbaa60cab8..7ca8ca05b3 100644 --- a/crates/component/src/sidebar/menu.rs +++ b/crates/component/src/sidebar/menu.rs @@ -8,9 +8,9 @@ use crate::{ v_flex, }; use gpui::{ - AnyElement, App, ClickEvent, ElementId, InteractiveElement as _, IntoElement, - ParentElement as _, SharedString, StatefulInteractiveElement as _, StyleRefinement, Styled, - Window, div, percentage, prelude::FluentBuilder, + AnyElement, App, ClickEvent, Div, ElementId, InteractiveElement as _, IntoElement, + ParentElement as _, SharedString, Stateful, StatefulInteractiveElement as _, StyleRefinement, + Styled, Window, div, percentage, prelude::FluentBuilder, }; use std::rc::Rc; @@ -101,6 +101,7 @@ pub struct SidebarMenuItem { click_to_toggle: bool, children: Vec, suffix: Option AnyElement + 'static>>, + item_with: Option) -> Stateful
>>, disabled: bool, context_menu: Option PopupMenu + 'static>>, } @@ -119,6 +120,7 @@ impl SidebarMenuItem { click_to_toggle: false, children: Vec::new(), suffix: None, + item_with: None, disabled: false, context_menu: None, } @@ -196,6 +198,19 @@ impl SidebarMenuItem { self } + /// Decorate the actual clickable row, excluding its expanded submenu. + /// + /// The existing click, open, hover and tooltip behavior is retained. This + /// hook supports accessibility and measured-row adapters without adding a + /// second interactive wrapper. It runs before the optional context menu. + pub fn item_with( + mut self, + decorate: impl Fn(Stateful
) -> Stateful
+ 'static, + ) -> Self { + self.item_with = Some(Rc::new(decorate)); + self + } + /// Set disabled flat for menu item. pub fn disable(mut self, disable: bool) -> Self { self.disabled = disable; @@ -369,6 +384,10 @@ impl SidebarItem for SidebarMenuItem { this } }) + .map(|this| match self.item_with { + Some(decorate) => decorate(this), + None => this, + }) .map(|this| { if let Some(context_menu) = self.context_menu { this.context_menu(move |menu, window, cx| { diff --git a/crates/component/src/sidebar/mod.rs b/crates/component/src/sidebar/mod.rs index 09c686bdb8..95a4d3d3c6 100644 --- a/crates/component/src/sidebar/mod.rs +++ b/crates/component/src/sidebar/mod.rs @@ -305,6 +305,7 @@ pub struct SidebarToggleButton { collapsed: bool, side: Side, on_click: Option>, + button_with: Option Button>>, } impl SidebarToggleButton { @@ -315,9 +316,17 @@ impl SidebarToggleButton { collapsed: false, side: Side::Left, on_click: None, + button_with: None, } } + /// Decorate the retained button after its icon, label and click handler + /// have been bound. The default leaves the existing button unchanged. + pub fn button_with(mut self, decorate: impl FnOnce(Button) -> Button + 'static) -> Self { + self.button_with = Some(Box::new(decorate)); + self + } + /// Set the side of the toggle button. /// /// Default is `Side::Left`. @@ -372,6 +381,10 @@ impl RenderOnce for SidebarToggleButton { false => t!("Sidebar.Collapse"), }) .icon(Icon::new(icon).size_4()) + .map(|button| match self.button_with { + Some(decorate) => decorate(button), + None => button, + }) } } diff --git a/patches/0023-sidebar-semantic-decoration.patch b/patches/0023-sidebar-semantic-decoration.patch new file mode 100644 index 0000000000..99ae39d716 --- /dev/null +++ b/patches/0023-sidebar-semantic-decoration.patch @@ -0,0 +1,105 @@ +diff --git a/crates/component/src/sidebar/menu.rs b/crates/component/src/sidebar/menu.rs +index cbaa60ca..7ca8ca05 100644 +--- a/crates/component/src/sidebar/menu.rs ++++ b/crates/component/src/sidebar/menu.rs +@@ -8,9 +8,9 @@ use crate::{ + v_flex, + }; + use gpui::{ +- AnyElement, App, ClickEvent, ElementId, InteractiveElement as _, IntoElement, +- ParentElement as _, SharedString, StatefulInteractiveElement as _, StyleRefinement, Styled, +- Window, div, percentage, prelude::FluentBuilder, ++ AnyElement, App, ClickEvent, Div, ElementId, InteractiveElement as _, IntoElement, ++ ParentElement as _, SharedString, Stateful, StatefulInteractiveElement as _, StyleRefinement, ++ Styled, Window, div, percentage, prelude::FluentBuilder, + }; + use std::rc::Rc; + +@@ -101,6 +101,7 @@ pub struct SidebarMenuItem { + click_to_toggle: bool, + children: Vec, + suffix: Option AnyElement + 'static>>, ++ item_with: Option) -> Stateful
>>, + disabled: bool, + context_menu: Option PopupMenu + 'static>>, + } +@@ -119,6 +120,7 @@ impl SidebarMenuItem { + click_to_toggle: false, + children: Vec::new(), + suffix: None, ++ item_with: None, + disabled: false, + context_menu: None, + } +@@ -196,6 +198,19 @@ impl SidebarMenuItem { + self + } + ++ /// Decorate the actual clickable row, excluding its expanded submenu. ++ /// ++ /// The existing click, open, hover and tooltip behavior is retained. This ++ /// hook supports accessibility and measured-row adapters without adding a ++ /// second interactive wrapper. It runs before the optional context menu. ++ pub fn item_with( ++ mut self, ++ decorate: impl Fn(Stateful
) -> Stateful
+ 'static, ++ ) -> Self { ++ self.item_with = Some(Rc::new(decorate)); ++ self ++ } ++ + /// Set disabled flat for menu item. + pub fn disable(mut self, disable: bool) -> Self { + self.disabled = disable; +@@ -369,6 +384,10 @@ impl SidebarItem for SidebarMenuItem { + this + } + }) ++ .map(|this| match self.item_with { ++ Some(decorate) => decorate(this), ++ None => this, ++ }) + .map(|this| { + if let Some(context_menu) = self.context_menu { + this.context_menu(move |menu, window, cx| { +diff --git a/crates/component/src/sidebar/mod.rs b/crates/component/src/sidebar/mod.rs +index 09c686bd..95a4d3d3 100644 +--- a/crates/component/src/sidebar/mod.rs ++++ b/crates/component/src/sidebar/mod.rs +@@ -305,6 +305,7 @@ pub struct SidebarToggleButton { + collapsed: bool, + side: Side, + on_click: Option>, ++ button_with: Option Button>>, + } + + impl SidebarToggleButton { +@@ -315,9 +316,17 @@ impl SidebarToggleButton { + collapsed: false, + side: Side::Left, + on_click: None, ++ button_with: None, + } + } + ++ /// Decorate the retained button after its icon, label and click handler ++ /// have been bound. The default leaves the existing button unchanged. ++ pub fn button_with(mut self, decorate: impl FnOnce(Button) -> Button + 'static) -> Self { ++ self.button_with = Some(Box::new(decorate)); ++ self ++ } ++ + /// Set the side of the toggle button. + /// + /// Default is `Side::Left`. +@@ -372,6 +381,10 @@ impl RenderOnce for SidebarToggleButton { + false => t!("Sidebar.Collapse"), + }) + .icon(Icon::new(icon).size_4()) ++ .map(|button| match self.button_with { ++ Some(decorate) => decorate(button), ++ None => button, ++ }) + } + } + diff --git a/patches/README.md b/patches/README.md index 012d2af5d4..35a1395ced 100644 --- a/patches/README.md +++ b/patches/README.md @@ -99,3 +99,14 @@ The lock follow-up synchronizes the 25 source URLs with that manifest pin. The initial guard counted URL lines rather than both revision occurrences in each URL and refused the lock write. Both exact revision occurrences now match; no package version, checksum, or dependency edge changes. + +The sidebar decoration patch exposes the existing clickable menu row through +`SidebarMenuItem::item_with` and the retained toggle button through +`SidebarToggleButton::button_with`. The row hook excludes expanded submenus; +the button hook runs after the component's icon, label and click handler are +bound. Both default to no decoration, preserving existing mechanics. They +allow the downstream semantic adapter to publish the actual activation +geometry without a second role or interactive wrapper. The ordered source +series replay and locked Wasm component library check pass; native measured +pointer/semantic parity is a consumer +gate and remains pending for this candidate. This draft requires review. diff --git a/patches/series b/patches/series index 2e56259a8f..9c66e4994c 100644 --- a/patches/series +++ b/patches/series @@ -20,3 +20,4 @@ 0020-textarea-replacement-presentation.patch 0021-gpui-selected-replacement-pin.patch 0022-gpui-selected-replacement-lock.patch +0023-sidebar-semantic-decoration.patch From b81a688dc71661b7120bed7bba6085accd4ffe49 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 10:14:24 -0400 Subject: [PATCH 23/24] fix(sidebar): retain composed keyboard and semantic row bindings --- crates/component/src/sidebar/menu.rs | 15 +++++++--- ...0024-compose-sidebar-row-decorations.patch | 30 +++++++++++++++++++ patches/README.md | 14 ++++++++- patches/series | 1 + 4 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 patches/0024-compose-sidebar-row-decorations.patch diff --git a/crates/component/src/sidebar/menu.rs b/crates/component/src/sidebar/menu.rs index 7ca8ca05b3..586ccd2b8d 100644 --- a/crates/component/src/sidebar/menu.rs +++ b/crates/component/src/sidebar/menu.rs @@ -200,14 +200,21 @@ impl SidebarMenuItem { /// Decorate the actual clickable row, excluding its expanded submenu. /// - /// The existing click, open, hover and tooltip behavior is retained. This - /// hook supports accessibility and measured-row adapters without adding a - /// second interactive wrapper. It runs before the optional context menu. + /// The existing click, open, hover and tooltip behavior is retained. + /// Repeated hooks compose in call order, supporting accessibility and + /// measured-row adapters without a second interactive wrapper. They run + /// before the optional context menu. pub fn item_with( mut self, decorate: impl Fn(Stateful
) -> Stateful
+ 'static, ) -> Self { - self.item_with = Some(Rc::new(decorate)); + let previous = self.item_with.take(); + self.item_with = Some(Rc::new(move |row| { + decorate(match &previous { + Some(previous) => previous(row), + None => row, + }) + })); self } diff --git a/patches/0024-compose-sidebar-row-decorations.patch b/patches/0024-compose-sidebar-row-decorations.patch new file mode 100644 index 0000000000..ae104b13eb --- /dev/null +++ b/patches/0024-compose-sidebar-row-decorations.patch @@ -0,0 +1,30 @@ +diff --git a/crates/component/src/sidebar/menu.rs b/crates/component/src/sidebar/menu.rs +index 7ca8ca05..586ccd2b 100644 +--- a/crates/component/src/sidebar/menu.rs ++++ b/crates/component/src/sidebar/menu.rs +@@ -200,14 +200,21 @@ impl SidebarMenuItem { + + /// Decorate the actual clickable row, excluding its expanded submenu. + /// +- /// The existing click, open, hover and tooltip behavior is retained. This +- /// hook supports accessibility and measured-row adapters without adding a +- /// second interactive wrapper. It runs before the optional context menu. ++ /// The existing click, open, hover and tooltip behavior is retained. ++ /// Repeated hooks compose in call order, supporting accessibility and ++ /// measured-row adapters without a second interactive wrapper. They run ++ /// before the optional context menu. + pub fn item_with( + mut self, + decorate: impl Fn(Stateful
) -> Stateful
+ 'static, + ) -> Self { +- self.item_with = Some(Rc::new(decorate)); ++ let previous = self.item_with.take(); ++ self.item_with = Some(Rc::new(move |row| { ++ decorate(match &previous { ++ Some(previous) => previous(row), ++ None => row, ++ }) ++ })); + self + } + diff --git a/patches/README.md b/patches/README.md index 35a1395ced..6df10adb58 100644 --- a/patches/README.md +++ b/patches/README.md @@ -109,4 +109,16 @@ allow the downstream semantic adapter to publish the actual activation geometry without a second role or interactive wrapper. The ordered source series replay and locked Wasm component library check pass; native measured pointer/semantic parity is a consumer -gate and remains pending for this candidate. This draft requires review. +gate. This draft requires review. + +Row decorations compose in call order. A native tab-stop decoration therefore +survives the subsequent semantic adapter: pinned GPUI delivers Enter and Space +through the row's existing click closure, including its submenu behavior. +No second key handler or interactive wrapper is installed. The actual consumer +AGPUI library, copied by hash into a bounded temporary workspace and bound to +this staged Kit source, passes all 159 native tests. Its new measured test +covers the parent row, expanded submenu exclusion, toggle button, pointer and +semantic activation, both keyboard keys, and disabled/read-only inertness. +The original activation, naming and Store source assertions also pass without +new exemptions. Locked consumer verification follows adoption of this exact +source revision; staged-source proof is not a browser deployment result. diff --git a/patches/series b/patches/series index 9c66e4994c..5e8c4af1d0 100644 --- a/patches/series +++ b/patches/series @@ -21,3 +21,4 @@ 0021-gpui-selected-replacement-pin.patch 0022-gpui-selected-replacement-lock.patch 0023-sidebar-semantic-decoration.patch +0024-compose-sidebar-row-decorations.patch From d03df3fbd09646b0a61dff147d8cbf74847a05d3 Mon Sep 17 00:00:00 2001 From: Travis Gilbert <1travisgilbert@gmail.com> Date: Sat, 5 Sep 2026 13:08:52 -0400 Subject: [PATCH 24/24] feat(text): expose measured link fragments and underline styles --- crates/base/src/text/inline.rs | 266 ++++++- crates/base/src/text/inline_flow.rs | 30 +- crates/base/src/text/node.rs | 21 +- crates/base/src/text/state.rs | 10 +- crates/base/src/text/text_view.rs | 83 +- crates/component/src/text/compat.rs | 25 + crates/component/src/text/mod.rs | 5 +- .../0025-measured-text-link-decoration.patch | 723 ++++++++++++++++++ patches/README.md | 10 + patches/series | 1 + 10 files changed, 1149 insertions(+), 25 deletions(-) create mode 100644 patches/0025-measured-text-link-decoration.patch diff --git a/crates/base/src/text/inline.rs b/crates/base/src/text/inline.rs index 09abe59c8b..c0711f85aa 100644 --- a/crates/base/src/text/inline.rs +++ b/crates/base/src/text/inline.rs @@ -1,15 +1,17 @@ use gpui::Corners; use std::{ + collections::BTreeMap, ops::Range, rc::Rc, sync::{Arc, Mutex}, }; use gpui::{ - App, BorderStyle, Bounds, ClickEvent, CursorStyle, Edges, Element, ElementId, GlobalElementId, - Half, HighlightStyle, Hitbox, HitboxBehavior, InspectorElementId, IntoElement, LayoutId, - MouseButton, MouseClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point, - SharedString, StyledText, TextLayout, Window, point, px, quad, + AnyElement, App, AvailableSpace, BorderStyle, Bounds, ClickEvent, CursorStyle, Edges, Element, + ElementId, GlobalElementId, Half, HighlightStyle, Hitbox, HitboxBehavior, InspectorElementId, + InteractiveElement as _, IntoElement, LayoutId, MouseButton, MouseClickEvent, MouseDownEvent, + MouseMoveEvent, MouseUpEvent, Pixels, Point, SharedString, StatefulInteractiveElement as _, + Styled as _, StyledText, TextLayout, Window, div, point, px, quad, size, }; use crate::{ @@ -19,7 +21,10 @@ use crate::{ text::node::LinkMark, text::selection::word_range_at, text::state::LineSpan, - text::text_view::{LinkClickHandlerFn, handle_link_click}, + text::text_view::{ + LinkClickHandlerFn, LinkFragment, LinkFragmentDecoratorFn, LinkUnderline, LinkUnderlineFn, + handle_link_click, + }, }; /// A inline element used to render a inline text and support selectable. @@ -32,6 +37,9 @@ pub(super) struct Inline { highlights: Vec<(Range, HighlightStyle)>, styled_text: StyledText, link_click_handler: Option>, + link_fragment_decorator: Option>, + link_source_offset: usize, + link_underline: Option>, state: Arc>, } @@ -72,10 +80,132 @@ impl Inline { text: text.clone(), styled_text: StyledText::new(text), link_click_handler, + link_fragment_decorator: None, + link_source_offset: 0, + link_underline: None, state, } } + pub(super) fn link_with( + mut self, + decorator: Option>, + source_offset: usize, + ) -> Self { + self.link_fragment_decorator = decorator; + self.link_source_offset = source_offset; + self + } + + pub(super) fn link_underline(mut self, style: Option>) -> Self { + self.link_underline = style; + self + } + + fn link_elements( + &self, + global_id: Option<&GlobalElementId>, + window: &mut Window, + cx: &mut App, + ) -> Vec { + let Some(decorator) = &self.link_fragment_decorator else { + return Vec::new(); + }; + let mut focus_handles = window + .with_element_state::, _>( + global_id.expect("Inline has a stable id"), + |retained, _| { + let state = retained.unwrap_or_default(); + (state.clone(), state) + }, + ); + let mut retained_ids = Vec::new(); + let layout = self.styled_text.layout(); + let mut elements = Vec::new(); + for (link_ix, (range, link)) in self.links.iter().enumerate() { + for (part_ix, (fragment_range, bounds)) in link_fragment_bounds(&layout, range.clone()) + .into_iter() + .enumerate() + { + let fragment = LinkFragment { + id: format!( + "link-{}-{:?}-{link_ix}-{part_ix}", + self.link_source_offset, self.id + ) + .into(), + url: link.url.clone(), + text: self.text[fragment_range].to_string().into(), + }; + let focus = focus_handles + .entry(fragment.id.clone()) + .or_insert_with(|| cx.focus_handle()) + .clone(); + retained_ids.push(fragment.id.clone()); + let click_focus = focus.clone(); + let handler = self.link_click_handler.clone(); + let url = link.url.clone(); + let text_view_state = GlobalState::global(cx).text_view_state().cloned(); + let click = move |event: &ClickEvent, window: &mut Window, cx: &mut App| { + if !matches!(event, ClickEvent::Keyboard(_)) + && text_view_state + .as_ref() + .is_some_and(|state| state.read(cx).has_selection(cx)) + { + return; + } + TextSelection::end(window, cx); + // The selection layer focuses its text participant on + // mouse down. A completed link click focuses the actual + // fragment, while a drag keeps the text selection focus. + click_focus.focus(window, cx); + // Selection queues its focus callback on mouse down. A + // semantic press can deliver down and up in one update, + // so that queued callback would otherwise run after this + // completed click and take focus back from the link. + // Correct only that participant's focus; navigation may + // have intentionally focused a different control. + if let Some(state) = &text_view_state { + let selection_focus = state.read(cx).focus_handle().clone(); + let completed_focus = click_focus.clone(); + window.defer(cx, move |window, cx| { + if selection_focus.is_focused(window) { + completed_focus.focus(window, cx); + } + }); + } + cx.stop_propagation(); + handle_link_click(&handler, url.clone(), event.clone(), window, cx); + }; + let target = div() + .id(fragment.id.clone()) + .tab_index(0) + .track_focus(&focus) + .w(bounds.size.width) + .h(bounds.size.height) + .cursor_pointer() + .on_click(click.clone()) + .on_aux_click(click); + let mut target = decorator(&fragment, target, window, cx).into_any_element(); + target.prepaint_as_root( + bounds.origin, + size( + AvailableSpace::Definite(bounds.size.width), + AvailableSpace::Definite(bounds.size.height), + ), + window, + cx, + ); + elements.push(target); + } + } + focus_handles.retain(|id, _| retained_ids.contains(id)); + window.with_element_state::, _>( + global_id.expect("Inline has a stable id"), + |_, _| ((), focus_handles), + ); + elements + } + /// Get link at given mouse position. fn link_for_position( layout: &TextLayout, @@ -338,7 +468,7 @@ impl IntoElement for Inline { impl Element for Inline { type RequestLayoutState = (); - type PrepaintState = Hitbox; + type PrepaintState = (Hitbox, Vec); fn id(&self) -> Option { Some(self.id.clone()) @@ -357,9 +487,34 @@ impl Element for Inline { ) -> (LayoutId, Self::RequestLayoutState) { let text_style = window.text_style(); + let overrides = self + .links + .iter() + .filter_map(|(range, link)| { + let style = self + .link_underline + .as_ref() + .map(|style| style(&link.url, cx)) + .unwrap_or_default(); + (style != LinkUnderline::Solid).then(|| { + ( + range.clone(), + HighlightStyle { + underline: Some(gpui::UnderlineStyle { + thickness: px(0.), + ..Default::default() + }), + ..Default::default() + }, + ) + }) + }) + .collect::>(); + let highlights = + gpui::combine_highlights(self.highlights.clone(), overrides).collect::>(); let mut runs = Vec::new(); let mut ix = 0; - for (range, highlight) in self.highlights.iter() { + for (range, highlight) in &highlights { if ix < range.start { runs.push(text_style.clone().to_run(range.start - ix)); } @@ -408,7 +563,7 @@ impl Element for Inline { } let hitbox = window.insert_hitbox(bounds, HitboxBehavior::Normal); - hitbox + (hitbox, self.link_elements(id, window, cx)) } fn paint( @@ -422,7 +577,7 @@ impl Element for Inline { cx: &mut App, ) { let current_view = window.current_view(); - let hitbox = prepaint; + let (hitbox, link_elements) = prepaint; let Ok(mut state) = self.state.lock() else { return; }; @@ -431,6 +586,31 @@ impl Element for Inline { self.styled_text .paint(global_id, None, bounds, &mut (), &mut (), window, cx); + for (range, link) in self.links.iter() { + if self + .link_underline + .as_ref() + .map(|style| style(&link.url, cx)) + != Some(LinkUnderline::Dotted) + { + continue; + } + let color = self + .highlights + .iter() + .find_map(|(span, style)| { + (span.start <= range.start && range.start < span.end) + .then_some(style.color) + .flatten() + }) + .unwrap_or(window.text_style().color); + for (_, fragment) in link_fragment_bounds(&text_layout, range.clone()) { + for dot in dotted_underline_bounds(fragment) { + window.paint_quad(gpui::fill(dot, color)); + } + } + } + // layout selections let (is_selectable, is_selection, selection) = self.layout_selections(&text_layout, &bounds, window, cx); @@ -541,7 +721,7 @@ impl Element for Inline { } }); - if !is_selection { + if !is_selection && self.link_fragment_decorator.is_none() { // click to open link window.on_mouse_event({ let links = self.links.clone(); @@ -581,7 +761,73 @@ impl Element for Inline { } }); } + // These are the actual link targets, positioned by the same glyph + // layout painted above. Their click handlers replace the legacy hit + // test only when the caller requested a decorator. + for element in link_elements { + element.paint(window, cx); + } + } +} + +/// Split at actual hard/soft line boundaries. Widths come from shaped glyph +/// advances, including the final glyph before a wrap, never an estimated font +/// width or a union spanning multiple lines. +fn link_fragment_bounds( + layout: &TextLayout, + range: Range, +) -> Vec<(Range, Bounds)> { + let mut fragments = Vec::new(); + let mut line_start = 0; + let mut line_y = layout.bounds().top(); + for line in layout.line_layouts() { + let boundaries = std::iter::once(0) + .chain(line.wrap_boundaries.iter().map(|boundary| { + line.unwrapped_layout.runs[boundary.run_ix].glyphs[boundary.glyph_ix].index + })) + .chain(std::iter::once(line.len())) + .collect::>(); + for (row_ix, row) in boundaries.windows(2).enumerate() { + let start = range.start.max(line_start + row[0]); + let end = range.end.min(line_start + row[1]); + if start >= end { + continue; + } + // position_for_index deliberately gives a wrap boundary the + // previous line's caret affinity. A visual fragment starts on the + // next row, so use the actual wrap row and shaped x advances. + let origin = point( + layout.bounds().left() + line.unwrapped_layout.x_for_index(start - line_start) + - line.unwrapped_layout.x_for_index(row[0]), + line_y + layout.line_height() * row_ix, + ); + let width = line.unwrapped_layout.x_for_index(end - line_start) + - line.unwrapped_layout.x_for_index(start - line_start); + if width > px(0.) { + fragments.push(( + start..end, + Bounds::new(origin, size(width, layout.line_height())), + )); + } + } + line_start += line.len() + 1; + line_y += line.size(layout.line_height()).height; + } + fragments +} + +/// One-pixel dots separated by two clear pixels on each measured fragment. +fn dotted_underline_bounds(fragment: Bounds) -> Vec> { + let mut dots = Vec::new(); + let mut x = fragment.left(); + while x < fragment.right() { + dots.push(Bounds::new( + point(x, fragment.bottom() - px(2.)), + size(px(1.).min(fragment.right() - x), px(1.)), + )); + x += px(3.); } + dots } fn selection_for_multi_click( diff --git a/crates/base/src/text/inline_flow.rs b/crates/base/src/text/inline_flow.rs index 0170601415..e36c716ab7 100644 --- a/crates/base/src/text/inline_flow.rs +++ b/crates/base/src/text/inline_flow.rs @@ -11,7 +11,9 @@ use gpui::{ WhiteSpace, Window, img, point, prelude::FluentBuilder as _, px, relative, size, }; -use crate::text::text_view::{LinkClickHandlerFn, handle_link_click}; +use crate::text::text_view::{ + LinkClickHandlerFn, LinkFragmentDecoratorFn, LinkUnderlineFn, handle_link_click, +}; use super::{ inline::{Inline, InlineState}, @@ -25,6 +27,9 @@ pub(super) struct InlineFlow { id: ElementId, items: Vec, link_click_handler: Option>, + link_fragment_decorator: Option>, + link_source_offset: usize, + link_underline: Option>, } pub(super) enum InlineFlowItem { @@ -111,9 +116,27 @@ impl InlineFlow { id: id.into(), items, link_click_handler, + link_fragment_decorator: None, + link_source_offset: 0, + link_underline: None, } } + pub(super) fn link_with( + mut self, + decorator: Option>, + source_offset: usize, + ) -> Self { + self.link_fragment_decorator = decorator; + self.link_source_offset = source_offset; + self + } + + pub(super) fn link_underline(mut self, style: Option>) -> Self { + self.link_underline = style; + self + } + fn image_element( ix: usize, url: &SharedUri, @@ -286,6 +309,11 @@ impl Element for InlineFlow { highlights, self.link_click_handler.clone(), ) + .link_with( + self.link_fragment_decorator.clone(), + self.link_source_offset + source_range.start, + ) + .link_underline(self.link_underline.clone()) .into_any_element(); element.prepaint_as_root( bounds.origin + origin, diff --git a/crates/base/src/text/node.rs b/crates/base/src/text/node.rs index a008ccc4de..34133f457f 100644 --- a/crates/base/src/text/node.rs +++ b/crates/base/src/text/node.rs @@ -17,8 +17,8 @@ use crate::{ StyledExt, h_flex, scrollable_mask::horizontal_scroll_area, text::{ - CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, MarkdownExtensions, - MarkdownNode, TableActionsFn, + CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, LinkFragmentDecoratorFn, + LinkUnderlineFn, MarkdownExtensions, MarkdownNode, TableActionsFn, document::NodeRenderOptions, inline::{Inline, InlineState}, inline_flow::{InlineFlow, InlineFlowItem}, @@ -1336,6 +1336,8 @@ pub(crate) struct NodeContext { pub(crate) code_block_actions: Option>, pub(crate) code_block_highlighter: Option>, pub(crate) table_actions: Option>, + pub(crate) link_underline: Option>, + pub(crate) link_fragment_decorator: Option>, pub(crate) link_click_handler: Option>, pub(crate) markdown_extensions: Arc, } @@ -1365,6 +1367,11 @@ impl Paragraph { self.inline_flow_items(node_cx, cx), node_cx.link_click_handler.clone(), ) + .link_with( + node_cx.link_fragment_decorator.clone(), + node_cx.offset + span.unwrap_or_default().start, + ) + .link_underline(node_cx.link_underline.clone()) .into_any_element(); } @@ -1393,6 +1400,11 @@ impl Paragraph { highlights.clone(), node_cx.link_click_handler.clone(), ) + .link_with( + node_cx.link_fragment_decorator.clone(), + node_cx.offset + span.unwrap_or_default().start, + ) + .link_underline(node_cx.link_underline.clone()) .into_any_element(), ); } @@ -1508,6 +1520,11 @@ impl Paragraph { highlights, node_cx.link_click_handler.clone(), ) + .link_with( + node_cx.link_fragment_decorator.clone(), + node_cx.offset + span.unwrap_or_default().start, + ) + .link_underline(node_cx.link_underline.clone()) .into_any_element(), ); } diff --git a/crates/base/src/text/state.rs b/crates/base/src/text/state.rs index 8e08c75ec7..073184475a 100644 --- a/crates/base/src/text/state.rs +++ b/crates/base/src/text/state.rs @@ -17,8 +17,8 @@ use crate::{ async_util::{Receiver, Sender, unbounded}, input::{self, SelectAll}, text::{ - CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, MarkdownExtensions, - TableActionsFn, TextViewStyle, + CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, LinkFragmentDecoratorFn, + LinkUnderlineFn, MarkdownExtensions, TableActionsFn, TextViewStyle, document::ParsedDocument, format, node::{self, NodeContext}, @@ -103,6 +103,8 @@ pub struct TextViewState { pub(super) code_block_actions: Option>, pub(super) code_block_highlighter: Option>, pub(super) table_actions: Option>, + pub(super) link_underline: Option>, + pub(super) link_fragment_decorator: Option>, pub(super) link_click_handler: Option>, pub(super) markdown_extensions: Arc, @@ -203,6 +205,8 @@ impl TextViewState { code_block_highlighter: None, table_actions: None, link_click_handler: None, + link_fragment_decorator: None, + link_underline: None, markdown_extensions: Arc::default(), is_selecting: false, auto_scroll: AutoScroll::default(), @@ -613,6 +617,8 @@ impl Render for TextViewState { node_cx.code_block_highlighter = self.code_block_highlighter.clone(); node_cx.table_actions = self.table_actions.clone(); node_cx.link_click_handler = self.link_click_handler.clone(); + node_cx.link_fragment_decorator = self.link_fragment_decorator.clone(); + node_cx.link_underline = self.link_underline.clone(); node_cx.markdown_extensions = self.markdown_extensions.clone(); node_cx.style = self.text_view_style.clone(); diff --git a/crates/base/src/text/text_view.rs b/crates/base/src/text/text_view.rs index 535ee643e4..2857e1c1fa 100644 --- a/crates/base/src/text/text_view.rs +++ b/crates/base/src/text/text_view.rs @@ -73,6 +73,34 @@ impl TextViewDefaults { pub(crate) type TableActionsFn = dyn Fn(&TableData, &mut Window, &mut App) -> AnyElement + Send + Sync; +/// A measured visual fragment of a parsed text link. Wrapped links publish one +/// fragment per visual line, never a rectangle covering the intervening prose. +#[derive(Clone, Debug)] +pub struct LinkFragment { + /// Stable fragment identity within the containing text view. + pub id: SharedString, + /// The URL resolved by the existing Markdown/HTML parser. + pub url: SharedString, + /// The visible text of this fragment, without Markdown syntax. + pub text: SharedString, +} + +/// Presentation of a parsed text link. The default is the existing solid +/// underline; dotted suggestions keep the same glyph layout and hit target. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub enum LinkUnderline { + #[default] + Solid, + Dotted, + None, +} + +pub(crate) type LinkUnderlineFn = dyn Fn(&SharedString, &App) -> LinkUnderline + Send + Sync; + +pub(crate) type LinkFragmentDecoratorFn = dyn Fn(&LinkFragment, gpui::Stateful, &mut Window, &mut App) -> gpui::Stateful + + Send + + Sync; + pub(crate) type LinkClickHandlerFn = dyn Fn(&SharedString, &ClickEvent, &mut Window, &mut App) + Send + Sync; @@ -128,6 +156,8 @@ pub struct TextView { code_block_highlighter: Option>, table_actions: Option>, link_click_handler: Option>, + link_fragment_decorator: Option>, + link_underline: Option>, markdown_extensions: Arc, } @@ -172,6 +202,8 @@ impl TextView { code_block_highlighter: None, table_actions: None, link_click_handler: None, + link_fragment_decorator: None, + link_underline: None, markdown_extensions: Arc::default(), } } @@ -193,6 +225,8 @@ impl TextView { code_block_highlighter: None, table_actions: None, link_click_handler: None, + link_fragment_decorator: None, + link_underline: None, markdown_extensions: Arc::default(), } } @@ -214,6 +248,8 @@ impl TextView { code_block_highlighter: None, table_actions: None, link_click_handler: None, + link_fragment_decorator: None, + link_underline: None, markdown_extensions: Arc::default(), } } @@ -333,6 +369,37 @@ impl TextView { self } + /// Selects link underline presentation without changing text or layout. + /// Unspecified views retain their existing solid underline. + pub fn link_underline(mut self, style: F) -> Self + where + F: Fn(&SharedString, &App) -> LinkUnderline + Send + Sync + 'static, + { + self.link_underline = Some(Arc::new(style)); + self + } + + /// Decorates each actual, measured text-link target after its ordinary + /// click handler is installed. This can publish accessibility, focus and + /// hover behavior on the same fragment. The parser, text layout and text + /// selection remain owned by TextView. The decorator must preserve the + /// supplied target's dimensions and existing click handler. + pub fn link_with(mut self, decorator: F) -> Self + where + F: Fn( + &LinkFragment, + gpui::Stateful, + &mut Window, + &mut App, + ) -> gpui::Stateful + + Send + + Sync + + 'static, + { + self.link_fragment_decorator = Some(Arc::new(decorator)); + self + } + /// Replace the Markdown extension registry. pub fn markdown_extensions(mut self, extensions: MarkdownExtensions) -> Self { self.markdown_extensions = Arc::new(extensions); @@ -554,6 +621,8 @@ impl Element for TextView { state.code_block_highlighter = code_block_highlighter.clone(); state.table_actions = self.table_actions.clone(); state.link_click_handler = self.link_click_handler.clone(); + state.link_fragment_decorator = self.link_fragment_decorator.clone(); + state.link_underline = self.link_underline.clone(); state.set_markdown_extensions(self.markdown_extensions.clone(), cx); state.selectable = self.selectable; state.selection_format = self.selection_format; @@ -630,16 +699,14 @@ impl Element for TextView { if let Ok(mut line_spans) = state.read(cx).line_spans.lock() { line_spans.clear(); } - // Descendant `Inline`s report their line spans through the state - // stack during prepaint (in addition to the paint-time push below). - GlobalState::global_mut(cx) - .text_view_state_stack - .push(state.clone()); } + // Measured link targets retain this same selection authority. Clamped + // descendants additionally report their line spans through the stack. + GlobalState::global_mut(cx) + .text_view_state_stack + .push(state.clone()); request_layout.element.prepaint(window, cx); - if max_lines_active { - GlobalState::global_mut(cx).text_view_state_stack.pop(); - } + GlobalState::global_mut(cx).text_view_state_stack.pop(); let mut clip_bottom = None; if max_lines_active { diff --git a/crates/component/src/text/compat.rs b/crates/component/src/text/compat.rs index a59bb5fb82..6ffcfe546a 100644 --- a/crates/component/src/text/compat.rs +++ b/crates/component/src/text/compat.rs @@ -107,6 +107,31 @@ impl TextView { self.inner = self.inner.on_link_click(f); self } + /// Selects Base's solid, dotted or absent underline on the existing text. + pub fn link_underline(mut self, style: F) -> Self + where + F: Fn(&SharedString, &App) -> gpui_base::text::LinkUnderline + Send + Sync + 'static, + { + self.inner = self.inner.link_underline(style); + self + } + /// Decorates the actual measured Base link targets, preserving its parser, + /// selection and click behavior. See [`gpui_base::TextView::link_with`]. + pub fn link_with(mut self, decorator: F) -> Self + where + F: Fn( + &gpui_base::text::LinkFragment, + gpui::Stateful, + &mut Window, + &mut App, + ) -> gpui::Stateful + + Send + + Sync + + 'static, + { + self.inner = self.inner.link_with(decorator); + self + } /// Sets which Markdown extensions the parser accepts. pub fn markdown_extensions(mut self, value: MarkdownExtensions) -> Self { self.inner = self.inner.markdown_extensions(value); diff --git a/crates/component/src/text/mod.rs b/crates/component/src/text/mod.rs index d594bd57e0..dee556464f 100644 --- a/crates/component/src/text/mod.rs +++ b/crates/component/src/text/mod.rs @@ -7,8 +7,9 @@ pub use compat::{ Text, TextView, TextViewLayoutState, TextViewPlugin, TextViewPrepaintState, html, markdown, }; pub use gpui_base::text::{ - MarkdownBlockParserFn, MarkdownBlockRenderFn, MarkdownExtensions, MarkdownNode, - MarkdownParseContext, MarkdownPlugin, SelectionFormat, TableData, TextViewState, markdown_ast, + LinkFragment, LinkUnderline, MarkdownBlockParserFn, MarkdownBlockRenderFn, MarkdownExtensions, + MarkdownNode, MarkdownParseContext, MarkdownPlugin, SelectionFormat, TableData, TextViewState, + markdown_ast, }; pub use style::TextViewStyle; diff --git a/patches/0025-measured-text-link-decoration.patch b/patches/0025-measured-text-link-decoration.patch new file mode 100644 index 0000000000..d911af6a74 --- /dev/null +++ b/patches/0025-measured-text-link-decoration.patch @@ -0,0 +1,723 @@ +diff --git a/crates/base/src/text/inline.rs b/crates/base/src/text/inline.rs +index 09abe59c..c0711f85 100644 +--- a/crates/base/src/text/inline.rs ++++ b/crates/base/src/text/inline.rs +@@ -1,15 +1,17 @@ + use gpui::Corners; + use std::{ ++ collections::BTreeMap, + ops::Range, + rc::Rc, + sync::{Arc, Mutex}, + }; + + use gpui::{ +- App, BorderStyle, Bounds, ClickEvent, CursorStyle, Edges, Element, ElementId, GlobalElementId, +- Half, HighlightStyle, Hitbox, HitboxBehavior, InspectorElementId, IntoElement, LayoutId, +- MouseButton, MouseClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point, +- SharedString, StyledText, TextLayout, Window, point, px, quad, ++ AnyElement, App, AvailableSpace, BorderStyle, Bounds, ClickEvent, CursorStyle, Edges, Element, ++ ElementId, GlobalElementId, Half, HighlightStyle, Hitbox, HitboxBehavior, InspectorElementId, ++ InteractiveElement as _, IntoElement, LayoutId, MouseButton, MouseClickEvent, MouseDownEvent, ++ MouseMoveEvent, MouseUpEvent, Pixels, Point, SharedString, StatefulInteractiveElement as _, ++ Styled as _, StyledText, TextLayout, Window, div, point, px, quad, size, + }; + + use crate::{ +@@ -19,7 +21,10 @@ use crate::{ + text::node::LinkMark, + text::selection::word_range_at, + text::state::LineSpan, +- text::text_view::{LinkClickHandlerFn, handle_link_click}, ++ text::text_view::{ ++ LinkClickHandlerFn, LinkFragment, LinkFragmentDecoratorFn, LinkUnderline, LinkUnderlineFn, ++ handle_link_click, ++ }, + }; + + /// A inline element used to render a inline text and support selectable. +@@ -32,6 +37,9 @@ pub(super) struct Inline { + highlights: Vec<(Range, HighlightStyle)>, + styled_text: StyledText, + link_click_handler: Option>, ++ link_fragment_decorator: Option>, ++ link_source_offset: usize, ++ link_underline: Option>, + + state: Arc>, + } +@@ -72,10 +80,132 @@ impl Inline { + text: text.clone(), + styled_text: StyledText::new(text), + link_click_handler, ++ link_fragment_decorator: None, ++ link_source_offset: 0, ++ link_underline: None, + state, + } + } + ++ pub(super) fn link_with( ++ mut self, ++ decorator: Option>, ++ source_offset: usize, ++ ) -> Self { ++ self.link_fragment_decorator = decorator; ++ self.link_source_offset = source_offset; ++ self ++ } ++ ++ pub(super) fn link_underline(mut self, style: Option>) -> Self { ++ self.link_underline = style; ++ self ++ } ++ ++ fn link_elements( ++ &self, ++ global_id: Option<&GlobalElementId>, ++ window: &mut Window, ++ cx: &mut App, ++ ) -> Vec { ++ let Some(decorator) = &self.link_fragment_decorator else { ++ return Vec::new(); ++ }; ++ let mut focus_handles = window ++ .with_element_state::, _>( ++ global_id.expect("Inline has a stable id"), ++ |retained, _| { ++ let state = retained.unwrap_or_default(); ++ (state.clone(), state) ++ }, ++ ); ++ let mut retained_ids = Vec::new(); ++ let layout = self.styled_text.layout(); ++ let mut elements = Vec::new(); ++ for (link_ix, (range, link)) in self.links.iter().enumerate() { ++ for (part_ix, (fragment_range, bounds)) in link_fragment_bounds(&layout, range.clone()) ++ .into_iter() ++ .enumerate() ++ { ++ let fragment = LinkFragment { ++ id: format!( ++ "link-{}-{:?}-{link_ix}-{part_ix}", ++ self.link_source_offset, self.id ++ ) ++ .into(), ++ url: link.url.clone(), ++ text: self.text[fragment_range].to_string().into(), ++ }; ++ let focus = focus_handles ++ .entry(fragment.id.clone()) ++ .or_insert_with(|| cx.focus_handle()) ++ .clone(); ++ retained_ids.push(fragment.id.clone()); ++ let click_focus = focus.clone(); ++ let handler = self.link_click_handler.clone(); ++ let url = link.url.clone(); ++ let text_view_state = GlobalState::global(cx).text_view_state().cloned(); ++ let click = move |event: &ClickEvent, window: &mut Window, cx: &mut App| { ++ if !matches!(event, ClickEvent::Keyboard(_)) ++ && text_view_state ++ .as_ref() ++ .is_some_and(|state| state.read(cx).has_selection(cx)) ++ { ++ return; ++ } ++ TextSelection::end(window, cx); ++ // The selection layer focuses its text participant on ++ // mouse down. A completed link click focuses the actual ++ // fragment, while a drag keeps the text selection focus. ++ click_focus.focus(window, cx); ++ // Selection queues its focus callback on mouse down. A ++ // semantic press can deliver down and up in one update, ++ // so that queued callback would otherwise run after this ++ // completed click and take focus back from the link. ++ // Correct only that participant's focus; navigation may ++ // have intentionally focused a different control. ++ if let Some(state) = &text_view_state { ++ let selection_focus = state.read(cx).focus_handle().clone(); ++ let completed_focus = click_focus.clone(); ++ window.defer(cx, move |window, cx| { ++ if selection_focus.is_focused(window) { ++ completed_focus.focus(window, cx); ++ } ++ }); ++ } ++ cx.stop_propagation(); ++ handle_link_click(&handler, url.clone(), event.clone(), window, cx); ++ }; ++ let target = div() ++ .id(fragment.id.clone()) ++ .tab_index(0) ++ .track_focus(&focus) ++ .w(bounds.size.width) ++ .h(bounds.size.height) ++ .cursor_pointer() ++ .on_click(click.clone()) ++ .on_aux_click(click); ++ let mut target = decorator(&fragment, target, window, cx).into_any_element(); ++ target.prepaint_as_root( ++ bounds.origin, ++ size( ++ AvailableSpace::Definite(bounds.size.width), ++ AvailableSpace::Definite(bounds.size.height), ++ ), ++ window, ++ cx, ++ ); ++ elements.push(target); ++ } ++ } ++ focus_handles.retain(|id, _| retained_ids.contains(id)); ++ window.with_element_state::, _>( ++ global_id.expect("Inline has a stable id"), ++ |_, _| ((), focus_handles), ++ ); ++ elements ++ } ++ + /// Get link at given mouse position. + fn link_for_position( + layout: &TextLayout, +@@ -338,7 +468,7 @@ impl IntoElement for Inline { + + impl Element for Inline { + type RequestLayoutState = (); +- type PrepaintState = Hitbox; ++ type PrepaintState = (Hitbox, Vec); + + fn id(&self) -> Option { + Some(self.id.clone()) +@@ -357,9 +487,34 @@ impl Element for Inline { + ) -> (LayoutId, Self::RequestLayoutState) { + let text_style = window.text_style(); + ++ let overrides = self ++ .links ++ .iter() ++ .filter_map(|(range, link)| { ++ let style = self ++ .link_underline ++ .as_ref() ++ .map(|style| style(&link.url, cx)) ++ .unwrap_or_default(); ++ (style != LinkUnderline::Solid).then(|| { ++ ( ++ range.clone(), ++ HighlightStyle { ++ underline: Some(gpui::UnderlineStyle { ++ thickness: px(0.), ++ ..Default::default() ++ }), ++ ..Default::default() ++ }, ++ ) ++ }) ++ }) ++ .collect::>(); ++ let highlights = ++ gpui::combine_highlights(self.highlights.clone(), overrides).collect::>(); + let mut runs = Vec::new(); + let mut ix = 0; +- for (range, highlight) in self.highlights.iter() { ++ for (range, highlight) in &highlights { + if ix < range.start { + runs.push(text_style.clone().to_run(range.start - ix)); + } +@@ -408,7 +563,7 @@ impl Element for Inline { + } + + let hitbox = window.insert_hitbox(bounds, HitboxBehavior::Normal); +- hitbox ++ (hitbox, self.link_elements(id, window, cx)) + } + + fn paint( +@@ -422,7 +577,7 @@ impl Element for Inline { + cx: &mut App, + ) { + let current_view = window.current_view(); +- let hitbox = prepaint; ++ let (hitbox, link_elements) = prepaint; + let Ok(mut state) = self.state.lock() else { + return; + }; +@@ -431,6 +586,31 @@ impl Element for Inline { + self.styled_text + .paint(global_id, None, bounds, &mut (), &mut (), window, cx); + ++ for (range, link) in self.links.iter() { ++ if self ++ .link_underline ++ .as_ref() ++ .map(|style| style(&link.url, cx)) ++ != Some(LinkUnderline::Dotted) ++ { ++ continue; ++ } ++ let color = self ++ .highlights ++ .iter() ++ .find_map(|(span, style)| { ++ (span.start <= range.start && range.start < span.end) ++ .then_some(style.color) ++ .flatten() ++ }) ++ .unwrap_or(window.text_style().color); ++ for (_, fragment) in link_fragment_bounds(&text_layout, range.clone()) { ++ for dot in dotted_underline_bounds(fragment) { ++ window.paint_quad(gpui::fill(dot, color)); ++ } ++ } ++ } ++ + // layout selections + let (is_selectable, is_selection, selection) = + self.layout_selections(&text_layout, &bounds, window, cx); +@@ -541,7 +721,7 @@ impl Element for Inline { + } + }); + +- if !is_selection { ++ if !is_selection && self.link_fragment_decorator.is_none() { + // click to open link + window.on_mouse_event({ + let links = self.links.clone(); +@@ -581,7 +761,73 @@ impl Element for Inline { + } + }); + } ++ // These are the actual link targets, positioned by the same glyph ++ // layout painted above. Their click handlers replace the legacy hit ++ // test only when the caller requested a decorator. ++ for element in link_elements { ++ element.paint(window, cx); ++ } ++ } ++} ++ ++/// Split at actual hard/soft line boundaries. Widths come from shaped glyph ++/// advances, including the final glyph before a wrap, never an estimated font ++/// width or a union spanning multiple lines. ++fn link_fragment_bounds( ++ layout: &TextLayout, ++ range: Range, ++) -> Vec<(Range, Bounds)> { ++ let mut fragments = Vec::new(); ++ let mut line_start = 0; ++ let mut line_y = layout.bounds().top(); ++ for line in layout.line_layouts() { ++ let boundaries = std::iter::once(0) ++ .chain(line.wrap_boundaries.iter().map(|boundary| { ++ line.unwrapped_layout.runs[boundary.run_ix].glyphs[boundary.glyph_ix].index ++ })) ++ .chain(std::iter::once(line.len())) ++ .collect::>(); ++ for (row_ix, row) in boundaries.windows(2).enumerate() { ++ let start = range.start.max(line_start + row[0]); ++ let end = range.end.min(line_start + row[1]); ++ if start >= end { ++ continue; ++ } ++ // position_for_index deliberately gives a wrap boundary the ++ // previous line's caret affinity. A visual fragment starts on the ++ // next row, so use the actual wrap row and shaped x advances. ++ let origin = point( ++ layout.bounds().left() + line.unwrapped_layout.x_for_index(start - line_start) ++ - line.unwrapped_layout.x_for_index(row[0]), ++ line_y + layout.line_height() * row_ix, ++ ); ++ let width = line.unwrapped_layout.x_for_index(end - line_start) ++ - line.unwrapped_layout.x_for_index(start - line_start); ++ if width > px(0.) { ++ fragments.push(( ++ start..end, ++ Bounds::new(origin, size(width, layout.line_height())), ++ )); ++ } ++ } ++ line_start += line.len() + 1; ++ line_y += line.size(layout.line_height()).height; ++ } ++ fragments ++} ++ ++/// One-pixel dots separated by two clear pixels on each measured fragment. ++fn dotted_underline_bounds(fragment: Bounds) -> Vec> { ++ let mut dots = Vec::new(); ++ let mut x = fragment.left(); ++ while x < fragment.right() { ++ dots.push(Bounds::new( ++ point(x, fragment.bottom() - px(2.)), ++ size(px(1.).min(fragment.right() - x), px(1.)), ++ )); ++ x += px(3.); + } ++ dots + } + + fn selection_for_multi_click( +diff --git a/crates/base/src/text/inline_flow.rs b/crates/base/src/text/inline_flow.rs +index 01706014..e36c716a 100644 +--- a/crates/base/src/text/inline_flow.rs ++++ b/crates/base/src/text/inline_flow.rs +@@ -11,7 +11,9 @@ use gpui::{ + WhiteSpace, Window, img, point, prelude::FluentBuilder as _, px, relative, size, + }; + +-use crate::text::text_view::{LinkClickHandlerFn, handle_link_click}; ++use crate::text::text_view::{ ++ LinkClickHandlerFn, LinkFragmentDecoratorFn, LinkUnderlineFn, handle_link_click, ++}; + + use super::{ + inline::{Inline, InlineState}, +@@ -25,6 +27,9 @@ pub(super) struct InlineFlow { + id: ElementId, + items: Vec, + link_click_handler: Option>, ++ link_fragment_decorator: Option>, ++ link_source_offset: usize, ++ link_underline: Option>, + } + + pub(super) enum InlineFlowItem { +@@ -111,9 +116,27 @@ impl InlineFlow { + id: id.into(), + items, + link_click_handler, ++ link_fragment_decorator: None, ++ link_source_offset: 0, ++ link_underline: None, + } + } + ++ pub(super) fn link_with( ++ mut self, ++ decorator: Option>, ++ source_offset: usize, ++ ) -> Self { ++ self.link_fragment_decorator = decorator; ++ self.link_source_offset = source_offset; ++ self ++ } ++ ++ pub(super) fn link_underline(mut self, style: Option>) -> Self { ++ self.link_underline = style; ++ self ++ } ++ + fn image_element( + ix: usize, + url: &SharedUri, +@@ -286,6 +309,11 @@ impl Element for InlineFlow { + highlights, + self.link_click_handler.clone(), + ) ++ .link_with( ++ self.link_fragment_decorator.clone(), ++ self.link_source_offset + source_range.start, ++ ) ++ .link_underline(self.link_underline.clone()) + .into_any_element(); + element.prepaint_as_root( + bounds.origin + origin, +diff --git a/crates/base/src/text/node.rs b/crates/base/src/text/node.rs +index a008ccc4..34133f45 100644 +--- a/crates/base/src/text/node.rs ++++ b/crates/base/src/text/node.rs +@@ -17,8 +17,8 @@ use crate::{ + StyledExt, h_flex, + scrollable_mask::horizontal_scroll_area, + text::{ +- CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, MarkdownExtensions, +- MarkdownNode, TableActionsFn, ++ CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, LinkFragmentDecoratorFn, ++ LinkUnderlineFn, MarkdownExtensions, MarkdownNode, TableActionsFn, + document::NodeRenderOptions, + inline::{Inline, InlineState}, + inline_flow::{InlineFlow, InlineFlowItem}, +@@ -1336,6 +1336,8 @@ pub(crate) struct NodeContext { + pub(crate) code_block_actions: Option>, + pub(crate) code_block_highlighter: Option>, + pub(crate) table_actions: Option>, ++ pub(crate) link_underline: Option>, ++ pub(crate) link_fragment_decorator: Option>, + pub(crate) link_click_handler: Option>, + pub(crate) markdown_extensions: Arc, + } +@@ -1365,6 +1367,11 @@ impl Paragraph { + self.inline_flow_items(node_cx, cx), + node_cx.link_click_handler.clone(), + ) ++ .link_with( ++ node_cx.link_fragment_decorator.clone(), ++ node_cx.offset + span.unwrap_or_default().start, ++ ) ++ .link_underline(node_cx.link_underline.clone()) + .into_any_element(); + } + +@@ -1393,6 +1400,11 @@ impl Paragraph { + highlights.clone(), + node_cx.link_click_handler.clone(), + ) ++ .link_with( ++ node_cx.link_fragment_decorator.clone(), ++ node_cx.offset + span.unwrap_or_default().start, ++ ) ++ .link_underline(node_cx.link_underline.clone()) + .into_any_element(), + ); + } +@@ -1508,6 +1520,11 @@ impl Paragraph { + highlights, + node_cx.link_click_handler.clone(), + ) ++ .link_with( ++ node_cx.link_fragment_decorator.clone(), ++ node_cx.offset + span.unwrap_or_default().start, ++ ) ++ .link_underline(node_cx.link_underline.clone()) + .into_any_element(), + ); + } +diff --git a/crates/base/src/text/state.rs b/crates/base/src/text/state.rs +index 8e08c75e..07318447 100644 +--- a/crates/base/src/text/state.rs ++++ b/crates/base/src/text/state.rs +@@ -17,8 +17,8 @@ use crate::{ + async_util::{Receiver, Sender, unbounded}, + input::{self, SelectAll}, + text::{ +- CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, MarkdownExtensions, +- TableActionsFn, TextViewStyle, ++ CodeBlockActionsFn, CodeBlockHighlighterFn, LinkClickHandlerFn, LinkFragmentDecoratorFn, ++ LinkUnderlineFn, MarkdownExtensions, TableActionsFn, TextViewStyle, + document::ParsedDocument, + format, + node::{self, NodeContext}, +@@ -103,6 +103,8 @@ pub struct TextViewState { + pub(super) code_block_actions: Option>, + pub(super) code_block_highlighter: Option>, + pub(super) table_actions: Option>, ++ pub(super) link_underline: Option>, ++ pub(super) link_fragment_decorator: Option>, + pub(super) link_click_handler: Option>, + pub(super) markdown_extensions: Arc, + +@@ -203,6 +205,8 @@ impl TextViewState { + code_block_highlighter: None, + table_actions: None, + link_click_handler: None, ++ link_fragment_decorator: None, ++ link_underline: None, + markdown_extensions: Arc::default(), + is_selecting: false, + auto_scroll: AutoScroll::default(), +@@ -613,6 +617,8 @@ impl Render for TextViewState { + node_cx.code_block_highlighter = self.code_block_highlighter.clone(); + node_cx.table_actions = self.table_actions.clone(); + node_cx.link_click_handler = self.link_click_handler.clone(); ++ node_cx.link_fragment_decorator = self.link_fragment_decorator.clone(); ++ node_cx.link_underline = self.link_underline.clone(); + node_cx.markdown_extensions = self.markdown_extensions.clone(); + node_cx.style = self.text_view_style.clone(); + +diff --git a/crates/base/src/text/text_view.rs b/crates/base/src/text/text_view.rs +index 535ee643..2857e1c1 100644 +--- a/crates/base/src/text/text_view.rs ++++ b/crates/base/src/text/text_view.rs +@@ -73,6 +73,34 @@ impl TextViewDefaults { + pub(crate) type TableActionsFn = + dyn Fn(&TableData, &mut Window, &mut App) -> AnyElement + Send + Sync; + ++/// A measured visual fragment of a parsed text link. Wrapped links publish one ++/// fragment per visual line, never a rectangle covering the intervening prose. ++#[derive(Clone, Debug)] ++pub struct LinkFragment { ++ /// Stable fragment identity within the containing text view. ++ pub id: SharedString, ++ /// The URL resolved by the existing Markdown/HTML parser. ++ pub url: SharedString, ++ /// The visible text of this fragment, without Markdown syntax. ++ pub text: SharedString, ++} ++ ++/// Presentation of a parsed text link. The default is the existing solid ++/// underline; dotted suggestions keep the same glyph layout and hit target. ++#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] ++pub enum LinkUnderline { ++ #[default] ++ Solid, ++ Dotted, ++ None, ++} ++ ++pub(crate) type LinkUnderlineFn = dyn Fn(&SharedString, &App) -> LinkUnderline + Send + Sync; ++ ++pub(crate) type LinkFragmentDecoratorFn = dyn Fn(&LinkFragment, gpui::Stateful, &mut Window, &mut App) -> gpui::Stateful ++ + Send ++ + Sync; ++ + pub(crate) type LinkClickHandlerFn = + dyn Fn(&SharedString, &ClickEvent, &mut Window, &mut App) + Send + Sync; + +@@ -128,6 +156,8 @@ pub struct TextView { + code_block_highlighter: Option>, + table_actions: Option>, + link_click_handler: Option>, ++ link_fragment_decorator: Option>, ++ link_underline: Option>, + markdown_extensions: Arc, + } + +@@ -172,6 +202,8 @@ impl TextView { + code_block_highlighter: None, + table_actions: None, + link_click_handler: None, ++ link_fragment_decorator: None, ++ link_underline: None, + markdown_extensions: Arc::default(), + } + } +@@ -193,6 +225,8 @@ impl TextView { + code_block_highlighter: None, + table_actions: None, + link_click_handler: None, ++ link_fragment_decorator: None, ++ link_underline: None, + markdown_extensions: Arc::default(), + } + } +@@ -214,6 +248,8 @@ impl TextView { + code_block_highlighter: None, + table_actions: None, + link_click_handler: None, ++ link_fragment_decorator: None, ++ link_underline: None, + markdown_extensions: Arc::default(), + } + } +@@ -333,6 +369,37 @@ impl TextView { + self + } + ++ /// Selects link underline presentation without changing text or layout. ++ /// Unspecified views retain their existing solid underline. ++ pub fn link_underline(mut self, style: F) -> Self ++ where ++ F: Fn(&SharedString, &App) -> LinkUnderline + Send + Sync + 'static, ++ { ++ self.link_underline = Some(Arc::new(style)); ++ self ++ } ++ ++ /// Decorates each actual, measured text-link target after its ordinary ++ /// click handler is installed. This can publish accessibility, focus and ++ /// hover behavior on the same fragment. The parser, text layout and text ++ /// selection remain owned by TextView. The decorator must preserve the ++ /// supplied target's dimensions and existing click handler. ++ pub fn link_with(mut self, decorator: F) -> Self ++ where ++ F: Fn( ++ &LinkFragment, ++ gpui::Stateful, ++ &mut Window, ++ &mut App, ++ ) -> gpui::Stateful ++ + Send ++ + Sync ++ + 'static, ++ { ++ self.link_fragment_decorator = Some(Arc::new(decorator)); ++ self ++ } ++ + /// Replace the Markdown extension registry. + pub fn markdown_extensions(mut self, extensions: MarkdownExtensions) -> Self { + self.markdown_extensions = Arc::new(extensions); +@@ -554,6 +621,8 @@ impl Element for TextView { + state.code_block_highlighter = code_block_highlighter.clone(); + state.table_actions = self.table_actions.clone(); + state.link_click_handler = self.link_click_handler.clone(); ++ state.link_fragment_decorator = self.link_fragment_decorator.clone(); ++ state.link_underline = self.link_underline.clone(); + state.set_markdown_extensions(self.markdown_extensions.clone(), cx); + state.selectable = self.selectable; + state.selection_format = self.selection_format; +@@ -630,16 +699,14 @@ impl Element for TextView { + if let Ok(mut line_spans) = state.read(cx).line_spans.lock() { + line_spans.clear(); + } +- // Descendant `Inline`s report their line spans through the state +- // stack during prepaint (in addition to the paint-time push below). +- GlobalState::global_mut(cx) +- .text_view_state_stack +- .push(state.clone()); + } ++ // Measured link targets retain this same selection authority. Clamped ++ // descendants additionally report their line spans through the stack. ++ GlobalState::global_mut(cx) ++ .text_view_state_stack ++ .push(state.clone()); + request_layout.element.prepaint(window, cx); +- if max_lines_active { +- GlobalState::global_mut(cx).text_view_state_stack.pop(); +- } ++ GlobalState::global_mut(cx).text_view_state_stack.pop(); + + let mut clip_bottom = None; + if max_lines_active { +diff --git a/crates/component/src/text/compat.rs b/crates/component/src/text/compat.rs +index a59bb5fb..6ffcfe54 100644 +--- a/crates/component/src/text/compat.rs ++++ b/crates/component/src/text/compat.rs +@@ -107,6 +107,31 @@ impl TextView { + self.inner = self.inner.on_link_click(f); + self + } ++ /// Selects Base's solid, dotted or absent underline on the existing text. ++ pub fn link_underline(mut self, style: F) -> Self ++ where ++ F: Fn(&SharedString, &App) -> gpui_base::text::LinkUnderline + Send + Sync + 'static, ++ { ++ self.inner = self.inner.link_underline(style); ++ self ++ } ++ /// Decorates the actual measured Base link targets, preserving its parser, ++ /// selection and click behavior. See [`gpui_base::TextView::link_with`]. ++ pub fn link_with(mut self, decorator: F) -> Self ++ where ++ F: Fn( ++ &gpui_base::text::LinkFragment, ++ gpui::Stateful, ++ &mut Window, ++ &mut App, ++ ) -> gpui::Stateful ++ + Send ++ + Sync ++ + 'static, ++ { ++ self.inner = self.inner.link_with(decorator); ++ self ++ } + /// Sets which Markdown extensions the parser accepts. + pub fn markdown_extensions(mut self, value: MarkdownExtensions) -> Self { + self.inner = self.inner.markdown_extensions(value); +diff --git a/crates/component/src/text/mod.rs b/crates/component/src/text/mod.rs +index d594bd57..dee55646 100644 +--- a/crates/component/src/text/mod.rs ++++ b/crates/component/src/text/mod.rs +@@ -7,8 +7,9 @@ pub use compat::{ + Text, TextView, TextViewLayoutState, TextViewPlugin, TextViewPrepaintState, html, markdown, + }; + pub use gpui_base::text::{ +- MarkdownBlockParserFn, MarkdownBlockRenderFn, MarkdownExtensions, MarkdownNode, +- MarkdownParseContext, MarkdownPlugin, SelectionFormat, TableData, TextViewState, markdown_ast, ++ LinkFragment, LinkUnderline, MarkdownBlockParserFn, MarkdownBlockRenderFn, MarkdownExtensions, ++ MarkdownNode, MarkdownParseContext, MarkdownPlugin, SelectionFormat, TableData, TextViewState, ++ markdown_ast, + }; + pub use style::TextViewStyle; + diff --git a/patches/README.md b/patches/README.md index 6df10adb58..fb3f0e778e 100644 --- a/patches/README.md +++ b/patches/README.md @@ -122,3 +122,13 @@ semantic activation, both keyboard keys, and disabled/read-only inertness. The original activation, naming and Store source assertions also pass without new exemptions. Locked consumer verification follows adoption of this exact source revision; staged-source proof is not a browser deployment result. + +The text-link decoration patch exposes each real parsed and measured line +fragment through `TextView::link_with`, preserving the original click handler +and source parser. `link_underline` selects solid, dotted, or absent underline +without reparsing text in the consumer. The default remains solid. Fragment +focus survives the selection layer's deferred mouse-down callback without +overriding focus chosen by navigation. The actual AGPUI consumer tests cover +wrapped pointer targets, semantic activation, Enter and Space, and drag +selection with the real TextSelectionLayer. Native interaction passed; browser +link and deployed application verification remain consumer gates. diff --git a/patches/series b/patches/series index 5e8c4af1d0..3c1ab613e3 100644 --- a/patches/series +++ b/patches/series @@ -22,3 +22,4 @@ 0022-gpui-selected-replacement-lock.patch 0023-sidebar-semantic-decoration.patch 0024-compose-sidebar-row-decorations.patch +0025-measured-text-link-decoration.patch