frontengine 1.0.66__tar.gz → 1.0.68__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.
- {frontengine-1.0.66 → frontengine-1.0.68}/PKG-INFO +1 -1
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/pet/desktop_pet.py +10 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/gif/gif_setting_ui.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/image/image_setting_ui.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/particle/particle_setting_ui.py +15 -2
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/pet/pet_setting_ui.py +70 -1
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/text/text_setting_ui.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/utils.py +57 -4
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/video/video_setting_ui.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/web/web_setting_ui.py +2 -0
- frontengine-1.0.68/frontengine/utils/input_watch/typing_watch.py +73 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/english.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/france.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/germany.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/italy.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/russian.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/simplified_chinese.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/traditional_chinese.py +2 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine.egg-info/PKG-INFO +1 -1
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine.egg-info/SOURCES.txt +1 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/pyproject.toml +1 -1
- {frontengine-1.0.66 → frontengine-1.0.68}/LICENSE +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/README.md +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/__main__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/base_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/camera/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/camera/camera_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/canvas/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/canvas/whiteboard_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/capture/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/capture/region_capture.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/focus_shield/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/focus_shield/focus_shield_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/gif/paint_gif.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/image/paint_image.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/load/load_someone_make_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/measure/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/measure/measure_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/monitor/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/monitor/monitor_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/notes/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/notes/sticky_note_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/overlay_factory.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/particle/particle_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/pet/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/presentation/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/presentation/annotation_overlay.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/presentation/cursor_effects.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/presentation/keystroke_display.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/presentation/magnifier.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/replica/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/replica/replica_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/scene/extend_graphic_scene.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/scene/extend_graphic_view.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/scene/scene.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/screen_care/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/screen_care/color_vision_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/screen_care/screen_filter.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/sound_player/sound_effect.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/sound_player/sound_player.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/spectrum/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/spectrum/spectrum_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/text/draw_text.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/toast/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/toast/toast_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/video/video_player.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/wallpaper/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/wallpaper/wallpaper_widget.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/web/webview.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/window_helpers.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/system_tray/extend_system_tray.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/color/global_color.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/app_profile_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/clipboard_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/how_to_use_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/reminder_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/remote_control_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/screen_privacy_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/screen_text_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/screensaver_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/signage_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/smart_pause_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/usage_report_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/window_pin_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/dialog/window_replica_dialog.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/main_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/menu/help_menu.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/menu/how_to_menu.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/menu/language_menu.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/menu/preset_menu.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/menu/settings_menu.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/nav/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/nav/sidebar.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/control_center/control_center_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/focus/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/focus/focus_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/layout_kit.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/pet/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/presentation/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/presentation/presentation_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/screen_care/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/screen_care/screen_care_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/tools/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/tools/tools_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/wallpaper/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/wallpaper/wallpaper_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/widgets/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/widgets/widgets_setting_ui.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/style/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/style/app_style.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/user_setting/preset_repository.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/user_setting/scene_setting.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/user_setting/user_setting_file.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/app_profile/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/app_profile/app_profile_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/audio_meter/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/audio_meter/audio_envelope.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/audio_meter/loopback_capture.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/audio_meter/microphone_meter.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/audio_meter/screen_audio.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/audio_meter/spectrum_analyzer.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/audio_meter/system_audio_meter.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/autostart/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/autostart/autostart_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/break_reminder/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/break_reminder/break_reminder.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/browser/browser.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/clipboard/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/clipboard/clipboard_history.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/clipboard/clipboard_watcher.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/color_vision/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/color_vision/color_vision.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/critical_exit/critical_exit.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/focus_shield/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/focus_shield/focus_shield.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/focus_timer/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/focus_timer/focus_timer.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/hotkey/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/hotkey/hotkey_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/input_watch/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/input_watch/input_watch_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/json/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/json/json_file.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/json/json_repository.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/logging/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/logging/loggin_instance.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/measure/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/measure/measure.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/midi/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/midi/midi_input.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/retranslate.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/now_playing/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/now_playing/now_playing.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/pet_chat/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/pet_chat/pet_chat_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/platform_info/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/platform_info/platform_info.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/playlist/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/playlist/playlist.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/plugins/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/plugins/plugin_loader.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/power_mode/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/power_mode/power_mode.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/preset_schedule/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/recording/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/recording/frame_recorder.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/recording/gif_writer.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/reminder/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/reminder/reminder_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/remote/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/remote/remote_server.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/screen_privacy/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/screen_privacy/capture_affinity.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/screen_privacy/share_watch.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/screen_text/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/screen_text/screen_text_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/screensaver/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/screensaver/screensaver_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/signage/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/signage/signage_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/smart_pause/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/smart_pause/pause_rules.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/steam/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/steam/steam_language.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/system_stats/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/system_stats/system_stats.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/text_source/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/text_source/text_source.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/theme_schedule/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/usage_tracking/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/usage_tracking/usage_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/usage_tracking/usage_tracker.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/virtual_camera/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/virtual_camera/camera_feed.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/virtual_camera/virtual_camera.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/weather/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/weather/weather_service.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/web_url.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/window_pin/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/window_pin/window_layout.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/window_pin/window_pin.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/window_replica/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/window_replica/dwm_thumbnail.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/workshop/__init__.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/workshop/workshop_content.py +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine.egg-info/entry_points.txt +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine.egg-info/requires.txt +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/frontengine.egg-info/top_level.txt +0 -0
- {frontengine-1.0.66 → frontengine-1.0.68}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.68
|
|
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
|
|
@@ -669,6 +669,9 @@ class PetMotion:
|
|
|
669
669
|
self.vx = float(self.speed)
|
|
670
670
|
self.vy = 0.0 if behaviour != BEHAVIOUR_WANDER else float(self.speed)
|
|
671
671
|
self._airborne = False
|
|
672
|
+
# 打字時安分下來:True 的時候 step() 原地不動。
|
|
673
|
+
# Settled while typing: step() stays put while this is True.
|
|
674
|
+
self.settled = False
|
|
672
675
|
self.state = "walk" # walk | idle | sleep
|
|
673
676
|
self._state_ticks = 0
|
|
674
677
|
self._idle_count = 0
|
|
@@ -784,6 +787,13 @@ class PetMotion:
|
|
|
784
787
|
self.follow_target_x = None
|
|
785
788
|
|
|
786
789
|
def step(self) -> Tuple[int, int]:
|
|
790
|
+
# 安分的時候原地不動。閘門放在這裡而不是各個行為分支裡:每個分支都要記得
|
|
791
|
+
# 檢查的話,總有一個會漏掉,而漏掉的那個就是打字時還在跑的那隻。
|
|
792
|
+
# Settled means staying put. The gate is here rather than inside each
|
|
793
|
+
# behaviour branch: with a check per branch one of them eventually gets
|
|
794
|
+
# missed, and the missed one is the pet still running about while you type.
|
|
795
|
+
if self.settled:
|
|
796
|
+
return int(self.x), int(self.y)
|
|
787
797
|
left, top, right, bottom = self.bounds
|
|
788
798
|
floor_y = bottom - self.height
|
|
789
799
|
if self.behaviour == BEHAVIOUR_CHASE:
|
|
@@ -14,6 +14,7 @@ from frontengine.ui.page.utils import (
|
|
|
14
14
|
enable_file_drop,
|
|
15
15
|
reload_recent_combobox,
|
|
16
16
|
resolve_preferred_monitor,
|
|
17
|
+
resolve_span,
|
|
17
18
|
show_on_primary_screen,
|
|
18
19
|
show_on_selected_monitor,
|
|
19
20
|
)
|
|
@@ -133,6 +134,7 @@ class GIFSettingUI(SettingPage):
|
|
|
133
134
|
widget, self.fullscreen_checkbox, monitor
|
|
134
135
|
),
|
|
135
136
|
preferred_monitor_index=resolve_preferred_monitor(self.target_monitor_combobox),
|
|
137
|
+
span_all_screens=resolve_span(self.target_monitor_combobox),
|
|
136
138
|
)
|
|
137
139
|
|
|
138
140
|
def choose_and_copy_file_to_cwd_gif_dir_then_play(self) -> None:
|
|
@@ -17,6 +17,7 @@ from frontengine.ui.page.utils import (
|
|
|
17
17
|
list_media_files,
|
|
18
18
|
reload_recent_combobox,
|
|
19
19
|
resolve_preferred_monitor,
|
|
20
|
+
resolve_span,
|
|
20
21
|
show_on_primary_screen,
|
|
21
22
|
show_on_selected_monitor,
|
|
22
23
|
)
|
|
@@ -155,6 +156,7 @@ class ImageSettingUI(SettingPage):
|
|
|
155
156
|
widget, self.fullscreen_checkbox, monitor
|
|
156
157
|
),
|
|
157
158
|
preferred_monitor_index=resolve_preferred_monitor(self.target_monitor_combobox),
|
|
159
|
+
span_all_screens=resolve_span(self.target_monitor_combobox),
|
|
158
160
|
)
|
|
159
161
|
if slideshow:
|
|
160
162
|
self._slideshow_timer.start(self._slideshow_interval_ms())
|
{frontengine-1.0.66 → frontengine-1.0.68}/frontengine/ui/page/particle/particle_setting_ui.py
RENAMED
|
@@ -15,6 +15,8 @@ from frontengine.ui.page.utils import (
|
|
|
15
15
|
enable_file_drop,
|
|
16
16
|
reload_recent_combobox,
|
|
17
17
|
resolve_preferred_monitor,
|
|
18
|
+
resolve_span,
|
|
19
|
+
virtual_desktop_geometry,
|
|
18
20
|
)
|
|
19
21
|
from frontengine.user_setting.user_setting_file import add_recent_file
|
|
20
22
|
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
@@ -149,9 +151,19 @@ class ParticleSettingUI(SettingPage):
|
|
|
149
151
|
message_box.exec()
|
|
150
152
|
return
|
|
151
153
|
|
|
154
|
+
span = resolve_span(self.target_monitor_combobox)
|
|
155
|
+
|
|
152
156
|
def factory(monitor):
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
# 粒子場的大小在建構時就固定了,所以橫跨模式必須拿整個桌面的尺寸來建,
|
|
158
|
+
# 不能建成單一螢幕大小再把視窗拉寬——那樣粒子只會落在其中一塊。
|
|
159
|
+
# The particle field is sized at construction, so spanning has to
|
|
160
|
+
# build it at the whole-desktop size. Building it screen-sized and
|
|
161
|
+
# then widening the window would leave the particles in one corner.
|
|
162
|
+
if span:
|
|
163
|
+
geometry = virtual_desktop_geometry()
|
|
164
|
+
else:
|
|
165
|
+
target = monitor or QGuiApplication.primaryScreen()
|
|
166
|
+
geometry = target.availableGeometry()
|
|
155
167
|
return self._create_particle_widget(geometry.width(), geometry.height())
|
|
156
168
|
|
|
157
169
|
def present_on_monitor(widget: ParticleOpenGLWidget, monitor, _idx: int) -> None:
|
|
@@ -166,6 +178,7 @@ class ParticleSettingUI(SettingPage):
|
|
|
166
178
|
present_primary=lambda widget: widget.showMaximized(),
|
|
167
179
|
present_on_monitor=present_on_monitor,
|
|
168
180
|
preferred_monitor_index=resolve_preferred_monitor(self.target_monitor_combobox),
|
|
181
|
+
span_all_screens=resolve_span(self.target_monitor_combobox),
|
|
169
182
|
)
|
|
170
183
|
|
|
171
184
|
def choose_and_copy_file_to_cwd_image_dir_then_play(self) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
|
-
from PySide6.QtCore import QTimer
|
|
3
|
+
from PySide6.QtCore import Qt, QTimer
|
|
4
4
|
from PySide6.QtGui import QGuiApplication
|
|
5
5
|
from PySide6.QtWidgets import (
|
|
6
6
|
QLabel, QPushButton, QMessageBox, QComboBox, QCheckBox, QFileDialog,
|
|
@@ -28,6 +28,8 @@ from frontengine.utils.focus_timer.focus_timer import (
|
|
|
28
28
|
PHASE_BREAK, PHASE_FOCUS, PHASE_LONG_BREAK, FocusTimer,
|
|
29
29
|
)
|
|
30
30
|
from frontengine.ui.page.layout_kit import SettingPage
|
|
31
|
+
from frontengine.utils.input_watch.input_watch_service import InputWatchService
|
|
32
|
+
from frontengine.utils.input_watch.typing_watch import TypingWatch
|
|
31
33
|
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
32
34
|
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
33
35
|
from frontengine.utils.multi_language.retranslate import retranslator, tr
|
|
@@ -49,6 +51,14 @@ class PetSettingUI(SettingPage):
|
|
|
49
51
|
|
|
50
52
|
# Init variable
|
|
51
53
|
self.pet_list: list = []
|
|
54
|
+
# 打字時安分:按鍵由既有的全域監聽服務推過來,這裡只記時間並在停手後放行
|
|
55
|
+
# Settling while typing: keys come from the existing global watch
|
|
56
|
+
# service; this only times them and lets the pet go once typing stops.
|
|
57
|
+
self._typing_watch = TypingWatch()
|
|
58
|
+
self._input_watch: Optional[InputWatchService] = None
|
|
59
|
+
self._settle_timer = QTimer(self)
|
|
60
|
+
self._settle_timer.setSingleShot(True)
|
|
61
|
+
self._settle_timer.timeout.connect(lambda: self._apply_settled(False))
|
|
52
62
|
self.ready_to_play = False
|
|
53
63
|
self.pet_image_path: Optional[str] = None
|
|
54
64
|
self.pet_sound_path: Optional[str] = None
|
|
@@ -106,6 +116,13 @@ class PetSettingUI(SettingPage):
|
|
|
106
116
|
self.sit_checkbox.setChecked(True)
|
|
107
117
|
self.tag_checkbox = tr(QCheckBox(), "pet_tag_label", "Play tag with each other")
|
|
108
118
|
self.tag_checkbox.toggled.connect(self._on_tag_toggled)
|
|
119
|
+
# 打字時安分:寵物在螢幕上跑過你正在看的那一行,是最常被抱怨的一點。
|
|
120
|
+
# Settle while typing: a pet walking over the line you are reading is
|
|
121
|
+
# the single thing people complain about most.
|
|
122
|
+
self.settle_typing_checkbox = tr(QCheckBox(), "pet_settle_typing",
|
|
123
|
+
"Settle while typing")
|
|
124
|
+
self.settle_typing_checkbox.clicked.connect(self._on_settle_typing_toggled)
|
|
125
|
+
|
|
109
126
|
self.speech_checkbox = tr(QCheckBox(), "pet_speech_label", "Speak out loud")
|
|
110
127
|
self.chat_checkbox = tr(QCheckBox(), "pet_chat_label", "AI chat (needs API key)")
|
|
111
128
|
self.chat_checkbox.setToolTip(
|
|
@@ -169,6 +186,7 @@ class PetSettingUI(SettingPage):
|
|
|
169
186
|
behaviour = self.add_section("section_behaviour", "Behaviour")
|
|
170
187
|
behaviour.add_row(self.behaviour_label, self.behaviour_combobox)
|
|
171
188
|
behaviour.add_inline(self.climb_checkbox, self.sit_checkbox)
|
|
189
|
+
behaviour.add_inline(self.settle_typing_checkbox)
|
|
172
190
|
|
|
173
191
|
sound = self.add_section("section_options", "Sound and speech")
|
|
174
192
|
sound.add_row(self.volume_label, self.volume_combobox)
|
|
@@ -189,6 +207,54 @@ class PetSettingUI(SettingPage):
|
|
|
189
207
|
self.finish_body()
|
|
190
208
|
self.set_footer(primary=self.start_button, status=self.ready_label)
|
|
191
209
|
|
|
210
|
+
def _start_typing_watch(self) -> bool:
|
|
211
|
+
"""開始監聽按鍵(只在第一次需要時建立)。pynput 不能用時安靜跳過。"""
|
|
212
|
+
if self._input_watch is None:
|
|
213
|
+
self._input_watch = InputWatchService(self)
|
|
214
|
+
# 按鍵在 pynput 自己的執行緒觸發,一定要排回 UI 執行緒才能碰 widget。
|
|
215
|
+
# Keys fire on pynput's own thread; this has to hop to the UI thread
|
|
216
|
+
# before touching any widget.
|
|
217
|
+
self._input_watch.key_pressed.connect(
|
|
218
|
+
self._on_key_pressed, Qt.ConnectionType.QueuedConnection)
|
|
219
|
+
# start() 本身是冪等的:已經在監聽時再呼叫不會多開一個 listener。
|
|
220
|
+
# start() is idempotent: calling it again does not add a second listener.
|
|
221
|
+
return self._input_watch.start(keyboard=True, mouse=False)
|
|
222
|
+
|
|
223
|
+
def _stop_typing_watch(self) -> None:
|
|
224
|
+
"""停止監聽並讓所有寵物恢復走動。"""
|
|
225
|
+
self._settle_timer.stop()
|
|
226
|
+
self._typing_watch.clear()
|
|
227
|
+
if self._input_watch is not None:
|
|
228
|
+
self._input_watch.stop()
|
|
229
|
+
self._apply_settled(False)
|
|
230
|
+
|
|
231
|
+
def _on_settle_typing_toggled(self) -> None:
|
|
232
|
+
if self.settle_typing_checkbox.isChecked():
|
|
233
|
+
if self.pet_list:
|
|
234
|
+
self._start_typing_watch()
|
|
235
|
+
else:
|
|
236
|
+
# 關掉時一定要放行。少了這一步,剛好在打字時關掉這個選項的寵物會
|
|
237
|
+
# 永遠停在原地——看起來就是寵物壞了。
|
|
238
|
+
# Releasing on the way out matters: switched off mid-keystroke
|
|
239
|
+
# without it, the pet stays frozen for good and simply looks broken.
|
|
240
|
+
self._stop_typing_watch()
|
|
241
|
+
|
|
242
|
+
def _on_key_pressed(self, _keys) -> None:
|
|
243
|
+
"""有人按了鍵:寵物先停下來,停手一段時間後再放行。"""
|
|
244
|
+
if not self.settle_typing_checkbox.isChecked():
|
|
245
|
+
return
|
|
246
|
+
self._typing_watch.note_key()
|
|
247
|
+
self._apply_settled(True)
|
|
248
|
+
self._settle_timer.start(int(self._typing_watch.settle_seconds * 1000))
|
|
249
|
+
|
|
250
|
+
def _apply_settled(self, settled: bool) -> None:
|
|
251
|
+
"""把安分狀態套到目前所有寵物身上。"""
|
|
252
|
+
for pet in self.pet_list[:]:
|
|
253
|
+
try:
|
|
254
|
+
pet.motion.settled = settled
|
|
255
|
+
except RuntimeError: # pragma: no cover - 底層物件已消失
|
|
256
|
+
continue
|
|
257
|
+
|
|
192
258
|
def _spawn_pet(self) -> None:
|
|
193
259
|
"""建立、顯示並開始移動一隻寵物(供 Start 與右鍵複製共用)。"""
|
|
194
260
|
if not self.pet_image_path:
|
|
@@ -215,6 +281,9 @@ class PetSettingUI(SettingPage):
|
|
|
215
281
|
if self.audio_react_checkbox.isChecked():
|
|
216
282
|
pet.set_audio_level_provider(self._audio_provider(geometry))
|
|
217
283
|
pet.set_pet_window_flag()
|
|
284
|
+
if self.settle_typing_checkbox.isChecked():
|
|
285
|
+
pet.motion.settled = self._typing_watch.typing()
|
|
286
|
+
self._start_typing_watch()
|
|
218
287
|
self.pet_list.append(pet)
|
|
219
288
|
pet.show()
|
|
220
289
|
self._start_tag_game()
|
|
@@ -14,6 +14,7 @@ from frontengine.ui.page.utils import (
|
|
|
14
14
|
build_target_monitor_combobox,
|
|
15
15
|
dispatch_to_monitors,
|
|
16
16
|
resolve_preferred_monitor,
|
|
17
|
+
resolve_span,
|
|
17
18
|
)
|
|
18
19
|
from frontengine.ui.page.layout_kit import SettingPage
|
|
19
20
|
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
@@ -322,4 +323,5 @@ class TextSettingUI(SettingPage):
|
|
|
322
323
|
present_primary=lambda widget: widget.showFullScreen(),
|
|
323
324
|
present_on_monitor=present_on_monitor,
|
|
324
325
|
preferred_monitor_index=resolve_preferred_monitor(self.target_monitor_combobox),
|
|
326
|
+
span_all_screens=resolve_span(self.target_monitor_combobox),
|
|
325
327
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from typing import Callable, Optional
|
|
3
3
|
|
|
4
|
-
from PySide6.QtCore import QEvent, QObject
|
|
4
|
+
from PySide6.QtCore import QEvent, QObject, QRect
|
|
5
5
|
from PySide6.QtGui import QGuiApplication, QScreen
|
|
6
6
|
from PySide6.QtWidgets import QCheckBox, QComboBox, QDialog, QGridLayout, QLabel, QPushButton, QWidget
|
|
7
7
|
|
|
@@ -96,6 +96,8 @@ def dispatch_to_monitors(
|
|
|
96
96
|
present_primary: Callable[[QWidget], None],
|
|
97
97
|
present_on_monitor: Callable[[QWidget, QScreen, int], None],
|
|
98
98
|
preferred_monitor_index: Optional[int] = None,
|
|
99
|
+
span_all_screens: bool = False,
|
|
100
|
+
screens: Optional[list] = None,
|
|
99
101
|
) -> None:
|
|
100
102
|
"""
|
|
101
103
|
Run the canonical monitor-dispatch flow the setting pages share:
|
|
@@ -108,7 +110,21 @@ def dispatch_to_monitors(
|
|
|
108
110
|
monitor so the user is not prompted; out-of-range values fall back
|
|
109
111
|
to the prompt flow.
|
|
110
112
|
"""
|
|
111
|
-
monitors = QGuiApplication.screens()
|
|
113
|
+
monitors = QGuiApplication.screens() if screens is None else screens
|
|
114
|
+
|
|
115
|
+
# 橫跨模式:一個覆蓋層蓋滿整個桌面,而不是每個螢幕各一個。要放在最前面判斷,
|
|
116
|
+
# 因為它和「問使用者要哪一個螢幕」是互斥的——已經選了全部就沒什麼好問的。
|
|
117
|
+
# Spanning: one overlay over the whole desktop rather than one per screen.
|
|
118
|
+
# It is decided first because it rules out asking which screen to use: the
|
|
119
|
+
# user has already said all of them.
|
|
120
|
+
if span_all_screens and len(monitors) > 1:
|
|
121
|
+
widget = factory(None)
|
|
122
|
+
geometry = virtual_desktop_geometry(monitors)
|
|
123
|
+
widget.setGeometry(geometry)
|
|
124
|
+
widget.show()
|
|
125
|
+
widget.raise_()
|
|
126
|
+
return
|
|
127
|
+
|
|
112
128
|
if not show_all_screen and len(monitors) <= 1:
|
|
113
129
|
widget = factory(None)
|
|
114
130
|
present_primary(widget)
|
|
@@ -138,19 +154,56 @@ def dispatch_to_monitors(
|
|
|
138
154
|
present_on_monitor(widget, monitor, index)
|
|
139
155
|
|
|
140
156
|
|
|
141
|
-
|
|
157
|
+
# 「橫跨所有螢幕」在下拉選單裡用這個值標記,和「第 N 個螢幕」的整數區分開。
|
|
158
|
+
# The "span every screen" entry carries this instead of a monitor index.
|
|
159
|
+
SPAN_ALL_DATA = "span"
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def virtual_desktop_geometry(screens=None) -> QRect:
|
|
163
|
+
"""
|
|
164
|
+
所有螢幕聯集起來的矩形,也就是整個桌面的範圍。
|
|
165
|
+
|
|
166
|
+
橫跨模式要的是一個蓋滿這塊範圍的覆蓋層,而不是每個螢幕各一個。螢幕不一定排成
|
|
167
|
+
一直線也不一定同樣高,所以要用聯集而不是把寬度加起來。
|
|
168
|
+
The union of every screen: the whole desktop. Spanning wants one overlay
|
|
169
|
+
covering that, not one per screen. Screens are not necessarily in a row or
|
|
170
|
+
the same height, so this unites rather than summing widths.
|
|
171
|
+
"""
|
|
172
|
+
geometry = QRect()
|
|
173
|
+
for screen in (QGuiApplication.screens() if screens is None else screens):
|
|
174
|
+
geometry = geometry.united(screen.geometry())
|
|
175
|
+
return geometry
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def build_target_monitor_combobox(screens=None) -> QComboBox:
|
|
142
179
|
"""
|
|
143
180
|
Build a combobox listing the current monitors plus an initial "Ask"
|
|
144
181
|
entry. Selection "Ask" (data=None) preserves today's prompt flow;
|
|
145
182
|
selecting a monitor index pre-selects that screen.
|
|
183
|
+
|
|
184
|
+
多螢幕時多一個「橫跨所有螢幕」。只有一個螢幕時不提供——那和一般顯示完全一樣,
|
|
185
|
+
列出來只會讓人以為自己漏掉了什麼。
|
|
186
|
+
On a multi-monitor system there is also a "span every screen" entry. It is
|
|
187
|
+
not offered on a single screen, where it would do exactly what the normal
|
|
188
|
+
path does and only leave the user wondering what they missed.
|
|
146
189
|
"""
|
|
190
|
+
monitors = QGuiApplication.screens() if screens is None else screens
|
|
147
191
|
combobox = QComboBox()
|
|
148
192
|
combobox.addItem(language_wrapper.language_word_dict.get("target_monitor_ask", "Ask"), None)
|
|
149
|
-
for index, _ in enumerate(
|
|
193
|
+
for index, _ in enumerate(monitors):
|
|
150
194
|
combobox.addItem(str(index), index)
|
|
195
|
+
if len(monitors) > 1:
|
|
196
|
+
combobox.addItem(
|
|
197
|
+
language_wrapper.language_word_dict.get("target_monitor_span", "Span all screens"),
|
|
198
|
+
SPAN_ALL_DATA)
|
|
151
199
|
return combobox
|
|
152
200
|
|
|
153
201
|
|
|
202
|
+
def resolve_span(combobox: Optional[QComboBox]) -> bool:
|
|
203
|
+
"""使用者是不是選了「橫跨所有螢幕」。"""
|
|
204
|
+
return combobox is not None and combobox.currentData() == SPAN_ALL_DATA
|
|
205
|
+
|
|
206
|
+
|
|
154
207
|
def resolve_preferred_monitor(combobox: Optional[QComboBox]) -> Optional[int]:
|
|
155
208
|
"""Return the selected monitor index, or None for the Ask entry."""
|
|
156
209
|
if combobox is None:
|
|
@@ -14,6 +14,7 @@ from frontengine.ui.page.utils import (
|
|
|
14
14
|
enable_file_drop,
|
|
15
15
|
reload_recent_combobox,
|
|
16
16
|
resolve_preferred_monitor,
|
|
17
|
+
resolve_span,
|
|
17
18
|
show_on_primary_screen,
|
|
18
19
|
show_on_selected_monitor,
|
|
19
20
|
)
|
|
@@ -154,6 +155,7 @@ class VideoSettingUI(SettingPage):
|
|
|
154
155
|
present_primary=lambda widget: show_on_primary_screen(widget, self.fullscreen_checkbox),
|
|
155
156
|
present_on_monitor=present_on_monitor,
|
|
156
157
|
preferred_monitor_index=resolve_preferred_monitor(self.target_monitor_combobox),
|
|
158
|
+
span_all_screens=resolve_span(self.target_monitor_combobox),
|
|
157
159
|
)
|
|
158
160
|
|
|
159
161
|
def choose_and_copy_file_to_cwd_video_dir_then_play(self) -> None:
|
|
@@ -12,6 +12,7 @@ from frontengine.ui.page.utils import (
|
|
|
12
12
|
build_target_monitor_combobox,
|
|
13
13
|
dispatch_to_monitors,
|
|
14
14
|
resolve_preferred_monitor,
|
|
15
|
+
resolve_span,
|
|
15
16
|
)
|
|
16
17
|
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
17
18
|
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
@@ -303,4 +304,5 @@ class WEBSettingUI(SettingPage):
|
|
|
303
304
|
present_primary=lambda widget: widget.showFullScreen(),
|
|
304
305
|
present_on_monitor=present_on_monitor,
|
|
305
306
|
preferred_monitor_index=resolve_preferred_monitor(self.target_monitor_combobox),
|
|
307
|
+
span_all_screens=resolve_span(self.target_monitor_combobox),
|
|
306
308
|
)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
「使用者正在打字嗎」——用來讓桌寵在打字時安分下來。
|
|
3
|
+
|
|
4
|
+
桌寵在螢幕上到處跑,是打字時最常被抱怨的一點:牠正好跑過你在看的那一行。這裡只
|
|
5
|
+
記住最後一次按鍵的時間,讓呼叫端問「現在算不算在打字」。
|
|
6
|
+
|
|
7
|
+
時鐘可以注入,所以測試不必真的等兩秒。
|
|
8
|
+
|
|
9
|
+
"Is the user typing?" - so the desktop pet can settle down while they are.
|
|
10
|
+
|
|
11
|
+
A pet wandering across the screen is the thing people complain about most while
|
|
12
|
+
typing: it walks over the line you are reading. This only remembers when the last
|
|
13
|
+
key went down and lets the caller ask whether that counts as typing now.
|
|
14
|
+
|
|
15
|
+
The clock is injectable, so tests do not wait two seconds.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import time
|
|
20
|
+
from typing import Any, Callable, Optional
|
|
21
|
+
|
|
22
|
+
DEFAULT_SETTLE_SECONDS = 2.0
|
|
23
|
+
MIN_SETTLE_SECONDS = 0.5
|
|
24
|
+
MAX_SETTLE_SECONDS = 30.0
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def clamp_settle_seconds(value: Any, fallback: float = DEFAULT_SETTLE_SECONDS) -> float:
|
|
28
|
+
"""安分的持續時間夾在 0.5 到 30 秒。"""
|
|
29
|
+
try:
|
|
30
|
+
return max(MIN_SETTLE_SECONDS, min(MAX_SETTLE_SECONDS, float(value)))
|
|
31
|
+
except (TypeError, ValueError):
|
|
32
|
+
return fallback
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TypingWatch:
|
|
36
|
+
"""
|
|
37
|
+
記住最後一次按鍵的時間,回答「現在還算在打字嗎」。
|
|
38
|
+
|
|
39
|
+
用單調時鐘而不是牆上時鐘:系統時間被調整(校時、換時區)時,牆上時鐘會讓
|
|
40
|
+
「距離上次按鍵幾秒」變成負數或一大跳,寵物就會莫名其妙卡住或突然衝出去。
|
|
41
|
+
Remembers when the last key went down and answers whether that still counts
|
|
42
|
+
as typing.
|
|
43
|
+
|
|
44
|
+
On a monotonic clock rather than the wall clock: when the system time is
|
|
45
|
+
adjusted - an NTP step, a timezone change - a wall clock makes "seconds since
|
|
46
|
+
the last key" negative or wildly large, and the pet either freezes for no
|
|
47
|
+
reason or bolts.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self, settle_seconds: Any = DEFAULT_SETTLE_SECONDS,
|
|
51
|
+
clock: Callable[[], float] = time.monotonic) -> None:
|
|
52
|
+
self.settle_seconds = clamp_settle_seconds(settle_seconds)
|
|
53
|
+
self._clock = clock
|
|
54
|
+
self._last_key: Optional[float] = None
|
|
55
|
+
|
|
56
|
+
def note_key(self) -> None:
|
|
57
|
+
"""記下這一刻有人按了鍵。"""
|
|
58
|
+
self._last_key = self._clock()
|
|
59
|
+
|
|
60
|
+
def clear(self) -> None:
|
|
61
|
+
"""忘掉先前的按鍵(功能關掉時用,免得寵物停在原地不動)。"""
|
|
62
|
+
self._last_key = None
|
|
63
|
+
|
|
64
|
+
def seconds_since_key(self) -> Optional[float]:
|
|
65
|
+
"""距離上次按鍵幾秒;還沒按過就是 None。"""
|
|
66
|
+
if self._last_key is None:
|
|
67
|
+
return None
|
|
68
|
+
return max(0.0, self._clock() - self._last_key)
|
|
69
|
+
|
|
70
|
+
def typing(self) -> bool:
|
|
71
|
+
"""現在算不算在打字。"""
|
|
72
|
+
elapsed = self.seconds_since_key()
|
|
73
|
+
return elapsed is not None and elapsed < self.settle_seconds
|
|
@@ -46,6 +46,8 @@ english_word_dict = {
|
|
|
46
46
|
"tools_shape": "Shape",
|
|
47
47
|
"tools_name": "Name",
|
|
48
48
|
"tools_saved": "Saved",
|
|
49
|
+
"pet_settle_typing": "Settle while typing",
|
|
50
|
+
"target_monitor_span": "Span all screens",
|
|
49
51
|
"tools_replicate_window": "Replicate a window...",
|
|
50
52
|
"window_replica_title": "Replicate a window",
|
|
51
53
|
"window_replica_refresh": "Refresh",
|
|
@@ -47,6 +47,8 @@ french_word_dict = {
|
|
|
47
47
|
"tools_shape": "Forme",
|
|
48
48
|
"tools_name": "Nom",
|
|
49
49
|
"tools_saved": "Enregistrés",
|
|
50
|
+
"pet_settle_typing": "Rester tranquille pendant la frappe",
|
|
51
|
+
"target_monitor_span": "Sur tous les écrans",
|
|
50
52
|
"tools_replicate_window": "Dupliquer une fenêtre...",
|
|
51
53
|
"window_replica_title": "Dupliquer une fenêtre",
|
|
52
54
|
"window_replica_refresh": "Actualiser",
|
|
@@ -47,6 +47,8 @@ germany_word_dict = {
|
|
|
47
47
|
"tools_shape": "Form",
|
|
48
48
|
"tools_name": "Name",
|
|
49
49
|
"tools_saved": "Gespeichert",
|
|
50
|
+
"pet_settle_typing": "Beim Tippen still halten",
|
|
51
|
+
"target_monitor_span": "Über alle Bildschirme",
|
|
50
52
|
"tools_replicate_window": "Fenster duplizieren...",
|
|
51
53
|
"window_replica_title": "Fenster duplizieren",
|
|
52
54
|
"window_replica_refresh": "Aktualisieren",
|
|
@@ -47,6 +47,8 @@ italian_word_dict = {
|
|
|
47
47
|
"tools_shape": "Forma",
|
|
48
48
|
"tools_name": "Nome",
|
|
49
49
|
"tools_saved": "Salvati",
|
|
50
|
+
"pet_settle_typing": "Fermo mentre scrivi",
|
|
51
|
+
"target_monitor_span": "Su tutti gli schermi",
|
|
50
52
|
"tools_replicate_window": "Duplica una finestra...",
|
|
51
53
|
"window_replica_title": "Duplica una finestra",
|
|
52
54
|
"window_replica_refresh": "Aggiorna",
|
|
@@ -47,6 +47,8 @@ russian_word_dict = {
|
|
|
47
47
|
"tools_shape": "Форма",
|
|
48
48
|
"tools_name": "Имя",
|
|
49
49
|
"tools_saved": "Сохранённые",
|
|
50
|
+
"pet_settle_typing": "Не двигаться при наборе текста",
|
|
51
|
+
"target_monitor_span": "На все экраны",
|
|
50
52
|
"tools_replicate_window": "Копия окна...",
|
|
51
53
|
"window_replica_title": "Копия окна",
|
|
52
54
|
"window_replica_refresh": "Обновить",
|
{frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/simplified_chinese.py
RENAMED
|
@@ -47,6 +47,8 @@ simplified_chinese_word_dict = {
|
|
|
47
47
|
"tools_shape": "形状",
|
|
48
48
|
"tools_name": "名称",
|
|
49
49
|
"tools_saved": "已保存",
|
|
50
|
+
"pet_settle_typing": "打字时安分",
|
|
51
|
+
"target_monitor_span": "横跨所有屏幕",
|
|
50
52
|
"tools_replicate_window": "窗口副本⋯",
|
|
51
53
|
"window_replica_title": "窗口副本",
|
|
52
54
|
"window_replica_refresh": "刷新",
|
{frontengine-1.0.66 → frontengine-1.0.68}/frontengine/utils/multi_language/traditional_chinese.py
RENAMED
|
@@ -47,6 +47,8 @@ traditional_chinese_word_dict = {
|
|
|
47
47
|
"tools_shape": "形狀",
|
|
48
48
|
"tools_name": "名稱",
|
|
49
49
|
"tools_saved": "已儲存",
|
|
50
|
+
"pet_settle_typing": "打字時安分",
|
|
51
|
+
"target_monitor_span": "橫跨所有螢幕",
|
|
50
52
|
"tools_replicate_window": "視窗複本⋯",
|
|
51
53
|
"window_replica_title": "視窗複本",
|
|
52
54
|
"window_replica_refresh": "重新整理",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.68
|
|
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
|
|
@@ -184,6 +184,7 @@ frontengine/utils/hotkey/__init__.py
|
|
|
184
184
|
frontengine/utils/hotkey/hotkey_service.py
|
|
185
185
|
frontengine/utils/input_watch/__init__.py
|
|
186
186
|
frontengine/utils/input_watch/input_watch_service.py
|
|
187
|
+
frontengine/utils/input_watch/typing_watch.py
|
|
187
188
|
frontengine/utils/json/__init__.py
|
|
188
189
|
frontengine/utils/json/json_file.py
|
|
189
190
|
frontengine/utils/json/json_repository.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/focus_shield/focus_shield_widget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/presentation/annotation_overlay.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.66 → frontengine-1.0.68}/frontengine/show/presentation/keystroke_display.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|