cleaning dependency in windowmanager
This commit is contained in:
parent
698473007a
commit
f755fdb9e3
@ -91,6 +91,7 @@ module.exports = {
|
|||||||
ipcMain.handle('listen:startMacosSystemAudio', async () => await listenService.handleStartMacosAudio());
|
ipcMain.handle('listen:startMacosSystemAudio', async () => await listenService.handleStartMacosAudio());
|
||||||
ipcMain.handle('listen:stopMacosSystemAudio', async () => await listenService.handleStopMacosAudio());
|
ipcMain.handle('listen:stopMacosSystemAudio', async () => await listenService.handleStopMacosAudio());
|
||||||
ipcMain.handle('update-google-search-setting', async (event, enabled) => await listenService.handleUpdateGoogleSearchSetting(enabled));
|
ipcMain.handle('update-google-search-setting', async (event, enabled) => await listenService.handleUpdateGoogleSearchSetting(enabled));
|
||||||
|
ipcMain.handle('listen:isSessionActive', async () => await listenService.isSessionActive());
|
||||||
ipcMain.handle('listen:changeSession', async (event, listenButtonText) => {
|
ipcMain.handle('listen:changeSession', async (event, listenButtonText) => {
|
||||||
console.log('[FeatureBridge] listen:changeSession from mainheader', listenButtonText);
|
console.log('[FeatureBridge] listen:changeSession from mainheader', listenButtonText);
|
||||||
try {
|
try {
|
||||||
|
@ -20,7 +20,6 @@ module.exports = {
|
|||||||
ipcMain.on('header-state-changed', (event, state) => windowManager.handleHeaderStateChanged(state));
|
ipcMain.on('header-state-changed', (event, state) => windowManager.handleHeaderStateChanged(state));
|
||||||
ipcMain.on('header-animation-finished', (event, state) => windowManager.handleHeaderAnimationFinished(state));
|
ipcMain.on('header-animation-finished', (event, state) => windowManager.handleHeaderAnimationFinished(state));
|
||||||
ipcMain.handle('get-header-position', () => windowManager.getHeaderPosition());
|
ipcMain.handle('get-header-position', () => windowManager.getHeaderPosition());
|
||||||
ipcMain.handle('move-header', (event, newX, newY) => windowManager.moveHeader(newX, newY));
|
|
||||||
ipcMain.handle('move-header-to', (event, newX, newY) => windowManager.moveHeaderTo(newX, newY));
|
ipcMain.handle('move-header-to', (event, newX, newY) => windowManager.moveHeaderTo(newX, newY));
|
||||||
ipcMain.handle('adjust-window-height', (event, targetHeight) => windowManager.adjustWindowHeight(event.sender, targetHeight));
|
ipcMain.handle('adjust-window-height', (event, targetHeight) => windowManager.adjustWindowHeight(event.sender, targetHeight));
|
||||||
},
|
},
|
||||||
|
@ -54,53 +54,7 @@ class ListenService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleListenRequest(listenButtonText) {
|
async handleListenRequest(listenButtonText) {
|
||||||
const { windowPool, updateLayout } = require('../../window/windowManager');
|
const { windowPool } = require('../../window/windowManager');
|
||||||
const listenWindow = windowPool.get('listen');
|
|
||||||
const header = windowPool.get('header');
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch (listenButtonText) {
|
|
||||||
case 'Listen':
|
|
||||||
console.log('[ListenService] changeSession to "Listen"');
|
|
||||||
listenWindow.show();
|
|
||||||
updateLayout();
|
|
||||||
listenWindow.webContents.send('window-show-animation');
|
|
||||||
await this.initializeSession();
|
|
||||||
listenWindow.webContents.send('session-state-changed', { isActive: true });
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Stop':
|
|
||||||
console.log('[ListenService] changeSession to "Stop"');
|
|
||||||
await this.closeSession();
|
|
||||||
listenWindow.webContents.send('session-state-changed', { isActive: false });
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Done':
|
|
||||||
console.log('[ListenService] changeSession to "Done"');
|
|
||||||
listenWindow.webContents.send('window-hide-animation');
|
|
||||||
listenWindow.webContents.send('session-state-changed', { isActive: false });
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error(`[ListenService] unknown listenButtonText: ${listenButtonText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
header.webContents.send('listen:changeSessionResult', { success: true });
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[ListenService] error in handleListenRequest:', error);
|
|
||||||
header.webContents.send('listen:changeSessionResult', { success: false });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
this.setupIpcHandlers();
|
|
||||||
console.log('[ListenService] Initialized and ready.');
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleListenRequest(listenButtonText) {
|
|
||||||
const { windowPool, updateLayout } = require('../../window/windowManager');
|
|
||||||
const listenWindow = windowPool.get('listen');
|
const listenWindow = windowPool.get('listen');
|
||||||
const header = windowPool.get('header');
|
const header = windowPool.get('header');
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ contextBridge.exposeInMainWorld('api', {
|
|||||||
stopMacosSystemAudio: () => ipcRenderer.invoke('listen:stopMacosSystemAudio'),
|
stopMacosSystemAudio: () => ipcRenderer.invoke('listen:stopMacosSystemAudio'),
|
||||||
|
|
||||||
// Session Management
|
// Session Management
|
||||||
isSessionActive: () => ipcRenderer.invoke('is-session-active'),
|
isSessionActive: () => ipcRenderer.invoke('listen:isSessionActive'),
|
||||||
|
|
||||||
// Listeners
|
// Listeners
|
||||||
onSystemAudioData: (callback) => ipcRenderer.on('system-audio-data', callback),
|
onSystemAudioData: (callback) => ipcRenderer.on('system-audio-data', callback),
|
||||||
|
@ -422,6 +422,12 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (isMacOS) {
|
if (isMacOS) {
|
||||||
|
|
||||||
|
const sessionActive = await window.api.listenCapture.isSessionActive();
|
||||||
|
if (!sessionActive) {
|
||||||
|
throw new Error('STT sessions not initialized - please wait for initialization to complete');
|
||||||
|
}
|
||||||
|
|
||||||
// On macOS, use SystemAudioDump for audio and getDisplayMedia for screen
|
// On macOS, use SystemAudioDump for audio and getDisplayMedia for screen
|
||||||
console.log('Starting macOS capture with SystemAudioDump...');
|
console.log('Starting macOS capture with SystemAudioDump...');
|
||||||
|
|
||||||
@ -466,6 +472,12 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu
|
|||||||
|
|
||||||
console.log('macOS screen capture started - audio handled by SystemAudioDump');
|
console.log('macOS screen capture started - audio handled by SystemAudioDump');
|
||||||
} else if (isLinux) {
|
} else if (isLinux) {
|
||||||
|
|
||||||
|
const sessionActive = await window.api.listenCapture.isSessionActive();
|
||||||
|
if (!sessionActive) {
|
||||||
|
throw new Error('STT sessions not initialized - please wait for initialization to complete');
|
||||||
|
}
|
||||||
|
|
||||||
// Linux - use display media for screen capture and getUserMedia for microphone
|
// Linux - use display media for screen capture and getUserMedia for microphone
|
||||||
mediaStream = await navigator.mediaDevices.getDisplayMedia({
|
mediaStream = await navigator.mediaDevices.getDisplayMedia({
|
||||||
video: {
|
video: {
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
const { screen } = require('electron');
|
const { screen } = require('electron');
|
||||||
|
|
||||||
|
|
||||||
|
function getCurrentDisplay(window) {
|
||||||
|
if (!window || window.isDestroyed()) return screen.getPrimaryDisplay();
|
||||||
|
|
||||||
|
const windowBounds = window.getBounds();
|
||||||
|
const windowCenter = {
|
||||||
|
x: windowBounds.x + windowBounds.width / 2,
|
||||||
|
y: windowBounds.y + windowBounds.height / 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
return screen.getDisplayNearestPoint(windowCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDisplayById(displayId) {
|
||||||
|
const displays = screen.getAllDisplays();
|
||||||
|
return displays.find(d => d.id === displayId) || screen.getPrimaryDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
class SmoothMovementManager {
|
class SmoothMovementManager {
|
||||||
constructor(windowPool, getDisplayById, getCurrentDisplay, updateLayout) {
|
constructor(windowPool, layoutManager) {
|
||||||
this.windowPool = windowPool;
|
this.windowPool = windowPool;
|
||||||
this.getDisplayById = getDisplayById;
|
this.layoutManager = layoutManager;
|
||||||
this.getCurrentDisplay = getCurrentDisplay;
|
|
||||||
this.updateLayout = updateLayout;
|
|
||||||
this.stepSize = 80;
|
this.stepSize = 80;
|
||||||
this.animationDuration = 300;
|
this.animationDuration = 300;
|
||||||
this.headerPosition = { x: 0, y: 0 };
|
this.headerPosition = { x: 0, y: 0 };
|
||||||
@ -39,11 +55,11 @@ class SmoothMovementManager {
|
|||||||
const header = this.windowPool.get('header');
|
const header = this.windowPool.get('header');
|
||||||
if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return;
|
if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return;
|
||||||
|
|
||||||
const targetDisplay = this.getDisplayById(displayId);
|
const targetDisplay = getDisplayById(displayId);
|
||||||
if (!targetDisplay) return;
|
if (!targetDisplay) return;
|
||||||
|
|
||||||
const currentBounds = header.getBounds();
|
const currentBounds = header.getBounds();
|
||||||
const currentDisplay = this.getCurrentDisplay(header);
|
const currentDisplay = getCurrentDisplay(header);
|
||||||
|
|
||||||
if (currentDisplay.id === targetDisplay.id) return;
|
if (currentDisplay.id === targetDisplay.id) return;
|
||||||
|
|
||||||
@ -60,56 +76,6 @@ class SmoothMovementManager {
|
|||||||
this.currentDisplayId = targetDisplay.id;
|
this.currentDisplayId = targetDisplay.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
hideToEdge(edge, callback, { instant = false } = {}) {
|
|
||||||
const header = this.windowPool.get('header');
|
|
||||||
if (!header || header.isDestroyed()) {
|
|
||||||
if (typeof callback === 'function') callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { x, y } = header.getBounds();
|
|
||||||
this.lastVisiblePosition = { x, y };
|
|
||||||
this.hiddenPosition = { edge };
|
|
||||||
|
|
||||||
if (instant) {
|
|
||||||
header.hide();
|
|
||||||
if (typeof callback === 'function') callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (!header || header.isDestroyed()) {
|
|
||||||
if (typeof callback === 'function') callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 숨기기 전에 기억해둔 위치 복구
|
|
||||||
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) {
|
moveStep(direction) {
|
||||||
const header = this.windowPool.get('header');
|
const header = this.windowPool.get('header');
|
||||||
@ -211,7 +177,7 @@ class SmoothMovementManager {
|
|||||||
setTimeout(step, 8); // requestAnimationFrame 대신 setTimeout으로 간결하게 처리
|
setTimeout(step, 8); // requestAnimationFrame 대신 setTimeout으로 간결하게 처리
|
||||||
} else {
|
} else {
|
||||||
// 애니메이션 종료
|
// 애니메이션 종료
|
||||||
this.updateLayout(); // 레이아웃 재정렬
|
this.layoutManager.updateLayout(); // 레이아웃 재정렬
|
||||||
if (onComplete) {
|
if (onComplete) {
|
||||||
onComplete(); // 완료 콜백 실행
|
onComplete(); // 완료 콜백 실행
|
||||||
}
|
}
|
||||||
@ -267,7 +233,7 @@ class SmoothMovementManager {
|
|||||||
// Update header position to the actual final position
|
// Update header position to the actual final position
|
||||||
this.headerPosition = { x: Math.round(targetX), y: Math.round(targetY) };
|
this.headerPosition = { x: Math.round(targetX), y: Math.round(targetY) };
|
||||||
}
|
}
|
||||||
this.updateLayout();
|
this.layoutManager.updateLayout();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
animate();
|
animate();
|
||||||
@ -277,7 +243,7 @@ class SmoothMovementManager {
|
|||||||
const header = this.windowPool.get('header');
|
const header = this.windowPool.get('header');
|
||||||
if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return;
|
if (!this._isWindowValid(header) || !header.isVisible() || this.isAnimating) return;
|
||||||
|
|
||||||
const display = this.getCurrentDisplay(header);
|
const display = getCurrentDisplay(header);
|
||||||
const { width, height } = display.workAreaSize;
|
const { width, height } = display.workAreaSize;
|
||||||
const { x: workAreaX, y: workAreaY } = display.workArea;
|
const { x: workAreaX, y: workAreaY } = display.workArea;
|
||||||
const currentBounds = header.getBounds();
|
const currentBounds = header.getBounds();
|
||||||
@ -313,7 +279,7 @@ class SmoothMovementManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.headerPosition = { x: targetX, y: targetY };
|
this.headerPosition = { x: targetX, y: targetY };
|
||||||
this.updateLayout();
|
this.layoutManager.updateLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
@ -37,6 +37,110 @@ class WindowLayoutManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getHeaderPosition = () => {
|
||||||
|
const header = this.windowPool.get('header');
|
||||||
|
if (header) {
|
||||||
|
const [x, y] = header.getPosition();
|
||||||
|
return { x, y };
|
||||||
|
}
|
||||||
|
return { x: 0, y: 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
resizeHeaderWindow = ({ width, height }) => {
|
||||||
|
const header = this.windowPool.get('header');
|
||||||
|
if (header) {
|
||||||
|
console.log(`[WindowManager] Resize request: ${width}x${height}`);
|
||||||
|
|
||||||
|
const currentBounds = header.getBounds();
|
||||||
|
console.log(`[WindowManager] Current bounds: ${currentBounds.width}x${currentBounds.height} at (${currentBounds.x}, ${currentBounds.y})`);
|
||||||
|
|
||||||
|
if (currentBounds.width === width && currentBounds.height === height) {
|
||||||
|
console.log('[WindowManager] Already at target size, skipping resize');
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const wasResizable = header.isResizable();
|
||||||
|
if (!wasResizable) {
|
||||||
|
header.setResizable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const centerX = currentBounds.x + currentBounds.width / 2;
|
||||||
|
const newX = Math.round(centerX - width / 2);
|
||||||
|
|
||||||
|
const display = getCurrentDisplay(header);
|
||||||
|
const { x: workAreaX, width: workAreaWidth } = display.workArea;
|
||||||
|
|
||||||
|
const clampedX = Math.max(workAreaX, Math.min(workAreaX + workAreaWidth - width, newX));
|
||||||
|
|
||||||
|
header.setBounds({ x: clampedX, y: currentBounds.y, width, height });
|
||||||
|
|
||||||
|
if (!wasResizable) {
|
||||||
|
header.setResizable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateLayout();
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
return { success: false, error: 'Header window not found' };
|
||||||
|
};
|
||||||
|
|
||||||
|
moveHeaderTo = (newX, newY) => {
|
||||||
|
const header = this.windowPool.get('header');
|
||||||
|
if (header) {
|
||||||
|
const targetDisplay = screen.getDisplayNearestPoint({ x: newX, y: newY });
|
||||||
|
const { x: workAreaX, y: workAreaY, width, height } = targetDisplay.workArea;
|
||||||
|
const headerBounds = header.getBounds();
|
||||||
|
|
||||||
|
let clampedX = newX;
|
||||||
|
let clampedY = newY;
|
||||||
|
|
||||||
|
if (newX < workAreaX) {
|
||||||
|
clampedX = workAreaX;
|
||||||
|
} else if (newX + headerBounds.width > workAreaX + width) {
|
||||||
|
clampedX = workAreaX + width - headerBounds.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newY < workAreaY) {
|
||||||
|
clampedY = workAreaY;
|
||||||
|
} else if (newY + headerBounds.height > workAreaY + height) {
|
||||||
|
clampedY = workAreaY + height - headerBounds.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
header.setPosition(clampedX, clampedY, false);
|
||||||
|
this.updateLayout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
adjustWindowHeight = (sender, targetHeight) => {
|
||||||
|
const senderWindow = this.windowPool.get(sender);
|
||||||
|
if (senderWindow) {
|
||||||
|
const wasResizable = senderWindow.isResizable();
|
||||||
|
if (!wasResizable) {
|
||||||
|
senderWindow.setResizable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentBounds = senderWindow.getBounds();
|
||||||
|
const minHeight = senderWindow.getMinimumSize()[1];
|
||||||
|
const maxHeight = senderWindow.getMaximumSize()[1];
|
||||||
|
|
||||||
|
let adjustedHeight;
|
||||||
|
if (maxHeight === 0) {
|
||||||
|
adjustedHeight = Math.max(minHeight, targetHeight);
|
||||||
|
} else {
|
||||||
|
adjustedHeight = Math.max(minHeight, Math.min(maxHeight, targetHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
senderWindow.setSize(currentBounds.width, adjustedHeight, false);
|
||||||
|
|
||||||
|
if (!wasResizable) {
|
||||||
|
senderWindow.setResizable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateLayout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {object} [visibilityOverride] - { listen: true, ask: true }
|
* @param {object} [visibilityOverride] - { listen: true, ask: true }
|
||||||
|
@ -38,11 +38,6 @@ let settingsHideTimer = null;
|
|||||||
|
|
||||||
|
|
||||||
let layoutManager = null;
|
let layoutManager = null;
|
||||||
function updateLayout() {
|
|
||||||
if (layoutManager) {
|
|
||||||
layoutManager.updateLayout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let movementManager = null;
|
let movementManager = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,6 +87,30 @@ const cancelHideSettingsWindow = () => {
|
|||||||
internalBridge.emit('window:requestVisibility', { name: 'settings', visible: true });
|
internalBridge.emit('window:requestVisibility', { name: 'settings', visible: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const moveWindowStep = (direction) => {
|
||||||
|
internalBridge.emit('window:moveStep', { direction });
|
||||||
|
};
|
||||||
|
|
||||||
|
const resizeHeaderWindow = ({ width, height }) => {
|
||||||
|
internalBridge.emit('window:resizeHeaderWindow', { width, height });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleHeaderAnimationFinished = (state) => {
|
||||||
|
internalBridge.emit('window:headerAnimationFinished', state);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getHeaderPosition = () => {
|
||||||
|
internalBridge.emit('window:getHeaderPosition');
|
||||||
|
};
|
||||||
|
|
||||||
|
const moveHeaderTo = (newX, newY) => {
|
||||||
|
internalBridge.emit('window:moveHeaderTo', { newX, newY });
|
||||||
|
};
|
||||||
|
|
||||||
|
const adjustWindowHeight = (sender, targetHeight) => {
|
||||||
|
internalBridge.emit('window:adjustWindowHeight', { sender, targetHeight });
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
function setupWindowController(windowPool, layoutManager, movementManager) {
|
function setupWindowController(windowPool, layoutManager, movementManager) {
|
||||||
internalBridge.on('window:requestVisibility', ({ name, visible }) => {
|
internalBridge.on('window:requestVisibility', ({ name, visible }) => {
|
||||||
@ -109,6 +128,21 @@ function setupWindowController(windowPool, layoutManager, movementManager) {
|
|||||||
internalBridge.on('window:moveStep', ({ direction }) => {
|
internalBridge.on('window:moveStep', ({ direction }) => {
|
||||||
movementManager.moveStep(direction);
|
movementManager.moveStep(direction);
|
||||||
});
|
});
|
||||||
|
internalBridge.on('window:resizeHeaderWindow', ({ width, height }) => {
|
||||||
|
resizingHeaderWindow(layoutManager, movementManager, { width, height });
|
||||||
|
});
|
||||||
|
internalBridge.on('window:headerAnimationFinished', (state) => {
|
||||||
|
handlingHeaderAnimationFinished(windowPool, layoutManager, state);
|
||||||
|
});
|
||||||
|
internalBridge.on('window:getHeaderPosition', () => {
|
||||||
|
gettingHeaderPosition(layoutManager);
|
||||||
|
});
|
||||||
|
internalBridge.on('window:moveHeaderTo', ({ newX, newY }) => {
|
||||||
|
movingHeaderTo(layoutManager, newX, newY);
|
||||||
|
});
|
||||||
|
internalBridge.on('window:adjustWindowHeight', ({ sender, targetHeight }) => {
|
||||||
|
adjustingWindowHeight(layoutManager, sender, targetHeight);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeAllWindowsVisibility(windowPool, targetVisibility) {
|
function changeAllWindowsVisibility(windowPool, targetVisibility) {
|
||||||
@ -249,8 +283,8 @@ async function handleWindowVisibilityRequest(windowPool, layoutManager, movement
|
|||||||
const otherWin = windowPool.get(otherName);
|
const otherWin = windowPool.get(otherName);
|
||||||
const isOtherWinVisible = otherWin && !otherWin.isDestroyed() && otherWin.isVisible();
|
const isOtherWinVisible = otherWin && !otherWin.isDestroyed() && otherWin.isVisible();
|
||||||
|
|
||||||
const ANIM_OFFSET_X = 100;
|
const ANIM_OFFSET_X = 50;
|
||||||
const ANIM_OFFSET_Y = 20;
|
const ANIM_OFFSET_Y = 20;
|
||||||
|
|
||||||
if (shouldBeVisible) {
|
if (shouldBeVisible) {
|
||||||
win.setOpacity(0);
|
win.setOpacity(0);
|
||||||
@ -305,7 +339,7 @@ async function handleWindowVisibilityRequest(windowPool, layoutManager, movement
|
|||||||
} else {
|
} else {
|
||||||
const currentBounds = win.getBounds();
|
const currentBounds = win.getBounds();
|
||||||
fadeWindow(
|
fadeWindow(
|
||||||
win, 1, 0, undefined,
|
win, 1, 0, 250,
|
||||||
() => win.hide()
|
() => win.hide()
|
||||||
);
|
);
|
||||||
if (name === 'listen') {
|
if (name === 'listen') {
|
||||||
@ -313,7 +347,7 @@ async function handleWindowVisibilityRequest(windowPool, layoutManager, movement
|
|||||||
const targetX = currentBounds.x - ANIM_OFFSET_X;
|
const targetX = currentBounds.x - ANIM_OFFSET_X;
|
||||||
movementManager.animateWindow(win, targetX, currentBounds.y);
|
movementManager.animateWindow(win, targetX, currentBounds.y);
|
||||||
} else {
|
} else {
|
||||||
const targetX = currentBounds.x - currentBounds.width;
|
const targetX = currentBounds.x - ANIM_OFFSET_X;
|
||||||
movementManager.animateWindow(win, targetX, currentBounds.y);
|
movementManager.animateWindow(win, targetX, currentBounds.y);
|
||||||
}
|
}
|
||||||
} else if (name === 'ask') {
|
} else if (name === 'ask') {
|
||||||
@ -353,52 +387,6 @@ const toggleContentProtection = () => {
|
|||||||
return newStatus;
|
return newStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
const resizeHeaderWindow = ({ width, height }) => {
|
|
||||||
const header = windowPool.get('header');
|
|
||||||
if (header) {
|
|
||||||
console.log(`[WindowManager] Resize request: ${width}x${height}`);
|
|
||||||
|
|
||||||
if (movementManager && movementManager.isAnimating) {
|
|
||||||
console.log('[WindowManager] Skipping resize during animation');
|
|
||||||
return { success: false, error: 'Cannot resize during animation' };
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentBounds = header.getBounds();
|
|
||||||
console.log(`[WindowManager] Current bounds: ${currentBounds.width}x${currentBounds.height} at (${currentBounds.x}, ${currentBounds.y})`);
|
|
||||||
|
|
||||||
if (currentBounds.width === width && currentBounds.height === height) {
|
|
||||||
console.log('[WindowManager] Already at target size, skipping resize');
|
|
||||||
return { success: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
const wasResizable = header.isResizable();
|
|
||||||
if (!wasResizable) {
|
|
||||||
header.setResizable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const centerX = currentBounds.x + currentBounds.width / 2;
|
|
||||||
const newX = Math.round(centerX - width / 2);
|
|
||||||
|
|
||||||
const display = getCurrentDisplay(header);
|
|
||||||
const { x: workAreaX, width: workAreaWidth } = display.workArea;
|
|
||||||
|
|
||||||
const clampedX = Math.max(workAreaX, Math.min(workAreaX + workAreaWidth - width, newX));
|
|
||||||
|
|
||||||
header.setBounds({ x: clampedX, y: currentBounds.y, width, height });
|
|
||||||
|
|
||||||
if (!wasResizable) {
|
|
||||||
header.setResizable(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateLayout) {
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true };
|
|
||||||
}
|
|
||||||
return { success: false, error: 'Header window not found' };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const openLoginPage = () => {
|
const openLoginPage = () => {
|
||||||
const webUrl = process.env.pickleglass_WEB_URL || 'http://localhost:3000';
|
const webUrl = process.env.pickleglass_WEB_URL || 'http://localhost:3000';
|
||||||
@ -407,12 +395,6 @@ const openLoginPage = () => {
|
|||||||
console.log('Opening personalization page:', personalizeUrl);
|
console.log('Opening personalization page:', personalizeUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveWindowStep = (direction) => {
|
|
||||||
if (movementManager) {
|
|
||||||
movementManager.moveStep(direction);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function createFeatureWindows(header, namesToCreate) {
|
function createFeatureWindows(header, namesToCreate) {
|
||||||
// if (windowPool.has('listen')) return;
|
// if (windowPool.has('listen')) return;
|
||||||
@ -617,14 +599,6 @@ function getCurrentDisplay(window) {
|
|||||||
return screen.getDisplayNearestPoint(windowCenter);
|
return screen.getDisplayNearestPoint(windowCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayById(displayId) {
|
|
||||||
const displays = screen.getAllDisplays();
|
|
||||||
return displays.find(d => d.id === displayId) || screen.getPrimaryDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function createWindows() {
|
function createWindows() {
|
||||||
@ -636,8 +610,7 @@ function createWindows() {
|
|||||||
|
|
||||||
const initialX = Math.round((screenWidth - DEFAULT_WINDOW_WIDTH) / 2);
|
const initialX = Math.round((screenWidth - DEFAULT_WINDOW_WIDTH) / 2);
|
||||||
const initialY = workAreaY + 21;
|
const initialY = workAreaY + 21;
|
||||||
movementManager = new SmoothMovementManager(windowPool, getDisplayById, getCurrentDisplay, updateLayout);
|
|
||||||
|
|
||||||
const header = new BrowserWindow({
|
const header = new BrowserWindow({
|
||||||
width: DEFAULT_WINDOW_WIDTH,
|
width: DEFAULT_WINDOW_WIDTH,
|
||||||
height: HEADER_HEIGHT,
|
height: HEADER_HEIGHT,
|
||||||
@ -687,15 +660,17 @@ function createWindows() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
windowPool.set('header', header);
|
windowPool.set('header', header);
|
||||||
header.on('moved', updateLayout);
|
|
||||||
layoutManager = new WindowLayoutManager(windowPool);
|
layoutManager = new WindowLayoutManager(windowPool);
|
||||||
|
movementManager = new SmoothMovementManager(windowPool, layoutManager);
|
||||||
|
|
||||||
|
header.on('moved', () => layoutManager.updateLayout());
|
||||||
|
|
||||||
header.webContents.once('dom-ready', () => {
|
header.webContents.once('dom-ready', () => {
|
||||||
shortcutsService.initialize(windowPool);
|
shortcutsService.initialize(windowPool);
|
||||||
shortcutsService.registerShortcuts();
|
shortcutsService.registerShortcuts();
|
||||||
});
|
});
|
||||||
|
|
||||||
setupIpcHandlers(movementManager);
|
setupIpcHandlers(movementManager, layoutManager);
|
||||||
setupWindowController(windowPool, layoutManager, movementManager);
|
setupWindowController(windowPool, layoutManager, movementManager);
|
||||||
|
|
||||||
if (currentHeaderState === 'main') {
|
if (currentHeaderState === 'main') {
|
||||||
@ -729,13 +704,13 @@ function createWindows() {
|
|||||||
|
|
||||||
header.on('resize', () => {
|
header.on('resize', () => {
|
||||||
console.log('[WindowManager] Header resize event triggered');
|
console.log('[WindowManager] Header resize event triggered');
|
||||||
updateLayout();
|
layoutManager.updateLayout();
|
||||||
});
|
});
|
||||||
|
|
||||||
return windowPool;
|
return windowPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupIpcHandlers(movementManager) {
|
function setupIpcHandlers(movementManager, layoutManager) {
|
||||||
// quit-application handler moved to windowBridge.js to avoid duplication
|
// quit-application handler moved to windowBridge.js to avoid duplication
|
||||||
screen.on('display-added', (event, newDisplay) => {
|
screen.on('display-added', (event, newDisplay) => {
|
||||||
console.log('[Display] New display added:', newDisplay.id);
|
console.log('[Display] New display added:', newDisplay.id);
|
||||||
@ -752,10 +727,11 @@ function setupIpcHandlers(movementManager) {
|
|||||||
|
|
||||||
screen.on('display-metrics-changed', (event, display, changedMetrics) => {
|
screen.on('display-metrics-changed', (event, display, changedMetrics) => {
|
||||||
// console.log('[Display] Display metrics changed:', display.id, changedMetrics);
|
// console.log('[Display] Display metrics changed:', display.id, changedMetrics);
|
||||||
updateLayout();
|
layoutManager.updateLayout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const handleHeaderStateChanged = (state) => {
|
const handleHeaderStateChanged = (state) => {
|
||||||
console.log(`[WindowManager] Header state changed to: ${state}`);
|
console.log(`[WindowManager] Header state changed to: ${state}`);
|
||||||
currentHeaderState = state;
|
currentHeaderState = state;
|
||||||
@ -768,7 +744,17 @@ const handleHeaderStateChanged = (state) => {
|
|||||||
internalBridge.emit('reregister-shortcuts');
|
internalBridge.emit('reregister-shortcuts');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleHeaderAnimationFinished = (state) => {
|
|
||||||
|
const resizingHeaderWindow = (layoutManager, movementManager, { width, height }) => {
|
||||||
|
if (movementManager.isAnimating) {
|
||||||
|
console.log('[WindowManager] Skipping resize during animation');
|
||||||
|
return { success: false, error: 'Cannot resize during animation' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return layoutManager.resizeHeaderWindow({ width, height });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlingHeaderAnimationFinished = (windowPool, layoutManager, state) => {
|
||||||
const header = windowPool.get('header');
|
const header = windowPool.get('header');
|
||||||
if (!header || header.isDestroyed()) return;
|
if (!header || header.isDestroyed()) return;
|
||||||
|
|
||||||
@ -777,87 +763,24 @@ const handleHeaderAnimationFinished = (state) => {
|
|||||||
console.log('[WindowManager] Header hidden after animation.');
|
console.log('[WindowManager] Header hidden after animation.');
|
||||||
} else if (state === 'visible') {
|
} else if (state === 'visible') {
|
||||||
console.log('[WindowManager] Header shown after animation.');
|
console.log('[WindowManager] Header shown after animation.');
|
||||||
updateLayout();
|
layoutManager.updateLayout();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getHeaderPosition = () => {
|
const gettingHeaderPosition = (layoutManager) => {
|
||||||
const header = windowPool.get('header');
|
return layoutManager.getHeaderPosition();
|
||||||
if (header) {
|
|
||||||
const [x, y] = header.getPosition();
|
|
||||||
return { x, y };
|
|
||||||
}
|
|
||||||
return { x: 0, y: 0 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveHeader = (newX, newY) => {
|
const movingHeaderTo = (layoutManager, newX, newY) => {
|
||||||
const header = windowPool.get('header');
|
layoutManager.moveHeaderTo(newX, newY);
|
||||||
if (header) {
|
|
||||||
const currentY = newY !== undefined ? newY : header.getBounds().y;
|
|
||||||
header.setPosition(newX, currentY, false);
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveHeaderTo = (newX, newY) => {
|
const adjustingWindowHeight = (layoutManager, sender, targetHeight) => {
|
||||||
const header = windowPool.get('header');
|
layoutManager.adjustWindowHeight(sender, targetHeight);
|
||||||
if (header) {
|
|
||||||
const targetDisplay = screen.getDisplayNearestPoint({ x: newX, y: newY });
|
|
||||||
const { x: workAreaX, y: workAreaY, width, height } = targetDisplay.workArea;
|
|
||||||
const headerBounds = header.getBounds();
|
|
||||||
|
|
||||||
let clampedX = newX;
|
|
||||||
let clampedY = newY;
|
|
||||||
|
|
||||||
if (newX < workAreaX) {
|
|
||||||
clampedX = workAreaX;
|
|
||||||
} else if (newX + headerBounds.width > workAreaX + width) {
|
|
||||||
clampedX = workAreaX + width - headerBounds.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newY < workAreaY) {
|
|
||||||
clampedY = workAreaY;
|
|
||||||
} else if (newY + headerBounds.height > workAreaY + height) {
|
|
||||||
clampedY = workAreaY + height - headerBounds.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.setPosition(clampedX, clampedY, false);
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const adjustWindowHeight = (sender, targetHeight) => {
|
|
||||||
const senderWindow = BrowserWindow.fromWebContents(sender);
|
|
||||||
if (senderWindow) {
|
|
||||||
const wasResizable = senderWindow.isResizable();
|
|
||||||
if (!wasResizable) {
|
|
||||||
senderWindow.setResizable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentBounds = senderWindow.getBounds();
|
|
||||||
const minHeight = senderWindow.getMinimumSize()[1];
|
|
||||||
const maxHeight = senderWindow.getMaximumSize()[1];
|
|
||||||
|
|
||||||
let adjustedHeight;
|
|
||||||
if (maxHeight === 0) {
|
|
||||||
adjustedHeight = Math.max(minHeight, targetHeight);
|
|
||||||
} else {
|
|
||||||
adjustedHeight = Math.max(minHeight, Math.min(maxHeight, targetHeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
senderWindow.setSize(currentBounds.width, adjustedHeight, false);
|
|
||||||
|
|
||||||
if (!wasResizable) {
|
|
||||||
senderWindow.setResizable(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
updateLayout,
|
|
||||||
createWindows,
|
createWindows,
|
||||||
windowPool,
|
windowPool,
|
||||||
toggleContentProtection,
|
toggleContentProtection,
|
||||||
@ -871,7 +794,6 @@ module.exports = {
|
|||||||
handleHeaderStateChanged,
|
handleHeaderStateChanged,
|
||||||
handleHeaderAnimationFinished,
|
handleHeaderAnimationFinished,
|
||||||
getHeaderPosition,
|
getHeaderPosition,
|
||||||
moveHeader,
|
|
||||||
moveHeaderTo,
|
moveHeaderTo,
|
||||||
adjustWindowHeight,
|
adjustWindowHeight,
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user