file manager
git clone https://git.lucas.co/cce-files.git
fix(osk): keep claiming an edited field on frames that replay the layout
The search and save-name boxes are painted only in rebuild_layout, and
display_list replays the cached frame otherwise, so a field claimed text
input on rebuild frames alone and the on-screen keyboard went away on the
next replayed frame. The rebuild now runs under
cce_ui::text_input::capture and its claim is made again every frame.
Repins cce-ui to 2e573c3 for capture.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cargo.lock | 37 ++++++++++++++++++++++++++++++++++++-
Cargo.toml | 2 +-
src/main.rs | 16 ++++++++++++++++
3 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 90d609f..d644f81 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -489,7 +489,7 @@ dependencies = [
[[package]]
name = "cce-ui"
version = "0.1.0"
-source = "git+https://github.com/lsgalante/cce-ui.git?rev=9afd4d8c634296572feaddc96ae7c7edd0582ce4#9afd4d8c634296572feaddc96ae7c7edd0582ce4"
+source = "git+https://github.com/lsgalante/cce-ui.git?rev=2e573c35b6826fff87ac216eba48b9cc3c5a3dac#2e573c35b6826fff87ac216eba48b9cc3c5a3dac"
dependencies = [
"ash",
"bitflags 2.13.1",
@@ -497,12 +497,19 @@ dependencies = [
"calloop",
"calloop-wayland-source",
"cosmic-text",
+ "cursor-icon",
+ "dispatch2",
"glam",
"gpu-allocator",
+ "js-sys",
"kdl 4.7.1",
"libc",
"log",
"naga",
+ "objc2",
+ "objc2-app-kit",
+ "objc2-foundation",
+ "objc2-quartz-core",
"png 0.17.16",
"raw-window-handle",
"resvg",
@@ -510,10 +517,14 @@ dependencies = [
"serde",
"serde_json",
"smithay-client-toolkit",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
"wayland-backend",
"wayland-client",
"wayland-protocols 0.31.2",
"wayland-scanner",
+ "web-sys",
+ "web-time",
"xkeysym",
]
@@ -1745,7 +1756,9 @@ dependencies = [
"bitflags 2.13.1",
"block2",
"objc2",
+ "objc2-core-foundation",
"objc2-foundation",
+ "objc2-quartz-core",
]
[[package]]
@@ -1776,6 +1789,18 @@ dependencies = [
"objc2-core-foundation",
]
+[[package]]
+name = "objc2-quartz-core"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
+dependencies = [
+ "bitflags 2.13.1",
+ "objc2",
+ "objc2-core-foundation",
+ "objc2-foundation",
+]
+
[[package]]
name = "once_cell"
version = "1.21.4"
@@ -3239,6 +3264,16 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "web-time"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
[[package]]
name = "weezl"
version = "0.1.12"
diff --git a/Cargo.toml b/Cargo.toml
index 966e37b..33cddbc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
-cce-ui = { git = "https://github.com/lsgalante/cce-ui.git", rev = "9afd4d8c634296572feaddc96ae7c7edd0582ce4" }
+cce-ui = { git = "https://github.com/lsgalante/cce-ui.git", rev = "2e573c35b6826fff87ac216eba48b9cc3c5a3dac" }
wayland-client = { version = "0.31", features = ["system"] }
calloop = "0.13.0"
chrono = "0.4.44"
diff --git a/src/main.rs b/src/main.rs
index bfe4c71..648880d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -469,6 +469,11 @@ struct FilesystemApp {
texts: Vec<(String, f32, f32, f32, [f32; 4], Option<String>, Option<[f32; 4]>)>,
font_system: FontSystem,
needs_rebuild: bool,
+ /// What the last rebuild's widgets claimed for text input (an editing
+ /// TextBox, `cce_ui::text_input::capture`). Claimed again every frame:
+ /// a frame that only replays the cached layout paints no widget, and
+ /// would otherwise read as the field closing.
+ text_claim: Option<[f32; 4]>,
width: u32,
height: u32,
scale_factor: f64,
@@ -619,7 +624,14 @@ impl FilesystemApp {
self.needs_rebuild = true;
}
+ /// Lay the window out and flatten it into the cached frame, keeping what
+ /// its widgets claimed for text input (`text_claim`).
fn rebuild_layout(&mut self) {
+ let ((), claim) = cce_ui::text_input::capture(|| self.rebuild_layout_inner());
+ self.text_claim = claim;
+ }
+
+ fn rebuild_layout_inner(&mut self) {
// Well focus → the emitters (each picks the tinted carve when set).
self.browse.list.focused = self.focused_well == FocusedWell::Content;
@@ -1352,6 +1364,7 @@ impl Application for FilesystemApp {
texts: Vec::new(),
font_system: cce_ui::create_font_system(),
needs_rebuild: true,
+ text_claim: None,
width: initial_w,
height: initial_h,
scale_factor: 1.0,
@@ -1844,6 +1857,9 @@ impl Application for FilesystemApp {
// with it: `paint_with_labels` carries the menu font's family, which
// the hand-rolled `paint` + `text_labels()` loop here did not.
cce_ui::widget::context_menu::paint_with_labels(&mut pc);
+ if let Some([x, y, w, h]) = self.text_claim {
+ cce_ui::text_input::claim(x, y, w, h);
+ }
Some(pc.finish())
}