Reset breaks after being idle longer than a long break duration (#386)

This commit is contained in:
Gobinath 2020-10-25 08:44:29 -04:00 committed by GitHub
parent f0daa0ee96
commit 2736321048
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 18 deletions

View File

@ -79,7 +79,7 @@ class SafeEyesCore:
self.default_postpone_duration = config.get('postpone_duration') * 60 # Convert to seconds self.default_postpone_duration = config.get('postpone_duration') * 60 # Convert to seconds
self.postpone_duration = self.default_postpone_duration self.postpone_duration = self.default_postpone_duration
def start(self, next_break_time=-1): def start(self, next_break_time=-1, reset_breaks=False):
""" """
Start Safe Eyes is it is not running already. Start Safe Eyes is it is not running already.
""" """
@ -88,6 +88,10 @@ class SafeEyesCore:
with self.lock: with self.lock:
if not self.running: if not self.running:
logging.info("Start Safe Eyes core") logging.info("Start Safe Eyes core")
if reset_breaks:
logging.info("Reset breaks to start from the beginning")
self.break_queue.reset()
self.running = True self.running = True
self.scheduled_next_break_timestamp = int(next_break_time) self.scheduled_next_break_timestamp = int(next_break_time)
utility.start_thread(self.__scheduler_job) utility.start_thread(self.__scheduler_job)
@ -100,7 +104,7 @@ class SafeEyesCore:
if not self.running: if not self.running:
return return
logging.info("Stop Safe Eye core") logging.info("Stop Safe Eyes core")
self.paused_time = datetime.datetime.now().timestamp() self.paused_time = datetime.datetime.now().timestamp()
# Stop the break thread # Stop the break thread
self.waiting_condition.acquire() self.waiting_condition.acquire()

View File

@ -20,9 +20,10 @@
This module contains the entity classes used by Safe Eyes and its plugins. This module contains the entity classes used by Safe Eyes and its plugins.
""" """
import logging
from distutils.version import LooseVersion from distutils.version import LooseVersion
from enum import Enum from enum import Enum
import logging
from safeeyes import utility from safeeyes import utility
@ -92,6 +93,9 @@ class BreakQueue:
config.get('long_breaks'), config.get('long_breaks'),
self.__long_break_time, self.__long_break_time,
config.get('long_break_duration')) config.get('long_break_duration'))
self.__short_header = self.__short_pointer
self.__long_header = self.__long_pointer
# Restore the last break from session # Restore the last break from session
if not self.is_empty(): if not self.is_empty():
last_break = context['session'].get('break') last_break = context['session'].get('break')
@ -99,7 +103,7 @@ class BreakQueue:
current_break = self.get_break() current_break = self.get_break()
if last_break != current_break.name: if last_break != current_break.name:
pointer = self.next() pointer = self.next()
while(pointer != current_break and pointer.name != last_break): while pointer != current_break and pointer.name != last_break:
pointer = self.next() pointer = self.next()
def get_break(self): def get_break(self):
@ -154,6 +158,29 @@ class BreakQueue:
return break_obj return break_obj
def reset(self):
self.__short_pointer = self.__short_header
self.__long_pointer = self.__long_header
self.__first_break = None
self.__current_break = None
# Reset all break time
short_pointer = self.__short_pointer
long_pointer = self.__long_pointer
short_pointer.time = self.__short_break_time
long_pointer.time = self.__long_break_time
short_pointer = short_pointer.next
long_pointer = long_pointer.next
while short_pointer != self.__short_header:
short_pointer.time = self.__short_break_time
short_pointer = short_pointer.next
while long_pointer != self.__long_header:
long_pointer.time = self.__long_break_time
long_pointer = long_pointer.next
def is_empty(self): def is_empty(self):
return self.__short_pointer is None and self.__long_pointer is None return self.__short_pointer is None and self.__long_pointer is None

View File

@ -41,7 +41,7 @@ smart_pause_activated = False
idle_start_time = None idle_start_time = None
next_break_time = None next_break_time = None
next_break_duration = 0 next_break_duration = 0
break_interval = 0 short_break_interval = 0
waiting_time = 2 waiting_time = 2
interpret_idle_as_break = False interpret_idle_as_break = False
is_wayland_and_gnome = False is_wayland_and_gnome = False
@ -110,7 +110,8 @@ def init(ctx, safeeyes_config, plugin_config):
global disable_safe_eyes global disable_safe_eyes
global postpone global postpone
global idle_time global idle_time
global break_interval global short_break_interval
global long_break_interval
global waiting_time global waiting_time
global interpret_idle_as_break global interpret_idle_as_break
global postpone_if_active global postpone_if_active
@ -123,8 +124,10 @@ def init(ctx, safeeyes_config, plugin_config):
idle_time = plugin_config['idle_time'] idle_time = plugin_config['idle_time']
interpret_idle_as_break = plugin_config['interpret_idle_as_break'] interpret_idle_as_break = plugin_config['interpret_idle_as_break']
postpone_if_active = plugin_config['postpone_if_active'] postpone_if_active = plugin_config['postpone_if_active']
break_interval = safeeyes_config.get( short_break_interval = safeeyes_config.get(
'short_break_interval') * 60 # Convert to seconds 'short_break_interval') * 60 # Convert to seconds
long_break_interval = safeeyes_config.get(
'long_break_interval') * 60 # Convert to seconds
waiting_time = min(2, idle_time) # If idle time is 1 sec, wait only 1 sec waiting_time = min(2, idle_time) # If idle time is 1 sec, wait only 1 sec
is_wayland_and_gnome = context['desktop'] == 'gnome' and context['is_wayland'] is_wayland_and_gnome = context['desktop'] == 'gnome' and context['is_wayland']
@ -151,7 +154,7 @@ def __start_idle_monitor():
idle_start_time = datetime.datetime.now() idle_start_time = datetime.datetime.now()
logging.info('Pause Safe Eyes due to system idle') logging.info('Pause Safe Eyes due to system idle')
disable_safe_eyes(None) disable_safe_eyes(None)
elif system_idle_time < idle_time and context['state'] == State.STOPPED: elif system_idle_time < idle_time and context['state'] == State.STOPPED and idle_start_time is not None:
logging.info('Resume Safe Eyes due to user activity') logging.info('Resume Safe Eyes due to user activity')
smart_pause_activated = False smart_pause_activated = False
idle_period = (datetime.datetime.now() - idle_start_time) idle_period = (datetime.datetime.now() - idle_start_time)
@ -159,8 +162,8 @@ def __start_idle_monitor():
context['idle_period'] = idle_seconds context['idle_period'] = idle_seconds
if interpret_idle_as_break and idle_seconds >= next_break_duration: if interpret_idle_as_break and idle_seconds >= next_break_duration:
# User is idle for break duration and wants to consider it as a break # User is idle for break duration and wants to consider it as a break
enable_safe_eyes() enable_safe_eyes(-1, idle_seconds >= long_break_interval)
elif idle_seconds < break_interval: elif idle_seconds < short_break_interval:
# Credit back the idle time # Credit back the idle time
if next_break is not None: if next_break is not None:
# This method runs in a thread since the start. # This method runs in a thread since the start.

View File

@ -69,8 +69,8 @@ class SafeEyes:
self.show_settings) self.show_settings)
self.context['api']['show_about'] = lambda: utility.execute_main_thread( self.context['api']['show_about'] = lambda: utility.execute_main_thread(
self.show_about) self.show_about)
self.context['api']['enable_safeeyes'] = lambda next_break_time=- \ self.context['api']['enable_safeeyes'] = lambda next_break_time=-1, reset_breaks=False: \
1: utility.execute_main_thread(self.enable_safeeyes, next_break_time) utility.execute_main_thread(self.enable_safeeyes, next_break_time, reset_breaks)
self.context['api']['disable_safeeyes'] = lambda status: utility.execute_main_thread( self.context['api']['disable_safeeyes'] = lambda status: utility.execute_main_thread(
self.disable_safeeyes, status) self.disable_safeeyes, status)
self.context['api']['status'] = self.status self.context['api']['status'] = self.status
@ -230,13 +230,13 @@ class SafeEyes:
Timer(1.0, self.safe_eyes_core.start).start() Timer(1.0, self.safe_eyes_core.start).start()
self.plugins_manager.start() self.plugins_manager.start()
def enable_safeeyes(self, scheduled_next_break_time=-1): def enable_safeeyes(self, scheduled_next_break_time=-1, reset_breaks=False):
""" """
Listen to tray icon enable action and send the signal to core. Listen to tray icon enable action and send the signal to core.
""" """
if not self.active and self.safe_eyes_core.has_breaks(): if not self.active and self.safe_eyes_core.has_breaks():
self.active = True self.active = True
self.safe_eyes_core.start(scheduled_next_break_time) self.safe_eyes_core.start(scheduled_next_break_time, reset_breaks)
self.plugins_manager.start() self.plugins_manager.start()
def disable_safeeyes(self, status=None): def disable_safeeyes(self, status=None):

View File

@ -267,7 +267,7 @@ class SettingsDialog:
""" """
short_break_interval = self.spin_short_break_interval.get_value_as_int() short_break_interval = self.spin_short_break_interval.get_value_as_int()
long_break_interval = self.spin_long_break_interval.get_value_as_int() long_break_interval = self.spin_long_break_interval.get_value_as_int()
self.spin_long_break_interval.set_range(short_break_interval, 120) self.spin_long_break_interval.set_range(short_break_interval * 2, 120)
self.spin_long_break_interval.set_increments(short_break_interval, short_break_interval * 2) self.spin_long_break_interval.set_increments(short_break_interval, short_break_interval * 2)
self.spin_long_break_interval.set_value(short_break_interval * math.ceil(long_break_interval / self.last_short_break_interval)) self.spin_long_break_interval.set_value(short_break_interval * math.ceil(long_break_interval / self.last_short_break_interval))
self.last_short_break_interval = short_break_interval self.last_short_break_interval = short_break_interval

View File

@ -90,12 +90,25 @@ def start_thread(target_function, **args):
thread.start() thread.start()
def execute_main_thread(target_function, args=None): # def execute_main_thread(target_function, args=None):
# """
# Execute the given function in main thread.
# """
# if args:
# GLib.idle_add(lambda: target_function(args))
# else:
# GLib.idle_add(target_function)
def execute_main_thread(target_function, arg1=None, arg2=None):
""" """
Execute the given function in main thread. Execute the given function in main thread.
""" """
if args: if arg1 is not None and arg2 is not None:
GLib.idle_add(lambda: target_function(args)) GLib.idle_add(lambda: target_function(arg1, arg2))
elif arg1 is not None:
GLib.idle_add(lambda: target_function(arg1))
elif arg2 is not None:
GLib.idle_add(lambda: target_function(arg2))
else: else:
GLib.idle_add(target_function) GLib.idle_add(target_function)