diff --git a/main/main.js b/main/main.js index bfc7078..193311e 100644 --- a/main/main.js +++ b/main/main.js @@ -87,7 +87,17 @@ function createWindow() { // 当渲染进程传来这个事件时,就移动窗口 ipcMain.on('move-window', (event, { x, y }) => { - mainWindow.setPosition(x, y, true); // true 表示动画平滑移动 + // 使用 Math.round 避免非整数坐标可能带来的问题 + mainWindow.setPosition(Math.round(x), Math.round(y), false); + }); + + // 添加一个 handle,用于响应前端获取窗口位置的请求 + ipcMain.handle('get-window-position', () => { + if (mainWindow) { + const [x, y] = mainWindow.getPosition(); + return { x, y }; + } + return { x: 0, y: 0 }; }); if (process.env.NODE_ENV === "development") { diff --git a/main/preload.js b/main/preload.js index 42a1d6e..6e3eb6b 100644 --- a/main/preload.js +++ b/main/preload.js @@ -14,5 +14,7 @@ contextBridge.exposeInMainWorld('electronAPI', { onUpdatePosition: (callback) => { ipcRenderer.on('update-position', (_, position) => callback(position)) }, - moveWindow: (position) => ipcRenderer.send('move-window', position) + moveWindow: (position) => ipcRenderer.send('move-window', position), + // 暴露获取窗口位置的函数 + getWindowPosition: () => ipcRenderer.invoke('get-window-position') }) \ No newline at end of file diff --git a/renderer/src/App.vue b/renderer/src/App.vue index f06b800..e959e51 100644 --- a/renderer/src/App.vue +++ b/renderer/src/App.vue @@ -36,22 +36,30 @@ const playRandomSound = async () => { setTimeout(() => (showTooltip.value = false), 2000); }; -// 新的拖拽与点击处理逻辑 const dragState = reactive({ - isDragging: false, // 是否正在拖动 - hasMoved: false, // 本次拖动是否真的移动了 - startX: 0, // 鼠标按下的起始 X 坐标 - startY: 0, // 鼠标按下的起始 Y 坐标 + isDragging: false, + hasMoved: false, + // 分别记录鼠标和窗口的起始位置 + mouseStartX: 0, + mouseStartY: 0, + windowStartX: 0, + windowStartY: 0, }); -// 鼠标按下事件 -function handleMouseDown(event) { - dragState.isDragging = true; - dragState.hasMoved = false; // 重置移动状态 - dragState.startX = event.screenX; - dragState.startY = event.screenY; +// 鼠标按下事件 (改为异步函数) +async function handleMouseDown(event) { + // 在拖动开始时,先获取窗口的当前位置 + const { x, y } = await window.electronAPI.getWindowPosition(); + dragState.windowStartX = x; + dragState.windowStartY = y; + + // 记录鼠标的初始位置 + dragState.mouseStartX = event.screenX; + dragState.mouseStartY = event.screenY; + + dragState.isDragging = true; + dragState.hasMoved = false; - // 添加全局监听器 window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mouseup', handleMouseUp); } @@ -60,16 +68,20 @@ function handleMouseDown(event) { function handleMouseMove(event) { if (!dragState.isDragging) return; - const deltaX = event.screenX - dragState.startX; - const deltaY = event.screenY - dragState.startY; + // 计算鼠标从起点移动的距离(偏移量) + const deltaX = event.screenX - dragState.mouseStartX; + const deltaY = event.screenY - dragState.mouseStartY; - // 如果移动超过一个小阈值(例如5像素),我们才认为这是一次“拖动” - if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) { + if (!dragState.hasMoved && (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5)) { dragState.hasMoved = true; } - // 实时通知主进程移动窗口 - window.electronAPI.moveWindow({ x: event.screenX, y: event.screenY }); + // 计算窗口的新位置 = 窗口初始位置 + 鼠标偏移量 + const newWindowX = dragState.windowStartX + deltaX; + const newWindowY = dragState.windowStartY + deltaY; + + // 将计算出的正确位置发送给主进程 + window.electronAPI.moveWindow({ x: newWindowX, y: newWindowY }); } // 鼠标抬起事件