╭ changed ────────╮ │src/main_wasm.zig│ ╰─────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │41 │ │42 fn tick(min_height: u32, max_width: u32) !void { │ │43 const root_ptr = if (root) |*root_value| root_value else return error.NotStarted;│ │44 + │ │45 + // apply actions queued during input. the wasm path has no repo, so this is │ │46 + // in-memory only; logged-in web persistence goes through the /ansi POST. │ │47 + session.applyPending(); │ │48 + │ │49 try root_ptr.build(allocator, .{ │ │50 // min_height lets the TUI fill the viewport when its content is │ │51 // short; max height stays null so taller content extends downward │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │80 defer allocator.free(overlay); │ │81 setOverlay(overlay); │ │82 │ │78 - // if focused widget is a TextInput, focus on the HTML element │ │83 + // browser-focus the focused overlay control (text input or submit button) │ │84 + // so the browser handles typing and Enter-to-submit natively. without this│ │85 + // the submit button never gets focus and Enter falls through to the wasm. │ │86 const root_focus = root_ptr.getFocus(); │ │87 if (root_focus.grandchild_id) |gid| { │ │88 if (root_focus.children.get(gid)) |child| { │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │89 switch (child.focus.kind) { │ │90 .text_input, .text_input_password => _focusInput(@intCast(gid)), │ │91 + .custom => |custom| if (std.mem.eql(u8, custom, "submit")) _focusInput(@intCast(gid)),│ │92 else => {}, │ │93 } │ │94 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │114 │ │115 fn onMouseClick(focus_id: usize) !void { │ │116 const root_ptr = if (root) |*root_value| root_value else return error.NotStarted;│ │109 - const root_focus = root_ptr.getFocus(); │ │110 - try root_focus.setFocus(focus_id); │ │111 - // forward a left press into the widget tree for plain in-tree clickables │ │112 - if (root_focus.children.get(focus_id)) |child| { │ │113 - const r = child.rect; │ │114 - try root_ptr.input(allocator, .{ .mouse = .{ │ │115 - .x = r.x, │ │116 - .y = r.y, │ │117 - .action = .{ .press = .left }, │ │118 - } }, root_focus); │ │119 - } │ │117 + try root_ptr.getFocus().setFocus(focus_id); │ │118 } │ │119 │ │120 fn consoleLog(arg: []const u8) void { │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯