frontengine 1.0.63__tar.gz → 1.0.65__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.63 → frontengine-1.0.65}/PKG-INFO +1 -1
- frontengine-1.0.65/frontengine/ui/dialog/screensaver_dialog.py +113 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/main_ui.py +81 -1
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/menu/settings_menu.py +7 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/english.py +6 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/france.py +6 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/germany.py +6 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/italy.py +6 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/russian.py +6 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/simplified_chinese.py +6 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/traditional_chinese.py +6 -0
- frontengine-1.0.65/frontengine/utils/screensaver/screensaver_service.py +177 -0
- frontengine-1.0.65/frontengine/utils/workshop/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine.egg-info/PKG-INFO +1 -1
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine.egg-info/SOURCES.txt +3 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/pyproject.toml +1 -1
- {frontengine-1.0.63 → frontengine-1.0.65}/LICENSE +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/README.md +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/__main__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/base_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/camera/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/camera/camera_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/canvas/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/canvas/whiteboard_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/capture/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/capture/region_capture.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/focus_shield/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/focus_shield/focus_shield_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/gif/paint_gif.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/image/paint_image.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/load/load_someone_make_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/measure/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/measure/measure_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/monitor/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/monitor/monitor_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/notes/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/notes/sticky_note_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/overlay_factory.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/particle/particle_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/pet/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/pet/desktop_pet.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/presentation/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/presentation/annotation_overlay.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/presentation/cursor_effects.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/presentation/keystroke_display.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/presentation/magnifier.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/scene/extend_graphic_scene.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/scene/extend_graphic_view.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/scene/scene.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/screen_care/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/screen_care/color_vision_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/screen_care/screen_filter.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/sound_player/sound_effect.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/sound_player/sound_player.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/spectrum/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/spectrum/spectrum_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/text/draw_text.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/toast/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/toast/toast_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/video/video_player.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/wallpaper/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/wallpaper/wallpaper_widget.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/web/webview.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/show/window_helpers.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/system_tray/extend_system_tray.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/color/global_color.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/app_profile_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/clipboard_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/how_to_use_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/reminder_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/remote_control_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/screen_privacy_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/screen_text_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/signage_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/smart_pause_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/usage_report_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/dialog/window_pin_dialog.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/menu/help_menu.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/menu/how_to_menu.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/menu/language_menu.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/menu/preset_menu.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/nav/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/nav/sidebar.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/control_center/control_center_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/focus/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/focus/focus_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/image/image_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/layout_kit.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/pet/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/pet/pet_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/presentation/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/presentation/presentation_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/screen_care/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/screen_care/screen_care_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/text/text_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/tools/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/tools/tools_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/utils.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/video/video_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/wallpaper/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/wallpaper/wallpaper_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/web/web_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/widgets/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/page/widgets/widgets_setting_ui.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/style/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/ui/style/app_style.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/user_setting/preset_repository.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/user_setting/scene_setting.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/user_setting/user_setting_file.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/app_profile/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/app_profile/app_profile_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/audio_meter/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/audio_meter/audio_envelope.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/audio_meter/loopback_capture.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/audio_meter/microphone_meter.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/audio_meter/screen_audio.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/audio_meter/spectrum_analyzer.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/audio_meter/system_audio_meter.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/autostart/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/autostart/autostart_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/break_reminder/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/break_reminder/break_reminder.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/browser/browser.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/clipboard/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/clipboard/clipboard_history.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/clipboard/clipboard_watcher.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/color_vision/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/color_vision/color_vision.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/critical_exit/critical_exit.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/focus_shield/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/focus_shield/focus_shield.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/focus_timer/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/focus_timer/focus_timer.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/hotkey/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/hotkey/hotkey_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/input_watch/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/input_watch/input_watch_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/json/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/json/json_file.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/json/json_repository.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/logging/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/logging/loggin_instance.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/measure/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/measure/measure.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/midi/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/midi/midi_input.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/retranslate.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/now_playing/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/now_playing/now_playing.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/pet_chat/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/pet_chat/pet_chat_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/platform_info/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/platform_info/platform_info.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/playlist/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/playlist/playlist.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/plugins/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/plugins/plugin_loader.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/power_mode/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/power_mode/power_mode.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/preset_schedule/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/recording/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/recording/frame_recorder.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/recording/gif_writer.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/reminder/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/reminder/reminder_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/remote/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/remote/remote_server.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/screen_privacy/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/screen_privacy/capture_affinity.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/screen_privacy/share_watch.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/screen_text/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/screen_text/screen_text_service.py +0 -0
- {frontengine-1.0.63/frontengine/utils/signage → frontengine-1.0.65/frontengine/utils/screensaver}/__init__.py +0 -0
- {frontengine-1.0.63/frontengine/utils/smart_pause → frontengine-1.0.65/frontengine/utils/signage}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/signage/signage_service.py +0 -0
- {frontengine-1.0.63/frontengine/utils/steam → frontengine-1.0.65/frontengine/utils/smart_pause}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/smart_pause/pause_rules.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
- {frontengine-1.0.63/frontengine/utils/system_stats → frontengine-1.0.65/frontengine/utils/steam}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/steam/steam_language.py +0 -0
- {frontengine-1.0.63/frontengine/utils/text_source → frontengine-1.0.65/frontengine/utils/system_stats}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/system_stats/system_stats.py +0 -0
- {frontengine-1.0.63/frontengine/utils/theme_schedule → frontengine-1.0.65/frontengine/utils/text_source}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/text_source/text_source.py +0 -0
- {frontengine-1.0.63/frontengine/utils/usage_tracking → frontengine-1.0.65/frontengine/utils/theme_schedule}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
- {frontengine-1.0.63/frontengine/utils/virtual_camera → frontengine-1.0.65/frontengine/utils/usage_tracking}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/usage_tracking/usage_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/usage_tracking/usage_tracker.py +0 -0
- {frontengine-1.0.63/frontengine/utils/weather → frontengine-1.0.65/frontengine/utils/virtual_camera}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/virtual_camera/camera_feed.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/virtual_camera/virtual_camera.py +0 -0
- {frontengine-1.0.63/frontengine/utils/window_pin → frontengine-1.0.65/frontengine/utils/weather}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/weather/weather_service.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/web_url.py +0 -0
- {frontengine-1.0.63/frontengine/utils/workshop → frontengine-1.0.65/frontengine/utils/window_pin}/__init__.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/window_pin/window_layout.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/window_pin/window_pin.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/workshop/workshop_content.py +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine.egg-info/entry_points.txt +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine.egg-info/requires.txt +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/frontengine.egg-info/top_level.txt +0 -0
- {frontengine-1.0.63 → frontengine-1.0.65}/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.65
|
|
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
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
螢幕保護設定:閒置多久之後,把哪一頁的覆蓋層放上來。
|
|
3
|
+
|
|
4
|
+
Screensaver settings: how long idle, and which page's overlay to put on screen.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
|
|
10
|
+
from PySide6.QtWidgets import (
|
|
11
|
+
QCheckBox, QComboBox, QDialog, QDialogButtonBox, QGridLayout, QLabel, QSpinBox, QWidget,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from frontengine.user_setting.user_setting_file import user_setting_dict, write_user_setting
|
|
15
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
16
|
+
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
17
|
+
from frontengine.utils.multi_language.retranslate import tr
|
|
18
|
+
from frontengine.utils.screensaver.screensaver_service import (
|
|
19
|
+
DEFAULT_SCREENSAVER, MAX_IDLE_MINUTES, MIN_IDLE_MINUTES, SOURCES, clamp_idle_minutes,
|
|
20
|
+
normalize_source,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
SETTING_KEY = "screensaver"
|
|
24
|
+
|
|
25
|
+
# 下拉選單的文字用各分頁既有的鍵,省得同一個詞在七種語言裡再翻一次。
|
|
26
|
+
# The dropdown reuses each page's existing key rather than translating the same
|
|
27
|
+
# word a second time in seven languages.
|
|
28
|
+
SOURCE_LABEL_KEYS = {
|
|
29
|
+
"video": ("tab_video_text", "Video"),
|
|
30
|
+
"image": ("tab_image_text", "Image"),
|
|
31
|
+
"gif": ("tab_gif_text", "GIF and WEBP"),
|
|
32
|
+
"particle": ("tab_particle_text", "Particle"),
|
|
33
|
+
"web": ("tab_web_text", "Web"),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _t(key: str, fallback: str) -> str:
|
|
38
|
+
return language_wrapper.language_word_dict.get(key, fallback)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def current_settings() -> Dict[str, Any]:
|
|
42
|
+
"""目前的螢幕保護設定(缺項目補預設值)。"""
|
|
43
|
+
stored = user_setting_dict.get(SETTING_KEY)
|
|
44
|
+
settings = dict(DEFAULT_SCREENSAVER)
|
|
45
|
+
if isinstance(stored, dict):
|
|
46
|
+
settings.update({key: stored[key] for key in DEFAULT_SCREENSAVER if key in stored})
|
|
47
|
+
settings["idle_minutes"] = clamp_idle_minutes(settings.get("idle_minutes"))
|
|
48
|
+
settings["source"] = normalize_source(settings.get("source"))
|
|
49
|
+
settings["enabled"] = bool(settings.get("enabled"))
|
|
50
|
+
return settings
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ScreensaverDialog(QDialog):
|
|
54
|
+
"""設定閒置多久、顯示哪一頁。"""
|
|
55
|
+
|
|
56
|
+
def __init__(self, parent: Optional[QWidget] = None) -> None:
|
|
57
|
+
front_engine_logger.info("[ScreensaverDialog] Init")
|
|
58
|
+
super().__init__(parent)
|
|
59
|
+
self.setWindowTitle(_t("screensaver_title", "Screensaver"))
|
|
60
|
+
settings = current_settings()
|
|
61
|
+
|
|
62
|
+
self.enable_checkbox = tr(QCheckBox(), "screensaver_enable", "Show something when idle")
|
|
63
|
+
self.enable_checkbox.setChecked(settings["enabled"])
|
|
64
|
+
|
|
65
|
+
self.idle_label = tr(QLabel(), "screensaver_idle_minutes", "Idle for (minutes)")
|
|
66
|
+
self.idle_spinbox = QSpinBox()
|
|
67
|
+
self.idle_spinbox.setRange(MIN_IDLE_MINUTES, MAX_IDLE_MINUTES)
|
|
68
|
+
self.idle_spinbox.setValue(settings["idle_minutes"])
|
|
69
|
+
|
|
70
|
+
self.source_label = tr(QLabel(), "screensaver_source", "Show")
|
|
71
|
+
self.source_combobox = QComboBox()
|
|
72
|
+
for name in SOURCES:
|
|
73
|
+
key, fallback = SOURCE_LABEL_KEYS[name]
|
|
74
|
+
self.source_combobox.addItem(_t(key, fallback), name)
|
|
75
|
+
index = self.source_combobox.findData(settings["source"])
|
|
76
|
+
if index >= 0:
|
|
77
|
+
self.source_combobox.setCurrentIndex(index)
|
|
78
|
+
|
|
79
|
+
self.hint_label = tr(
|
|
80
|
+
QLabel(), "screensaver_hint",
|
|
81
|
+
"It uses that page as you have it set up, so choose the file there first. "
|
|
82
|
+
"Nothing appears while the page has nothing to show. Moving the mouse or "
|
|
83
|
+
"pressing a key takes it away again, and anything you opened yourself stays.")
|
|
84
|
+
self.hint_label.setWordWrap(True)
|
|
85
|
+
|
|
86
|
+
buttons = QDialogButtonBox(
|
|
87
|
+
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
|
88
|
+
buttons.accepted.connect(self.accept)
|
|
89
|
+
buttons.rejected.connect(self.reject)
|
|
90
|
+
|
|
91
|
+
layout = QGridLayout(self)
|
|
92
|
+
layout.addWidget(self.enable_checkbox, 0, 0, 1, 2)
|
|
93
|
+
layout.addWidget(self.idle_label, 1, 0)
|
|
94
|
+
layout.addWidget(self.idle_spinbox, 1, 1)
|
|
95
|
+
layout.addWidget(self.source_label, 2, 0)
|
|
96
|
+
layout.addWidget(self.source_combobox, 2, 1)
|
|
97
|
+
layout.addWidget(self.hint_label, 3, 0, 1, 2)
|
|
98
|
+
layout.addWidget(buttons, 4, 0, 1, 2)
|
|
99
|
+
|
|
100
|
+
def collect(self) -> Dict[str, Any]:
|
|
101
|
+
"""把畫面上的選擇讀成設定。"""
|
|
102
|
+
return {
|
|
103
|
+
"enabled": self.enable_checkbox.isChecked(),
|
|
104
|
+
"idle_minutes": clamp_idle_minutes(self.idle_spinbox.value()),
|
|
105
|
+
"source": normalize_source(self.source_combobox.currentData()),
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
def accept(self) -> None:
|
|
109
|
+
user_setting_dict[SETTING_KEY] = self.collect()
|
|
110
|
+
write_user_setting()
|
|
111
|
+
front_engine_logger.info(
|
|
112
|
+
f"[ScreensaverDialog] saved | {user_setting_dict[SETTING_KEY]}")
|
|
113
|
+
super().accept()
|
|
@@ -67,6 +67,7 @@ from frontengine.utils.midi.midi_input import MidiInput, binding_key
|
|
|
67
67
|
from frontengine.utils.remote.remote_server import RemoteServer
|
|
68
68
|
from frontengine.ui.dialog.smart_pause_dialog import current_rules
|
|
69
69
|
from frontengine.utils.screen_privacy.share_watch import ShareWatchService
|
|
70
|
+
from frontengine.utils.screensaver.screensaver_service import ScreensaverService
|
|
70
71
|
from frontengine.utils.app_profile.app_profile_service import AppProfileService
|
|
71
72
|
from frontengine.utils.clipboard.clipboard_history import DEFAULT_LIMIT, ClipboardHistory
|
|
72
73
|
from frontengine.utils.clipboard.clipboard_watcher import ClipboardWatcher
|
|
@@ -329,6 +330,15 @@ class FrontEngineMainUI(QMainWindow):
|
|
|
329
330
|
)
|
|
330
331
|
self.preset_schedule_service.start()
|
|
331
332
|
|
|
333
|
+
# 閒置夠久就把選定的覆蓋層放上來 / Show the chosen overlay once idle
|
|
334
|
+
self._screensaver_overlays: list = []
|
|
335
|
+
self.screensaver_service = ScreensaverService(
|
|
336
|
+
config_provider=lambda: user_setting_dict.get("screensaver", {})
|
|
337
|
+
)
|
|
338
|
+
self.screensaver_service.screensaver_started.connect(self._start_screensaver)
|
|
339
|
+
self.screensaver_service.screensaver_stopped.connect(self._stop_screensaver)
|
|
340
|
+
self.screensaver_service.start()
|
|
341
|
+
|
|
332
342
|
# 還原上次工作階段(若有開啟),再套用啟動預設集
|
|
333
343
|
# Restore the last session when enabled, then apply the startup preset.
|
|
334
344
|
if user_setting_dict.get("restore_last_session"):
|
|
@@ -383,6 +393,76 @@ class FrontEngineMainUI(QMainWindow):
|
|
|
383
393
|
self.control_center_ui.register_overlay_source(
|
|
384
394
|
lambda attribute=attribute: getattr(self.tools_setting_ui, attribute, []))
|
|
385
395
|
|
|
396
|
+
# 螢幕保護能顯示哪些分頁:來源名稱 -> (頁面屬性, 啟動方法, 覆蓋層清單屬性)
|
|
397
|
+
# What the screensaver can show: source -> (page attribute, start method,
|
|
398
|
+
# the page's overlay list).
|
|
399
|
+
_SCREENSAVER_SOURCES = {
|
|
400
|
+
"video": ("video_setting_ui", "start_play_video", "video_widget_list"),
|
|
401
|
+
"image": ("image_setting_ui", "start_play_image", "image_widget_list"),
|
|
402
|
+
"gif": ("gif_setting_ui", "start_play_gif", "gif_widget_list"),
|
|
403
|
+
"particle": ("particle_setting_ui", "start_play_particle", "particle_list"),
|
|
404
|
+
"web": ("web_setting_ui", "start_open_web_with_url", "web_widget_list"),
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
@staticmethod
|
|
408
|
+
def _screensaver_ready(source: str, page: Any) -> bool:
|
|
409
|
+
"""
|
|
410
|
+
這一頁現在按下開始會不會出東西。
|
|
411
|
+
|
|
412
|
+
非問不可:每個分頁在沒選檔案時都會跳一個 modal 訊息框,而螢幕保護正好是
|
|
413
|
+
在沒有人的時候啟動的——那個對話框會擋在畫面上直到有人回來按掉。
|
|
414
|
+
Whether pressing start on this page would actually show something.
|
|
415
|
+
|
|
416
|
+
This has to be asked: every page opens a modal message box when no file
|
|
417
|
+
is chosen, and the screensaver fires precisely when nobody is there - the
|
|
418
|
+
dialog would sit on screen until someone came back and dismissed it.
|
|
419
|
+
"""
|
|
420
|
+
if source == "web":
|
|
421
|
+
field = getattr(page, "web_url_input", None)
|
|
422
|
+
return bool(field is not None and field.text().strip())
|
|
423
|
+
return bool(getattr(page, "ready_to_play", False))
|
|
424
|
+
|
|
425
|
+
def _start_screensaver(self, source: str) -> None:
|
|
426
|
+
"""閒置夠久了:把選定分頁的覆蓋層放上來,並記住是哪幾個。"""
|
|
427
|
+
entry = self._SCREENSAVER_SOURCES.get(source)
|
|
428
|
+
if entry is None:
|
|
429
|
+
return
|
|
430
|
+
attribute, start_method, list_name = entry
|
|
431
|
+
page = getattr(self, attribute, None)
|
|
432
|
+
overlays = getattr(page, list_name, None) if page is not None else None
|
|
433
|
+
if page is None or overlays is None:
|
|
434
|
+
return
|
|
435
|
+
if not self._screensaver_ready(source, page):
|
|
436
|
+
front_engine_logger.info(
|
|
437
|
+
f"[FrontEngineMainUI] screensaver source '{source}' has nothing set up")
|
|
438
|
+
return
|
|
439
|
+
before = len(overlays)
|
|
440
|
+
try:
|
|
441
|
+
getattr(page, start_method)()
|
|
442
|
+
except Exception as error: # pragma: no cover - defensive boundary
|
|
443
|
+
front_engine_logger.warning(f"[FrontEngineMainUI] screensaver start failed: {error!r}")
|
|
444
|
+
return
|
|
445
|
+
# 只記下這次新增的那幾個。人回來時關掉的就只有這些,使用者自己開著的
|
|
446
|
+
# 覆蓋層不會跟著被收走。
|
|
447
|
+
# Only what this call added. Coming back closes these and nothing else,
|
|
448
|
+
# so overlays the user opened themselves survive.
|
|
449
|
+
self._screensaver_overlays = [(overlays, widget) for widget in overlays[before:]]
|
|
450
|
+
|
|
451
|
+
def _stop_screensaver(self) -> None:
|
|
452
|
+
"""人回來了:關掉螢幕保護開的那幾個覆蓋層,其他的留著。"""
|
|
453
|
+
for overlays, widget in self._screensaver_overlays:
|
|
454
|
+
try:
|
|
455
|
+
# 先 close() 再從清單移除:只丟掉參考不會跑 closeEvent,計時器與
|
|
456
|
+
# 媒體都停不下來。
|
|
457
|
+
# close() before dropping the reference: dropping it alone never
|
|
458
|
+
# runs closeEvent, so timers and media keep going.
|
|
459
|
+
widget.close()
|
|
460
|
+
except RuntimeError: # pragma: no cover - 底層物件已消失
|
|
461
|
+
pass
|
|
462
|
+
if widget in overlays:
|
|
463
|
+
overlays.remove(widget)
|
|
464
|
+
self._screensaver_overlays = []
|
|
465
|
+
|
|
386
466
|
@staticmethod
|
|
387
467
|
def _startup_language() -> str:
|
|
388
468
|
"""
|
|
@@ -741,7 +821,7 @@ class FrontEngineMainUI(QMainWindow):
|
|
|
741
821
|
# The background services to stop on close, outermost first.
|
|
742
822
|
_CLOSING_SERVICES = (
|
|
743
823
|
"preset_schedule_service", "theme_schedule_service", "usage_service",
|
|
744
|
-
"signage_service",
|
|
824
|
+
"signage_service", "screensaver_service",
|
|
745
825
|
"remote_server", "midi_input", "share_watch_service", "reminder_service",
|
|
746
826
|
"app_profile_service", "smart_pause_service", "hotkey_service",
|
|
747
827
|
)
|
|
@@ -12,6 +12,7 @@ from frontengine.ui.dialog.hotkey_settings_dialog import HotkeySettingsDialog
|
|
|
12
12
|
from frontengine.ui.dialog.reminder_dialog import ReminderDialog
|
|
13
13
|
from frontengine.ui.dialog.remote_control_dialog import RemoteControlDialog
|
|
14
14
|
from frontengine.ui.dialog.screen_privacy_dialog import ScreenPrivacyDialog
|
|
15
|
+
from frontengine.ui.dialog.screensaver_dialog import ScreensaverDialog
|
|
15
16
|
from frontengine.ui.dialog.signage_dialog import SignageDialog
|
|
16
17
|
from frontengine.ui.dialog.smart_pause_dialog import SmartPauseDialog
|
|
17
18
|
from frontengine.ui.dialog.usage_report_dialog import UsageReportDialog
|
|
@@ -107,6 +108,12 @@ def build_settings_menu(ui: "FrontEngineMainUI") -> None:
|
|
|
107
108
|
menu.addAction(reminder_action)
|
|
108
109
|
ui.reminder_action = reminder_action
|
|
109
110
|
|
|
111
|
+
screensaver_action = QAction(_t("settings_menu_screensaver", "Screensaver..."), menu)
|
|
112
|
+
retranslator.bind(screensaver_action, "settings_menu_screensaver", "Screensaver...")
|
|
113
|
+
screensaver_action.triggered.connect(lambda: ScreensaverDialog(ui).exec())
|
|
114
|
+
menu.addAction(screensaver_action)
|
|
115
|
+
ui.screensaver_action = screensaver_action
|
|
116
|
+
|
|
110
117
|
signage_action = QAction(_t("settings_menu_signage", "Signage mode..."), menu)
|
|
111
118
|
retranslator.bind(signage_action, "settings_menu_signage", "Signage mode...")
|
|
112
119
|
signage_action.triggered.connect(lambda: _open_signage_dialog(ui))
|
|
@@ -46,6 +46,12 @@ english_word_dict = {
|
|
|
46
46
|
"tools_shape": "Shape",
|
|
47
47
|
"tools_name": "Name",
|
|
48
48
|
"tools_saved": "Saved",
|
|
49
|
+
"settings_menu_screensaver": "Screensaver...",
|
|
50
|
+
"screensaver_title": "Screensaver",
|
|
51
|
+
"screensaver_enable": "Show something when idle",
|
|
52
|
+
"screensaver_idle_minutes": "Idle for (minutes)",
|
|
53
|
+
"screensaver_source": "Show",
|
|
54
|
+
"screensaver_hint": "It uses that page as you have it set up, so choose the file there first. Nothing appears while the page has nothing to show. Moving the mouse or pressing a key takes it away again, and anything you opened yourself stays.",
|
|
49
55
|
"section_close": "CLOSE",
|
|
50
56
|
"section_everything": "EVERYTHING AT ONCE",
|
|
51
57
|
"section_log": "MESSAGES",
|
|
@@ -47,6 +47,12 @@ french_word_dict = {
|
|
|
47
47
|
"tools_shape": "Forme",
|
|
48
48
|
"tools_name": "Nom",
|
|
49
49
|
"tools_saved": "Enregistrés",
|
|
50
|
+
"settings_menu_screensaver": "Économiseur d'écran...",
|
|
51
|
+
"screensaver_title": "Économiseur d'écran",
|
|
52
|
+
"screensaver_enable": "Afficher quelque chose en cas d'inactivité",
|
|
53
|
+
"screensaver_idle_minutes": "Inactif depuis (minutes)",
|
|
54
|
+
"screensaver_source": "Afficher",
|
|
55
|
+
"screensaver_hint": "Il affiche la page telle que vous l'avez réglée : choisissez-y d'abord un fichier. Tant que la page n'a rien à montrer, rien n'apparaît. Un mouvement de souris ou une touche le retire, et ce que vous avez ouvert vous-même reste.",
|
|
50
56
|
"section_close": "FERMER",
|
|
51
57
|
"section_everything": "TOUT À LA FOIS",
|
|
52
58
|
"section_log": "MESSAGES",
|
|
@@ -47,6 +47,12 @@ germany_word_dict = {
|
|
|
47
47
|
"tools_shape": "Form",
|
|
48
48
|
"tools_name": "Name",
|
|
49
49
|
"tools_saved": "Gespeichert",
|
|
50
|
+
"settings_menu_screensaver": "Bildschirmschoner...",
|
|
51
|
+
"screensaver_title": "Bildschirmschoner",
|
|
52
|
+
"screensaver_enable": "Bei Untätigkeit etwas anzeigen",
|
|
53
|
+
"screensaver_idle_minutes": "Untätig seit (Minuten)",
|
|
54
|
+
"screensaver_source": "Anzeigen",
|
|
55
|
+
"screensaver_hint": "Es zeigt die gewählte Seite so, wie Sie sie eingerichtet haben - wählen Sie dort also zuerst eine Datei. Solange die Seite nichts zu zeigen hat, erscheint nichts. Eine Mausbewegung oder ein Tastendruck nimmt es wieder weg, und was Sie selbst geöffnet haben, bleibt.",
|
|
50
56
|
"section_close": "SCHLIESSEN",
|
|
51
57
|
"section_everything": "ALLES AUF EINMAL",
|
|
52
58
|
"section_log": "MELDUNGEN",
|
|
@@ -47,6 +47,12 @@ italian_word_dict = {
|
|
|
47
47
|
"tools_shape": "Forma",
|
|
48
48
|
"tools_name": "Nome",
|
|
49
49
|
"tools_saved": "Salvati",
|
|
50
|
+
"settings_menu_screensaver": "Salvaschermo...",
|
|
51
|
+
"screensaver_title": "Salvaschermo",
|
|
52
|
+
"screensaver_enable": "Mostra qualcosa quando sei inattivo",
|
|
53
|
+
"screensaver_idle_minutes": "Inattivo da (minuti)",
|
|
54
|
+
"screensaver_source": "Mostra",
|
|
55
|
+
"screensaver_hint": "Mostra quella pagina così come l'hai impostata, quindi scegli prima un file lì. Finché la pagina non ha nulla da mostrare, non compare niente. Muovere il mouse o premere un tasto lo toglie, e ciò che hai aperto tu resta.",
|
|
50
56
|
"section_close": "CHIUDI",
|
|
51
57
|
"section_everything": "TUTTO IN UNA VOLTA",
|
|
52
58
|
"section_log": "MESSAGGI",
|
|
@@ -47,6 +47,12 @@ russian_word_dict = {
|
|
|
47
47
|
"tools_shape": "Форма",
|
|
48
48
|
"tools_name": "Имя",
|
|
49
49
|
"tools_saved": "Сохранённые",
|
|
50
|
+
"settings_menu_screensaver": "Заставка...",
|
|
51
|
+
"screensaver_title": "Заставка",
|
|
52
|
+
"screensaver_enable": "Показывать что-нибудь при простое",
|
|
53
|
+
"screensaver_idle_minutes": "Простой (минут)",
|
|
54
|
+
"screensaver_source": "Показывать",
|
|
55
|
+
"screensaver_hint": "Показывается выбранная страница в том виде, как вы её настроили, поэтому сначала выберите там файл. Пока странице нечего показать, ничего не появится. Движение мыши или нажатие клавиши убирает наложение, а то, что вы открыли сами, остаётся.",
|
|
50
56
|
"section_close": "ЗАКРЫТЬ",
|
|
51
57
|
"section_everything": "ВСЁ СРАЗУ",
|
|
52
58
|
"section_log": "СООБЩЕНИЯ",
|
{frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/simplified_chinese.py
RENAMED
|
@@ -47,6 +47,12 @@ simplified_chinese_word_dict = {
|
|
|
47
47
|
"tools_shape": "形状",
|
|
48
48
|
"tools_name": "名称",
|
|
49
49
|
"tools_saved": "已保存",
|
|
50
|
+
"settings_menu_screensaver": "屏幕保护⋯",
|
|
51
|
+
"screensaver_title": "屏幕保护",
|
|
52
|
+
"screensaver_enable": "空闲时显示东西",
|
|
53
|
+
"screensaver_idle_minutes": "空闲多久(分钟)",
|
|
54
|
+
"screensaver_source": "显示",
|
|
55
|
+
"screensaver_hint": "它会按那一页当前的设置显示,所以请先在那一页选好文件。那一页没有东西可放时就不会出现。动一下鼠标或按任何键就会收掉,而且只收它自己开的,你原本开着的覆盖层都留着。",
|
|
50
56
|
"section_close": "关闭",
|
|
51
57
|
"section_everything": "一次全部",
|
|
52
58
|
"section_log": "消息",
|
{frontengine-1.0.63 → frontengine-1.0.65}/frontengine/utils/multi_language/traditional_chinese.py
RENAMED
|
@@ -47,6 +47,12 @@ traditional_chinese_word_dict = {
|
|
|
47
47
|
"tools_shape": "形狀",
|
|
48
48
|
"tools_name": "名稱",
|
|
49
49
|
"tools_saved": "已儲存",
|
|
50
|
+
"settings_menu_screensaver": "螢幕保護⋯",
|
|
51
|
+
"screensaver_title": "螢幕保護",
|
|
52
|
+
"screensaver_enable": "閒置時顯示東西",
|
|
53
|
+
"screensaver_idle_minutes": "閒置多久(分鐘)",
|
|
54
|
+
"screensaver_source": "顯示",
|
|
55
|
+
"screensaver_hint": "它會照那一頁目前的設定顯示,所以請先在那一頁選好檔案。那一頁沒有東西可放時就不會出現。動一下滑鼠或按任何鍵就會收掉,而且只收它自己開的,你原本開著的覆蓋層都留著。",
|
|
50
56
|
"section_close": "關閉",
|
|
51
57
|
"section_everything": "一次全部",
|
|
52
58
|
"section_log": "訊息",
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""
|
|
2
|
+
螢幕保護模式:閒置到一定時間就把選定的覆蓋層放上來,人回來就收掉。
|
|
3
|
+
|
|
4
|
+
這個程式的介紹一直寫著「or only use like screen saver」,但真正讓它自己啟動的
|
|
5
|
+
那一段從來沒有寫。閒置秒數在 `platform_info.idle_seconds()` 裡早就有了(Windows、
|
|
6
|
+
macOS、X11 三種都有),只是沒有任何地方在用。
|
|
7
|
+
|
|
8
|
+
閒置判斷是純邏輯,時間來源可以注入,所以測試不必真的等五分鐘也不必去動滑鼠。
|
|
9
|
+
Qt 服務只負責定時問它「狀態變了嗎」。
|
|
10
|
+
|
|
11
|
+
Screensaver mode: put the chosen overlay on screen once the machine has been
|
|
12
|
+
idle long enough, and take it away when someone comes back.
|
|
13
|
+
|
|
14
|
+
The application has always described itself as "or only use like screen saver",
|
|
15
|
+
but the part that starts it on its own was never written. The idle seconds were
|
|
16
|
+
already there in `platform_info.idle_seconds()` - Windows, macOS and X11 - with
|
|
17
|
+
nothing reading them.
|
|
18
|
+
|
|
19
|
+
The idle decision is pure logic with an injectable clock, so a test does not have
|
|
20
|
+
to wait five minutes or move a mouse. The Qt service only asks it, on a timer,
|
|
21
|
+
whether the state changed.
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from typing import Any, Callable, Dict, Optional
|
|
26
|
+
|
|
27
|
+
from PySide6.QtCore import QObject, QTimer, Signal
|
|
28
|
+
|
|
29
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
30
|
+
from frontengine.utils.platform_info.platform_info import idle_seconds
|
|
31
|
+
|
|
32
|
+
DEFAULT_IDLE_MINUTES = 5
|
|
33
|
+
MIN_IDLE_MINUTES = 1
|
|
34
|
+
MAX_IDLE_MINUTES = 24 * 60
|
|
35
|
+
|
|
36
|
+
# 可以當螢幕保護內容的分頁。順序就是設定畫面下拉選單的順序。
|
|
37
|
+
# The pages that can be the screensaver. This order is the order in the dialog.
|
|
38
|
+
SOURCES = ("video", "image", "gif", "particle", "web")
|
|
39
|
+
DEFAULT_SOURCE = "video"
|
|
40
|
+
|
|
41
|
+
DEFAULT_SCREENSAVER: Dict[str, Any] = {
|
|
42
|
+
"enabled": False,
|
|
43
|
+
"idle_minutes": DEFAULT_IDLE_MINUTES,
|
|
44
|
+
"source": DEFAULT_SOURCE,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def clamp_idle_minutes(value: Any, fallback: int = DEFAULT_IDLE_MINUTES) -> int:
|
|
49
|
+
"""閒置門檻夾在 1 分鐘到 24 小時之間。"""
|
|
50
|
+
try:
|
|
51
|
+
return max(MIN_IDLE_MINUTES, min(MAX_IDLE_MINUTES, int(float(value))))
|
|
52
|
+
except (TypeError, ValueError):
|
|
53
|
+
return fallback
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def normalize_source(value: Any, fallback: str = DEFAULT_SOURCE) -> str:
|
|
57
|
+
"""把設定裡的來源名稱正規化;不認得的就用預設。"""
|
|
58
|
+
name = str(value or "").strip().lower()
|
|
59
|
+
return name if name in SOURCES else fallback
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ScreensaverState:
|
|
63
|
+
"""
|
|
64
|
+
依閒置秒數決定該開還是該關。純邏輯,閒置秒數可以注入。
|
|
65
|
+
|
|
66
|
+
只在「狀態真的改變」時回話,所以呼叫端不必自己記上一次是什麼——每次輪詢都
|
|
67
|
+
回報「該開了」會把覆蓋層重開一遍又一遍。
|
|
68
|
+
|
|
69
|
+
Decides from the idle seconds whether it should be on or off, as pure logic
|
|
70
|
+
with an injectable idle source.
|
|
71
|
+
|
|
72
|
+
It speaks only when the state actually changes, so the caller does not have
|
|
73
|
+
to remember the last answer: reporting "should be on" on every poll would
|
|
74
|
+
reopen the overlay over and over.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
def __init__(self, config_provider: Callable[[], Dict[str, Any]],
|
|
78
|
+
idle_provider: Callable[[], Optional[float]] = idle_seconds) -> None:
|
|
79
|
+
self._config_provider = config_provider
|
|
80
|
+
self._idle = idle_provider
|
|
81
|
+
self.active = False
|
|
82
|
+
|
|
83
|
+
def _config(self) -> Dict[str, Any]:
|
|
84
|
+
config = self._config_provider() or {}
|
|
85
|
+
return config if isinstance(config, dict) else {}
|
|
86
|
+
|
|
87
|
+
def enabled(self) -> bool:
|
|
88
|
+
return bool(self._config().get("enabled"))
|
|
89
|
+
|
|
90
|
+
def idle_minutes(self) -> int:
|
|
91
|
+
return clamp_idle_minutes(self._config().get("idle_minutes"))
|
|
92
|
+
|
|
93
|
+
def source(self) -> str:
|
|
94
|
+
return normalize_source(self._config().get("source"))
|
|
95
|
+
|
|
96
|
+
def poll(self) -> Optional[bool]:
|
|
97
|
+
"""
|
|
98
|
+
回傳 True 表示「現在該開」、False 表示「現在該關」、None 表示沒有變化。
|
|
99
|
+
|
|
100
|
+
關掉的條件不只是「人回來了」:功能被關掉時也要收乾淨,否則使用者關掉開關
|
|
101
|
+
之後畫面上還留著一層自己不會消失的覆蓋層。
|
|
102
|
+
|
|
103
|
+
True to start now, False to stop now, None when nothing changed.
|
|
104
|
+
|
|
105
|
+
Stopping is not only about someone coming back: switching the feature off
|
|
106
|
+
has to clear the screen too, or the user is left with an overlay that
|
|
107
|
+
will not go away on its own.
|
|
108
|
+
"""
|
|
109
|
+
if not self.enabled():
|
|
110
|
+
if self.active:
|
|
111
|
+
self.active = False
|
|
112
|
+
return False
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
seconds = self._idle()
|
|
116
|
+
if seconds is None:
|
|
117
|
+
# 這個平台問不到閒置時間,就不要自作主張把東西放上螢幕。
|
|
118
|
+
# No idle reading on this platform: do not put things on screen by guess.
|
|
119
|
+
if self.active:
|
|
120
|
+
self.active = False
|
|
121
|
+
return False
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
should_be_active = seconds >= self.idle_minutes() * 60
|
|
125
|
+
if should_be_active == self.active:
|
|
126
|
+
return None
|
|
127
|
+
self.active = should_be_active
|
|
128
|
+
return should_be_active
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ScreensaverService(QObject):
|
|
132
|
+
"""把閒置判斷接上 QTimer,狀態改變時發出訊號。"""
|
|
133
|
+
|
|
134
|
+
screensaver_started = Signal(str) # 要顯示哪一個來源 / which source to show
|
|
135
|
+
screensaver_stopped = Signal()
|
|
136
|
+
|
|
137
|
+
def __init__(self, config_provider: Callable[[], Dict[str, Any]],
|
|
138
|
+
idle_provider: Callable[[], Optional[float]] = idle_seconds,
|
|
139
|
+
interval_ms: int = 5000, parent: Optional[QObject] = None) -> None:
|
|
140
|
+
super().__init__(parent)
|
|
141
|
+
self.state = ScreensaverState(config_provider, idle_provider)
|
|
142
|
+
self._timer = QTimer(self)
|
|
143
|
+
self._timer.setInterval(max(1000, int(interval_ms)))
|
|
144
|
+
self._timer.timeout.connect(self.poll_once)
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def running(self) -> bool:
|
|
148
|
+
return self._timer.isActive()
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def active(self) -> bool:
|
|
152
|
+
return self.state.active
|
|
153
|
+
|
|
154
|
+
def start(self) -> None:
|
|
155
|
+
self._timer.start()
|
|
156
|
+
front_engine_logger.info("[Screensaver] start")
|
|
157
|
+
|
|
158
|
+
def stop(self) -> None:
|
|
159
|
+
self._timer.stop()
|
|
160
|
+
front_engine_logger.info("[Screensaver] stop")
|
|
161
|
+
|
|
162
|
+
def poll_once(self) -> None:
|
|
163
|
+
"""檢查一次閒置狀態(測試直接呼叫這個,不必等計時器)。"""
|
|
164
|
+
try:
|
|
165
|
+
change = self.state.poll()
|
|
166
|
+
except Exception as error: # pragma: no cover - defensive boundary
|
|
167
|
+
front_engine_logger.warning(f"[Screensaver] poll error: {error!r}")
|
|
168
|
+
return
|
|
169
|
+
if change is None:
|
|
170
|
+
return
|
|
171
|
+
if change:
|
|
172
|
+
source = self.state.source()
|
|
173
|
+
front_engine_logger.info(f"[Screensaver] idle, showing {source}")
|
|
174
|
+
self.screensaver_started.emit(source)
|
|
175
|
+
else:
|
|
176
|
+
front_engine_logger.info("[Screensaver] back, clearing")
|
|
177
|
+
self.screensaver_stopped.emit()
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.65
|
|
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
|
|
@@ -80,6 +80,7 @@ frontengine/ui/dialog/reminder_dialog.py
|
|
|
80
80
|
frontengine/ui/dialog/remote_control_dialog.py
|
|
81
81
|
frontengine/ui/dialog/screen_privacy_dialog.py
|
|
82
82
|
frontengine/ui/dialog/screen_text_dialog.py
|
|
83
|
+
frontengine/ui/dialog/screensaver_dialog.py
|
|
83
84
|
frontengine/ui/dialog/signage_dialog.py
|
|
84
85
|
frontengine/ui/dialog/smart_pause_dialog.py
|
|
85
86
|
frontengine/ui/dialog/usage_report_dialog.py
|
|
@@ -227,6 +228,8 @@ frontengine/utils/screen_privacy/capture_affinity.py
|
|
|
227
228
|
frontengine/utils/screen_privacy/share_watch.py
|
|
228
229
|
frontengine/utils/screen_text/__init__.py
|
|
229
230
|
frontengine/utils/screen_text/screen_text_service.py
|
|
231
|
+
frontengine/utils/screensaver/__init__.py
|
|
232
|
+
frontengine/utils/screensaver/screensaver_service.py
|
|
230
233
|
frontengine/utils/signage/__init__.py
|
|
231
234
|
frontengine/utils/signage/signage_service.py
|
|
232
235
|
frontengine/utils/smart_pause/__init__.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.63 → frontengine-1.0.65}/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
|