From 1bd91173a0863d8ec08e30fca1d53e7ad48b765f Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 4 Nov 2026 03:50:29 +0100 Subject: [PATCH 1/3] chore: continue compatibility maintenance Start the next maintenance cycle after stack-v0.4.13. Preserve the existing compatibility goal and its remaining work. From 9d97127b2c93e40f6d3ce93fb859f7b9b52a0993 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 4 Nov 2026 04:59:18 +0100 Subject: [PATCH 2/3] fix(capture): avoid reactivating the focused window Repeated activation restacks the window and resends WM_TAKE_FOCUS before each input command. SDL can respond by rebuilding the screen and clearing text focus. Leave an already-focused window active while retaining the activation protocol when switching windows. Verify consecutive typing without reactivation on an isolated X server. --- native/capture-x11/src/x11.rs | 4 +++ native/capture-x11/tests/xvfb.rs | 52 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/native/capture-x11/src/x11.rs b/native/capture-x11/src/x11.rs index b2a27323..d97c0bb8 100644 --- a/native/capture-x11/src/x11.rs +++ b/native/capture-x11/src/x11.rs @@ -334,6 +334,10 @@ impl Display { fn focus(&self, window: Window) -> Result<()> { self.geometry(window)?; + if self.connection.get_input_focus()?.reply()?.focus == window { + // Repeated activation can make SDL rebuild a focused text editor. + return Ok(()); + } let time = self.server_time()?; self.connection .configure_window( diff --git a/native/capture-x11/tests/xvfb.rs b/native/capture-x11/tests/xvfb.rs index 1c91f2a3..fea23cc2 100644 --- a/native/capture-x11/tests/xvfb.rs +++ b/native/capture-x11/tests/xvfb.rs @@ -502,6 +502,58 @@ fn discovers_reparented_clients_and_delivers_their_focus_protocol_before_input() ); } +#[test] +#[ignore = "requires Xvfb; run cargo test -- --include-ignored"] +fn typing_in_the_focused_window_does_not_repeat_window_activation() { + let fixture = Fixture::new(24); + let protocols = fixture.atom(b"WM_PROTOCOLS"); + let take_focus = fixture.atom(b"WM_TAKE_FOCUS"); + fixture + .connection + .change_property32( + PropMode::REPLACE, + fixture.window, + protocols, + AtomEnum::ATOM, + &[take_focus], + ) + .unwrap() + .check() + .unwrap(); + fixture + .connection + .change_window_attributes( + fixture.window, + &xproto::ChangeWindowAttributesAux::new().event_mask( + EventMask::KEY_PRESS | EventMask::KEY_RELEASE | EventMask::STRUCTURE_NOTIFY, + ), + ) + .unwrap() + .check() + .unwrap(); + let id = fixture.window.to_string(); + fixture.success(&["focus", &id]); + fixture.events(); + + fixture.success(&["type", &id, "a"]); + let events = fixture.events(); + assert!( + events + .iter() + .any(|event| matches!(event, Event::KeyPress(_))) + ); + assert!( + events + .iter() + .any(|event| matches!(event, Event::KeyRelease(_))) + ); + assert!( + !events + .iter() + .any(|event| matches!(event, Event::ConfigureNotify(_) | Event::ClientMessage(_))) + ); +} + #[test] #[ignore = "requires Xvfb; run cargo test -- --include-ignored"] fn emits_ordered_input_and_releases_it_on_interrupts_and_window_failure() { From 83cd58466e5db9f504a61f4f09b81d1e2f214c61 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 4 Nov 2026 04:59:18 +0100 Subject: [PATCH 3/3] docs(inventory): verify multiplayer search lifetime Compare official Bedrock 1.26.60.5 and owned BDS 1.26.60.6 controls on protocol 2225 with installed direct and ViaProxy clients. All retain Creative search through both dimension transitions and clear it after reconnecting within the same game process. The native control uses an offline transport/authentication relay with blob caching disabled and unmodified inventory/movement packets. The proxy query uses normal UI paste because lab framebuffer changes interrupt typed input. Keep server transfers, other world changes, and complete input parity unverified. --- docs/native-player-inventory.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/native-player-inventory.md b/docs/native-player-inventory.md index c63846bc..1b51bba8 100644 --- a/docs/native-player-inventory.md +++ b/docs/native-player-inventory.md @@ -233,8 +233,11 @@ Unchanged Java Creative slot echoes preserve the existing native stack and netwo Installed direct and ViaProxy controls confirm these pointer, capacity, and reopening cases through successful server responses. Recipe families beyond the captured plank, cake, and honey controls, recipes with more than two outputs, and complete installed native parity remain unfinished. -Local Bedrock 1.26.60.5 controls retain Creative search through Overworld/Nether transitions and clear it after world exit and re-entry. -Multiplayer reconnects, server transfers, other world changes, and matching Java runtime comparisons remain unverified. +Bedrock 1.26.60.5 controls retain Creative search through Overworld/Nether transitions in local worlds and on an owned BDS 1.26.60.6 server. +Installed direct and ViaProxy controls match this multiplayer retention. +Native and both Java routes clear search after disconnecting and reconnecting in the same game process. Local Bedrock also clears it after world exit and re-entry. +The native multiplayer control uses a transport/authentication relay with blob caching disabled. Inventory and movement packets remain unchanged. The proxy control enters its query through normal UI paste. +Server transfers, other world changes, and complete search input parity remain unverified. Official Bedrock 1.26.60.5/BDS 1.26.60.6 controls delay the initial open acknowledgment by four seconds on protocol 2225. They establish visible admission, repeated input, movement, and cancellation through Escape or chat. Rebuilt direct and ViaProxy controls retain the world during that same delay in Survival, Creative, and workbench openings.