refactor(electron+vue): 优化窗口拖拽和激活逻辑

1. 为提交窗口标题栏添加拖拽支持,同时关闭关闭按钮的拖拽区域
2. 重构窗口激活显示逻辑为复用函数showAndFocusMainWindow
3. 修复窗口实例管理和托盘图标点击的逻辑问题
This commit is contained in:
2026-07-17 21:39:34 +08:00
parent ca5e7b98ac
commit e8a2bb921b
2 changed files with 49 additions and 25 deletions
+37 -23
View File
@@ -256,8 +256,22 @@ const requestApplicationExit = (): void => {
app.quit(); app.quit();
}; };
const showAndFocusMainWindow = (): void => {
if (!win || win.isDestroyed()) {
createWindow();
return;
}
if (win.isMinimized()) {
win.restore();
}
win.show();
win.setSkipTaskbar(false);
win.focus();
};
async function createWindow() { async function createWindow() {
win = new BrowserWindow({ const mainWindow = new BrowserWindow({
title: "星火应用商店", title: "星火应用商店",
width: 1366, width: 1366,
height: 768, height: 768,
@@ -274,30 +288,40 @@ async function createWindow() {
// contextIsolation: false, // contextIsolation: false,
}, },
}); });
win = mainWindow;
if (VITE_DEV_SERVER_URL) { if (VITE_DEV_SERVER_URL) {
// #298 // #298
win.loadURL(VITE_DEV_SERVER_URL); mainWindow.loadURL(VITE_DEV_SERVER_URL);
// Open devTool if the app is not packaged // Open devTool if the app is not packaged
win.webContents.openDevTools({ mode: "detach" }); mainWindow.webContents.openDevTools({ mode: "detach" });
} else { } else {
win.loadFile(indexHtml); mainWindow.loadFile(indexHtml);
} }
// Test actively push message to the Electron-Renderer // Test actively push message to the Electron-Renderer
win.webContents.on("did-finish-load", () => { mainWindow.webContents.on("did-finish-load", () => {
win?.webContents.send("main-process-message", new Date().toLocaleString()); mainWindow.webContents.send(
"main-process-message",
new Date().toLocaleString(),
);
logger.info("Renderer process is ready."); logger.info("Renderer process is ready.");
}); });
// Make all links open with the browser, not with the application // Make all links open with the browser, not with the application
win.webContents.setWindowOpenHandler(({ url }) => { mainWindow.webContents.setWindowOpenHandler(({ url }) => {
if (url.startsWith("https:")) shell.openExternal(url); if (url.startsWith("https:")) shell.openExternal(url);
return { action: "deny" }; return { action: "deny" };
}); });
// win.webContents.on('will-navigate', (event, url) => { }) #344 // win.webContents.on('will-navigate', (event, url) => { }) #344
win.on("close", (event) => { mainWindow.on("closed", () => {
if (win === mainWindow) {
win = null;
}
});
mainWindow.on("close", (event) => {
if (allowAppExit) { if (allowAppExit) {
return; return;
} }
@@ -476,20 +500,11 @@ app.on("window-all-closed", () => {
}); });
app.on("second-instance", () => { app.on("second-instance", () => {
if (win) { showAndFocusMainWindow();
// Focus on the main window if the user tried to open another
if (win.isMinimized()) win.restore();
win.focus();
}
}); });
app.on("activate", () => { app.on("activate", () => {
const allWindows = BrowserWindow.getAllWindows(); showAndFocusMainWindow();
if (allWindows.length) {
allWindows[0].focus();
} else {
createWindow();
}
}); });
app.on("will-quit", () => { app.on("will-quit", () => {
@@ -542,7 +557,7 @@ app.whenReady().then(() => {
{ {
label: "显示主界面", label: "显示主界面",
click: () => { click: () => {
win.show(); showAndFocusMainWindow();
}, },
}, },
{ {
@@ -557,12 +572,11 @@ app.whenReady().then(() => {
// 双击触发 // 双击触发
tray.on("click", () => { tray.on("click", () => {
// 双击通知区图标实现应用的显示或隐藏 // 双击通知区图标实现应用的显示或隐藏
if (win.isVisible()) { if (win && !win.isDestroyed() && win.isVisible()) {
win.hide(); win.hide();
win.setSkipTaskbar(true); win.setSkipTaskbar(true);
} else { } else {
win.show(); showAndFocusMainWindow();
win.setSkipTaskbar(false);
} }
}); });
}); });
+12 -2
View File
@@ -3,7 +3,7 @@
class="h-screen overflow-y-auto bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-slate-100" class="h-screen overflow-y-auto bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-slate-100"
> >
<div <div
class="sticky top-0 z-30 border-b border-slate-200/70 bg-white px-4 py-3 dark:border-slate-800/70 dark:bg-slate-900" class="submitter-titlebar sticky top-0 z-30 border-b border-slate-200/70 bg-white px-4 py-3 dark:border-slate-800/70 dark:bg-slate-900"
> >
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
@@ -16,7 +16,7 @@
</div> </div>
<button <button
type="button" type="button"
class="inline-flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-800" class="submitter-close-button inline-flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-800"
@click="closeWindow" @click="closeWindow"
> >
<i class="fas fa-times"></i> <i class="fas fa-times"></i>
@@ -1734,3 +1734,13 @@ onMounted(async () => {
await getGitEmail(); await getGitEmail();
}); });
</script> </script>
<style scoped>
.submitter-titlebar {
-webkit-app-region: drag;
}
.submitter-close-button {
-webkit-app-region: no-drag;
}
</style>