Find in page: the shell's find bar per pane (Ctrl+F, the app menu, the palette) over the engine's own find

Host: `tab_find {id, action, query}` (shell-only; start, next, previous, stop). On Windows it drives WebView2's own find (`ICoreWebView2Find` from `ICoreWebView2_28`, find options from `ICoreWebView2Environment15`; its built-in find bar suppressed, all matches highlighted) and reports the engine's match count and active match to the shell as `tab-find` events. On macOS, Linux and an older WebView2 Runtime native code evaluates the engine's `window.find` in the tab instead (next and previous work, no count); WKWebView's and WebKitGTK's native find are not wired here because this tree cannot be compiled or run for them on this machine. The query is one typed line (1..=256 characters, no control characters), goes to the engine and is kept nowhere. Tabs gain no command: a tab forwards the existing key name `find` (Ctrl+F) through tab_shortcut.

Frame: FindBar.tsx takes the address field's place in its pane's toolbar while open, so the page does not move and in split view the bar is the searched pane's. "3/17" where the engine counts, "No matches" for none; Enter / F3 next, Shift+Enter / Shift+F3 previous, Esc closes, clears the highlights and gives the page the keyboard. `features.find` (on by default) gates the menu row, the palette entry and the keys. Only what the page has rendered can be found, as in a browser.

Also: this makes `pub mod find` in lib.rs (already in HEAD) resolve again.
This commit is contained in:
CRTkafa 2026-09-30 22:34:48 +07:00
parent 24c8620d4e
commit 8324bc94af
17 changed files with 449 additions and 19 deletions

View file

@ -559,6 +559,15 @@ async fn tab_zoom(webview: Webview, app: AppHandle, id: String, factor: Option<f
host::tab_zoom(&app, &id, factor)
}
/// Find in page for tab `id` (the shell's find bar): `start` with a query, `next`, `previous`, `stop`.
/// The engine's own find where this build can drive it (counts arrive as `tab-find` events), else the
/// evaluated `window.find`. The query is one typed line (validated) and is kept nowhere.
#[tauri::command]
async fn tab_find(webview: Webview, app: AppHandle, id: String, action: String, query: Option<String>) -> Result<(), String> {
shell_only(&webview)?;
host::tab_find(&app, &id, &action, query.as_deref())
}
/// Gives keyboard focus back to the shell (e.g. Ctrl+L pressed inside a tab).
#[tauri::command]
async fn shell_focus(webview: Webview) -> Result<(), String> {
@ -974,6 +983,7 @@ fn host_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 's
tab_navigate,
tab_action,
tab_zoom,
tab_find,
open_external_url,
shell_focus,
shell_ready,