-
Notifications
You must be signed in to change notification settings - Fork 625
feat: add floating button position persistence with boundary validation #729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,11 +3,13 @@ import path from 'path' | |
| import { FloatingButtonConfig, FloatingButtonState } from './types' | ||
| import logger from '../../../shared/logger' | ||
| import { platform } from '@electron-toolkit/utils' | ||
| import windowStateManager from 'electron-window-state' | ||
|
|
||
| export class FloatingButtonWindow { | ||
| private window: BrowserWindow | null = null | ||
| private config: FloatingButtonConfig | ||
| private state: FloatingButtonState | ||
| private windowState: any | ||
|
|
||
| constructor(config: FloatingButtonConfig) { | ||
| this.config = config | ||
|
|
@@ -20,6 +22,13 @@ export class FloatingButtonWindow { | |
| height: config.size.height | ||
| } | ||
| } | ||
|
|
||
| // 初始化窗口状态管理器 | ||
| this.windowState = windowStateManager({ | ||
| file: 'floating-button-window-state.json', | ||
| defaultWidth: config.size.width, | ||
| defaultHeight: config.size.height | ||
| }) | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -31,16 +40,14 @@ export class FloatingButtonWindow { | |
| } | ||
|
|
||
| try { | ||
| const position = this.calculatePosition() | ||
|
|
||
| // 根据环境选择正确的预加载脚本路径 | ||
| const isDev = process.env.NODE_ENV === 'development' | ||
|
|
||
| this.window = new BrowserWindow({ | ||
| width: this.config.size.width, | ||
| height: this.config.size.height, | ||
| x: position.x, | ||
| y: position.y, | ||
| x: this.windowState.x, | ||
| y: this.windowState.y, | ||
| width: this.windowState.width, | ||
| height: this.windowState.height, | ||
| frame: false, | ||
| transparent: platform.isMacOS, | ||
| alwaysOnTop: this.config.alwaysOnTop, | ||
|
|
@@ -63,6 +70,7 @@ export class FloatingButtonWindow { | |
| sandbox: false // 禁用沙盒模式,确保预加载脚本能正常工作 | ||
| } | ||
| }) | ||
| this.windowState.manage(this.window) | ||
| this.window.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }) | ||
| this.window.setAlwaysOnTop(true, 'floating') | ||
| // 设置窗口透明度 | ||
|
|
@@ -140,7 +148,7 @@ export class FloatingButtonWindow { | |
| } | ||
|
|
||
| if (config.position || config.offset) { | ||
| const position = this.calculatePosition() | ||
| const position = this.getDefaultPosition() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify position calculation logic change. The change from Run the following script to verify if the removed 🏁 Script executed: #!/bin/bash
# Description: Check if calculatePosition method existed and how it handled different position types
# Search for any references to calculatePosition in the codebase
rg -A 10 -B 5 "calculatePosition"
# Search for position-related logic that might have been removed
rg -A 5 -B 5 "(top-left|top-right|bottom-left|bottom-right)" --type tsLength of output: 5898 🏁 Script executed: #!/bin/bash
# Inspect getDefaultPosition and surrounding logic in FloatingButtonWindow.ts
rg -C 10 "getDefaultPosition" --glob "src/main/presenter/floatingButtonPresenter/FloatingButtonWindow.ts"Length of output: 4044 Re-enable configurable positioning for the floating button The current call to • File: src/main/presenter/floatingButtonPresenter/FloatingButtonWindow.ts • Implement a new - private getDefaultPosition(): { x: number; y: number } {
- const { workArea } = screen.getPrimaryDisplay()
- return {
- x: workArea.width - this.config.size.width - 20,
- y: workArea.height - this.config.size.height - 20
- }
- }
+ private calculatePosition(): { x: number; y: number } {
+ const { workArea } = screen.getPrimaryDisplay()
+ const { width, height } = this.config.size
+ const { x: ox, y: oy } = this.config.offset
+ let x: number, y: number
+ switch (this.config.position) {
+ case 'top-left':
+ x = workArea.x + ox; y = workArea.y + oy; break
+ case 'top-right':
+ x = workArea.width - width - ox; y = workArea.y + oy; break
+ case 'bottom-left':
+ x = workArea.x + ox; y = workArea.height - height - oy; break
+ default: // 'bottom-right'
+ x = workArea.width - width - ox; y = workArea.height - height - oy;
+ }
+ return { x, y }
+ }• Update the call site to use This will ensure all four corner options and custom offsets behave as intended. 🤖 Prompt for AI Agents |
||
| this.window.setPosition(position.x, position.y) | ||
| this.state.bounds.x = position.x | ||
| this.state.bounds.y = position.y | ||
|
|
@@ -175,35 +183,16 @@ export class FloatingButtonWindow { | |
| } | ||
|
|
||
| /** | ||
| * 计算悬浮按钮位置 | ||
| * 获取默认位置(右下角) | ||
| */ | ||
| private calculatePosition(): { x: number; y: number } { | ||
| private getDefaultPosition(): { x: number; y: number } { | ||
| const primaryDisplay = screen.getPrimaryDisplay() | ||
| const { workAreaSize } = primaryDisplay | ||
|
|
||
| let x: number, y: number | ||
|
|
||
| switch (this.config.position) { | ||
| case 'top-left': | ||
| x = this.config.offset.x | ||
| y = this.config.offset.y | ||
| break | ||
| case 'top-right': | ||
| x = workAreaSize.width - this.config.size.width - this.config.offset.x | ||
| y = this.config.offset.y | ||
| break | ||
| case 'bottom-left': | ||
| x = this.config.offset.x | ||
| y = workAreaSize.height - this.config.size.height - this.config.offset.y | ||
| break | ||
| case 'bottom-right': | ||
| default: | ||
| x = workAreaSize.width - this.config.size.width - this.config.offset.x | ||
| y = workAreaSize.height - this.config.size.height - this.config.offset.y | ||
| break | ||
| } | ||
| const { workArea } = primaryDisplay | ||
|
|
||
| return { x, y } | ||
| return { | ||
| x: workArea.width - this.config.size.width - 20, | ||
| y: workArea.height - this.config.size.height - 20 | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use proper TypeScript typing for windowState property.
The
windowStateproperty should use a proper type instead ofanyto enable better type safety and IntelliSense support.Apply this diff to add proper typing:
📝 Committable suggestion
🤖 Prompt for AI Agents