header animation removed, crash fix
This commit is contained in:
parent
6bbca03719
commit
86e903ec4b
@ -100,13 +100,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.window-sliding-down {
|
.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;
|
will-change: transform, opacity;
|
||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.window-sliding-up {
|
.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;
|
will-change: transform, opacity;
|
||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
}
|
}
|
||||||
@ -156,14 +156,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.settings-window-show {
|
.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%;
|
transform-origin: 85% 0%;
|
||||||
will-change: transform, opacity;
|
will-change: transform, opacity;
|
||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-window-hide {
|
.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%;
|
transform-origin: 85% 0%;
|
||||||
will-change: transform, opacity;
|
will-change: transform, opacity;
|
||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
@ -250,7 +250,7 @@
|
|||||||
if (animationTimeout) clearTimeout(animationTimeout);
|
if (animationTimeout) clearTimeout(animationTimeout);
|
||||||
animationTimeout = setTimeout(() => {
|
animationTimeout = setTimeout(() => {
|
||||||
app.classList.remove('window-sliding-down');
|
app.classList.remove('window-sliding-down');
|
||||||
}, 250);
|
}, 120);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('window-hide-animation', () => {
|
ipcRenderer.on('window-hide-animation', () => {
|
||||||
@ -262,7 +262,7 @@
|
|||||||
animationTimeout = setTimeout(() => {
|
animationTimeout = setTimeout(() => {
|
||||||
app.classList.remove('window-sliding-up');
|
app.classList.remove('window-sliding-up');
|
||||||
app.classList.add('window-hidden');
|
app.classList.add('window-hidden');
|
||||||
}, 180);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('settings-window-hide-animation', () => {
|
ipcRenderer.on('settings-window-hide-animation', () => {
|
||||||
@ -274,7 +274,7 @@
|
|||||||
animationTimeout = setTimeout(() => {
|
animationTimeout = setTimeout(() => {
|
||||||
app.classList.remove('settings-window-hide');
|
app.classList.remove('settings-window-hide');
|
||||||
app.classList.add('window-hidden');
|
app.classList.add('window-hidden');
|
||||||
}, 180);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('listen-window-move-to-center', () => {
|
ipcRenderer.on('listen-window-move-to-center', () => {
|
||||||
|
@ -60,140 +60,55 @@ class SmoothMovementManager {
|
|||||||
this.currentDisplayId = targetDisplay.id;
|
this.currentDisplayId = targetDisplay.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
hideToEdge(edge, callback) {
|
hideToEdge(edge, callback, { instant = false } = {}) {
|
||||||
const header = this.windowPool.get('header');
|
const header = this.windowPool.get('header');
|
||||||
if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return;
|
if (!header || header.isDestroyed()) {
|
||||||
|
if (typeof callback === 'function') callback();
|
||||||
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.');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastVisiblePosition = { x: currentBounds.x, y: currentBounds.y };
|
const { x, y } = header.getBounds();
|
||||||
this.headerPosition = { x: currentBounds.x, y: currentBounds.y };
|
this.lastVisiblePosition = { x, y };
|
||||||
|
this.hiddenPosition = { edge };
|
||||||
const { width: screenWidth, height: screenHeight } = display.workAreaSize;
|
|
||||||
const { x: workAreaX, y: workAreaY } = display.workArea;
|
if (instant) {
|
||||||
|
header.hide();
|
||||||
let targetX = this.headerPosition.x;
|
if (typeof callback === 'function') callback();
|
||||||
let targetY = this.headerPosition.y;
|
return;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
header.webContents.send('window-hide-animation');
|
||||||
const progress = Math.min(elapsed / duration, 1);
|
|
||||||
const eased = progress * progress * progress;
|
setTimeout(() => {
|
||||||
const currentX = startX + (targetX - startX) * eased;
|
if (!header.isDestroyed()) header.hide();
|
||||||
const currentY = startY + (targetY - startY) * eased;
|
if (typeof callback === 'function') callback();
|
||||||
|
}, 5);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showFromEdge(callback) {
|
showFromEdge(callback) {
|
||||||
const header = this.windowPool.get('header');
|
const header = this.windowPool.get('header');
|
||||||
if (
|
if (!header || header.isDestroyed()) {
|
||||||
!this._isWindowValid(header) || this.isAnimating ||
|
if (typeof callback === 'function') callback();
|
||||||
!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;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._isWindowValid(header)) return;
|
// 숨기기 전에 기억해둔 위치 복구
|
||||||
header.setPosition(this.hiddenPosition.x, this.hiddenPosition.y);
|
if (this.lastVisiblePosition) {
|
||||||
|
header.setPosition(
|
||||||
this.headerPosition = { x: this.hiddenPosition.x, y: this.hiddenPosition.y };
|
this.lastVisiblePosition.x,
|
||||||
const targetX = this.lastVisiblePosition.x;
|
this.lastVisiblePosition.y,
|
||||||
const targetY = this.lastVisiblePosition.y;
|
false // animate: false
|
||||||
this.isAnimating = true;
|
);
|
||||||
const startX = this.headerPosition.x;
|
}
|
||||||
const startY = this.headerPosition.y;
|
|
||||||
const duration = 500;
|
header.show();
|
||||||
const startTime = Date.now();
|
header.webContents.send('window-show-animation');
|
||||||
|
|
||||||
const animate = () => {
|
// 내부 상태 초기화
|
||||||
if (!this._isWindowValid(header)) return;
|
this.hiddenPosition = null;
|
||||||
|
this.lastVisiblePosition = null;
|
||||||
const elapsed = Date.now() - startTime;
|
|
||||||
const progress = Math.min(elapsed / duration, 1);
|
if (typeof callback === 'function') callback();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moveStep(direction) {
|
moveStep(direction) {
|
||||||
|
@ -236,12 +236,13 @@ function toggleAllWindowsVisibility(movementManager) {
|
|||||||
if (win.isVisible()) {
|
if (win.isVisible()) {
|
||||||
lastVisibleWindows.add(name);
|
lastVisibleWindows.add(name);
|
||||||
if (name !== 'header') {
|
if (name !== 'header') {
|
||||||
win.webContents.send('window-hide-animation');
|
// win.webContents.send('window-hide-animation');
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
if (!win.isDestroyed()) {
|
// if (!win.isDestroyed()) {
|
||||||
win.hide();
|
// win.hide();
|
||||||
}
|
// }
|
||||||
}, 200);
|
// }, 200);
|
||||||
|
win.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -251,7 +252,7 @@ function toggleAllWindowsVisibility(movementManager) {
|
|||||||
movementManager.hideToEdge(nearestEdge, () => {
|
movementManager.hideToEdge(nearestEdge, () => {
|
||||||
header.hide();
|
header.hide();
|
||||||
console.log('[Visibility] Smart hide completed');
|
console.log('[Visibility] Smart hide completed');
|
||||||
});
|
}, { instant: true });
|
||||||
} else {
|
} else {
|
||||||
console.log('[Visibility] Smart showing from hidden position');
|
console.log('[Visibility] Smart showing from hidden position');
|
||||||
console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows));
|
console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows));
|
||||||
@ -372,7 +373,7 @@ function createWindows() {
|
|||||||
// loadAndRegisterShortcuts();
|
// loadAndRegisterShortcuts();
|
||||||
// });
|
// });
|
||||||
|
|
||||||
ipcMain.handle('toggle-all-windows-visibility', toggleAllWindowsVisibility);
|
ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager));
|
||||||
|
|
||||||
ipcMain.handle('toggle-feature', async (event, featureName) => {
|
ipcMain.handle('toggle-feature', async (event, featureName) => {
|
||||||
if (!windowPool.get(featureName) && currentHeaderState === 'main') {
|
if (!windowPool.get(featureName) && currentHeaderState === 'main') {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user