diff --git a/apps/yaak-proxy/lib/windowSync.test.ts b/apps/yaak-proxy/lib/windowSync.test.ts index 6d69c9f66..ff6029322 100644 --- a/apps/yaak-proxy/lib/windowSync.test.ts +++ b/apps/yaak-proxy/lib/windowSync.test.ts @@ -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); diff --git a/apps/yaak-proxy/lib/windows.test.ts b/apps/yaak-proxy/lib/windows.test.ts index 05e801e22..63ab700ae 100644 --- a/apps/yaak-proxy/lib/windows.test.ts +++ b/apps/yaak-proxy/lib/windows.test.ts @@ -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"); }); diff --git a/apps/yaak-proxy/lib/windows.ts b/apps/yaak-proxy/lib/windows.ts index b86862b5c..de8037859 100644 --- a/apps/yaak-proxy/lib/windows.ts +++ b/apps/yaak-proxy/lib/windows.ts @@ -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"; diff --git a/crates-tauri/yaak-app-proxy/src/lib.rs b/crates-tauri/yaak-app-proxy/src/lib.rs index 6d523a07b..6b6042059 100644 --- a/crates-tauri/yaak-app-proxy/src/lib.rs +++ b/crates-tauri/yaak-app-proxy/src/lib.rs @@ -90,8 +90,11 @@ fn bundled_protoc(app: &tauri::AppHandle) -> Option 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( - parent: &WebviewWindow, - (width, height): (f64, f64), -) -> tauri::Result<(f64, f64)> { - let scale = parent.scale_factor()?; - let pos = parent.inner_position()?.to_logical::(scale); - let size = parent.inner_size()?.to_logical::(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(main: &WebviewWindow) { - 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>, @@ -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() {