mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-22 00:01:06 +00:00
fix: reconcile client locations after no-focus pane moves (#4171)
refs #4153 Root cause: A no-focus pane move can remove the source tab without changing the server's numeric workspace and tab coordinates. PaneMove is not classified as a topology change, so a client viewing that tab retains its deleted ID. Its target lookup falls back to the server default and can follow a later, unrelated focus change instead of staying in the source workspace. Fix: Include PaneMove in the existing client-location reconciliation path. Extend the existing focus-guard test with a client on the removed tab and verify that a later server-default change cannot move its view. Preserve the other client's view and existing error, no-op and zoom assertions. Validation: The minimized regression fails five times on PR #4159's unchanged head and passes five times with the one-line fix. All 19 pane-move tests, native lint, maintenance, architecture and integration-asset checks pass. Full native just ci on the publication branch, including the unchanged prerequisites from #4159 and #4168, passes 3585 Rust tests with six default skips plus lint, 106 maintenance, six architecture and 39 integration-asset tests. All seven docs contract tests pass. Local Windows cross-lint was not run because its SDK is unavailable. No geometry policy, protocol or periodic rendering behavior is changed.
This commit is contained in:
@@ -230,6 +230,7 @@ impl HeadlessServer {
|
||||
Method::CommandInvoke(_)
|
||||
| Method::PaneClose(_)
|
||||
| Method::PaneEditScrollback(_)
|
||||
| Method::PaneMove(_)
|
||||
| Method::PaneSplit(_)
|
||||
| Method::TabClose(_)
|
||||
| Method::TabCreate(_)
|
||||
|
||||
@@ -185,6 +185,7 @@ async fn public_pane_move_without_effective_focus_preserves_client_views() {
|
||||
let remaining_tab = server.app.public_tab_id(0, 1).unwrap();
|
||||
let destination_tab = server.app.public_tab_id(1, 0).unwrap();
|
||||
let (_control, _render) = connect_test_shell(&mut server, 9, 80, 23);
|
||||
let (_source_control, _source_render) = connect_test_shell(&mut server, 10, 80, 23);
|
||||
// Keep a valid view distinct from the server default in every case.
|
||||
assert!(server.focus_shell_client_on_tab(9, &remaining_tab));
|
||||
let location_before = server.clients[&9].shell_location.clone();
|
||||
@@ -221,6 +222,15 @@ async fn public_pane_move_without_effective_focus_preserves_client_views() {
|
||||
"{case}"
|
||||
);
|
||||
assert_eq!(server.app.state.active, Some(0));
|
||||
if case == "no-focus" {
|
||||
// A later change to the server default must not move this client.
|
||||
server.app.state.switch_workspace_tab(1, 0);
|
||||
assert_eq!(
|
||||
server.shell_tab_id_for_client(10).as_deref(),
|
||||
Some(remaining_tab.as_str()),
|
||||
"the removed source tab must be reconciled to the remaining source tab"
|
||||
);
|
||||
}
|
||||
shutdown_test_runtimes(&mut server);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user