3939
4040
4141class BreakScreen :
42- """The fullscreen window which prevents users from using the computer.
42+ """The fullscreen windows which prevent users from using the computer.
4343
44- This class reads the break_screen.glade and build the user
45- interface.
44+ This class creates and manages the fullscreen windows for every monitor.
4645 """
4746
4847 def __init__ (self , application , context , on_skipped , on_postponed ):
4948 self .application = application
5049 self .context = context
51- self .count_labels = []
5250 self .x11_display = None
5351 self .enable_postpone = False
5452 self .enable_shortcut = False
@@ -100,11 +98,6 @@ def postpone_break(self):
10098 self .on_postponed ()
10199 self .close ()
102100
103- def on_window_delete (self , * args ):
104- """Window close event handler."""
105- logging .info ("Closing the break screen" )
106- self .close ()
107-
108101 def on_skip_clicked (self , button ):
109102 """Skip button press event handler."""
110103 self .skip_break ()
@@ -140,16 +133,6 @@ def close(self):
140133 # Destroy other windows if exists
141134 GLib .idle_add (lambda : self .__destroy_all_screens ())
142135
143- def __tray_action (self , button , tray_action : TrayAction ):
144- """Tray action handler.
145-
146- Hides all toolbar buttons for this action, if it is single use,
147- and call the action provided by the plugin.
148- """
149- if tray_action .single_use :
150- tray_action .reset ()
151- tray_action .action ()
152-
153136 def __show_break_screen (self , message , image_path , widget , tray_actions ):
154137 """Show an empty break screen on all screens."""
155138 # Lock the keyboard
@@ -171,12 +154,20 @@ def __show_break_screen(self, message, image_path, widget, tray_actions):
171154 i = 0
172155
173156 for monitor in monitors :
174- builder = Gtk .Builder ()
175- builder .add_from_file (BREAK_SCREEN_GLADE )
157+ w = BreakScreenWindow (
158+ self .application ,
159+ message ,
160+ image_path ,
161+ widget ,
162+ tray_actions ,
163+ lambda : self .close (),
164+ self .show_postpone_button ,
165+ self .on_postpone_clicked ,
166+ self .show_skip_button ,
167+ self .on_skip_clicked ,
168+ )
176169
177- window = builder .get_object ("window_main" )
178- window .set_application (self .application )
179- window .connect ("close-request" , self .on_window_delete )
170+ window = w .window
180171
181172 if self .context ["is_wayland" ]:
182173 # Note: in theory, this could also be used on X11
@@ -187,54 +178,8 @@ def __show_break_screen(self, message, image_path, widget, tray_actions):
187178 window .add_controller (controller )
188179
189180 window .set_title ("SafeEyes-" + str (i ))
190- lbl_message = builder .get_object ("lbl_message" )
191- lbl_count = builder .get_object ("lbl_count" )
192- lbl_widget = builder .get_object ("lbl_widget" )
193- img_break = builder .get_object ("img_break" )
194- box_buttons = builder .get_object ("box_buttons" )
195- toolbar = builder .get_object ("toolbar" )
196-
197- for tray_action in tray_actions :
198- # TODO: apparently, this would be better served with an icon theme
199- # + Gtk.button.new_from_icon_name
200- icon = tray_action .get_icon ()
201- toolbar_button = Gtk .Button ()
202- toolbar_button .set_child (icon )
203- tray_action .add_toolbar_button (toolbar_button )
204- toolbar_button .connect (
205- "clicked" ,
206- lambda button , action : self .__tray_action (button , action ),
207- tray_action ,
208- )
209- toolbar_button .set_tooltip_text (_ (tray_action .name ))
210- toolbar .append (toolbar_button )
211- toolbar_button .show ()
212-
213- # Add the buttons
214- if self .show_postpone_button :
215- # Add postpone button
216- btn_postpone = Gtk .Button .new_with_label (_ ("Postpone" ))
217- btn_postpone .get_style_context ().add_class ("btn_postpone" )
218- btn_postpone .connect ("clicked" , self .on_postpone_clicked )
219- btn_postpone .set_visible (True )
220- box_buttons .append (btn_postpone )
221-
222- if self .show_skip_button :
223- # Add the skip button
224- btn_skip = Gtk .Button .new_with_label (_ ("Skip" ))
225- btn_skip .get_style_context ().add_class ("btn_skip" )
226- btn_skip .connect ("clicked" , self .on_skip_clicked )
227- btn_skip .set_visible (True )
228- box_buttons .append (btn_skip )
229-
230- # Set values
231- if image_path :
232- img_break .set_from_file (image_path )
233- lbl_message .set_label (message )
234- lbl_widget .set_markup (widget )
235-
236- self .windows .append (window )
237- self .count_labels .append (lbl_count )
181+
182+ self .windows .append (w )
238183
239184 if self .context ["desktop" ] == "kde" :
240185 # Fix flickering screen in KDE by setting opacity to 1
@@ -259,8 +204,8 @@ def __show_break_screen(self, message, image_path, widget, tray_actions):
259204
260205 def __update_count_down (self , count ):
261206 """Update the countdown on all break screens."""
262- for label in self .count_labels :
263- label . set_text (count )
207+ for window in self .windows :
208+ window . set_count_down (count )
264209
265210 def __window_set_keep_above_x11 (self , window ):
266211 """Use EWMH hints to keep window above and on all desktops."""
@@ -353,6 +298,98 @@ def __release_keyboard_x11(self):
353298 def __destroy_all_screens (self ):
354299 """Close all the break screens."""
355300 for win in self .windows :
356- win .destroy ()
301+ win .window . destroy ()
357302 del self .windows [:]
358- del self .count_labels [:]
303+
304+
305+ class BreakScreenWindow :
306+ """This class manages the UI for the break screen window.
307+
308+ Each instance is a single window, covering a single monitor.
309+ """
310+
311+ def __init__ (
312+ self ,
313+ application ,
314+ message ,
315+ image_path ,
316+ widget ,
317+ tray_actions ,
318+ on_close ,
319+ show_postpone ,
320+ on_postpone ,
321+ show_skip ,
322+ on_skip ,
323+ ):
324+ self .on_close = on_close
325+
326+ builder = Gtk .Builder ()
327+ builder .add_from_file (BREAK_SCREEN_GLADE )
328+
329+ self .window = builder .get_object ("window_main" )
330+ self .window .set_application (application )
331+ self .window .connect ("close-request" , self .on_window_delete )
332+
333+ lbl_message = builder .get_object ("lbl_message" )
334+ self .lbl_count = builder .get_object ("lbl_count" )
335+ lbl_widget = builder .get_object ("lbl_widget" )
336+ img_break = builder .get_object ("img_break" )
337+ box_buttons = builder .get_object ("box_buttons" )
338+ toolbar = builder .get_object ("toolbar" )
339+
340+ for tray_action in tray_actions :
341+ # TODO: apparently, this would be better served with an icon theme
342+ # + Gtk.button.new_from_icon_name
343+ icon = tray_action .get_icon ()
344+ toolbar_button = Gtk .Button ()
345+ toolbar_button .set_child (icon )
346+ tray_action .add_toolbar_button (toolbar_button )
347+ toolbar_button .connect (
348+ "clicked" ,
349+ lambda button , action : self .__tray_action (button , action ),
350+ tray_action ,
351+ )
352+ toolbar_button .set_tooltip_text (_ (tray_action .name ))
353+ toolbar .append (toolbar_button )
354+ toolbar_button .show ()
355+
356+ # Add the buttons
357+ if show_postpone :
358+ # Add postpone button
359+ btn_postpone = Gtk .Button .new_with_label (_ ("Postpone" ))
360+ btn_postpone .get_style_context ().add_class ("btn_postpone" )
361+ btn_postpone .connect ("clicked" , on_postpone )
362+ btn_postpone .set_visible (True )
363+ box_buttons .append (btn_postpone )
364+
365+ if show_skip :
366+ # Add the skip button
367+ btn_skip = Gtk .Button .new_with_label (_ ("Skip" ))
368+ btn_skip .get_style_context ().add_class ("btn_skip" )
369+ btn_skip .connect ("clicked" , on_skip )
370+ btn_skip .set_visible (True )
371+ box_buttons .append (btn_skip )
372+
373+ # Set values
374+ if image_path :
375+ img_break .set_from_file (image_path )
376+ lbl_message .set_label (message )
377+ lbl_widget .set_markup (widget )
378+
379+ def set_count_down (self , count ):
380+ self .lbl_count .set_text (count )
381+
382+ def __tray_action (self , button , tray_action : TrayAction ):
383+ """Tray action handler.
384+
385+ Hides all toolbar buttons for this action and call the action
386+ provided by the plugin.
387+ """
388+ if tray_action .single_use :
389+ tray_action .reset ()
390+ tray_action .action ()
391+
392+ def on_window_delete (self , * args ):
393+ """Window close event handler."""
394+ logging .info ("Closing the break screen" )
395+ self .on_close ()
0 commit comments