Open setting window on mouse screen

This commit is contained in:
qianlifeng 2023-11-23 14:40:43 +08:00
parent 68faeb9cac
commit da69e626d4
11 changed files with 149 additions and 136 deletions

View File

@ -4,5 +4,5 @@ pre-commit:
root: "Wox/"
run: go vet
ui-build:
root: "Wox.UI.Tauri/"
root: "Wox.UI.React/"
run: pnpm build

View File

@ -1,8 +1,8 @@
const {app, BrowserWindow, ipcMain, remote, dialog, nativeTheme} = require("electron")
const { app, BrowserWindow, ipcMain, remote, dialog, nativeTheme } = require("electron")
if (process.argv.length !== 10) {
dialog.showErrorBox("Error", "Arguments not enough")
process.exit(1)
dialog.showErrorBox("Error", "Arguments not enough")
process.exit(1)
}
const preloadJs = process.argv[3]
@ -16,120 +16,130 @@ let settingWindow = null
// watch pid if exists, otherwise exit
setInterval(() => {
try {
process.kill(pid, 0)
} catch (e) {
process.exit(0)
}
try {
process.kill(pid, 0)
} catch (e) {
process.exit(0)
}
}, 1000)
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 70,
show: false,
vibrancy: "popover",
visualEffectState: "active",
frame: false,
resizable: false,
webPreferences: {
preload: preloadJs
}
const win = new BrowserWindow({
width: 800,
height: 70,
show: false,
vibrancy: "popover",
visualEffectState: "active",
frame: false,
resizable: false,
webPreferences: {
preload: preloadJs
}
})
win.setAlwaysOnTop(true, "screen-saver")
win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true })
win.setSkipTaskbar(true)
win.setFullScreenable(false)
win.setBackgroundColor(appBackgroundColor)
win.on("blur", e => {
win.webContents.send("onBlur")
})
win.on("resize", e => {
const size = win.getSize()
console.log(`resize: ${size[0]} ${size[1]}`)
})
ipcMain.on("show", event => {
win.show()
})
ipcMain.on("hide", event => {
if (process.platform === "darwin") {
// Hides the window
win.hide()
// Make other windows to gain focus
if (settingWindow !== null && !settingWindow.isDestroyed() && settingWindow.isVisible()) {
//don't hide app when setting window is visible
} else {
app.hide()
}
} else {
// On Windows 11, previously active window gain focus when the current window is minimized
win.minimize()
// Then we call hide to hide app from the taskbar
win.hide()
}
})
ipcMain.on("setSize", (event, width, height) => {
win.setBounds({ width, height })
})
ipcMain.on("openDevTools", event => {
win.openDevTools()
})
ipcMain.on("setPosition", (event, x, y) => {
win.setPosition(x, y)
})
ipcMain.on("setBackgroundColor", (event, backgroundColor) => {
win.setBackgroundColor(backgroundColor)
})
ipcMain.on("focus", event => {
win.focus()
})
ipcMain.on("openSettingWindow", (event, url, x, y) => {
if (settingWindow !== null && !settingWindow.isDestroyed()) {
settingWindow.focus()
return
}
settingWindow = new BrowserWindow({
width: 1280,
height: 800,
minWidth: 800,
minHeight: 600,
vibrancy: "popover",
show: false,
titleBarStyle: "hiddenInset",
x: x,
y: y
})
win.setAlwaysOnTop(true, "screen-saver")
win.setVisibleOnAllWorkspaces(true, {visibleOnFullScreen: true})
win.setSkipTaskbar(true)
win.setFullScreenable(false)
win.setBackgroundColor(appBackgroundColor)
win.on("blur", (e) => {
win.webContents.send("onBlur")
settingWindow.loadURL(baseUrl + url)
settingWindow.once("ready-to-show", () => {
//make sure is rendered
setTimeout(() => {
settingWindow.show()
}, 300)
})
})
win.on("resize", (e) => {
const size = win.getSize()
console.log(`resize: ${size[0]} ${size[1]}`)
})
ipcMain.on("log", (event, msg) => {
console.log(`UI: ${msg}`)
})
ipcMain.on("show", (event) => {
win.show()
})
ipcMain.handle("isVisible", async event => {
return win.isVisible()
})
ipcMain.on("hide", (event) => {
if (process.platform === "darwin") {
// Hides the window
win.hide()
// Make other windows to gain focus
if (settingWindow !== null && !settingWindow.isDestroyed() && settingWindow.isVisible()) {
//don't hide app when setting window is visible
} else {
app.hide()
}
} else {
// On Windows 11, previously active window gain focus when the current window is minimized
win.minimize()
// Then we call hide to hide app from the taskbar
win.hide()
}
})
ipcMain.handle("isDev", async event => {
return isDev === "true"
})
ipcMain.on("setSize", (event, width, height) => {
win.setBounds({width, height})
})
ipcMain.handle("getServerPort", async event => {
return serverPort
})
ipcMain.on("openDevTools", (event) => {
win.openDevTools()
})
ipcMain.on("setPosition", (event, x, y) => {
win.setPosition(x, y)
})
ipcMain.on("setBackgroundColor", (event, backgroundColor) => {
win.setBackgroundColor(backgroundColor)
})
ipcMain.on("focus", (event) => {
win.focus()
})
ipcMain.on("openSettingWindow", (event, url) => {
if (settingWindow !== null && !settingWindow.isDestroyed()) {
settingWindow.focus()
return
}
settingWindow = new BrowserWindow({
width: 1280,
height: 800,
minWidth: 800,
minHeight: 600,
vibrancy: "popover",
titleBarStyle: "hiddenInset",
})
settingWindow.loadURL(baseUrl + url)
})
ipcMain.on("log", (event, msg) => {
console.log(`UI: ${msg}`)
})
ipcMain.handle("isVisible", async (event) => {
return win.isVisible()
})
ipcMain.handle("isDev", async (event) => {
return isDev === "true"
})
ipcMain.handle("getServerPort", async (event) => {
return serverPort
})
win.loadURL(homeUrl)
win.loadURL(homeUrl)
}
app.whenReady().then(() => {
nativeTheme.themeSource = "light"
createWindow()
})
nativeTheme.themeSource = "light"
createWindow()
})

View File

@ -1,17 +1,17 @@
const {contextBridge, ipcRenderer} = require("electron")
const { contextBridge, ipcRenderer } = require("electron")
contextBridge.exposeInMainWorld("electronAPI", {
show: () => ipcRenderer.send("show"),
hide: () => ipcRenderer.send("hide"),
isVisible: async () => ipcRenderer.invoke("isVisible"),
getServerPort: async () => ipcRenderer.invoke("getServerPort"),
isDev: async () => ipcRenderer.invoke("isDev"),
setPosition: (x, y) => ipcRenderer.send("setPosition", x, y),
log: (msg) => ipcRenderer.send("log", msg),
openDevTools: () => ipcRenderer.send("openDevTools"),
setBackgroundColor: (backgroundColor) => ipcRenderer.send("setBackgroundColor", backgroundColor),
setSize: (width, height) => ipcRenderer.send("setSize", width, height),
focus: () => ipcRenderer.send("focus"),
openSettingWindow: (url) => ipcRenderer.send("openSettingWindow", url),
onBlur: (callback) => ipcRenderer.on("onBlur", callback)
})
show: () => ipcRenderer.send("show"),
hide: () => ipcRenderer.send("hide"),
isVisible: async () => ipcRenderer.invoke("isVisible"),
getServerPort: async () => ipcRenderer.invoke("getServerPort"),
isDev: async () => ipcRenderer.invoke("isDev"),
setPosition: (x, y) => ipcRenderer.send("setPosition", x, y),
log: msg => ipcRenderer.send("log", msg),
openDevTools: () => ipcRenderer.send("openDevTools"),
setBackgroundColor: backgroundColor => ipcRenderer.send("setBackgroundColor", backgroundColor),
setSize: (width, height) => ipcRenderer.send("setSize", width, height),
focus: () => ipcRenderer.send("focus"),
openSettingWindow: (url, x, y) => ipcRenderer.send("openSettingWindow", url, x, y),
onBlur: callback => ipcRenderer.on("onBlur", callback)
})

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"
import { useEffect, useState } from "react"
import { WoxPluginHelper } from "../../utils/WoxPluginHelper.ts"
import { Box, Button, CircularProgress, Divider, List, ListItem, ListItemAvatar, ListItemText } from "@mui/material"
import styled from "styled-components"

View File

@ -9,6 +9,6 @@ export class WoxMessageRequestMethodEnum extends BaseEnum {
static readonly ToggleApp = WoxMessageRequestMethodEnum.define("ToggleApp", "Toggle App")
static readonly ShowMsg = WoxMessageRequestMethodEnum.define("ShowMsg", "Show Msg")
static readonly ChangeTheme = WoxMessageRequestMethodEnum.define("ChangeTheme", "Change Theme")
static readonly OpenSettingDialog = WoxMessageRequestMethodEnum.define("OpenSettingDialog", "Open Setting Dialog")
static readonly OpenSettingWindow = WoxMessageRequestMethodEnum.define("OpenSettingWindow", "Open Setting Dialog")
static readonly OpenDevTools = WoxMessageRequestMethodEnum.define("OpenDevTools", "Open Dev Tools")
}

View File

@ -146,8 +146,8 @@ export default () => {
if (message.Method === WoxMessageRequestMethodEnum.ChangeTheme.code) {
await changeTheme(message.Data as string)
}
if (message.Method === WoxMessageRequestMethodEnum.OpenSettingDialog.code) {
await WoxUIHelper.getInstance().openSettingWindow()
if (message.Method === WoxMessageRequestMethodEnum.OpenSettingWindow.code) {
await WoxUIHelper.getInstance().openSettingWindow(message.Data as { x: number; y: number })
}
if (message.Method === WoxMessageRequestMethodEnum.OpenDevTools.code) {
await WoxUIHelper.getInstance().openDevTools()

View File

@ -127,9 +127,9 @@ export class WoxUIHelper {
console.log(msg)
}
public async openSettingWindow() {
public async openSettingWindow(position: { x: number; y: number }) {
if (this.isElectron()) {
await this.getElectronAPI().openSettingWindow("/setting")
await this.getElectronAPI().openSettingWindow("/setting", position.x, position.y)
return Promise.resolve(true)
}
return undefined

View File

@ -84,7 +84,7 @@ func (r *SysPlugin) Init(ctx context.Context, initParams plugin.InitParams) {
SubTitle: "",
Icon: plugin.NewWoxImageBase64(`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC9UlEQVR4nO2Zy27TQBSGB0ThMbijBNRV1sCymYlYdhMWXCRCKSvaHS1BAglQJSg7eAFYtLYDiugO5ZwTsQus+gSgPkObboKOc7PH48ShsZMU/9KRIo1nPF/mXGbGQqRKlSpVqlRTpvzOzpk84u1CHUpekwDFxd3d02JWJAlWFGHLZNwmZkWK4FUYCLeJaVKu0ZhTiOuSaveOCsJj8Fi5RmNOJCl+oUR0PJMr+0AQ3w4A+eCDQHzWcztEJzGYIETP91/erNVOFQCuS4S9cBDcd1cSYF4SbATGwQRgwiB6hnA4ACCyybhh+J8cx0SjGazFBuIGZUIgBcQ7sYHowTnADhSBxUUwD6DY3IJIaLfbhq5GOVaIKDCS8Kv68f1sWN+FWu2cQqiG94cNkaQU4a9gkMI70WqdGNb3eat1UhJsGkEA5pMhEELwfkkR/NZXIgqEF8a4MojrsU1aAqxKxDc9IyQ9Jthl9L4Zx7mSse1ltqxlXdbbbyGeN8TMviT42HsXwOpYNpq8i40QnFYAwrJKGdtuZm275ZplHWQc54H+3MC6RG3jORwZRCIuDU2VdSgZVqIP4YG5urV1adTxJeJSMiCICz4Q234cgOgYu5lv/DrIqQFRVMtrIMthIFnH8U2Ka8z0gCA+9PbhwGY3MrnWNce5OOr4chwgUYKdK7bejwPbB8O/t7fv688phMrQ8QGKsaRfRfhJT7+cSvW+vDKd1PtIXwlWoV6/IBGaWlHd48LaT/WwEus5XxJ88bsXVLnIjVQQCb8Z3PSGSFLuniq4T9qMAtOBeB+EgEM+nCVD0D6Tl8MDH6omN/O6k3El+sX1xeQh+n7e5IrN2aa7jXezE0JFj4mJbONlggcrhXj3WBx1JcHTSV4+VExJwGB/JMHPcNfEyd2k8Kmx+4xE/DwAFrp1wRRvcpJ3W16IYTeNkuC19mx5IhC+K1OCNdNtx6hXphzYHBO5pCGO1SX2v35WUERPxKxosb3RLM78h55UqVKlSvXf6C+Yr/vPFuJ7FAAAAABJRU5ErkJggg==`),
Action: func(actionContext plugin.ActionContext) {
plugin.GetPluginManager().GetUI().OpenSettingDialog(ctx)
plugin.GetPluginManager().GetUI().OpenSettingWindow(ctx)
},
},
}

View File

@ -31,7 +31,7 @@ type UI interface {
ShowMsg(ctx context.Context, title string, description string, icon string)
GetServerPort(ctx context.Context) int
ChangeTheme(ctx context.Context, theme string)
OpenSettingDialog(ctx context.Context)
OpenSettingWindow(ctx context.Context)
OpenDevTools(ctx context.Context)
}

View File

@ -14,7 +14,7 @@ type Position struct {
}
func NewMouseScreenPosition() Position {
x, y := getWindowShowLocation()
x, y := getWindowMouseScreenLocation(800)
return Position{
Type: PositionTypeMouseScreen,
X: x,

View File

@ -52,8 +52,12 @@ func (u *uiImpl) ChangeTheme(ctx context.Context, theme string) {
u.send(ctx, "ChangeTheme", theme)
}
func (u *uiImpl) OpenSettingDialog(ctx context.Context) {
u.send(ctx, "OpenSettingDialog", nil)
func (u *uiImpl) OpenSettingWindow(ctx context.Context) {
x, y := getWindowMouseScreenLocation(1200)
u.send(ctx, "OpenSettingWindow", map[string]int{
"x": x,
"y": y,
})
}
func (u *uiImpl) OpenDevTools(ctx context.Context) {
@ -407,8 +411,7 @@ func getWebsocketMsgParameter(ctx context.Context, msg WebsocketMsg, key string)
return paramterData.String(), nil
}
func getWindowShowLocation() (int, int) {
windowWidth := 800
func getWindowMouseScreenLocation(windowWidth int) (int, int) {
size := screen.GetMouseScreen()
x := size.X + (size.Width-windowWidth)/2
y := size.Height / 6