From d3633353734a50d05a30a3d05690b88bb7ccac03 Mon Sep 17 00:00:00 2001 From: Val Alexander Date: Sun, 5 Apr 2026 01:45:20 -0500 Subject: [PATCH] Remove window opacity setting - Drop deprecated window opacity setting from desktop and web UI - Keep persisted settings and IPC contracts aligned --- apps/desktop/src/main.ts | 12 +------- apps/desktop/src/preload.ts | 2 -- apps/web/src/appSettings.test.ts | 12 ++++++++ apps/web/src/appSettings.ts | 2 -- apps/web/src/i18n/messages/en.json | 3 -- apps/web/src/i18n/messages/es.json | 3 -- apps/web/src/i18n/messages/fr.json | 3 -- apps/web/src/i18n/messages/zh-CN.json | 3 -- apps/web/src/routes/_chat.settings.tsx | 40 -------------------------- apps/web/src/routes/_chat.tsx | 7 ----- packages/contracts/src/ipc.ts | 1 - 11 files changed, 13 insertions(+), 75 deletions(-) diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index eeb12027d..86d96efaa 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -54,7 +54,6 @@ syncShellEnvironment(); const PICK_FOLDER_CHANNEL = "desktop:pick-folder"; const CONFIRM_CHANNEL = "desktop:confirm"; const SET_THEME_CHANNEL = "desktop:set-theme"; -const SET_WINDOW_OPACITY_CHANNEL = "desktop:set-window-opacity"; const SET_SIDEBAR_OPACITY_CHANNEL = "desktop:set-sidebar-opacity"; const CONTEXT_MENU_CHANNEL = "desktop:context-menu"; const OPEN_EXTERNAL_CHANNEL = "desktop:open-external"; @@ -1160,16 +1159,6 @@ function registerIpcHandlers(): void { nativeTheme.themeSource = theme; }); - ipcMain.removeHandler(SET_WINDOW_OPACITY_CHANNEL); - ipcMain.handle(SET_WINDOW_OPACITY_CHANNEL, async (event, rawOpacity: unknown) => { - if (typeof rawOpacity !== "number" || !Number.isFinite(rawOpacity)) return; - const opacity = Math.max(0.3, Math.min(1, rawOpacity)); - const window = BrowserWindow.fromWebContents(event.sender); - if (window) { - window.setOpacity(opacity); - } - }); - ipcMain.removeHandler(SET_SIDEBAR_OPACITY_CHANNEL); ipcMain.handle(SET_SIDEBAR_OPACITY_CHANNEL, async (_event, _rawOpacity: unknown) => { // Sidebar opacity is handled purely on the renderer side via CSS. @@ -1399,6 +1388,7 @@ function createWindow(): BrowserWindow { sandbox: true, }, }); + window.setOpacity(1); window.webContents.on("context-menu", (event, params) => { event.preventDefault(); diff --git a/apps/desktop/src/preload.ts b/apps/desktop/src/preload.ts index 20cd1e005..91477c600 100644 --- a/apps/desktop/src/preload.ts +++ b/apps/desktop/src/preload.ts @@ -4,7 +4,6 @@ import type { DesktopBridge } from "@okcode/contracts"; const PICK_FOLDER_CHANNEL = "desktop:pick-folder"; const CONFIRM_CHANNEL = "desktop:confirm"; const SET_THEME_CHANNEL = "desktop:set-theme"; -const SET_WINDOW_OPACITY_CHANNEL = "desktop:set-window-opacity"; const SET_SIDEBAR_OPACITY_CHANNEL = "desktop:set-sidebar-opacity"; const CONTEXT_MENU_CHANNEL = "desktop:context-menu"; const OPEN_EXTERNAL_CHANNEL = "desktop:open-external"; @@ -32,7 +31,6 @@ contextBridge.exposeInMainWorld("desktopBridge", { pickFolder: () => ipcRenderer.invoke(PICK_FOLDER_CHANNEL), confirm: (message) => ipcRenderer.invoke(CONFIRM_CHANNEL, message), setTheme: (theme) => ipcRenderer.invoke(SET_THEME_CHANNEL, theme), - setWindowOpacity: (opacity) => ipcRenderer.invoke(SET_WINDOW_OPACITY_CHANNEL, opacity), setSidebarOpacity: (opacity) => ipcRenderer.invoke(SET_SIDEBAR_OPACITY_CHANNEL, opacity), showContextMenu: (items, position) => ipcRenderer.invoke(CONTEXT_MENU_CHANNEL, items, position), openExternal: (url: string) => ipcRenderer.invoke(OPEN_EXTERNAL_CHANNEL, url), diff --git a/apps/web/src/appSettings.test.ts b/apps/web/src/appSettings.test.ts index 186e76217..f3f947345 100644 --- a/apps/web/src/appSettings.test.ts +++ b/apps/web/src/appSettings.test.ts @@ -25,6 +25,18 @@ describe("AppSettingsSchema", () => { expect(settings.showAuthFailuresAsErrors).toBe(true); }); + + it("drops deprecated window opacity values from persisted settings", () => { + const decode = Schema.decodeSync(Schema.fromJsonString(AppSettingsSchema)); + + expect( + decode( + JSON.stringify({ + windowOpacity: 0.3, + }), + ), + ).not.toHaveProperty("windowOpacity"); + }); }); describe("normalizeCustomModelSlugs", () => { diff --git a/apps/web/src/appSettings.ts b/apps/web/src/appSettings.ts index afe8e50fe..7f4c85d46 100644 --- a/apps/web/src/appSettings.ts +++ b/apps/web/src/appSettings.ts @@ -80,7 +80,6 @@ export const AppSettingsSchema = Schema.Struct({ withDefaults(() => DEFAULT_SIDEBAR_THREAD_SORT_ORDER), ), timestampFormat: TimestampFormat.pipe(withDefaults(() => DEFAULT_TIMESTAMP_FORMAT)), - windowOpacity: Schema.Number.pipe(withDefaults(() => 1)), sidebarOpacity: Schema.Number.pipe(withDefaults(() => 1)), sidebarHideFiles: Schema.Boolean.pipe(withDefaults(() => false)), sidebarAccentProjectNames: Schema.Boolean.pipe(withDefaults(() => true)), @@ -159,7 +158,6 @@ function clampOpacity(value: number): number { function normalizeAppSettings(settings: AppSettings): AppSettings { return { ...settings, - windowOpacity: clampOpacity(settings.windowOpacity), sidebarOpacity: clampOpacity(settings.sidebarOpacity), customCodexModels: normalizeCustomModelSlugs(settings.customCodexModels, "codex"), customClaudeModels: normalizeCustomModelSlugs(settings.customClaudeModels, "claudeAgent"), diff --git a/apps/web/src/i18n/messages/en.json b/apps/web/src/i18n/messages/en.json index 24552ad8c..8cd5d4c28 100644 --- a/apps/web/src/i18n/messages/en.json +++ b/apps/web/src/i18n/messages/en.json @@ -232,9 +232,6 @@ "settings.general.timeFormat.option.24Hour": "24-hour", "settings.general.timeFormat.option.locale": "System default", "settings.general.timeFormat.title": "Time format", - "settings.general.windowOpacity.aria": "Window opacity", - "settings.general.windowOpacity.description": "Adjust the transparency of the entire application window.", - "settings.general.windowOpacity.title": "Window opacity", "settings.models.customModels.addButton": "Add", "settings.models.customModels.description": "Add custom model slugs for Codex or Anthropic. The chat picker groups models by provider.", "settings.models.customModels.providerAria": "Custom model provider", diff --git a/apps/web/src/i18n/messages/es.json b/apps/web/src/i18n/messages/es.json index e09e58023..57c5daabf 100644 --- a/apps/web/src/i18n/messages/es.json +++ b/apps/web/src/i18n/messages/es.json @@ -232,9 +232,6 @@ "settings.general.timeFormat.option.24Hour": "24 horas", "settings.general.timeFormat.option.locale": "Predeterminado del sistema", "settings.general.timeFormat.title": "Formato de hora", - "settings.general.windowOpacity.aria": "Opacidad de la ventana", - "settings.general.windowOpacity.description": "Ajusta la transparencia de toda la ventana de la aplicación.", - "settings.general.windowOpacity.title": "Opacidad de la ventana", "settings.models.customModels.addButton": "Agregar", "settings.models.customModels.description": "Añade slugs de modelos personalizados para Codex o Anthropic. El selector de chat agrupa los modelos por proveedor.", "settings.models.customModels.providerAria": "Proveedor de modelo personalizado", diff --git a/apps/web/src/i18n/messages/fr.json b/apps/web/src/i18n/messages/fr.json index b93be2358..6708fee39 100644 --- a/apps/web/src/i18n/messages/fr.json +++ b/apps/web/src/i18n/messages/fr.json @@ -232,9 +232,6 @@ "settings.general.timeFormat.option.24Hour": "24 heures", "settings.general.timeFormat.option.locale": "Par défaut du système", "settings.general.timeFormat.title": "Format de l'heure", - "settings.general.windowOpacity.aria": "Opacité de la fenêtre", - "settings.general.windowOpacity.description": "Ajustez la transparence de toute la fenêtre de l'application.", - "settings.general.windowOpacity.title": "Opacité de la fenêtre", "settings.models.customModels.addButton": "Ajouter", "settings.models.customModels.description": "Ajoutez des slugs de modèles personnalisés pour Codex ou Anthropic. Le sélecteur de chat regroupe les modèles par fournisseur.", "settings.models.customModels.providerAria": "Fournisseur de modèle personnalisé", diff --git a/apps/web/src/i18n/messages/zh-CN.json b/apps/web/src/i18n/messages/zh-CN.json index c5fe781dd..5a76b03cd 100644 --- a/apps/web/src/i18n/messages/zh-CN.json +++ b/apps/web/src/i18n/messages/zh-CN.json @@ -232,9 +232,6 @@ "settings.general.timeFormat.option.24Hour": "24 小时制", "settings.general.timeFormat.option.locale": "系统默认", "settings.general.timeFormat.title": "时间格式", - "settings.general.windowOpacity.aria": "窗口透明度", - "settings.general.windowOpacity.description": "调整整个应用窗口的透明度。", - "settings.general.windowOpacity.title": "窗口透明度", "settings.models.customModels.addButton": "添加", "settings.models.customModels.description": "为 Codex 或 Anthropic 添加自定义模型 slug。聊天选择器会按提供方对模型分组。", "settings.models.customModels.providerAria": "自定义模型提供方", diff --git a/apps/web/src/routes/_chat.settings.tsx b/apps/web/src/routes/_chat.settings.tsx index 8a3ebd9f7..663cf2bbd 100644 --- a/apps/web/src/routes/_chat.settings.tsx +++ b/apps/web/src/routes/_chat.settings.tsx @@ -846,46 +846,6 @@ function SettingsRouteView() { } /> - { - updateSettings({ windowOpacity: defaults.windowOpacity }); - if (isElectron && window.desktopBridge) { - void window.desktopBridge.setWindowOpacity(defaults.windowOpacity); - } - }} - /> - ) : null - } - control={ -
- { - const value = Number(e.target.value) / 100; - updateSettings({ windowOpacity: value }); - if (isElectron && window.desktopBridge) { - void window.desktopBridge.setWindowOpacity(value); - } - }} - className="h-1.5 w-24 cursor-pointer appearance-none rounded-full bg-muted accent-foreground sm:w-28" - aria-label="Window opacity" - /> - - {Math.round(settings.windowOpacity * 100)}% - -
- } - /> - { - if (window.desktopBridge) { - void window.desktopBridge.setWindowOpacity(settings.windowOpacity); - } - }, [settings.windowOpacity]); - return ( diff --git a/packages/contracts/src/ipc.ts b/packages/contracts/src/ipc.ts index 3f7e1ed0e..ce2d86f95 100644 --- a/packages/contracts/src/ipc.ts +++ b/packages/contracts/src/ipc.ts @@ -225,7 +225,6 @@ export interface DesktopBridge { pickFolder: () => Promise; confirm: (message: string) => Promise; setTheme: (theme: DesktopTheme) => Promise; - setWindowOpacity: (opacity: number) => Promise; setSidebarOpacity: (opacity: number) => Promise; showContextMenu: ( items: readonly ContextMenuItem[],