Compare commits

...

4 Commits

Author SHA1 Message Date
deltragon b10038fb1a
Merge b2df0e9a56 into 00c33908a3 2024-03-06 19:38:33 +00:00
deltragon b2df0e9a56
fix deprecations in settings dialog 2024-03-06 20:38:26 +01:00
deltragon 1ebcfa2bb8
port to Gtk.Application
Gtk.main() and Gtk.main_quit() are dropped in gtk4 in favor of
subclassing Gtk.Application.

This commit also moves argument handling from a separate thread to
GtkApplication.do_startup().
2024-01-02 13:19:53 +01:00
deltragon f45b83cfe6
fix deprecations 2024-01-02 13:19:40 +01:00
4 changed files with 58 additions and 52 deletions

View File

@ -25,9 +25,7 @@ import locale
import logging import logging
import signal import signal
import sys import sys
from threading import Timer
import gi
import psutil import psutil
from safeeyes import utility from safeeyes import utility
from safeeyes.model import Config from safeeyes.model import Config
@ -35,9 +33,6 @@ from safeeyes.safeeyes import SafeEyes
from safeeyes.safeeyes import SAFE_EYES_VERSION from safeeyes.safeeyes import SAFE_EYES_VERSION
from safeeyes.rpc import RPCClient from safeeyes.rpc import RPCClient
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
gettext.install('safeeyes', utility.LOCALE_PATH) gettext.install('safeeyes', utility.LOCALE_PATH)
@ -68,22 +63,6 @@ def __running():
return False return False
def __evaluate_arguments(args, safe_eyes):
"""
Evaluate the arguments and execute the operations.
"""
if args.about:
utility.execute_main_thread(safe_eyes.show_about)
elif args.disable:
utility.execute_main_thread(safe_eyes.disable_safeeyes)
elif args.enable:
utility.execute_main_thread(safe_eyes.enable_safeeyes)
elif args.settings:
utility.execute_main_thread(safe_eyes.show_settings)
elif args.take_break:
utility.execute_main_thread(safe_eyes.take_break)
def main(): def main():
""" """
Start the Safe Eyes. Start the Safe Eyes.
@ -147,10 +126,8 @@ def main():
sys.exit(0) sys.exit(0)
elif not args.quit: elif not args.quit:
logging.info("Starting Safe Eyes") logging.info("Starting Safe Eyes")
safe_eyes = SafeEyes(system_locale, config) safe_eyes = SafeEyes(system_locale, config, args)
safe_eyes.start() safe_eyes.start()
Timer(1.0, lambda: __evaluate_arguments(args, safe_eyes)).start()
Gtk.main()
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -38,17 +38,21 @@ from safeeyes.core import SafeEyesCore
from safeeyes.ui.settings_dialog import SettingsDialog from safeeyes.ui.settings_dialog import SettingsDialog
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
from gi.repository import Gtk from gi.repository import Gtk, Gio
SAFE_EYES_VERSION = "2.1.6" SAFE_EYES_VERSION = "2.1.6"
class SafeEyes: class SafeEyes(Gtk.Application):
""" """
This class represents a runnable Safe Eyes instance. This class represents a runnable Safe Eyes instance.
""" """
def __init__(self, system_locale, config): def __init__(self, system_locale, config, cli_args):
super().__init__(
application_id="io.github.slgobinath.SafeEyes",
flags=Gio.ApplicationFlags.IS_SERVICE
)
self.active = False self.active = False
self.break_screen = None self.break_screen = None
self.safe_eyes_core = None self.safe_eyes_core = None
@ -58,6 +62,7 @@ class SafeEyes:
self.settings_dialog_active = False self.settings_dialog_active = False
self.rpc_server = None self.rpc_server = None
self._status = '' self._status = ''
self.cli_args = cli_args
# Initialize the Safe Eyes Context # Initialize the Safe Eyes Context
self.context['version'] = SAFE_EYES_VERSION self.context['version'] = SAFE_EYES_VERSION
@ -98,6 +103,9 @@ class SafeEyes:
self.context['api']['postpone'] = self.safe_eyes_core.postpone self.context['api']['postpone'] = self.safe_eyes_core.postpone
self.context['api']['get_break_time'] = self.safe_eyes_core.get_break_time self.context['api']['get_break_time'] = self.safe_eyes_core.get_break_time
self.plugins_manager.init(self.context, self.config) self.plugins_manager.init(self.context, self.config)
self.hold()
atexit.register(self.persist_session) atexit.register(self.persist_session)
def start(self): def start(self):
@ -114,6 +122,22 @@ class SafeEyes:
self.safe_eyes_core.start() self.safe_eyes_core.start()
self.handle_system_suspend() self.handle_system_suspend()
self.run()
def do_startup(self):
Gtk.Application.do_startup(self)
if self.cli_args.about:
self.show_about()
elif self.cli_args.disable:
self.disable_safeeyes()
elif self.cli_args.enable:
self.enable_safeeyes()
elif self.cli_args.settings:
self.show_settings()
elif self.cli_args.take_break:
self.take_break()
def show_settings(self): def show_settings(self):
""" """
Listen to tray icon Settings action and send the signal to Settings dialog. Listen to tray icon Settings action and send the signal to Settings dialog.
@ -144,9 +168,8 @@ class SafeEyes:
self.plugins_manager.exit() self.plugins_manager.exit()
self.__stop_rpc_server() self.__stop_rpc_server()
self.persist_session() self.persist_session()
Gtk.main_quit()
# Exit all threads super().quit()
os._exit(0)
def handle_suspend_callback(self, sleeping): def handle_suspend_callback(self, sleeping):
""" """

View File

@ -151,12 +151,14 @@ class BreakScreen:
# Lock the keyboard # Lock the keyboard
utility.start_thread(self.__lock_keyboard) utility.start_thread(self.__lock_keyboard)
screen = Gtk.Window().get_screen() display = Gdk.Display.get_default()
no_of_monitors = screen.get_n_monitors() screen = display.get_default_screen()
no_of_monitors = display.get_n_monitors()
logging.info("Show break screens in %d display(s)", no_of_monitors) logging.info("Show break screens in %d display(s)", no_of_monitors)
for monitor in range(no_of_monitors): for monitor_num in range(no_of_monitors):
monitor_gemoetry = screen.get_monitor_geometry(monitor) monitor = display.get_monitor(monitor_num)
monitor_gemoetry = monitor.get_geometry()
x = monitor_gemoetry.x x = monitor_gemoetry.x
y = monitor_gemoetry.y y = monitor_gemoetry.y
@ -165,7 +167,7 @@ class BreakScreen:
builder.connect_signals(self) builder.connect_signals(self)
window = builder.get_object("window_main") window = builder.get_object("window_main")
window.set_title("SafeEyes-" + str(monitor)) window.set_title("SafeEyes-" + str(monitor_num))
lbl_message = builder.get_object("lbl_message") lbl_message = builder.get_object("lbl_message")
lbl_count = builder.get_object("lbl_count") lbl_count = builder.get_object("lbl_count")
lbl_widget = builder.get_object("lbl_widget") lbl_widget = builder.get_object("lbl_widget")
@ -188,7 +190,7 @@ class BreakScreen:
# Add the buttons # Add the buttons
if self.enable_postpone: if self.enable_postpone:
# Add postpone button # Add postpone button
btn_postpone = Gtk.Button(_('Postpone')) btn_postpone = Gtk.Button.new_with_label(_('Postpone'))
btn_postpone.get_style_context().add_class('btn_postpone') btn_postpone.get_style_context().add_class('btn_postpone')
btn_postpone.connect('clicked', self.on_postpone_clicked) btn_postpone.connect('clicked', self.on_postpone_clicked)
btn_postpone.set_visible(True) btn_postpone.set_visible(True)
@ -196,7 +198,7 @@ class BreakScreen:
if not self.strict_break: if not self.strict_break:
# Add the skip button # Add the skip button
btn_skip = Gtk.Button(_('Skip')) btn_skip = Gtk.Button.new_with_label(_('Skip'))
btn_skip.get_style_context().add_class('btn_skip') btn_skip.get_style_context().add_class('btn_skip')
btn_skip.connect('clicked', self.on_skip_clicked) btn_skip.connect('clicked', self.on_skip_clicked)
btn_skip.set_visible(True) btn_skip.set_visible(True)
@ -222,7 +224,7 @@ class BreakScreen:
window.resize(monitor_gemoetry.width, monitor_gemoetry.height) window.resize(monitor_gemoetry.width, monitor_gemoetry.height)
window.stick() window.stick()
window.set_keep_above(True) window.set_keep_above(True)
window.fullscreen() window.fullscreen_on_monitor(screen, monitor_num)
window.present() window.present()
# In other desktop environments, move the window after present # In other desktop environments, move the window after present
window.move(x, y) window.move(x, y)

View File

@ -170,14 +170,16 @@ class SettingsDialog:
self.__initialize(self.config) self.__initialize(self.config)
widget.destroy() widget.destroy()
messagedialog = Gtk.MessageDialog(parent=self.window, messagedialog = Gtk.MessageDialog()
flags=Gtk.DialogFlags.MODAL, messagedialog.set_modal(True)
type=Gtk.MessageType.WARNING, messagedialog.set_transient_for(self.window)
buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, messagedialog.set_property('message_type', Gtk.MessageType.WARNING)
_("Reset"), Gtk.ResponseType.OK), messagedialog.set_property('text', _("Are you sure you want to reset all settings to default?"))
message_format=_("Are you sure you want to reset all settings to default?")) messagedialog.set_property('secondary-text', _("You can't undo this action."))
messagedialog.add_button('_Cancel', Gtk.ResponseType.CANCEL)
messagedialog.add_button(_("Reset"), Gtk.ResponseType.OK)
messagedialog.connect("response", __confirmation_dialog_response) messagedialog.connect("response", __confirmation_dialog_response)
messagedialog.format_secondary_text(_("You can't undo this action."))
messagedialog.show() messagedialog.show()
def __delete_break(self, break_config, is_short, on_remove): def __delete_break(self, break_config, is_short, on_remove):
@ -194,14 +196,16 @@ class SettingsDialog:
on_remove() on_remove()
widget.destroy() widget.destroy()
messagedialog = Gtk.MessageDialog(parent=self.window, messagedialog = Gtk.MessageDialog()
flags=Gtk.DialogFlags.MODAL, messagedialog.set_modal(True)
type=Gtk.MessageType.WARNING, messagedialog.set_transient_for(self.window)
buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, messagedialog.set_property('message_type', Gtk.MessageType.WARNING)
_("Delete"), Gtk.ResponseType.OK), messagedialog.set_property('text', _("Are you sure you want to delete this break?"))
message_format=_("Are you sure you want to delete this break?")) messagedialog.set_property('secondary-text', _("You can't undo this action."))
messagedialog.add_button('_Cancel', Gtk.ResponseType.CANCEL)
messagedialog.add_button(_("Delete"), Gtk.ResponseType.OK)
messagedialog.connect("response", __confirmation_dialog_response) messagedialog.connect("response", __confirmation_dialog_response)
messagedialog.format_secondary_text(_("You can't undo this action."))
messagedialog.show() messagedialog.show()
def __create_plugin_item(self, plugin_config): def __create_plugin_item(self, plugin_config):