Save interface-scale changes from every window
Ctrl/Cmd +/-/0 in editor and connection-manager windows called SettingsService.persist() -> saveSettings, but only the main window's RPC served that request: it went unanswered, the new scale applied locally, and the next broadcast from main snapped it back. All three window RPCs now serve saveSettings through one shared saveSettingsHandler (persist, then hand off). index.ts's settingsSaved() is the single place settings side effects run — transfer concurrency, locale + app menu, the preload snapshot — whichever window saved, and it rebroadcasts to every window EXCEPT the sender: an echo arriving behind a newer local change (a held Cmd+) would drag it backwards. Editors are skipped by their registry key, main and the manager by name. Known ceiling, noted at the handler: whole-object writes, so two windows saving in the same instant means the later one wins. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+24
-8
@@ -1,6 +1,6 @@
|
||||
import { BrowserView, Updater, Utils } from "electrobun/bun";
|
||||
import type { AppRPC, EditorOpenContext } from "../shared/rpc";
|
||||
import { effectiveConcurrency, type AppSettings, type Result } from "../shared/types";
|
||||
import type { AppSettings, Result } from "../shared/types";
|
||||
import { readFileText, writeFileText, type EditManager } from "./edits";
|
||||
import { listLocalDrives } from "./fs/local";
|
||||
import type { SessionRegistry } from "./fs/registry";
|
||||
@@ -99,6 +99,22 @@ function connectionStoreHandlers(store: ConnectionStore, onChanged: () => void)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* saveSettings for every window kind: persist, then hand the new object to the
|
||||
* composition root (index.ts), which applies the side effects once and
|
||||
* rebroadcasts to every OTHER window. Known ceiling: whole-object writes — two
|
||||
* windows saving in the same instant, the later one wins. Upgrade path: send a
|
||||
* patch and merge it bun-side.
|
||||
*/
|
||||
const saveSettingsHandler =
|
||||
(store: SettingsStore, onSaved: (next: AppSettings) => void) =>
|
||||
({ settings: next }: { settings: AppSettings }) =>
|
||||
wrap(async () => {
|
||||
await store.save(next);
|
||||
onSaved(next);
|
||||
return {};
|
||||
});
|
||||
|
||||
const pickKeyFileHandler = () =>
|
||||
wrap(async () => {
|
||||
const { homedir } = await import("node:os");
|
||||
@@ -224,13 +240,7 @@ export function createAppRPC({
|
||||
// ---- settings ----
|
||||
getSettings: () => wrap(async () => ({ settings: await settings.load() })),
|
||||
|
||||
saveSettings: ({ settings: next }) =>
|
||||
wrap(async () => {
|
||||
await settings.save(next);
|
||||
engine.setConcurrency(effectiveConcurrency(next));
|
||||
events.settingsChanged(next);
|
||||
return {};
|
||||
}),
|
||||
saveSettings: saveSettingsHandler(settings, (next) => events.settingsChanged(next)),
|
||||
|
||||
// ---- file editing ----
|
||||
readFile: ({ sessionId, path }) =>
|
||||
@@ -347,6 +357,8 @@ export interface EditorRpcHooks {
|
||||
onSaved: () => void;
|
||||
/** Webview resolved its dirty prompt: close without the native fallback. */
|
||||
onCloseConfirmed: () => void;
|
||||
/** This window saved settings (e.g. the scale shortcuts) — rebroadcast them. */
|
||||
onSettingsSaved: (next: AppSettings) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,6 +380,7 @@ export function createEditorRPC(
|
||||
})),
|
||||
|
||||
getSettings: () => wrap(async () => ({ settings: await deps.settings.load() })),
|
||||
saveSettings: saveSettingsHandler(deps.settings, hooks.onSettingsSaved),
|
||||
|
||||
editorSave: ({ content }) =>
|
||||
wrap(async () => {
|
||||
@@ -397,6 +410,8 @@ export interface ManagerRpcHooks {
|
||||
onConnect: (id: string) => void;
|
||||
onOpenStack: (id: string) => void;
|
||||
onClose: () => void;
|
||||
/** This window saved settings (e.g. the scale shortcuts) — rebroadcast them. */
|
||||
onSettingsSaved: (next: AppSettings) => void;
|
||||
}
|
||||
|
||||
/** RPC for the single connection-manager window (per-window instance). */
|
||||
@@ -411,6 +426,7 @@ export function createManagerRPC(
|
||||
...connectionStoreHandlers(deps.store, hooks.onChanged),
|
||||
pickKeyFile: pickKeyFileHandler,
|
||||
getSettings: () => wrap(async () => ({ settings: await deps.settings.load() })),
|
||||
saveSettings: saveSettingsHandler(deps.settings, hooks.onSettingsSaved),
|
||||
|
||||
managerConnect: ({ id }) =>
|
||||
wrap(async () => {
|
||||
|
||||
Reference in New Issue
Block a user