frontengine 1.0.48__tar.gz → 1.0.49__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. {frontengine-1.0.48 → frontengine-1.0.49}/PKG-INFO +1 -1
  2. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/gaming/crosshair_widget.py +9 -8
  3. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/teleprompter/teleprompter_widget.py +3 -3
  4. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/main_ui.py +42 -5
  5. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/control_center/control_center_ui.py +39 -12
  6. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/presentation/presentation_setting_ui.py +7 -6
  7. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/remote/remote_server.py +1 -3
  8. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/screen_privacy/capture_affinity.py +6 -3
  9. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/virtual_camera/camera_feed.py +1 -1
  10. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/virtual_camera/virtual_camera.py +4 -4
  11. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine.egg-info/PKG-INFO +1 -1
  12. {frontengine-1.0.48 → frontengine-1.0.49}/pyproject.toml +1 -1
  13. {frontengine-1.0.48 → frontengine-1.0.49}/LICENSE +0 -0
  14. {frontengine-1.0.48 → frontengine-1.0.49}/README.md +0 -0
  15. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/__init__.py +0 -0
  16. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/__main__.py +0 -0
  17. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/__init__.py +0 -0
  18. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/base_widget.py +0 -0
  19. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/camera/__init__.py +0 -0
  20. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/camera/camera_widget.py +0 -0
  21. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/canvas/__init__.py +0 -0
  22. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/canvas/whiteboard_widget.py +0 -0
  23. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/capture/__init__.py +0 -0
  24. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/capture/region_capture.py +0 -0
  25. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/focus_shield/__init__.py +0 -0
  26. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/focus_shield/focus_shield_widget.py +0 -0
  27. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/gaming/__init__.py +0 -0
  28. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/gif/__init__.py +0 -0
  29. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/gif/paint_gif.py +0 -0
  30. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/image/__init__.py +0 -0
  31. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/image/paint_image.py +0 -0
  32. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/load/__init__.py +0 -0
  33. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/load/load_someone_make_ui.py +0 -0
  34. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/measure/__init__.py +0 -0
  35. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/measure/measure_widget.py +0 -0
  36. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/monitor/__init__.py +0 -0
  37. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/monitor/monitor_widget.py +0 -0
  38. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/notes/__init__.py +0 -0
  39. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/notes/sticky_note_widget.py +0 -0
  40. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/overlay_factory.py +0 -0
  41. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/particle/__init__.py +0 -0
  42. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/particle/particle_ui.py +0 -0
  43. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/pet/__init__.py +0 -0
  44. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/pet/desktop_pet.py +0 -0
  45. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/presentation/__init__.py +0 -0
  46. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/presentation/annotation_overlay.py +0 -0
  47. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/presentation/cursor_effects.py +0 -0
  48. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/presentation/keystroke_display.py +0 -0
  49. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/presentation/magnifier.py +0 -0
  50. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/scene/__init__.py +0 -0
  51. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/scene/extend_graphic_scene.py +0 -0
  52. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/scene/extend_graphic_view.py +0 -0
  53. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/scene/scene.py +0 -0
  54. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/screen_care/__init__.py +0 -0
  55. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/screen_care/color_vision_widget.py +0 -0
  56. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/screen_care/screen_filter.py +0 -0
  57. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/sound_player/__init__.py +0 -0
  58. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/sound_player/sound_effect.py +0 -0
  59. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/sound_player/sound_player.py +0 -0
  60. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/spectrum/__init__.py +0 -0
  61. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/spectrum/spectrum_widget.py +0 -0
  62. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/teleprompter/__init__.py +0 -0
  63. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/text/__init__.py +0 -0
  64. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/text/draw_text.py +0 -0
  65. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/toast/__init__.py +0 -0
  66. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/toast/toast_widget.py +0 -0
  67. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/video/__init__.py +0 -0
  68. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/video/video_player.py +0 -0
  69. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/wallpaper/__init__.py +0 -0
  70. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/wallpaper/wallpaper_widget.py +0 -0
  71. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/web/__init__.py +0 -0
  72. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/web/webview.py +0 -0
  73. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/show/window_helpers.py +0 -0
  74. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/system_tray/__init__.py +0 -0
  75. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/system_tray/extend_system_tray.py +0 -0
  76. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/__init__.py +0 -0
  77. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/color/__init__.py +0 -0
  78. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/color/global_color.py +0 -0
  79. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/__init__.py +0 -0
  80. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/app_profile_dialog.py +0 -0
  81. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
  82. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/clipboard_dialog.py +0 -0
  83. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
  84. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/reminder_dialog.py +0 -0
  85. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/remote_control_dialog.py +0 -0
  86. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/save_file_dialog.py +0 -0
  87. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/screen_privacy_dialog.py +0 -0
  88. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/screen_text_dialog.py +0 -0
  89. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/signage_dialog.py +0 -0
  90. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/smart_pause_dialog.py +0 -0
  91. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/usage_report_dialog.py +0 -0
  92. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/dialog/window_pin_dialog.py +0 -0
  93. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/menu/__init__.py +0 -0
  94. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/menu/help_menu.py +0 -0
  95. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/menu/how_to_menu.py +0 -0
  96. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/menu/language_menu.py +0 -0
  97. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/menu/preset_menu.py +0 -0
  98. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/menu/settings_menu.py +0 -0
  99. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/__init__.py +0 -0
  100. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/control_center/__init__.py +0 -0
  101. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/focus/__init__.py +0 -0
  102. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/focus/focus_setting_ui.py +0 -0
  103. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/gif/__init__.py +0 -0
  104. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
  105. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/image/__init__.py +0 -0
  106. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/image/image_setting_ui.py +0 -0
  107. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/particle/__init__.py +0 -0
  108. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
  109. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/pet/__init__.py +0 -0
  110. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/pet/pet_setting_ui.py +0 -0
  111. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/presentation/__init__.py +0 -0
  112. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/__init__.py +0 -0
  113. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
  114. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
  115. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
  116. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
  117. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
  118. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
  119. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
  120. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
  121. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
  122. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
  123. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
  124. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/screen_care/__init__.py +0 -0
  125. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/screen_care/screen_care_setting_ui.py +1 -1
  126. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/sound_player/__init__.py +0 -0
  127. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
  128. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/stream/__init__.py +0 -0
  129. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/stream/stream_setting_ui.py +0 -0
  130. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/text/__init__.py +0 -0
  131. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/text/text_setting_ui.py +0 -0
  132. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/tools/__init__.py +0 -0
  133. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/tools/tools_setting_ui.py +0 -0
  134. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/utils.py +0 -0
  135. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/video/__init__.py +0 -0
  136. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/video/video_setting_ui.py +0 -0
  137. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/wallpaper/__init__.py +0 -0
  138. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/wallpaper/wallpaper_setting_ui.py +0 -0
  139. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/web/__init__.py +0 -0
  140. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/web/web_setting_ui.py +0 -0
  141. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/widgets/__init__.py +0 -0
  142. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/ui/page/widgets/widgets_setting_ui.py +0 -0
  143. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/user_setting/__init__.py +0 -0
  144. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/user_setting/preset_repository.py +0 -0
  145. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/user_setting/scene_setting.py +0 -0
  146. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/user_setting/user_setting_file.py +0 -0
  147. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/__init__.py +0 -0
  148. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/app_profile/__init__.py +0 -0
  149. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/app_profile/app_profile_service.py +0 -0
  150. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/audio_meter/__init__.py +0 -0
  151. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/audio_meter/audio_envelope.py +0 -0
  152. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/audio_meter/loopback_capture.py +0 -0
  153. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/audio_meter/microphone_meter.py +0 -0
  154. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/audio_meter/screen_audio.py +0 -0
  155. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/audio_meter/spectrum_analyzer.py +0 -0
  156. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/audio_meter/system_audio_meter.py +0 -0
  157. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/autostart/__init__.py +0 -0
  158. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/autostart/autostart_service.py +0 -0
  159. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/break_reminder/__init__.py +0 -0
  160. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/break_reminder/break_reminder.py +0 -0
  161. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/browser/__init__.py +0 -0
  162. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/browser/browser.py +0 -0
  163. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/clipboard/__init__.py +0 -0
  164. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/clipboard/clipboard_history.py +0 -0
  165. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/clipboard/clipboard_watcher.py +0 -0
  166. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/color_vision/__init__.py +0 -0
  167. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/color_vision/color_vision.py +0 -0
  168. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/critical_exit/__init__.py +0 -0
  169. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
  170. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/critical_exit/critical_exit.py +0 -0
  171. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/critical_exit/win32_vk.py +0 -0
  172. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/exception/__init__.py +0 -0
  173. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/exception/exception_tags.py +0 -0
  174. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/exception/exceptions.py +0 -0
  175. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/file/__init__.py +0 -0
  176. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/file/open/__init__.py +0 -0
  177. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/file/open/open_file.py +0 -0
  178. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/file/save/__init__.py +0 -0
  179. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/file/save/save_file.py +0 -0
  180. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/focus_shield/__init__.py +0 -0
  181. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/focus_shield/focus_shield.py +0 -0
  182. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/focus_timer/__init__.py +0 -0
  183. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/focus_timer/focus_timer.py +0 -0
  184. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/hotkey/__init__.py +0 -0
  185. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/hotkey/hotkey_service.py +0 -0
  186. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/input_watch/__init__.py +0 -0
  187. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/input_watch/input_watch_service.py +0 -0
  188. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/json/__init__.py +0 -0
  189. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/json/json_file.py +0 -0
  190. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/json/json_repository.py +0 -0
  191. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/json_format/__init__.py +0 -0
  192. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/json_format/json_process.py +0 -0
  193. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/logging/__init__.py +0 -0
  194. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/logging/loggin_instance.py +0 -0
  195. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/measure/__init__.py +0 -0
  196. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/measure/measure.py +0 -0
  197. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/midi/__init__.py +0 -0
  198. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/midi/midi_input.py +0 -0
  199. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/__init__.py +0 -0
  200. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/english.py +0 -0
  201. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/france.py +0 -0
  202. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/germany.py +0 -0
  203. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/italy.py +0 -0
  204. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/language_wrapper.py +0 -0
  205. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/russian.py +0 -0
  206. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
  207. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/multi_language/traditional_chinese.py +0 -0
  208. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/now_playing/__init__.py +0 -0
  209. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/now_playing/now_playing.py +0 -0
  210. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/obs/__init__.py +0 -0
  211. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/obs/obs_client.py +0 -0
  212. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/obs/obs_protocol.py +0 -0
  213. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/obs/websocket_frames.py +0 -0
  214. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/pet_chat/__init__.py +0 -0
  215. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/pet_chat/pet_chat_service.py +0 -0
  216. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/platform_info/__init__.py +0 -0
  217. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/platform_info/platform_info.py +0 -0
  218. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/playlist/__init__.py +0 -0
  219. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/playlist/playlist.py +0 -0
  220. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/plugins/__init__.py +0 -0
  221. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/plugins/plugin_loader.py +0 -0
  222. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/power_mode/__init__.py +0 -0
  223. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/power_mode/power_mode.py +0 -0
  224. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/preset_schedule/__init__.py +0 -0
  225. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
  226. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/recording/__init__.py +0 -0
  227. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/recording/frame_recorder.py +0 -0
  228. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/recording/gif_writer.py +0 -0
  229. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/redirect_manager/__init__.py +0 -0
  230. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
  231. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/reminder/__init__.py +0 -0
  232. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/reminder/reminder_service.py +0 -0
  233. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/remote/__init__.py +0 -0
  234. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/screen_privacy/__init__.py +0 -0
  235. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/screen_privacy/share_watch.py +0 -0
  236. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/screen_text/__init__.py +0 -0
  237. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/screen_text/screen_text_service.py +0 -0
  238. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/signage/__init__.py +0 -0
  239. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/signage/signage_service.py +0 -0
  240. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/smart_pause/__init__.py +0 -0
  241. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/smart_pause/pause_rules.py +0 -0
  242. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
  243. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/soundboard/__init__.py +0 -0
  244. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/soundboard/soundboard.py +0 -0
  245. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/system_stats/__init__.py +0 -0
  246. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/system_stats/system_stats.py +0 -0
  247. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/text_source/__init__.py +0 -0
  248. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/text_source/text_source.py +0 -0
  249. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/theme_schedule/__init__.py +0 -0
  250. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
  251. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/usage_tracking/__init__.py +0 -0
  252. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/usage_tracking/usage_service.py +0 -0
  253. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/usage_tracking/usage_tracker.py +0 -0
  254. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/virtual_camera/__init__.py +0 -0
  255. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/weather/__init__.py +0 -0
  256. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/weather/weather_service.py +0 -0
  257. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/web_url.py +0 -0
  258. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/window_pin/__init__.py +0 -0
  259. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/window_pin/window_layout.py +0 -0
  260. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/window_pin/window_pin.py +0 -0
  261. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/workshop/__init__.py +0 -0
  262. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/utils/workshop/workshop_content.py +0 -0
  263. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/worker/__init__.py +0 -0
  264. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine/worker/qthread_worker.py +0 -0
  265. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine.egg-info/SOURCES.txt +0 -0
  266. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine.egg-info/dependency_links.txt +0 -0
  267. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine.egg-info/entry_points.txt +0 -0
  268. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine.egg-info/requires.txt +0 -0
  269. {frontengine-1.0.48 → frontengine-1.0.49}/frontengine.egg-info/top_level.txt +0 -0
  270. {frontengine-1.0.48 → frontengine-1.0.49}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frontengine
3
- Version: 1.0.48
3
+ Version: 1.0.49
4
4
  Summary: FrontEngine is use-define frontview or only use like screen saver
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/FrontEngine
@@ -13,10 +13,10 @@ stacks windows and not something to work around.
13
13
  """
14
14
  from __future__ import annotations
15
15
 
16
- from typing import Tuple
16
+ from typing import Any, Optional, Tuple
17
17
 
18
18
  from PySide6.QtCore import QPointF, Qt
19
- from PySide6.QtGui import QColor, QPainter, QPen
19
+ from PySide6.QtGui import QColor, QPainter, QPen, QScreen
20
20
 
21
21
  from frontengine.show.base_widget import BaseWidget
22
22
  from frontengine.utils.logging.loggin_instance import front_engine_logger
@@ -35,13 +35,13 @@ MIN_SIZE = 4
35
35
  MAX_SIZE = 200
36
36
 
37
37
 
38
- def normalize_style(style) -> str:
38
+ def normalize_style(style: Any) -> str:
39
39
  """把準星樣式正規化;不認得的一律當十字。"""
40
40
  name = str(style or "").strip().lower()
41
41
  return name if name in STYLES else STYLE_CROSS
42
42
 
43
43
 
44
- def clamp_size(value, fallback: int = DEFAULT_SIZE) -> int:
44
+ def clamp_size(value: Any, fallback: int = DEFAULT_SIZE) -> int:
45
45
  """準星尺寸夾在看得見又不誇張的範圍。"""
46
46
  try:
47
47
  return max(MIN_SIZE, min(MAX_SIZE, int(value)))
@@ -49,7 +49,7 @@ def clamp_size(value, fallback: int = DEFAULT_SIZE) -> int:
49
49
  return fallback
50
50
 
51
51
 
52
- def clamp_thickness(value, fallback: int = DEFAULT_THICKNESS) -> int:
52
+ def clamp_thickness(value: Any, fallback: int = DEFAULT_THICKNESS) -> int:
53
53
  """線寬夾在 1~12。"""
54
54
  try:
55
55
  return max(1, min(12, int(value)))
@@ -57,7 +57,7 @@ def clamp_thickness(value, fallback: int = DEFAULT_THICKNESS) -> int:
57
57
  return fallback
58
58
 
59
59
 
60
- def clamp_gap(value, size: int = DEFAULT_SIZE, fallback: int = DEFAULT_GAP) -> int:
60
+ def clamp_gap(value: Any, size: int = DEFAULT_SIZE, fallback: int = DEFAULT_GAP) -> int:
61
61
  """
62
62
  中央空隙不能大到把準星吃光,所以上限跟著尺寸走。
63
63
  The centre gap cannot swallow the crosshair, so its ceiling follows the size.
@@ -100,7 +100,8 @@ class CrosshairWidget(BaseWidget):
100
100
  self.opacity = 1.0
101
101
  self.resize(self.size * 2 + 8, self.size * 2 + 8)
102
102
 
103
- def set_crosshair(self, style=None, color=None, size=None,
103
+ def set_crosshair(self, style: Optional[str] = None, color: Optional[str] = None,
104
+ size: Optional[int] = None,
104
105
  thickness=None, gap=None) -> None:
105
106
  """一次改好幾項設定,改完立刻重畫。"""
106
107
  if style is not None:
@@ -119,7 +120,7 @@ class CrosshairWidget(BaseWidget):
119
120
  self.centre_on_screen()
120
121
  self.update()
121
122
 
122
- def centre_on_screen(self, screen=None) -> None:
123
+ def centre_on_screen(self, screen: Optional[QScreen] = None) -> None:
123
124
  """擺到螢幕正中央(準星要對準的是畫面中心)。"""
124
125
  from PySide6.QtGui import QGuiApplication
125
126
 
@@ -12,7 +12,7 @@ and it stops at the last line rather than snapping back to the top mid-read.
12
12
  """
13
13
  from __future__ import annotations
14
14
 
15
- from typing import List, Optional
15
+ from typing import Any, List, Optional
16
16
 
17
17
  from PySide6.QtCore import Qt, QTimer
18
18
  from PySide6.QtGui import QColor, QFont, QFontMetrics, QPainter, QTransform
@@ -31,7 +31,7 @@ _TICK_MS = 33
31
31
  _SIDE_MARGIN = 40
32
32
 
33
33
 
34
- def clamp_speed(value, fallback: int = DEFAULT_SPEED) -> int:
34
+ def clamp_speed(value: Any, fallback: int = DEFAULT_SPEED) -> int:
35
35
  """捲動速度夾在讀得完又跟得上的範圍。"""
36
36
  try:
37
37
  return max(MIN_SPEED, min(MAX_SPEED, int(value)))
@@ -39,7 +39,7 @@ def clamp_speed(value, fallback: int = DEFAULT_SPEED) -> int:
39
39
  return fallback
40
40
 
41
41
 
42
- def clamp_font_size(value, fallback: int = DEFAULT_FONT_SIZE) -> int:
42
+ def clamp_font_size(value: Any, fallback: int = DEFAULT_FONT_SIZE) -> int:
43
43
  """字級夾在看得見的範圍。"""
44
44
  try:
45
45
  return max(MIN_FONT_SIZE, min(MAX_FONT_SIZE, int(value)))
@@ -2,7 +2,7 @@ import os
2
2
  import sys
3
3
  from os import getcwd
4
4
  from pathlib import Path
5
- from typing import Dict, Optional, Type
5
+ from typing import Any, Dict, Optional, Type
6
6
 
7
7
  from PySide6.QtCore import QByteArray, QTimer, QCoreApplication
8
8
  from PySide6.QtGui import QIcon, Qt
@@ -74,6 +74,20 @@ from frontengine.utils.theme_schedule.theme_schedule_service import ThemeSchedul
74
74
  FrontEngine_EXTEND_TAB: Dict[str, Type[QWidget]] = {}
75
75
 
76
76
 
77
+ def tray_can_restore_window(window: Any) -> bool:
78
+ """
79
+ 系統匣能不能把主視窗叫回來。任何「把主視窗藏起來」的功能都得先問這件事,
80
+ 不然藏掉的就是唯一能把該功能關掉的畫面。
81
+ Whether the tray can bring the main window back. Anything that hides the
82
+ window has to ask first: otherwise what it hides is the only screen that
83
+ can turn that same thing off.
84
+ """
85
+ tray = getattr(window, "system_tray", None)
86
+ return bool(ExtendSystemTray.isSystemTrayAvailable()
87
+ and getattr(window, "show_system_tray_ray", False)
88
+ and tray is not None and tray.isVisible())
89
+
90
+
77
91
  class FrontEngineMainUI(QMainWindow):
78
92
  """
79
93
  FrontEngine 主視窗
@@ -321,9 +335,10 @@ class FrontEngineMainUI(QMainWindow):
321
335
  """
322
336
  sources = (
323
337
  (self.screen_care_setting_ui, ("filter_widget_list", "ruler_widget_list",
324
- "break_overlay_list")),
338
+ "break_overlay_list", "color_vision_widget_list")),
325
339
  (self.presentation_setting_ui, ("annotation_widget_list", "cursor_widget_list",
326
- "keystroke_widget_list", "magnifier_widget_list")),
340
+ "keystroke_widget_list", "magnifier_widget_list",
341
+ "whiteboard_widget_list")),
327
342
  (self.focus_setting_ui, ("dim_widget_list", "mask_widget_list")),
328
343
  )
329
344
  for page, attributes in sources:
@@ -334,6 +349,12 @@ class FrontEngineMainUI(QMainWindow):
334
349
  # The wallpaper page keys its widgets by monitor, so hand over the values.
335
350
  self.control_center_ui.register_overlay_source(
336
351
  lambda: list(self.wallpaper_setting_ui.wallpaper_widgets.values()))
352
+ self.control_center_ui.register_overlay_source(
353
+ lambda: getattr(self.web_setting_ui, "dashboard_widgets", []))
354
+ # 批次關閉之後,沒有覆蓋層在聽就把全域輸入監聽收掉
355
+ # After a batch close nothing is listening, so drop the global input hook.
356
+ self.control_center_ui.register_cleanup(
357
+ self.presentation_setting_ui.release_input_watch)
337
358
  for attribute in ("spectrum_widget_list", "monitor_widget_list",
338
359
  "now_playing_widget_list", "note_widget_list"):
339
360
  self.control_center_ui.register_overlay_source(
@@ -518,12 +539,28 @@ class FrontEngineMainUI(QMainWindow):
518
539
  self._handle_hotkey(action)
519
540
 
520
541
  def start_signage(self) -> Optional[str]:
521
- """開始輪播;設定要求的話也把主視窗收起來。"""
542
+ """開始輪播;設定要求、而且托盤能把視窗叫回來時才收起主視窗。"""
522
543
  first = self.signage_service.start()
523
544
  if first is not None and current_signage_settings().get("hide_window", True):
524
- self.hide()
545
+ self._hide_for_signage()
525
546
  return first
526
547
 
548
+ def _hide_for_signage(self) -> None:
549
+ """
550
+ 收起主視窗——但只在系統匣真的能把它叫回來的時候。沒有系統匣就等於
551
+ 把唯一能關掉輪播的畫面藏起來,重開也只會再被藏一次,使用者就只能去
552
+ 手動改設定檔了。
553
+ Put the main window away - but only when the tray can actually bring it
554
+ back. Without a tray this would hide the only screen that can turn the
555
+ rotation off, and restarting just hides it again, leaving the settings
556
+ file as the only way out.
557
+ """
558
+ if tray_can_restore_window(self):
559
+ self.hide()
560
+ return
561
+ front_engine_logger.info(
562
+ "[FrontEngineMainUI] signage kept the window visible: no tray to restore it from")
563
+
527
564
  def stop_signage(self) -> None:
528
565
  """停止輪播並把主視窗放回來。"""
529
566
  self.signage_service.stop()
@@ -1,3 +1,5 @@
1
+ from typing import Callable
2
+
1
3
  from PySide6.QtCore import QTimer, Qt
2
4
  from PySide6.QtWidgets import (
3
5
  QComboBox, QGridLayout, QLabel, QPushButton, QScrollArea, QTextEdit, QWidget,
@@ -93,6 +95,7 @@ class ControlCenterUI(QWidget):
93
95
  # 其他分頁登記進來的覆蓋層來源(桌布、專注、護眼、簡報…)
94
96
  # Overlay sources registered by the other pages: wallpaper, focus, screen care, presenting.
95
97
  self._extra_overlay_sources: list = []
98
+ self._cleanup_callbacks: list = []
96
99
  self.low_power_button = self._create_button(
97
100
  "control_center_low_power_on", self.toggle_low_power)
98
101
  self._hidden_from_capture = False
@@ -190,19 +193,29 @@ class ControlCenterUI(QWidget):
190
193
  self.scene_setting_ui.close_scene()
191
194
 
192
195
  def clear_all(self) -> None:
196
+ """
197
+ 關閉所有覆蓋層。先真的 close() 再清空清單:close() 會跑到 closeEvent,
198
+ 計時器、媒體、全域監聽才停得掉;只丟掉 Python 參考做不到這件事,而且
199
+ 對「其他分頁註冊進來的」覆蓋層根本沒作用——它們會留在螢幕上。
200
+ Close every overlay. Actually call close() before emptying the lists:
201
+ that runs closeEvent, which is what stops timers, releases media and
202
+ drops global listeners. Merely dropping a Python reference does none of
203
+ that, and for the overlays other pages registered it did nothing at all
204
+ - they stayed on screen.
205
+ """
193
206
  front_engine_logger.info("ControlCenterUI clear_all")
194
- self.video_setting_ui.video_widget_list.clear()
195
- self.image_setting_ui.image_widget_list.clear()
196
- self.web_setting_ui.web_widget_list.clear()
197
- self.gif_setting_ui.gif_widget_list.clear()
198
- self.sound_player_setting_ui.sound_widget_list.clear()
199
- self.text_setting_ui.text_widget_list.clear()
200
- self.particle_setting_ui.particle_list.clear()
201
- if self.pet_setting_ui is not None:
202
- self.pet_setting_ui.pet_list.clear()
207
+ self._for_each_overlay(lambda widget: widget.close())
208
+ for widget_list in self._all_overlay_widget_lists():
209
+ widget_list.clear()
203
210
  self.scene_setting_ui.close_scene()
211
+ for callback in self._cleanup_callbacks:
212
+ try:
213
+ callback()
214
+ except Exception as error:
215
+ front_engine_logger.warning(
216
+ f"[ControlCenterUI] cleanup failed: {error!r}")
204
217
 
205
- def register_overlay_source(self, provider) -> None:
218
+ def register_overlay_source(self, provider: Callable[[], list]) -> None:
206
219
  """
207
220
  讓控制中心也管得到其他分頁開的覆蓋層。provider 是一個回傳 widget 清單
208
221
  的函式(每次都重新問,才拿得到當下還活著的那些)。
@@ -212,6 +225,16 @@ class ControlCenterUI(QWidget):
212
225
  """
213
226
  self._extra_overlay_sources.append(provider)
214
227
 
228
+ def register_cleanup(self, callback: Callable[[], None]) -> None:
229
+ """
230
+ 批次關閉之後要順手收掉的東西。例如全域輸入監聽:覆蓋層都關掉了就
231
+ 沒有東西需要它,繼續掛著只是白吃資源。
232
+ Something to release after a batch close - a global input listener,
233
+ say: with every overlay gone nothing needs it, and leaving it hooked
234
+ just costs for nothing.
235
+ """
236
+ self._cleanup_callbacks.append(callback)
237
+
215
238
  def _all_overlay_widget_lists(self) -> list:
216
239
  """回傳所有覆蓋層 widget 清單 / All overlay widget lists."""
217
240
  lists = [
@@ -231,11 +254,15 @@ class ControlCenterUI(QWidget):
231
254
  except Exception as error: # pragma: no cover - defensive boundary
232
255
  front_engine_logger.warning(f"[ControlCenterUI] overlay source failed: {error!r}")
233
256
  continue
257
+ # 交回原本的清單物件(不是複本),死掉的參考才清得掉、
258
+ # 「全部關閉」也才真的能把它們清空。
259
+ # Hand back the provider's own list rather than a copy, so pruning
260
+ # a dead reference - and closing everything - reaches the real one.
234
261
  if widgets:
235
- lists.append(list(widgets))
262
+ lists.append(widgets if isinstance(widgets, list) else list(widgets))
236
263
  return lists
237
264
 
238
- def _for_each_overlay(self, action) -> None:
265
+ def _for_each_overlay(self, action: Callable[[QWidget], None]) -> None:
239
266
  """
240
267
  對每個仍存活的覆蓋層 widget 執行 action(widget)。手動關閉的覆蓋層因
241
268
  WA_DeleteOnClose 已被銷毀,其 Python 參考仍留在清單中,呼叫時會
@@ -6,7 +6,7 @@ The presentation page: screen annotation, cursor emphasis (ring, click ripple,
6
6
  spotlight), a keystroke display and a region magnifier. Everything except the
7
7
  annotation layer passes clicks straight through.
8
8
  """
9
- from typing import List
9
+ from typing import List, Optional
10
10
 
11
11
  from PySide6.QtCore import Qt
12
12
  from PySide6.QtGui import QGuiApplication
@@ -181,7 +181,8 @@ class PresentationSettingUI(QWidget):
181
181
  if self.keystroke_widget_list or self.cursor_widget_list:
182
182
  self.input_watch.start()
183
183
 
184
- def _release_input_watch(self) -> None:
184
+ def release_input_watch(self) -> None:
185
+ """沒有覆蓋層要聽了就收掉全域輸入監聽(批次關閉之後也會呼叫)。"""
185
186
  if not self.keystroke_widget_list and not self.cursor_widget_list:
186
187
  self.input_watch.stop()
187
188
 
@@ -250,7 +251,7 @@ class PresentationSettingUI(QWidget):
250
251
 
251
252
  def stop_cursor_effects(self) -> None:
252
253
  self._close_all(self.cursor_widget_list)
253
- self._release_input_watch()
254
+ self.release_input_watch()
254
255
  self.cursor_button.setText(
255
256
  language_wrapper.language_word_dict.get("cursor_effect_start", "Turn cursor effects on"))
256
257
 
@@ -285,7 +286,7 @@ class PresentationSettingUI(QWidget):
285
286
 
286
287
  def stop_keystrokes(self) -> None:
287
288
  self._close_all(self.keystroke_widget_list)
288
- self._release_input_watch()
289
+ self.release_input_watch()
289
290
  self.keystroke_button.setText(
290
291
  language_wrapper.language_word_dict.get("keystroke_start", "Show keystrokes"))
291
292
 
@@ -341,7 +342,6 @@ class PresentationSettingUI(QWidget):
341
342
  except RuntimeError:
342
343
  self.magnifier_widget_list.remove(widget)
343
344
 
344
- # --- preset state ----------------------------------------------------
345
345
  # --- whiteboard ------------------------------------------------------
346
346
  def toggle_whiteboard(self) -> None:
347
347
  if self.whiteboard_widget_list:
@@ -364,7 +364,7 @@ class PresentationSettingUI(QWidget):
364
364
  self.whiteboard_button.setText(
365
365
  language_wrapper.language_word_dict.get("whiteboard_start", "Whiteboard"))
366
366
 
367
- def save_whiteboard(self):
367
+ def save_whiteboard(self) -> Optional[str]:
368
368
  """把白板存成圖片;沒畫東西就不存。"""
369
369
  for board in self.whiteboard_widget_list[:]:
370
370
  try:
@@ -377,6 +377,7 @@ class PresentationSettingUI(QWidget):
377
377
  self.whiteboard_widget_list.remove(board)
378
378
  return None
379
379
 
380
+ # --- preset state ----------------------------------------------------
380
381
  def get_state(self) -> dict:
381
382
  return {
382
383
  "annotate_tool": self.annotate_tool_combobox.currentData(),
@@ -24,7 +24,7 @@ import secrets
24
24
  import socket
25
25
  import threading
26
26
  from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
27
- from typing import Any, Dict, List, Optional, Tuple
27
+ from typing import Any, Dict, Optional, Tuple
28
28
  from urllib.parse import parse_qs, urlparse
29
29
 
30
30
  from PySide6.QtCore import QObject, Signal
@@ -138,7 +138,6 @@ class RemoteServer(QObject):
138
138
  self._on_action = on_action
139
139
  self._server: Optional[ThreadingHTTPServer] = None
140
140
  self._thread: Optional[threading.Thread] = None
141
- self.received: List[str] = []
142
141
 
143
142
  @property
144
143
  def running(self) -> bool:
@@ -192,7 +191,6 @@ class RemoteServer(QObject):
192
191
  return 403
193
192
  if not is_allowed(action):
194
193
  return 400
195
- self.received.append(str(action))
196
194
  self.action_requested.emit(str(action))
197
195
  if self._on_action is not None:
198
196
  self._on_action(str(action))
@@ -22,10 +22,13 @@ determined attacker, and it never hides the window from the person at the desk.
22
22
  from __future__ import annotations
23
23
 
24
24
  import sys
25
- from typing import Optional
25
+ from typing import TYPE_CHECKING, Iterable, Optional
26
26
 
27
27
  from frontengine.utils.logging.loggin_instance import front_engine_logger
28
28
 
29
+ if TYPE_CHECKING: # 只為了型別標註,執行時不需要把 Qt 拉進這支純 ctypes 工具
30
+ from PySide6.QtWidgets import QWidget
31
+
29
32
  # WDA_NONE:正常擷取;WDA_EXCLUDEFROMCAPTURE:擷取時整片留白
30
33
  # WDA_NONE captures normally; WDA_EXCLUDEFROMCAPTURE comes out blank.
31
34
  WDA_NONE = 0x00000000
@@ -92,7 +95,7 @@ def is_excluded_from_capture(handle: int) -> Optional[bool]:
92
95
  return None
93
96
 
94
97
 
95
- def apply_to_widget(widget, excluded: bool) -> bool:
98
+ def apply_to_widget(widget: Optional[QWidget], excluded: bool) -> bool:
96
99
  """
97
100
  對一個 Qt widget 套用擷取可見性。視窗還沒建立原生 handle 時回傳 False,
98
101
  呼叫端可以等 show() 之後再試一次。
@@ -108,7 +111,7 @@ def apply_to_widget(widget, excluded: bool) -> bool:
108
111
  return set_excluded_from_capture(handle, excluded)
109
112
 
110
113
 
111
- def apply_to_widgets(widgets, excluded: bool) -> int:
114
+ def apply_to_widgets(widgets: Optional[Iterable[QWidget]], excluded: bool) -> int:
112
115
  """對一批 widget 套用,回傳成功的數量。"""
113
116
  applied = 0
114
117
  for widget in tuple(widgets or ()):
@@ -46,7 +46,7 @@ class VirtualCameraFeed(QObject):
46
46
  return None
47
47
  return screen.grabWindow(0, rect.x(), rect.y(), rect.width(), rect.height())
48
48
 
49
- def set_grabber(self, grabber) -> None:
49
+ def set_grabber(self, grabber: Optional[Callable[[QRect], Optional[QPixmap]]]) -> None:
50
50
  self._grabber = grabber or self._default_grabber
51
51
 
52
52
  def start(self, region: QRect, fps: int) -> bool:
@@ -15,7 +15,7 @@ False and the feature stays off; nothing is ever sent quietly.
15
15
  """
16
16
  from __future__ import annotations
17
17
 
18
- from typing import Optional, Tuple
18
+ from typing import Any, Optional, Tuple
19
19
 
20
20
  import numpy
21
21
 
@@ -47,7 +47,7 @@ def available() -> bool:
47
47
  return _module() is not None
48
48
 
49
49
 
50
- def clamp_fps(value, fallback: int = DEFAULT_FPS) -> int:
50
+ def clamp_fps(value: Any, fallback: int = DEFAULT_FPS) -> int:
51
51
  """每秒張數夾在驅動接受的範圍。"""
52
52
  try:
53
53
  return max(MIN_FPS, min(MAX_FPS, int(value)))
@@ -55,9 +55,9 @@ def clamp_fps(value, fallback: int = DEFAULT_FPS) -> int:
55
55
  return fallback
56
56
 
57
57
 
58
- def even_size(width, height) -> Tuple[int, int]:
58
+ def even_size(width: Any, height: Any) -> Tuple[int, int]:
59
59
  """把尺寸調成偶數且不小於 2x2。"""
60
- def fix(value, fallback):
60
+ def fix(value: Any, fallback: int) -> int:
61
61
  try:
62
62
  number = max(_SIZE_STEP, int(value))
63
63
  except (TypeError, ValueError):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frontengine
3
- Version: 1.0.48
3
+ Version: 1.0.49
4
4
  Summary: FrontEngine is use-define frontview or only use like screen saver
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/FrontEngine
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "frontengine"
9
- version = "1.0.48"
9
+ version = "1.0.49"
10
10
  authors = [
11
11
  { name = "JE-Chen", email = "jechenmailman@gmail.com" },
12
12
  ]
File without changes
File without changes