fix: Resolve a series of miniWindow display issues and improve app behavior across platforms (#3072)

This commit is contained in:
fullex 2025-03-31 21:07:16 +08:00 committed by GitHub
parent 2da8a73124
commit 8a7db19e73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 112 additions and 46 deletions

View File

@ -23,17 +23,8 @@ function getShortcutHandler(shortcut: Shortcut) {
configManager.setZoomFactor(1)
}
case 'show_app':
return (window: BrowserWindow) => {
if (window.isVisible()) {
if (window.isFocused()) {
window.hide()
} else {
window.focus()
}
} else {
window.show()
window.focus()
}
return () => {
windowService.toggleMainWindow()
}
case 'mini_window':
return () => {

View File

@ -16,6 +16,9 @@ export class WindowService {
private mainWindow: BrowserWindow | null = null
private miniWindow: BrowserWindow | null = null
private wasFullScreen: boolean = false
//hacky-fix: store the focused status of mainWindow before miniWindow shows
//to restore the focus status when miniWindow hides
private wasMainWindowFocused: boolean = false
private selectionMenuWindow: BrowserWindow | null = null
private lastSelectedText: string = ''
private contextMenu: Menu | null = null
@ -30,6 +33,7 @@ export class WindowService {
public createMainWindow(): BrowserWindow {
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
this.mainWindow.show()
this.mainWindow.focus()
return this.mainWindow
}
@ -56,7 +60,7 @@ export class WindowService {
titleBarOverlay: theme === 'dark' ? titleBarOverlayDark : titleBarOverlayLight,
backgroundColor: isMac ? undefined : theme === 'dark' ? '#181818' : '#FFFFFF',
trafficLightPosition: { x: 8, y: 12 },
...(process.platform === 'linux' ? { icon } : {}),
...(isLinux ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
@ -68,6 +72,12 @@ export class WindowService {
this.setupMainWindow(this.mainWindow, mainWindowState)
//preload miniWindow to resolve series of issues about miniWindow in Mac
const enableQuickAssistant = configManager.getEnableQuickAssistant()
if (enableQuickAssistant && !this.miniWindow) {
this.miniWindow = this.createMiniWindow(true)
}
return this.mainWindow
}
@ -148,6 +158,8 @@ export class WindowService {
// show window only when laucn to tray not set
const isLaunchToTray = configManager.getLaunchToTray()
if (!isLaunchToTray) {
//[mac]hacky-fix: miniWindow set visibleOnFullScreen:true will cause dock icon disappeared
app.dock?.show()
mainWindow.show()
}
})
@ -305,9 +317,8 @@ export class WindowService {
event.preventDefault()
mainWindow.hide()
if (isMac && isTrayOnClose) {
app.dock?.hide() //for mac to hide to tray
}
//for mac users, should hide dock icon if close to tray
app.dock?.hide()
})
mainWindow.on('closed', () => {
@ -328,44 +339,48 @@ export class WindowService {
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
if (this.mainWindow.isMinimized()) {
return this.mainWindow.restore()
this.mainWindow.restore()
return
}
//[macOS] Known Issue
// setVisibleOnAllWorkspaces true/false will NOT bring window to current desktop in Mac (works fine with Windows)
// AppleScript may be a solution, but it's not worth
this.mainWindow.setVisibleOnAllWorkspaces(true)
this.mainWindow.show()
this.mainWindow.focus()
this.mainWindow.setVisibleOnAllWorkspaces(false)
} else {
this.mainWindow = this.createMainWindow()
this.mainWindow.focus()
}
//for mac users, when window is shown, should show dock icon (dock may be set to hide when launch)
app.dock?.show()
}
public showMiniWindow() {
const enableQuickAssistant = configManager.getEnableQuickAssistant()
if (!enableQuickAssistant) {
public toggleMainWindow() {
// should not toggle main window when in full screen
if (this.wasFullScreen) {
return
}
if (this.selectionMenuWindow && !this.selectionMenuWindow.isDestroyed()) {
this.selectionMenuWindow.hide()
}
if (this.miniWindow && !this.miniWindow.isDestroyed()) {
if (this.miniWindow.isMinimized()) {
this.miniWindow.restore()
if (this.mainWindow && !this.mainWindow.isDestroyed() && this.mainWindow.isVisible()) {
if (this.mainWindow.isFocused()) {
// if tray is enabled, hide the main window, else do nothing
if (configManager.getTray()) {
this.mainWindow.hide()
app.dock?.hide()
}
} else {
this.mainWindow.focus()
}
this.miniWindow.show()
this.miniWindow.center()
this.miniWindow.focus()
return
}
this.showMainWindow()
}
public createMiniWindow(isPreload: boolean = false): BrowserWindow {
this.miniWindow = new BrowserWindow({
width: 500,
height: 520,
show: true,
show: false,
autoHideMenuBar: true,
transparent: isMac,
vibrancy: 'under-window',
@ -375,6 +390,11 @@ export class WindowService {
alwaysOnTop: true,
resizable: false,
useContentSize: true,
...(isMac ? { type: 'panel' } : {}),
skipTaskbar: true,
minimizable: false,
maximizable: false,
fullscreenable: false,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
@ -383,8 +403,23 @@ export class WindowService {
}
})
//miniWindow should show in current desktop
this.miniWindow?.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true })
//make miniWindow always on top of fullscreen apps with level set
this.miniWindow.setAlwaysOnTop(true, 'screen-saver', 1)
this.miniWindow.on('ready-to-show', () => {
if (isPreload) {
return
}
this.wasMainWindowFocused = this.mainWindow?.isFocused() || false
this.miniWindow?.center()
this.miniWindow?.show()
})
this.miniWindow.on('blur', () => {
this.miniWindow?.hide()
this.hideMiniWindow()
})
this.miniWindow.on('closed', () => {
@ -410,9 +445,48 @@ export class WindowService {
hash: '#/mini'
})
}
return this.miniWindow
}
public showMiniWindow() {
const enableQuickAssistant = configManager.getEnableQuickAssistant()
if (!enableQuickAssistant) {
return
}
if (this.selectionMenuWindow && !this.selectionMenuWindow.isDestroyed()) {
this.selectionMenuWindow.hide()
}
if (this.miniWindow && !this.miniWindow.isDestroyed()) {
this.wasMainWindowFocused = this.mainWindow?.isFocused() || false
if (this.miniWindow.isMinimized()) {
this.miniWindow.restore()
}
this.miniWindow.show()
return
}
this.miniWindow = this.createMiniWindow()
}
public hideMiniWindow() {
//hacky-fix:[mac/win] previous window(not self-app) should be focused again after miniWindow hide
if (isWin) {
this.miniWindow?.minimize()
this.miniWindow?.hide()
return
} else if (isMac) {
this.miniWindow?.hide()
if (!this.wasMainWindowFocused) {
app.hide()
}
return
}
this.miniWindow?.hide()
}
@ -421,11 +495,12 @@ export class WindowService {
}
public toggleMiniWindow() {
if (this.miniWindow) {
this.miniWindow.isVisible() ? this.miniWindow.hide() : this.miniWindow.show()
} else {
this.showMiniWindow()
if (this.miniWindow && !this.miniWindow.isDestroyed() && this.miniWindow.isVisible()) {
this.hideMiniWindow()
return
}
this.showMiniWindow()
}
public showSelectionMenu(bounds: { x: number; y: number }) {

View File

@ -1190,7 +1190,7 @@
"reset_defaults_confirm": "Are you sure you want to reset all shortcuts?",
"reset_to_default": "Reset to Default",
"search_message": "Search Message",
"show_app": "Show App",
"show_app": "Show/Hide App",
"show_settings": "Open Settings",
"title": "Keyboard Shortcuts",
"toggle_new_context": "Clear Context",

View File

@ -1189,7 +1189,7 @@
"reset_defaults_confirm": "すべてのショートカットをリセットしてもよろしいですか?",
"reset_to_default": "デフォルトにリセット",
"search_message": "メッセージを検索",
"show_app": "アプリを表示",
"show_app": "アプリを表示/非表示",
"show_settings": "設定を開く",
"title": "ショートカット",
"toggle_new_context": "コンテキストをクリア",

View File

@ -1189,7 +1189,7 @@
"reset_defaults_confirm": "Вы уверены, что хотите сбросить все горячие клавиши?",
"reset_to_default": "Сбросить настройки по умолчанию",
"search_message": "Поиск сообщения",
"show_app": "Показать приложение",
"show_app": "Показать/скрыть приложение",
"show_settings": "Открыть настройки",
"title": "Горячие клавиши",
"toggle_new_context": "Очистить контекст",

View File

@ -1190,7 +1190,7 @@
"reset_defaults_confirm": "确定要重置所有快捷键吗?",
"reset_to_default": "重置为默认",
"search_message": "搜索消息",
"show_app": "显示应用",
"show_app": "显示/隐藏应用",
"show_settings": "打开设置",
"title": "快捷方式",
"toggle_new_context": "清除上下文",

View File

@ -1189,7 +1189,7 @@
"reset_defaults_confirm": "確定要重設所有快捷鍵嗎?",
"reset_to_default": "重設為預設",
"search_message": "搜尋訊息",
"show_app": "顯示應用程式",
"show_app": "顯示/隱藏應用程式",
"show_settings": "開啟設定",
"title": "快速方式",
"toggle_new_context": "清除上下文",

View File

@ -175,7 +175,7 @@ const GeneralSettings: FC = () => {
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.tray.onclose')}</SettingRowTitle>
<Switch checked={trayOnClose} onChange={(checked) => updateTrayOnClose(checked)} disabled={!tray} />
<Switch checked={trayOnClose} onChange={(checked) => updateTrayOnClose(checked)} />
</SettingRow>
</SettingGroup>
</SettingContainer>