|
3 | 3 | # ================================================== |
4 | 4 |
|
5 | 5 | from loguru import logger |
| 6 | +import os |
| 7 | +import ctypes |
6 | 8 | from PySide6.QtWidgets import QWidget, QVBoxLayout, QApplication |
7 | 9 | from PySide6.QtGui import QFontDatabase |
| 10 | +from PySide6.QtCore import QSignalBlocker |
8 | 11 | from qfluentwidgets import ( |
9 | 12 | GroupHeaderCardWidget, |
10 | 13 | SwitchButton, |
|
15 | 18 | Theme, |
16 | 19 | setTheme, |
17 | 20 | setThemeColor, |
| 21 | + MessageBox, |
18 | 22 | ) |
19 | 23 |
|
| 24 | +from app.tools.variable import EXIT_CODE_RESTART |
| 25 | + |
20 | 26 | from app.tools.personalised import get_theme_icon |
21 | 27 | from app.tools.settings_access import readme_settings_async, update_settings |
22 | 28 | from app.tools.settings_visibility_manager import is_setting_visible |
|
41 | 47 | NotificationConfig, |
42 | 48 | ) |
43 | 49 | from app.common.IPC_URL import URLIPCHandler |
| 50 | +from app.common.windows.uiaccess import is_uiaccess_process |
44 | 51 | from app.page_building.another_window import ( |
45 | 52 | create_log_viewer_window, |
46 | 53 | create_backup_manager_window, |
@@ -150,6 +157,19 @@ def __init__(self, parent=None): |
150 | 157 | self.__on_auto_save_window_size_changed |
151 | 158 | ) |
152 | 159 |
|
| 160 | + # 主窗口置顶设置 |
| 161 | + self.main_window_topmost_mode_combo_box = ComboBox() |
| 162 | + self.main_window_topmost_mode_combo_box.addItems( |
| 163 | + get_content_combo_name_async("basic_settings", "main_window_topmost_mode") |
| 164 | + ) |
| 165 | + topmost_mode = readme_settings_async( |
| 166 | + "basic_settings", "main_window_topmost_mode" |
| 167 | + ) |
| 168 | + self.main_window_topmost_mode_combo_box.setCurrentIndex(int(topmost_mode or 0)) |
| 169 | + self.main_window_topmost_mode_combo_box.currentIndexChanged.connect( |
| 170 | + self.__on_main_window_topmost_mode_changed |
| 171 | + ) |
| 172 | + |
153 | 173 | # 后台驻留设置 |
154 | 174 | self.resident_switch = SwitchButton() |
155 | 175 | self.resident_switch.setOffText( |
@@ -215,6 +235,15 @@ def __init__(self, parent=None): |
215 | 235 | ), |
216 | 236 | self.auto_save_window_size_switch, |
217 | 237 | ) |
| 238 | + if is_setting_visible("basic_settings", "main_window_topmost_mode"): |
| 239 | + self.addGroup( |
| 240 | + get_theme_icon("ic_fluent_pin_20_filled"), |
| 241 | + get_content_name_async("basic_settings", "main_window_topmost_mode"), |
| 242 | + get_content_description_async( |
| 243 | + "basic_settings", "main_window_topmost_mode" |
| 244 | + ), |
| 245 | + self.main_window_topmost_mode_combo_box, |
| 246 | + ) |
218 | 247 | if is_setting_visible("basic_settings", "background_resident"): |
219 | 248 | self.addGroup( |
220 | 249 | get_theme_icon("ic_fluent_resize_20_filled"), |
@@ -388,6 +417,107 @@ def __on_auto_save_window_size_changed(self, checked): |
388 | 417 | parent=self.window(), |
389 | 418 | ) |
390 | 419 |
|
| 420 | + def __on_main_window_topmost_mode_changed(self, index): |
| 421 | + previous_index = int( |
| 422 | + readme_settings_async("basic_settings", "main_window_topmost_mode") or 0 |
| 423 | + ) |
| 424 | + |
| 425 | + # 如果当前已经是 UIA 进程,切换到 UIA 模式不需要重启 |
| 426 | + if index == 2 and is_uiaccess_process(): |
| 427 | + update_settings("basic_settings", "main_window_topmost_mode", index) |
| 428 | + return |
| 429 | + |
| 430 | + # 如果当前是 UIA 进程,且浮窗也是 UIA 模式,切换回非 UIA 模式不需要重启(因为进程必须保持 UIA) |
| 431 | + if previous_index == 2 and index != 2 and is_uiaccess_process(): |
| 432 | + floating_mode = int( |
| 433 | + readme_settings_async( |
| 434 | + "floating_window_management", "floating_window_topmost_mode" |
| 435 | + ) |
| 436 | + or 0 |
| 437 | + ) |
| 438 | + if floating_mode == 2: |
| 439 | + update_settings("basic_settings", "main_window_topmost_mode", index) |
| 440 | + return |
| 441 | + |
| 442 | + if previous_index == 2 and index != 2: |
| 443 | + dialog = MessageBox( |
| 444 | + get_content_name_async( |
| 445 | + "basic_settings", "uia_topmost_restart_dialog_title" |
| 446 | + ), |
| 447 | + get_content_name_async( |
| 448 | + "basic_settings", |
| 449 | + "uia_topmost_disable_restart_dialog_content", |
| 450 | + ), |
| 451 | + self.window(), |
| 452 | + ) |
| 453 | + dialog.yesButton.setText( |
| 454 | + get_content_name_async( |
| 455 | + "basic_settings", |
| 456 | + "uia_topmost_disable_restart_dialog_ok_btn", |
| 457 | + ) |
| 458 | + ) |
| 459 | + dialog.cancelButton.setText( |
| 460 | + get_content_name_async( |
| 461 | + "basic_settings", |
| 462 | + "uia_topmost_restart_dialog_cancel_btn", |
| 463 | + ) |
| 464 | + ) |
| 465 | + if dialog.exec(): |
| 466 | + update_settings("basic_settings", "main_window_topmost_mode", index) |
| 467 | + else: |
| 468 | + blocker = QSignalBlocker(self.main_window_topmost_mode_combo_box) |
| 469 | + self.main_window_topmost_mode_combo_box.setCurrentIndex(previous_index) |
| 470 | + del blocker |
| 471 | + return |
| 472 | + |
| 473 | + if index == 2 and previous_index != 2: |
| 474 | + dialog = MessageBox( |
| 475 | + get_content_name_async( |
| 476 | + "basic_settings", "uia_topmost_restart_dialog_title" |
| 477 | + ), |
| 478 | + get_content_name_async( |
| 479 | + "basic_settings", "uia_topmost_restart_dialog_content" |
| 480 | + ), |
| 481 | + self.window(), |
| 482 | + ) |
| 483 | + dialog.yesButton.setText( |
| 484 | + get_content_name_async( |
| 485 | + "basic_settings", |
| 486 | + "uia_topmost_restart_dialog_restart_btn", |
| 487 | + ) |
| 488 | + ) |
| 489 | + dialog.cancelButton.setText( |
| 490 | + get_content_name_async( |
| 491 | + "basic_settings", |
| 492 | + "uia_topmost_restart_dialog_cancel_btn", |
| 493 | + ) |
| 494 | + ) |
| 495 | + if dialog.exec(): |
| 496 | + update_settings("basic_settings", "main_window_topmost_mode", index) |
| 497 | + try: |
| 498 | + from app.common.windows.uiaccess import ( |
| 499 | + ELEVATE_RESTART_ENV, |
| 500 | + UIACCESS_RESTART_ENV, |
| 501 | + ) |
| 502 | + |
| 503 | + os.environ[str(UIACCESS_RESTART_ENV)] = "1" |
| 504 | + try: |
| 505 | + is_admin = bool(ctypes.windll.shell32.IsUserAnAdmin()) |
| 506 | + except Exception: |
| 507 | + is_admin = False |
| 508 | + if not is_admin: |
| 509 | + os.environ[str(ELEVATE_RESTART_ENV)] = "1" |
| 510 | + except Exception: |
| 511 | + pass |
| 512 | + QApplication.exit(EXIT_CODE_RESTART) |
| 513 | + else: |
| 514 | + blocker = QSignalBlocker(self.main_window_topmost_mode_combo_box) |
| 515 | + self.main_window_topmost_mode_combo_box.setCurrentIndex(previous_index) |
| 516 | + del blocker |
| 517 | + return |
| 518 | + |
| 519 | + update_settings("basic_settings", "main_window_topmost_mode", index) |
| 520 | + |
391 | 521 | def __on_url_protocol_changed(self, checked): |
392 | 522 | """URL协议开关变化处理""" |
393 | 523 | # 临时断开信号连接,避免递归 |
|
0 commit comments