From f0996645b1496aba635356d74a118317dd96b049 Mon Sep 17 00:00:00 2001 From: samhyun Date: Thu, 29 Oct 2026 15:34:14 +0900 Subject: [PATCH] M8: the browser applies input sent over its control channel `ui.input` over `window.figcraft` (the page's control channel, `?control`) never did anything in the browser: the batch was queued for the next frame as on the desktop, but the browser shell has no `raw_input_hook`, the eframe callback that hands a queued batch to the frame about to draw (`windows::take_input`). The events stayed in their queue and the request's promise never settled, so an agent driving the page could run commands and take screenshots but not point, click or type. The browser shell now has the hook the desktop app has: the batch goes into the frame's raw input, is applied by it and is acknowledged once the frame is presented, as on the desktop. Checked in Chrome on the release web build: `ui.input` with a key (O, R, F: the ellipse, rectangle and frame tools) and with a pointer gesture (a drag with the rectangle tool: a rectangle drawn) resolves and takes effect, where on `main` the same requests time out and change nothing. Co-Authored-By: Claude Fable 5.1 --- apps/figcraft-web/src/web.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apps/figcraft-web/src/web.rs b/apps/figcraft-web/src/web.rs index de17cc36..a938bf0f 100644 --- a/apps/figcraft-web/src/web.rs +++ b/apps/figcraft-web/src/web.rs @@ -85,6 +85,15 @@ impl eframe::App for WebShell { figcraft_ui_egui::windows::guard(&mut self.fig, ctx, |fig| fig.background_tick(ctx)); } + fn raw_input_hook(&mut self, _ctx: &egui::Context, raw_input: &mut egui::RawInput) { + // Pointer and key events sent over the control channel (`ui.input`), for the frame about + // to draw: the batch is applied by this frame and acknowledged once it is presented, as on + // the desktop (`apps/figcraft/src/main.rs`). Without this hook the batch sat in its queue + // and its promise never settled. + let events = figcraft_ui_egui::windows::take_input(&mut self.fig, raw_input.viewport_id); + raw_input.events.extend(events); + } + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { self.fig.control_queue.extend(crate::api::take_requests()); self.fig.ui(ui);