fix: preserve source focus across native chrome activation

This commit is contained in:
2026-10-24 19:50:31 +08:00
parent d3165b1224
commit 3cb44b96eb
3 changed files with 23 additions and 6 deletions
+12 -1
View File
@@ -13,7 +13,7 @@ This audit follows the full conversation, including later corrections. Implement
| Close/activate/reorder/migrate/detach | Ordinary managed Page methods retained; animated hit bounds and drag anchors use current visual bounds | Native close and drag-out to Endor Window 2 succeeded. API detach/move-back preserved Page 1:135:0. Native cross-window drop, dwell and mixed-DPI were not re-run in this final build |
| Four developer tools separated | Independent Page instances; Console/Sources/Network/Settings modules and separate per-view state | Earlier native top-level Sources/Console activation and read-only copy/paste verified; no nested navigation remains |
| Four tools not default or permanently placed | No Tools menu, rail buttons or new-page tool directory; existing API/shortcut retained | Final default surfaces viewed without tool entries |
| Source reading/selection/copy | Grapheme-boundary selection, no gutter in copy, select-all/copy, Shift navigation, drag edge scrolling | Native single-line drag/copy/paste verified earlier in this change. Final added keyboard/edge behavior compiled; not all combinations manually exercised |
| Source reading/selection/copy | Grapheme-boundary selection, no gutter in copy, select-all/copy, Shift navigation, drag edge scrolling | Native single-line drag/copy/paste verified earlier in this change. Final keyboard copy was re-run after the chrome-focus fix: drag-copy matched the complete selected line; four Shift+Right operations copied the expected four characters; select-all copied multiline source without a gutter. Drag edge behavior compiled; exhaustive combinations remain untested |
| Clicking Console output must not jump to prompt/end | Input hit region restricted to actual prompt rows | Native reading/copy path verified earlier; no input hit over transcript-only area |
| Default page reflects Endor | Objects, code and UI share identity; persistence/model connections explicitly described as work in progress | Referenced chats read: 01a16819-28c3-7ce0-9423-0ffaa19402ce and 01a1689b-77d8-75a2-ba9e-b2fa3dce654e; actual native start surface viewed |
| Sensible source organization | Runtime/API tests separated; four page view modules; shared painter/selection; native tool Page factory; motion module | All-target Clippy compiled production and test sources. Runtime host reduced from ~7000 to ~1380 lines |
@@ -33,3 +33,14 @@ One placement probe used unsupported == syntax and returned a parse error before
## Remaining verification
Isolated Chrome timing/shape comparison, frame-by-frame animation capture, fresh native cross-window drop/dwell on the final build, mixed-DPI cross-screen interaction and exhaustive keyboard/source-selection combinations remain without new runtime evidence. These are not silently marked passed. The shipped Page lifetime/GC model was preserved; no new persistence or AI backend is claimed.
## Final focus regression fix
Final native retesting found a real regression: title-strip mouse events cleared the active editor focus. Window activation performed before automated key events exposed the same behavior. Chrome mouse presses now preserve content focus; developer pane hit testing ignores points outside the pane; frame publication updates the keyboard route according to the active Page. No source, tab geometry or selection state is logged by the shipped build.
After the fix, direct system clipboard comparisons (without printing clipboard contents) confirmed selected-line equality (28 characters), Shift+Right selection equality (4 characters), and multiline select-all with no line-number gutter. The temporary Sources Page was closed afterwards. All-target Clippy, formatting and release building passed again.
## Local delivery state
Implementation commits: 3220544 (runtime test-source separation), 656522e (managed workspace/chrome implementation), d3165b1 (behavior and requirement audit), followed by the chrome-focus fix commit. A push to origin/main was attempted once and rejected by automatic approval review because explicit authorization for this default-branch remote mutation was required. No alternative push route was attempted. The remote remains unchanged pending the user's approval.
+10 -4
View File
@@ -325,6 +325,10 @@ impl TesseraApp {
if let Ok(namespace) = self.namespace.read() {
self.developer_tools.document_updated(&namespace.document);
let frame = &namespace.document.frame;
self.guest_keyboard = !frame
.tabs
.iter()
.any(|tab| tab.active && tab.developer_tool.is_some());
if self.tab_pressed.as_ref().is_some_and(|pressed| {
frame.session != pressed.session
|| frame.fault.is_some()
@@ -1397,7 +1401,12 @@ impl ApplicationHandler<AppEvent> for TesseraApp {
{
let _ = window.drag_window();
}
self.guest_keyboard = !self.guest_covered(self.pointer);
if self.pointer.y >= crate::tabs::height(&[]) {
self.guest_keyboard = !self.guest_covered(self.pointer);
if self.guest_keyboard {
self.developer_tools.blur();
}
}
self.tab_pressed = self.tab_hit();
self.tab_drag_grab = self
.tab_pressed
@@ -1406,9 +1415,6 @@ impl ApplicationHandler<AppEvent> for TesseraApp {
.and_then(|input| self.drag_anchor(input));
self.tab_drag_origin = self.tab_drag_grab.map(|_| self.pointer);
self.guest_pressed = self.guest_hit();
if self.guest_keyboard {
self.developer_tools.blur();
}
self.developer_tools.press(
&self.layout.developer_tools,
self.pointer,
+1 -1
View File
@@ -296,7 +296,7 @@ impl DeveloperToolsState {
self.preedit.clear();
}
pub fn press(&mut self, layout: &DeveloperToolsLayout, p: Point, activity: &Activity) {
if !self.open {
if !self.open || !layout.panel.contains(p) {
return;
}
self.preedit.clear();