retrieve mouth dragging on button of main header
This commit is contained in:
		
							parent
							
								
									50ffaa0894
								
							
						
					
					
						commit
						2ce82a7edc
					
				@ -78,6 +78,7 @@ export class ApiKeyHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .close-button {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            position: absolute;
 | 
			
		||||
            top: 10px;
 | 
			
		||||
            right: 10px;
 | 
			
		||||
@ -157,6 +158,7 @@ export class ApiKeyHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .api-input {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            height: 34px;
 | 
			
		||||
            background: rgba(255, 255, 255, 0.1);
 | 
			
		||||
@ -184,6 +186,7 @@ export class ApiKeyHeader extends LitElement {
 | 
			
		||||
        .provider-column { flex: 1; display: flex; flex-direction: column; align-items: center; }
 | 
			
		||||
        .provider-label { color: rgba(255, 255, 255, 0.7); font-size: 11px; font-weight: 500; margin-bottom: 6px; }
 | 
			
		||||
        .api-input, .provider-select {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            height: 34px;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
@ -210,6 +213,7 @@ export class ApiKeyHeader extends LitElement {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        .action-button {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            height: 34px;
 | 
			
		||||
            background: rgba(255, 255, 255, 0.2);
 | 
			
		||||
 | 
			
		||||
@ -82,6 +82,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .listen-button {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            height: 26px;
 | 
			
		||||
            padding: 0 13px;
 | 
			
		||||
            background: transparent;
 | 
			
		||||
@ -189,6 +190,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .header-actions {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            height: 26px;
 | 
			
		||||
            box-sizing: border-box;
 | 
			
		||||
            justify-content: flex-start;
 | 
			
		||||
@ -260,6 +262,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .settings-button {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            padding: 5px;
 | 
			
		||||
            border-radius: 50%;
 | 
			
		||||
            background: transparent;
 | 
			
		||||
@ -350,6 +353,61 @@ export class MainHeader extends LitElement {
 | 
			
		||||
        this.actionText = 'Listen';
 | 
			
		||||
        this.animationEndTimer = null;
 | 
			
		||||
        this.handleAnimationEnd = this.handleAnimationEnd.bind(this);
 | 
			
		||||
        this.handleMouseMove = this.handleMouseMove.bind(this);
 | 
			
		||||
        this.handleMouseUp = this.handleMouseUp.bind(this);
 | 
			
		||||
        this.dragState = null;
 | 
			
		||||
        this.wasJustDragged = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async handleMouseDown(e) {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
 | 
			
		||||
        const { ipcRenderer } = window.require('electron');
 | 
			
		||||
        const initialPosition = await ipcRenderer.invoke('get-header-position');
 | 
			
		||||
 | 
			
		||||
        this.dragState = {
 | 
			
		||||
            initialMouseX: e.screenX,
 | 
			
		||||
            initialMouseY: e.screenY,
 | 
			
		||||
            initialWindowX: initialPosition.x,
 | 
			
		||||
            initialWindowY: initialPosition.y,
 | 
			
		||||
            moved: false,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        window.addEventListener('mousemove', this.handleMouseMove, { capture: true });
 | 
			
		||||
        window.addEventListener('mouseup', this.handleMouseUp, { once: true, capture: true });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    handleMouseMove(e) {
 | 
			
		||||
        if (!this.dragState) return;
 | 
			
		||||
 | 
			
		||||
        const deltaX = Math.abs(e.screenX - this.dragState.initialMouseX);
 | 
			
		||||
        const deltaY = Math.abs(e.screenY - this.dragState.initialMouseY);
 | 
			
		||||
        
 | 
			
		||||
        if (deltaX > 3 || deltaY > 3) {
 | 
			
		||||
            this.dragState.moved = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const newWindowX = this.dragState.initialWindowX + (e.screenX - this.dragState.initialMouseX);
 | 
			
		||||
        const newWindowY = this.dragState.initialWindowY + (e.screenY - this.dragState.initialMouseY);
 | 
			
		||||
 | 
			
		||||
        const { ipcRenderer } = window.require('electron');
 | 
			
		||||
        ipcRenderer.invoke('move-header-to', newWindowX, newWindowY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    handleMouseUp(e) {
 | 
			
		||||
        if (!this.dragState) return;
 | 
			
		||||
 | 
			
		||||
        const wasDragged = this.dragState.moved;
 | 
			
		||||
 | 
			
		||||
        window.removeEventListener('mousemove', this.handleMouseMove, { capture: true });
 | 
			
		||||
        this.dragState = null;
 | 
			
		||||
 | 
			
		||||
        if (wasDragged) {
 | 
			
		||||
            this.wasJustDragged = true;
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
                this.wasJustDragged = false;
 | 
			
		||||
            }, 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    toggleVisibility() {
 | 
			
		||||
@ -455,6 +513,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    invoke(channel, ...args) {
 | 
			
		||||
        if (this.wasJustDragged) return;
 | 
			
		||||
        if (window.require) {
 | 
			
		||||
            window.require('electron').ipcRenderer.invoke(channel, ...args);
 | 
			
		||||
        }
 | 
			
		||||
@ -462,6 +521,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    showSettingsWindow(element) {
 | 
			
		||||
        if (this.wasJustDragged) return;
 | 
			
		||||
        if (window.require) {
 | 
			
		||||
            const { ipcRenderer } = window.require('electron');
 | 
			
		||||
            console.log(`[MainHeader] showSettingsWindow called at ${Date.now()}`);
 | 
			
		||||
@ -481,6 +541,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hideSettingsWindow() {
 | 
			
		||||
        if (this.wasJustDragged) return;
 | 
			
		||||
        if (window.require) {
 | 
			
		||||
            console.log(`[MainHeader] hideSettingsWindow called at ${Date.now()}`);
 | 
			
		||||
            window.require('electron').ipcRenderer.send('hide-settings-window');
 | 
			
		||||
@ -488,6 +549,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _handleListenClick() {
 | 
			
		||||
        if (this.wasJustDragged) return;
 | 
			
		||||
        if (this.isTogglingSession) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@ -536,7 +598,7 @@ export class MainHeader extends LitElement {
 | 
			
		||||
        const showStopIcon = this.actionText === 'Stop' || this.actionText === 'Done';
 | 
			
		||||
 | 
			
		||||
        return html`
 | 
			
		||||
            <div class="header">
 | 
			
		||||
            <div class="header" @mousedown=${this.handleMouseDown}>
 | 
			
		||||
                <button 
 | 
			
		||||
                    class="listen-button ${Object.keys(buttonClasses).filter(k => buttonClasses[k]).join(' ')}"
 | 
			
		||||
                    @click=${this._handleListenClick}
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,7 @@ export class PermissionHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .close-button {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            position: absolute;
 | 
			
		||||
            top: 10px;
 | 
			
		||||
            right: 10px;
 | 
			
		||||
@ -146,6 +147,7 @@ export class PermissionHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .action-button {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            height: 34px;
 | 
			
		||||
            background: rgba(255, 255, 255, 0.2);
 | 
			
		||||
@ -187,6 +189,7 @@ export class PermissionHeader extends LitElement {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .continue-button {
 | 
			
		||||
            -webkit-app-region: no-drag;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            height: 34px;
 | 
			
		||||
            background: rgba(34, 197, 94, 0.8);
 | 
			
		||||
 | 
			
		||||
@ -37,8 +37,7 @@ const isLiquidGlassSupported = () => {
 | 
			
		||||
    }
 | 
			
		||||
    const majorVersion = parseInt(os.release().split('.')[0], 10);
 | 
			
		||||
    // return majorVersion >= 25; // macOS 26+ (Darwin 25+)
 | 
			
		||||
    return majorVersion >= 25; // See you soon!
 | 
			
		||||
    return majorVersion >= 25; // See you soon!
 | 
			
		||||
    return majorVersion >= 26; // See you soon!
 | 
			
		||||
};
 | 
			
		||||
let shouldUseLiquidGlass = isLiquidGlassSupported();
 | 
			
		||||
if (shouldUseLiquidGlass) {
 | 
			
		||||
@ -395,7 +394,6 @@ function createWindows() {
 | 
			
		||||
        headerLoadOptions.query = { glass: 'true' };
 | 
			
		||||
        header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions);
 | 
			
		||||
        header.webContents.once('did-finish-load', () => {
 | 
			
		||||
            const viewId = liquidGlass.addView(header.getNativeWindowHandle());
 | 
			
		||||
            const viewId = liquidGlass.addView(header.getNativeWindowHandle());
 | 
			
		||||
            if (viewId !== -1) {
 | 
			
		||||
                liquidGlass.unstable_setVariant(viewId, liquidGlass.GlassMaterialVariant.bubbles);
 | 
			
		||||
@ -948,6 +946,57 @@ function setupIpcHandlers(movementManager) {
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // ipcMain.handle('get-header-position', () => {
 | 
			
		||||
    //     const header = windowPool.get('header');
 | 
			
		||||
    //     if (header) {
 | 
			
		||||
    //         const [x, y] = header.getPosition();
 | 
			
		||||
    //         return { x, y };
 | 
			
		||||
    //     }
 | 
			
		||||
    //     return { x: 0, y: 0 };
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
    // ipcMain.handle('move-header', (event, newX, newY) => {
 | 
			
		||||
    //     const header = windowPool.get('header');
 | 
			
		||||
    //     if (header) {
 | 
			
		||||
    //         const currentY = newY !== undefined ? newY : header.getBounds().y;
 | 
			
		||||
    //         header.setPosition(newX, currentY, false);
 | 
			
		||||
 | 
			
		||||
    //         updateLayout();
 | 
			
		||||
    //     }
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
    // ipcMain.handle('move-header-to', (event, newX, newY) => {
 | 
			
		||||
    //     const header = 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();
 | 
			
		||||
 | 
			
		||||
    //         // Only clamp if the new position would actually go out of bounds
 | 
			
		||||
    //         // This prevents progressive restriction of movement
 | 
			
		||||
    //         let clampedX = newX;
 | 
			
		||||
    //         let clampedY = newY;
 | 
			
		||||
            
 | 
			
		||||
    //         // Check if we need to clamp X position
 | 
			
		||||
    //         if (newX < workAreaX) {
 | 
			
		||||
    //             clampedX = workAreaX;
 | 
			
		||||
    //         } else if (newX + headerBounds.width > workAreaX + width) {
 | 
			
		||||
    //             clampedX = workAreaX + width - headerBounds.width;
 | 
			
		||||
    //         }
 | 
			
		||||
            
 | 
			
		||||
    //         // Check if we need to clamp Y position  
 | 
			
		||||
    //         if (newY < workAreaY) {
 | 
			
		||||
    //             clampedY = workAreaY;
 | 
			
		||||
    //         } else if (newY + headerBounds.height > workAreaY + height) {
 | 
			
		||||
    //             clampedY = workAreaY + height - headerBounds.height;
 | 
			
		||||
    //         }
 | 
			
		||||
 | 
			
		||||
    //         header.setPosition(clampedX, clampedY, false);
 | 
			
		||||
 | 
			
		||||
    //         updateLayout();
 | 
			
		||||
    //     }
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ipcMain.handle('move-window-step', (event, direction) => {
 | 
			
		||||
        if (movementManager) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user