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 {
|
.close-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
@ -157,6 +158,7 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.api-input {
|
.api-input {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(255, 255, 255, 0.1);
|
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-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; }
|
.provider-label { color: rgba(255, 255, 255, 0.7); font-size: 11px; font-weight: 500; margin-bottom: 6px; }
|
||||||
.api-input, .provider-select {
|
.api-input, .provider-select {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -210,6 +213,7 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
|
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
@ -82,6 +82,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.listen-button {
|
.listen-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
padding: 0 13px;
|
padding: 0 13px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@ -189,6 +190,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-actions {
|
.header-actions {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
@ -260,6 +262,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.settings-button {
|
.settings-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@ -350,6 +353,61 @@ export class MainHeader extends LitElement {
|
|||||||
this.actionText = 'Listen';
|
this.actionText = 'Listen';
|
||||||
this.animationEndTimer = null;
|
this.animationEndTimer = null;
|
||||||
this.handleAnimationEnd = this.handleAnimationEnd.bind(this);
|
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() {
|
toggleVisibility() {
|
||||||
@ -455,6 +513,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
invoke(channel, ...args) {
|
invoke(channel, ...args) {
|
||||||
|
if (this.wasJustDragged) return;
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
window.require('electron').ipcRenderer.invoke(channel, ...args);
|
window.require('electron').ipcRenderer.invoke(channel, ...args);
|
||||||
}
|
}
|
||||||
@ -462,6 +521,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showSettingsWindow(element) {
|
showSettingsWindow(element) {
|
||||||
|
if (this.wasJustDragged) return;
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
console.log(`[MainHeader] showSettingsWindow called at ${Date.now()}`);
|
console.log(`[MainHeader] showSettingsWindow called at ${Date.now()}`);
|
||||||
@ -481,6 +541,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hideSettingsWindow() {
|
hideSettingsWindow() {
|
||||||
|
if (this.wasJustDragged) return;
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
console.log(`[MainHeader] hideSettingsWindow called at ${Date.now()}`);
|
console.log(`[MainHeader] hideSettingsWindow called at ${Date.now()}`);
|
||||||
window.require('electron').ipcRenderer.send('hide-settings-window');
|
window.require('electron').ipcRenderer.send('hide-settings-window');
|
||||||
@ -488,6 +549,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _handleListenClick() {
|
async _handleListenClick() {
|
||||||
|
if (this.wasJustDragged) return;
|
||||||
if (this.isTogglingSession) {
|
if (this.isTogglingSession) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -536,7 +598,7 @@ export class MainHeader extends LitElement {
|
|||||||
const showStopIcon = this.actionText === 'Stop' || this.actionText === 'Done';
|
const showStopIcon = this.actionText === 'Stop' || this.actionText === 'Done';
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="header">
|
<div class="header" @mousedown=${this.handleMouseDown}>
|
||||||
<button
|
<button
|
||||||
class="listen-button ${Object.keys(buttonClasses).filter(k => buttonClasses[k]).join(' ')}"
|
class="listen-button ${Object.keys(buttonClasses).filter(k => buttonClasses[k]).join(' ')}"
|
||||||
@click=${this._handleListenClick}
|
@click=${this._handleListenClick}
|
||||||
|
@ -56,6 +56,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.close-button {
|
.close-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
@ -146,6 +147,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
@ -187,6 +189,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.continue-button {
|
.continue-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(34, 197, 94, 0.8);
|
background: rgba(34, 197, 94, 0.8);
|
||||||
|
@ -37,8 +37,7 @@ const isLiquidGlassSupported = () => {
|
|||||||
}
|
}
|
||||||
const majorVersion = parseInt(os.release().split('.')[0], 10);
|
const majorVersion = parseInt(os.release().split('.')[0], 10);
|
||||||
// return majorVersion >= 25; // macOS 26+ (Darwin 25+)
|
// return majorVersion >= 25; // macOS 26+ (Darwin 25+)
|
||||||
return majorVersion >= 25; // See you soon!
|
return majorVersion >= 26; // See you soon!
|
||||||
return majorVersion >= 25; // See you soon!
|
|
||||||
};
|
};
|
||||||
let shouldUseLiquidGlass = isLiquidGlassSupported();
|
let shouldUseLiquidGlass = isLiquidGlassSupported();
|
||||||
if (shouldUseLiquidGlass) {
|
if (shouldUseLiquidGlass) {
|
||||||
@ -395,7 +394,6 @@ function createWindows() {
|
|||||||
headerLoadOptions.query = { glass: 'true' };
|
headerLoadOptions.query = { glass: 'true' };
|
||||||
header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions);
|
header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions);
|
||||||
header.webContents.once('did-finish-load', () => {
|
header.webContents.once('did-finish-load', () => {
|
||||||
const viewId = liquidGlass.addView(header.getNativeWindowHandle());
|
|
||||||
const viewId = liquidGlass.addView(header.getNativeWindowHandle());
|
const viewId = liquidGlass.addView(header.getNativeWindowHandle());
|
||||||
if (viewId !== -1) {
|
if (viewId !== -1) {
|
||||||
liquidGlass.unstable_setVariant(viewId, liquidGlass.GlassMaterialVariant.bubbles);
|
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) => {
|
ipcMain.handle('move-window-step', (event, direction) => {
|
||||||
if (movementManager) {
|
if (movementManager) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user