Skip to content

Commit 266e735

Browse files
committed
feat: add configurable GPU acceleration toggle
- Add disableHardwareAcceleration setting to electron-store - Add GPU toggle UI in settings page with tooltip - Show restart prompt when toggle changes - Add i18n support for 5 languages (zh/en/tr/ja/hu) - Update TypeScript types and Vuex store
1 parent 9c413d9 commit 266e735

6 files changed

Lines changed: 123 additions & 2 deletions

File tree

src/background.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,23 @@ declare const __static: string
4040

4141
const Store = require('electron-store')
4242
const electronStore = new Store()
43+
const DISABLE_HARDWARE_ACCELERATION_SETTING_KEY = 'settings.disableHardwareAcceleration'
4344
let theme: Theme = 'light'
4445
let syncOsTheme = false
4546
let autoCheckUpdate: boolean = true
4647
const isDevelopment: boolean = process.env.NODE_ENV !== 'production'
4748
const isMac: boolean = process.platform === 'darwin'
4849

50+
const disableHardwareAccelerationBySetting =
51+
electronStore.get(DISABLE_HARDWARE_ACCELERATION_SETTING_KEY, false) === true
52+
53+
// Hardware acceleration must be configured before the app is ready, so this
54+
// setting is read from electron-store instead of the database settings table.
55+
if (disableHardwareAccelerationBySetting) {
56+
app.disableHardwareAcceleration()
57+
console.log('[GPU] Hardware acceleration disabled')
58+
}
59+
4960
// Keep a global reference of the window object, if you don't, the window will
5061
// be closed automatically when the JavaScript object is garbage collected.
5162
let win: BrowserWindow | null
@@ -222,6 +233,7 @@ async function createWindow() {
222233
logLevel: setting.logLevel,
223234
ignoreQoS0Message: setting.ignoreQoS0Message,
224235
topicWhitespaceDetection: electronStore.get('settings.topicWhitespaceDetection', false),
236+
disableHardwareAcceleration: disableHardwareAccelerationBySetting,
225237
}
226238
}
227239
} catch (error) {
@@ -234,6 +246,7 @@ async function createWindow() {
234246
currentLang: 'en',
235247
syncOsTheme: false,
236248
topicWhitespaceDetection: electronStore.get('settings.topicWhitespaceDetection', false),
249+
disableHardwareAcceleration: disableHardwareAccelerationBySetting,
237250
}
238251
}
239252
// Create the browser window.

src/lang/settings.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,48 @@ export default {
153153
ja: 'トピック内の空白を示し、送受信の不一致を防ぐための確認に役立ちます。',
154154
hu: 'Highlights whitespace in topics to help prevent publish/subscribe mismatches.',
155155
},
156+
disableHardwareAcceleration: {
157+
zh: '禁用 GPU 加速',
158+
en: 'Disable GPU Acceleration',
159+
tr: 'Disable GPU Acceleration',
160+
ja: 'Disable GPU Acceleration',
161+
hu: 'Disable GPU Acceleration',
162+
},
163+
disableHardwareAccelerationDesc: {
164+
zh: 'GPU 加速利用显卡硬件渲染界面,可使操作更流畅并降低 CPU 占用。如遇画面卡顿、花屏或兼容性问题,可尝试关闭此选项。',
165+
en: 'GPU acceleration uses graphics hardware to render the UI, making operations smoother and reducing CPU usage. Disable this option if you experience screen lag, artifacts, or compatibility issues.',
166+
tr: 'GPU acceleration uses graphics hardware to render the UI, making operations smoother and reducing CPU usage. Disable this option if you experience screen lag, artifacts, or compatibility issues.',
167+
ja: 'GPU acceleration uses graphics hardware to render the UI, making operations smoother and reducing CPU usage. Disable this option if you experience screen lag, artifacts, or compatibility issues.',
168+
hu: 'GPU acceleration uses graphics hardware to render the UI, making operations smoother and reducing CPU usage. Disable this option if you experience screen lag, artifacts, or compatibility issues.',
169+
},
170+
restartRequired: {
171+
zh: '需要重启',
172+
en: 'Restart Required',
173+
tr: 'Restart Required',
174+
ja: 'Restart Required',
175+
hu: 'Restart Required',
176+
},
177+
restartRequiredDesc: {
178+
zh: 'GPU 加速设置已更新。需要重启应用才能生效,是否立即重启?',
179+
en: 'The GPU acceleration setting has been updated. Restart the app now to apply the change?',
180+
tr: 'The GPU acceleration setting has been updated. Restart the app now to apply the change?',
181+
ja: 'The GPU acceleration setting has been updated. Restart the app now to apply the change?',
182+
hu: 'The GPU acceleration setting has been updated. Restart the app now to apply the change?',
183+
},
184+
restartNow: {
185+
zh: '立即重启',
186+
en: 'Restart Now',
187+
tr: 'Restart Now',
188+
ja: 'Restart Now',
189+
hu: 'Restart Now',
190+
},
191+
restartLater: {
192+
zh: '稍后重启',
193+
en: 'Later',
194+
tr: 'Later',
195+
ja: 'Later',
196+
hu: 'Later',
197+
},
156198
autoResubDesc: {
157199
zh: '开启后,MQTTX 连接后会自动重新订阅本地保存的所有订阅',
158200
en: 'Once enabled, MQTTX will automatically resubscribe to all locally saved subscriptions after connecting',

src/store/getter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const getters = {
2626
ignoreQoS0Message: (state: State) => state.app.ignoreQoS0Message,
2727
topicWhitespaceDetection: (state: State) => state.app.topicWhitespaceDetection,
2828
maxPayloadDisplaySize: (state: State) => state.app.maxPayloadDisplaySize,
29+
disableHardwareAcceleration: (state: State) => state.app.disableHardwareAcceleration,
2930
}
3031

3132
export default getters

src/store/modules/app.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ const SET_DATABASE_FAIL_MESSAGE = 'SET_DATABASE_FAIL_MESSAGE'
3535
const TOGGLE_IGNORE_QOS0_MESSAGE = 'TOGGLE_IGNORE_QOS0_MESSAGE'
3636
const TOGGLE_TOPIC_WHITESPACE_DETECTION = 'TOGGLE_TOPIC_WHITESPACE_DETECTION'
3737
const SET_MAX_PAYLOAD_DISPLAY_SIZE = 'SET_MAX_PAYLOAD_DISPLAY_SIZE'
38+
const TOGGLE_DISABLE_HARDWARE_ACCELERATION = 'TOGGLE_DISABLE_HARDWARE_ACCELERATION'
39+
const DISABLE_HARDWARE_ACCELERATION_SETTING_KEY = 'settings.disableHardwareAcceleration'
3840

3941
const getShowConnectionList = (): boolean => {
4042
const _showConnectionList: string | null = localStorage.getItem('showConnectionList')
@@ -77,6 +79,9 @@ const app = {
7779
maxPayloadDisplaySize: normalizeMaxPayloadDisplaySize(
7880
electronStore.get('settings.maxPayloadDisplaySize', DEFAULT_MAX_PAYLOAD_DISPLAY_SIZE),
7981
),
82+
disableHardwareAcceleration:
83+
settingData.disableHardwareAcceleration ??
84+
electronStore.get(DISABLE_HARDWARE_ACCELERATION_SETTING_KEY, false) === true,
8085
},
8186
mutations: {
8287
[TOGGLE_THEME](state: App, currentTheme: Theme) {
@@ -190,6 +195,9 @@ const app = {
190195
[SET_MAX_PAYLOAD_DISPLAY_SIZE](state: App, maxPayloadDisplaySize: number) {
191196
state.maxPayloadDisplaySize = maxPayloadDisplaySize
192197
},
198+
[TOGGLE_DISABLE_HARDWARE_ACCELERATION](state: App, disableHardwareAcceleration: boolean) {
199+
state.disableHardwareAcceleration = disableHardwareAcceleration
200+
},
193201
},
194202
actions: {
195203
async TOGGLE_THEME({ commit }: any, payload: App) {
@@ -325,6 +333,11 @@ const app = {
325333
commit(SET_MAX_PAYLOAD_DISPLAY_SIZE, normalizedValue)
326334
electronStore.set('settings.maxPayloadDisplaySize', normalizedValue)
327335
},
336+
TOGGLE_DISABLE_HARDWARE_ACCELERATION({ commit }: any, payload: App) {
337+
commit(TOGGLE_DISABLE_HARDWARE_ACCELERATION, payload.disableHardwareAcceleration)
338+
settingData.disableHardwareAcceleration = payload.disableHardwareAcceleration
339+
electronStore.set(DISABLE_HARDWARE_ACCELERATION_SETTING_KEY, payload.disableHardwareAcceleration)
340+
},
328341
},
329342
}
330343

src/types/global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ declare global {
116116
ignoreQoS0Message: boolean
117117
topicWhitespaceDetection: boolean
118118
maxPayloadDisplaySize: number
119+
disableHardwareAcceleration: boolean
119120
}
120121

121122
interface State {

src/views/settings/index.vue

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,32 @@
370370
</el-row>
371371
<el-divider></el-divider>
372372

373+
<el-row class="settings-item" type="flex" justify="space-between">
374+
<el-col :span="20">
375+
<label>{{ $t('settings.disableHardwareAcceleration') }}</label>
376+
<el-tooltip
377+
placement="top"
378+
:effect="currentTheme !== 'light' ? 'light' : 'dark'"
379+
:open-delay="500"
380+
:content="$t('settings.disableHardwareAccelerationDesc')"
381+
>
382+
<a href="javascript:;" class="icon-oper">
383+
<i class="el-icon-warning-outline"></i>
384+
</a>
385+
</el-tooltip>
386+
</el-col>
387+
<el-col :span="4">
388+
<el-switch
389+
:value="disableHardwareAcceleration"
390+
active-color="#13ce66"
391+
inactive-color="#A2A9B0"
392+
@change="handleDisableHardwareAccelerationChange"
393+
>
394+
</el-switch>
395+
</el-col>
396+
</el-row>
397+
<el-divider></el-divider>
398+
373399
<ImportData :visible.sync="showImportData" />
374400
<ExportData :visible.sync="showExportData" />
375401
<ClearUpHistoryData :visible.sync="showHistoryData" />
@@ -474,7 +500,7 @@
474500
import { Component, Vue } from 'vue-property-decorator'
475501
import { Getter, Action } from 'vuex-class'
476502
import { ipcRenderer } from 'electron'
477-
import { nativeTheme } from '@electron/remote'
503+
import { app as remoteApp, nativeTheme } from '@electron/remote'
478504
import ImportData from '@/components/ImportData.vue'
479505
import ExportData from '@/components/ExportData.vue'
480506
import ClearUpHistoryData from '@/components/ClearUpHistoryData.vue'
@@ -521,6 +547,9 @@ export default class Settings extends Vue {
521547
@Action('SET_MAX_PAYLOAD_DISPLAY_SIZE') private actionSetMaxPayloadDisplaySize!: (payload: {
522548
maxPayloadDisplaySize: number
523549
}) => void
550+
@Action('TOGGLE_DISABLE_HARDWARE_ACCELERATION') private actionToggleDisableHardwareAcceleration!: (payload: {
551+
disableHardwareAcceleration: boolean
552+
}) => void
524553
525554
@Getter('currentTheme') private currentTheme!: Theme
526555
@Getter('currentLang') private currentLang!: Language
@@ -538,6 +567,7 @@ export default class Settings extends Vue {
538567
@Getter('ignoreQoS0Message') private ignoreQoS0Message!: boolean
539568
@Getter('topicWhitespaceDetection') private topicWhitespaceDetection!: boolean
540569
@Getter('maxPayloadDisplaySize') private maxPayloadDisplaySize!: number
570+
@Getter('disableHardwareAcceleration') private disableHardwareAcceleration!: boolean
541571
542572
private showAIModelsSelect = false
543573
@@ -630,6 +660,11 @@ export default class Settings extends Vue {
630660
this.actionToggleTopicWhitespaceDetection({ topicWhitespaceDetection: value })
631661
}
632662
663+
private handleDisableHardwareAccelerationChange(value: boolean) {
664+
this.actionToggleDisableHardwareAcceleration({ disableHardwareAcceleration: value })
665+
this.promptAppRestart()
666+
}
667+
633668
private handleInputChanged(value: number) {
634669
this.actionMaxReconnectTimes({ maxReconnectTimes: value })
635670
}
@@ -701,14 +736,30 @@ export default class Settings extends Vue {
701736
this.showAIModelsSelect = false
702737
}
703738
704-
private queryAIAPIHost(queryString: string, cb: (r: any[]) => {}) {
739+
private queryAIAPIHost(queryString: string, cb: (r: any[]) => void) {
705740
cb(queryString ? this.AIAPIHostOptions.filter((item) => item.value.includes(queryString)) : this.AIAPIHostOptions)
706741
}
707742
708743
private handleIgnoreQoS0MessageSwitchChange(value: boolean) {
709744
this.actionToggleIgnoreQoS0Message({ ignoreQoS0Message: value })
710745
}
711746
747+
private promptAppRestart() {
748+
this.$confirm(this.$t('settings.restartRequiredDesc') as string, {
749+
title: this.$t('settings.restartRequired') as string,
750+
showClose: false,
751+
closeOnClickModal: false,
752+
confirmButtonText: this.$t('settings.restartNow') as string,
753+
cancelButtonText: this.$t('settings.restartLater') as string,
754+
type: 'warning',
755+
})
756+
.then(() => {
757+
remoteApp.relaunch()
758+
remoteApp.exit()
759+
})
760+
.catch(() => undefined)
761+
}
762+
712763
private created() {
713764
this.getAIConfigs()
714765
this.payloadDisplaySizeValue = this.maxPayloadDisplaySize

0 commit comments

Comments
 (0)