From 10770756c95d788926006ff5a3c82dbcb26d5d98 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Fri, 14 Feb 2025 17:30:24 +0100 Subject: [PATCH] feat(suite-desktop): open system settings using desktopApi --- packages/suite-desktop-api/src/api.ts | 2 + packages/suite-desktop-api/src/factory.ts | 1 + .../suite-desktop-core/src/modules/index.ts | 2 + .../src/modules/system-settings.ts | 55 +++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 packages/suite-desktop-core/src/modules/system-settings.ts diff --git a/packages/suite-desktop-api/src/api.ts b/packages/suite-desktop-api/src/api.ts index d06fdbf6218..342ba735fb6 100644 --- a/packages/suite-desktop-api/src/api.ts +++ b/packages/suite-desktop-api/src/api.ts @@ -109,6 +109,7 @@ export interface InvokeChannels { 'connect-popup/ready': () => void; 'connect-popup/response': (response: ConnectPopupResponse) => void; 'system/get-system-information': () => InvokeResult; + 'system/open-settings': (settings: 'bluetooth') => InvokeResult; } type DesktopApiListener = ListenerMethod; @@ -175,4 +176,5 @@ export interface DesktopApi { connectPopupResponse: DesktopApiInvoke<'connect-popup/response'>; //system getSystemInformation: DesktopApiInvoke<'system/get-system-information'>; + openSystemSettings: DesktopApiInvoke<'system/open-settings'>; } diff --git a/packages/suite-desktop-api/src/factory.ts b/packages/suite-desktop-api/src/factory.ts index 7b2f6a9d7b3..551085efb14 100644 --- a/packages/suite-desktop-api/src/factory.ts +++ b/packages/suite-desktop-api/src/factory.ts @@ -183,5 +183,6 @@ export const factory = >( connectPopupResponse: response => ipcRenderer.invoke('connect-popup/response', response), getSystemInformation: () => ipcRenderer.invoke('system/get-system-information'), + openSystemSettings: settings => ipcRenderer.invoke('system/open-settings', settings), }; }; diff --git a/packages/suite-desktop-core/src/modules/index.ts b/packages/suite-desktop-core/src/modules/index.ts index 669947ad2c3..03edd5e87d6 100644 --- a/packages/suite-desktop-core/src/modules/index.ts +++ b/packages/suite-desktop-core/src/modules/index.ts @@ -30,6 +30,7 @@ import * as requestInterceptor from './request-interceptor'; import * as shortcuts from './shortcuts'; import * as store from './store'; import * as systemInformation from './system-information'; +import * as systemSettings from './system-settings'; import * as theme from './theme'; import * as tray from './tray'; import * as trezorConnect from './trezor-connect'; @@ -63,6 +64,7 @@ const MODULES: Module[] = [ autoStart, bridge, systemInformation, + systemSettings, // Modules used only in dev/prod mode ...(isDevEnv ? [] : [csp, fileProtocol]), ]; diff --git a/packages/suite-desktop-core/src/modules/system-settings.ts b/packages/suite-desktop-core/src/modules/system-settings.ts new file mode 100644 index 00000000000..5ed032a033a --- /dev/null +++ b/packages/suite-desktop-core/src/modules/system-settings.ts @@ -0,0 +1,55 @@ +import { exec } from 'child_process'; + +import { isLinux, isMacOs, isWindows } from '@trezor/env-utils'; + +import { ipcMain } from '../typed-electron'; + +import type { ModuleInit } from './index'; + +export const SERVICE_NAME = 'system-settings'; + +const openSettings = (cmd: string, env?: Record) => + new Promise(resolve => { + exec(cmd, { env: { ...process.env, ...env } }, error => { + if (error) { + resolve({ success: false, error } as const); + } else { + resolve({ success: true } as const); + } + }); + }); + +const openBluetoothSettings = () => { + if (isLinux()) { + // https://github.com/electron/electron/blob/ab2a4fd836d539194bc5cde5f0d665eddeb6a134/docs/api/environment-variables.md?plain=1#L190 + // Electron modifies the value of XDG_CURRENT_DESKTOP + const xdg = process.env.ORIGINAL_XDG_CURRENT_DESKTOP || process.env.XDG_CURRENT_DESKTOP; + if (xdg?.includes('GNOME')) { + return openSettings('gnome-control-center bluetooth', { + XDG_CURRENT_DESKTOP: xdg, + }); + } else if (xdg?.includes('KDE')) { + return openSettings('systemsettings5', { + XDG_CURRENT_DESKTOP: xdg, + }); + } + } + if (isMacOs()) { + return openSettings('open "x-apple.systempreferences:com.apple.Bluetooth"'); + } + if (isWindows()) { + return openSettings('start ms-settings:bluetooth'); + } + + return { success: false, error: 'Unsupported os' }; +}; + +export const init: ModuleInit = () => { + ipcMain.handle('system/open-settings', (_, settings) => { + if (settings === 'bluetooth') { + return openBluetoothSettings(); + } + + return { success: false, error: `Unknown settings: ${settings}` }; + }); +};