Yaak Proxy: open Settings as a child of the main window

Settings now opens through the shared create_child_window, as Yaak's
does, so it stays in front of the main window, takes focus back when the
main window is clicked, and closes with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Gregory SchierandClaude Opus 5.5 authored and Stetta task tk_mwb56agvne2hw21h committed 2026-11-10 16:34:22 -07:00
1 parent 7057a902c7
commit 5148b0f0ba
4 files changed
+44 -54

No files matched your search

+3 -3
View File
@@ -33,9 +33,9 @@ describe("windowSync", () => {
});
test("a change is announced as coming from this window", () => {
tauri.label = "settings";
tauri.label = "other__settings";
announceEngineChange();
expect(tauri.sent).toEqual([{ event: "window_changed_engine", payload: { from: "settings" } }]);
expect(tauri.sent).toEqual([{ event: "window_changed_engine", payload: { from: "other__settings" } }]);
});
test("a change in another window reads the state and the settings' queries again", () => {
@@ -44,7 +44,7 @@ describe("windowSync", () => {
const invalidate = vi.spyOn(queryClient, "invalidateQueries");
syncFromOtherWindows(store, queryClient);
tauri.handlers.get("window_changed_engine")?.({ from: "settings" });
tauri.handlers.get("window_changed_engine")?.({ from: "other__settings" });
expect(refreshProxyState).toHaveBeenCalledWith(store);
expect(invalidate).toHaveBeenCalledTimes(1);
+2 -1
View File
@@ -3,7 +3,7 @@ import { openSettingsVia, requestedSettingsTab, windowKind } from "./windows";
describe("windowKind", () => {
test("the Settings window holds the settings", () => {
expect(windowKind("settings")).toBe("settings");
expect(windowKind("other__settings")).toBe("settings");
});
test("a main window holds the app", () => {
@@ -13,6 +13,7 @@ describe("windowKind", () => {
test("a page outside the app's windows holds the app on its own", () => {
expect(windowKind("harness")).toBe("page");
expect(windowKind("settings")).toBe("page");
expect(windowKind("settings_0")).toBe("page");
expect(windowKind("")).toBe("page");
});
+5 -2
View File
@@ -1,5 +1,8 @@
/** The Settings window's label, which `cmd_open_settings` gives it */
export const SETTINGS_WINDOW_LABEL = "settings";
/**
* The Settings window's label, which `cmd_open_settings` gives it: opened as a child of the
* main window, as Yaak's, it takes the prefix the shared window code gives child windows
*/
export const SETTINGS_WINDOW_LABEL = "other__settings";
/** The event that moves an open Settings window to another tab */
export const SETTINGS_TAB_EVENT = "settings_tab";
+34 -48
View File
@@ -90,8 +90,11 @@ fn bundled_protoc<R: Runtime>(app: &tauri::AppHandle<R>) -> Option<yaak_proxy_li
/// The main window's label.
const MAIN_WINDOW_LABEL: &str = "main_0";
/// The Settings window's label, by which its page renders the settings alone.
const SETTINGS_WINDOW_LABEL: &str = "settings";
/// The name the Settings window is opened under, and the key its size and position are kept by.
const SETTINGS_WINDOW_NAME: &str = "settings";
/// The Settings window's label, by which its page renders the settings alone: its name with the
/// prefix the shared code gives each child window, as Yaak's Settings window has.
const SETTINGS_WINDOW_LABEL: &str = "other__settings";
/// The event that moves an open Settings window to another tab.
const SETTINGS_TAB_EVENT: &str = "settings_tab";
/// The Settings window's size, as Yaak's.
@@ -105,8 +108,10 @@ fn settings_tab_script(tab: &str) -> String {
format!("window.__YAAK_SETTINGS_TAB__ = {tab};")
}
/// Opens Settings in its own window on `tab`, or, when it is open, brings it forward and moves
/// it to `tab` if one is given.
/// Opens Settings on `tab` in a child of the main window, or, when it is open, brings it forward
/// and moves it to `tab` if one is given. As Yaak's, the child sits over the middle of the main
/// window the first time and where it was left after; it stays in front, taking focus back when
/// the main window is clicked, and closes with it.
#[tauri::command]
async fn cmd_open_settings(
app_handle: tauri::AppHandle,
@@ -124,53 +129,25 @@ async fn cmd_open_settings(
return Ok(());
}
// Over the middle of the main window the first time, as Yaak's; after that, where it was left
let position = app_handle
let main = app_handle
.get_webview_window(MAIN_WINDOW_LABEL)
.and_then(|main| centered_over(&main, SETTINGS_WINDOW_SIZE).ok());
let config = CreateWindowConfig {
url: "/",
label: SETTINGS_WINDOW_LABEL,
title: "Yaak Proxy Settings",
inner_size: Some(SETTINGS_WINDOW_SIZE),
position,
initialization_script: tab.as_deref().map(settings_tab_script),
hidden: true,
hide_titlebar: true,
..Default::default()
};
let win = yaak_window::window::create_window(&app_handle, config).map_err(|e| e.to_string())?;
.ok_or("The main window is not open to open Settings over")?;
let win = yaak_window::window::create_child_window(
&main,
"/",
SETTINGS_WINDOW_NAME,
"Yaak Proxy Settings",
SETTINGS_WINDOW_SIZE,
tab.as_deref().map(settings_tab_script),
false,
)
.map_err(|e| e.to_string())?;
let (width, height) = SETTINGS_WINDOW_MIN_SIZE;
win.set_min_size(Some(tauri::LogicalSize::new(width, height))).map_err(|e| e.to_string())?;
handle_menu_events(&win);
Ok(())
}
/// Where a window of `size` sits centred over `parent`, in logical pixels.
fn centered_over<R: Runtime>(
parent: &WebviewWindow<R>,
(width, height): (f64, f64),
) -> tauri::Result<(f64, f64)> {
let scale = parent.scale_factor()?;
let pos = parent.inner_position()?.to_logical::<f64>(scale);
let size = parent.inner_size()?.to_logical::<f64>(scale);
Ok((pos.x + (size.width - width) / 2.0, pos.y + (size.height - height) / 2.0))
}
/// Closing the main window closes Settings with it, which would otherwise keep the app open
/// with nothing to set.
fn close_settings_with<R: Runtime>(main: &WebviewWindow<R>) {
let app_handle = main.app_handle().clone();
main.on_window_event(move |event| {
if let tauri::WindowEvent::CloseRequested { .. } = event
&& let Some(settings) = app_handle.get_webview_window(SETTINGS_WINDOW_LABEL)
&& let Err(e) = settings.close()
{
warn!("Failed to close the settings window: {e}");
}
});
}
#[tauri::command]
async fn rpc(
router: State<'_, RpcRouter<ProxyCtx>>,
@@ -262,10 +239,7 @@ pub fn run() {
..Default::default()
};
match yaak_window::window::create_window(app_handle, config) {
Ok(win) => {
setup_window_menu(&win);
close_settings_with(&win);
}
Ok(win) => setup_window_menu(&win),
Err(e) => error!("Failed to create proxy window: {e:?}"),
}
}
@@ -333,6 +307,18 @@ mod tests {
}
}
/// The page knows the Settings window by the label the shared code gives a child window
/// opened under its name, or it would render the whole app in it.
#[test]
fn the_page_knows_the_settings_window_by_its_label() {
assert_eq!(SETTINGS_WINDOW_LABEL, format!("other__{SETTINGS_WINDOW_NAME}"));
let windows = include_str!("../../../apps/yaak-proxy/lib/windows.ts");
assert!(
windows.contains(&format!("SETTINGS_WINDOW_LABEL = \"{SETTINGS_WINDOW_LABEL}\"")),
"the page's Settings window label is not {SETTINGS_WINDOW_LABEL}"
);
}
/// The tab reaches the new window's page as a string literal, whatever it holds.
#[test]
fn the_settings_tab_script_quotes_the_tab() {