From 86e903ec4b53500cb6e7561494259f30d89c9db8 Mon Sep 17 00:00:00 2001 From: entry-gi Date: Mon, 7 Jul 2025 16:33:19 +0900 Subject: [PATCH] header animation removed, crash fix --- src/app/content.html | 14 +-- src/electron/smoothMovementManager.js | 163 ++++++-------------------- src/electron/windowManager.js | 17 +-- 3 files changed, 55 insertions(+), 139 deletions(-) diff --git a/src/app/content.html b/src/app/content.html index 61768e1..130c7ac 100644 --- a/src/app/content.html +++ b/src/app/content.html @@ -100,13 +100,13 @@ } .window-sliding-down { - animation: slideDownFromHeader 0.25s cubic-bezier(0.23, 1, 0.32, 1) forwards; + animation: slideDownFromHeader 0.12s cubic-bezier(0.23, 1, 0.32, 1) forwards; will-change: transform, opacity; transform-style: preserve-3d; } .window-sliding-up { - animation: slideUpToHeader 0.18s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; + animation: slideUpToHeader 0.10s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; will-change: transform, opacity; transform-style: preserve-3d; } @@ -156,14 +156,14 @@ } .settings-window-show { - animation: settingsPopFromButton 0.22s cubic-bezier(0.23, 1, 0.32, 1) forwards; + animation: settingsPopFromButton 0.12s cubic-bezier(0.23, 1, 0.32, 1) forwards; transform-origin: 85% 0%; will-change: transform, opacity; transform-style: preserve-3d; } .settings-window-hide { - animation: settingsCollapseToButton 0.18s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; + animation: settingsCollapseToButton 0.10s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards; transform-origin: 85% 0%; will-change: transform, opacity; transform-style: preserve-3d; @@ -250,7 +250,7 @@ if (animationTimeout) clearTimeout(animationTimeout); animationTimeout = setTimeout(() => { app.classList.remove('window-sliding-down'); - }, 250); + }, 120); }); ipcRenderer.on('window-hide-animation', () => { @@ -262,7 +262,7 @@ animationTimeout = setTimeout(() => { app.classList.remove('window-sliding-up'); app.classList.add('window-hidden'); - }, 180); + }, 100); }); ipcRenderer.on('settings-window-hide-animation', () => { @@ -274,7 +274,7 @@ animationTimeout = setTimeout(() => { app.classList.remove('settings-window-hide'); app.classList.add('window-hidden'); - }, 180); + }, 100); }); ipcRenderer.on('listen-window-move-to-center', () => { diff --git a/src/electron/smoothMovementManager.js b/src/electron/smoothMovementManager.js index 2550d0a..a676c82 100644 --- a/src/electron/smoothMovementManager.js +++ b/src/electron/smoothMovementManager.js @@ -60,140 +60,55 @@ class SmoothMovementManager { this.currentDisplayId = targetDisplay.id; } - hideToEdge(edge, callback) { + hideToEdge(edge, callback, { instant = false } = {}) { const header = this.windowPool.get('header'); - if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return; - - const currentBounds = header.getBounds(); - const display = this.getCurrentDisplay(header); - - if ( - !currentBounds || typeof currentBounds.x !== 'number' || typeof currentBounds.y !== 'number' || - !display || !display.workArea || !display.workAreaSize || - typeof display.workArea.x !== 'number' || typeof display.workArea.y !== 'number' || - typeof display.workAreaSize.width !== 'number' || typeof display.workAreaSize.height !== 'number' - ) { - console.error('[MovementManager] Invalid bounds or display info for hideToEdge. Aborting.'); + if (!header || header.isDestroyed()) { + if (typeof callback === 'function') callback(); return; } - - this.lastVisiblePosition = { x: currentBounds.x, y: currentBounds.y }; - this.headerPosition = { x: currentBounds.x, y: currentBounds.y }; - - const { width: screenWidth, height: screenHeight } = display.workAreaSize; - const { x: workAreaX, y: workAreaY } = display.workArea; - - let targetX = this.headerPosition.x; - let targetY = this.headerPosition.y; - - switch (edge) { - case 'top': targetY = workAreaY - currentBounds.height - 20; break; - case 'bottom': targetY = workAreaY + screenHeight + 20; break; - case 'left': targetX = workAreaX - currentBounds.width - 20; break; - case 'right': targetX = workAreaX + screenWidth + 20; break; + + const { x, y } = header.getBounds(); + this.lastVisiblePosition = { x, y }; + this.hiddenPosition = { edge }; + + if (instant) { + header.hide(); + if (typeof callback === 'function') callback(); + return; } - - this.hiddenPosition = { x: targetX, y: targetY, edge }; - this.isAnimating = true; - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const duration = 400; - const startTime = Date.now(); - - const animate = () => { - if (!this._isWindowValid(header)) return; - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / duration, 1); - const eased = progress * progress * progress; - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - this.isAnimating = false; - return; - } - - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(currentX), Math.round(currentY)); - - if (progress < 1) { - this.animationFrameId = setTimeout(animate, 8); - } else { - this.animationFrameId = null; - this.headerPosition = { x: targetX, y: targetY }; - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(targetX), Math.round(targetY)); - } - this.isAnimating = false; - if (typeof callback === 'function') callback(); - } - }; - animate(); + header.webContents.send('window-hide-animation'); + + setTimeout(() => { + if (!header.isDestroyed()) header.hide(); + if (typeof callback === 'function') callback(); + }, 5); } - + showFromEdge(callback) { const header = this.windowPool.get('header'); - if ( - !this._isWindowValid(header) || this.isAnimating || - !this.hiddenPosition || !this.lastVisiblePosition || - typeof this.hiddenPosition.x !== 'number' || typeof this.hiddenPosition.y !== 'number' || - typeof this.lastVisiblePosition.x !== 'number' || typeof this.lastVisiblePosition.y !== 'number' - ) { - console.error('[MovementManager] Invalid state for showFromEdge. Aborting.'); - this.isAnimating = false; - this.hiddenPosition = null; - this.lastVisiblePosition = null; + if (!header || header.isDestroyed()) { + if (typeof callback === 'function') callback(); return; } - - if (!this._isWindowValid(header)) return; - header.setPosition(this.hiddenPosition.x, this.hiddenPosition.y); - - this.headerPosition = { x: this.hiddenPosition.x, y: this.hiddenPosition.y }; - const targetX = this.lastVisiblePosition.x; - const targetY = this.lastVisiblePosition.y; - this.isAnimating = true; - const startX = this.headerPosition.x; - const startY = this.headerPosition.y; - const duration = 500; - const startTime = Date.now(); - - const animate = () => { - if (!this._isWindowValid(header)) return; - - const elapsed = Date.now() - startTime; - const progress = Math.min(elapsed / duration, 1); - const c1 = 1.70158; - const c3 = c1 + 1; - const eased = 1 + c3 * Math.pow(progress - 1, 3) + c1 * Math.pow(progress - 1, 2); - const currentX = startX + (targetX - startX) * eased; - const currentY = startY + (targetY - startY) * eased; - if (!Number.isFinite(currentX) || !Number.isFinite(currentY)) { - this.isAnimating = false; - return; - } - - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(currentX), Math.round(currentY)); - - if (progress < 1) { - this.animationFrameId = setTimeout(animate, 8); - } else { - this.animationFrameId = null; - this.headerPosition = { x: targetX, y: targetY }; - if (Number.isFinite(targetX) && Number.isFinite(targetY)) { - if (!this._isWindowValid(header)) return; - header.setPosition(Math.round(targetX), Math.round(targetY)); - } - this.isAnimating = false; - this.hiddenPosition = null; - this.lastVisiblePosition = null; - if (callback) callback(); - } - }; - animate(); + + // 숨기기 전에 기억해둔 위치 복구 + if (this.lastVisiblePosition) { + header.setPosition( + this.lastVisiblePosition.x, + this.lastVisiblePosition.y, + false // animate: false + ); + } + + header.show(); + header.webContents.send('window-show-animation'); + + // 내부 상태 초기화 + this.hiddenPosition = null; + this.lastVisiblePosition = null; + + if (typeof callback === 'function') callback(); } moveStep(direction) { diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 9d74334..6c74a0f 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -236,12 +236,13 @@ function toggleAllWindowsVisibility(movementManager) { if (win.isVisible()) { lastVisibleWindows.add(name); if (name !== 'header') { - win.webContents.send('window-hide-animation'); - setTimeout(() => { - if (!win.isDestroyed()) { - win.hide(); - } - }, 200); + // win.webContents.send('window-hide-animation'); + // setTimeout(() => { + // if (!win.isDestroyed()) { + // win.hide(); + // } + // }, 200); + win.hide(); } } }); @@ -251,7 +252,7 @@ function toggleAllWindowsVisibility(movementManager) { movementManager.hideToEdge(nearestEdge, () => { header.hide(); console.log('[Visibility] Smart hide completed'); - }); + }, { instant: true }); } else { console.log('[Visibility] Smart showing from hidden position'); console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows)); @@ -372,7 +373,7 @@ function createWindows() { // loadAndRegisterShortcuts(); // }); - ipcMain.handle('toggle-all-windows-visibility', toggleAllWindowsVisibility); + ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager)); ipcMain.handle('toggle-feature', async (event, featureName) => { if (!windowPool.get(featureName) && currentHeaderState === 'main') {