优化程序

This commit is contained in:
hero920103 committed 2026-10-12 14:57:46 +08:00
1 parent 68e8eb91a7
commit 6df29c9254
27 files changed
+1974 -203

No files matched your search

+39 -15
View File
@@ -78,10 +78,16 @@ def _install_requirements_on_startup() -> None:
class GlobalHotkey(QAbstractNativeEventFilter):
"""用 Win32 RegisterHotKey 注册真正的全局快捷键 Alt+`"""
_HOTKEY_ID = 0x4E4D # 任意唯一 ID
_MOD_ALT = 0x0001
_VK_BACKTICK = 0xC0 # VK_OEM_3 = ` 键
"""
Win32 RegisterHotKey 注册两个全局快捷键:
- Alt+` : 唤醒/折叠面板(在"面板↔悬浮球"间切换)
- Ctrl+` : 缩小成悬浮球(任何状态都最小化到悬浮球)
"""
_HK_ALT = 0x4E4D # Alt+`
_HK_CTRL = 0x4E4E # Ctrl+`
_MOD_ALT = 0x0001
_MOD_CTRL = 0x0002
_VK_BACKTICK = 0xC0 # ` 键
def __init__(self, panel: "PanelWindow", ball: "FloatBall"):
super().__init__()
@@ -91,15 +97,16 @@ class GlobalHotkey(QAbstractNativeEventFilter):
def install(self):
if sys.platform != "win32":
return
# 注册线程级别的全局热键,避免因主窗口 hide/show 导致 HWND 重建/失效
ctypes.windll.user32.RegisterHotKey(
None, self._HOTKEY_ID, self._MOD_ALT, self._VK_BACKTICK
)
user32 = ctypes.windll.user32
user32.RegisterHotKey(None, self._HK_ALT, self._MOD_ALT, self._VK_BACKTICK)
user32.RegisterHotKey(None, self._HK_CTRL, self._MOD_CTRL, self._VK_BACKTICK)
QApplication.instance().installNativeEventFilter(self)
def uninstall(self):
if sys.platform == "win32":
ctypes.windll.user32.UnregisterHotKey(None, self._HOTKEY_ID)
user32 = ctypes.windll.user32
user32.UnregisterHotKey(None, self._HK_ALT)
user32.UnregisterHotKey(None, self._HK_CTRL)
QApplication.instance().removeNativeEventFilter(self)
def nativeEventFilter(self, event_type, message):
@@ -107,18 +114,32 @@ class GlobalHotkey(QAbstractNativeEventFilter):
import ctypes
msg = ctypes.cast(int(message), ctypes.POINTER(ctypes.wintypes.MSG)).contents
WM_HOTKEY = 0x0312
if msg.message == WM_HOTKEY and msg.wParam == self._HOTKEY_ID:
self._toggle()
if msg.message == WM_HOTKEY:
if msg.wParam == self._HK_ALT:
self._toggle_alt()
elif msg.wParam == self._HK_CTRL:
self._toggle_ctrl()
return False, 0
def _toggle(self):
if self._panel.is_really_visible():
self._panel.minimize_to_ball()
def _toggle_alt(self):
"""Alt+`:只唤醒面板(如果已显示就忽略,不再缩小)"""
if self._panel.isVisible():
# 已经显示着了 —— 不做任何事(取消原来的缩小行为)
# 只尝试把它 raise 到最前
self._panel.raise_()
self._panel.activateWindow()
else:
# 悬浮球状态 → 唤醒面板
self._panel.show_near(self._ball.pos(), BALL_SIZE)
self._panel.raise_()
self._panel.activateWindow()
def _toggle_ctrl(self):
"""Ctrl+`:强制缩小成悬浮球(任何状态都生效)"""
if self._panel.isVisible():
self._panel.minimize_to_ball()
# 已经是悬浮球状态,什么都不做
# ===================== 打包兼容核心函数 =====================
def get_resource_path(relative_path):
"""
@@ -182,7 +203,9 @@ def _wake_existing_or_exit() -> bool:
def main():
if not _wake_existing_or_exit():
# 外部更新器启动时带 --from-update,跳过单实例检测(旧 mutex 可能还没完全释放)
from_update = "--from-update" in sys.argv
if not from_update and not _wake_existing_or_exit():
return
_install_requirements_on_startup()
@@ -216,6 +239,7 @@ def main():
panel._ball_ref = ball
panel._apply_pin_window_layer()
panel._load_file_boxes()
ball.clicked.connect(lambda: panel.show_near(ball.pos(), BALL_SIZE))
ball.right_clicked.connect(lambda pos: panel.tray.contextMenu().exec(pos))