Improvements to "interpret idle as break" #551

This commit is contained in:
AdamPS 2023-11-30 17:06:20 +00:00
parent 777d48603d
commit 903d407faf
6 changed files with 22 additions and 35 deletions

View File

@ -104,7 +104,6 @@
"version": "0.0.3",
"settings": {
"idle_time": 5,
"interpret_idle_as_break": false,
"postpone_if_active": false
}
},

View File

@ -96,7 +96,7 @@ class SafeEyesCore:
self.scheduled_next_break_timestamp = int(next_break_time)
utility.start_thread(self.__scheduler_job)
def stop(self):
def stop(self, is_resting=False):
"""
Stop Safe Eyes if it is running.
"""
@ -110,7 +110,7 @@ class SafeEyesCore:
self.waiting_condition.acquire()
self.running = False
if self.context['state'] != State.QUIT:
self.context['state'] = State.STOPPED
self.context['state'] = State.RESTING if (is_resting) else State.STOPPED
self.waiting_condition.notify_all()
self.waiting_condition.release()
@ -174,7 +174,7 @@ class SafeEyesCore:
self.running = False
self.waiting_condition.notify_all()
self.waiting_condition.release()
time.sleep(1) # Wait for 1 sec to ensure the sceduler is dead
time.sleep(1) # Wait for 1 sec to ensure the scheduler is dead
self.running = True
if break_type is not None and self.break_queue.get_break().type != break_type:
@ -188,7 +188,6 @@ class SafeEyesCore:
if not self.running:
return
self.context['state'] = State.WAITING
# Convert to seconds
time_to_wait = self.break_queue.get_break().time * 60
current_time = datetime.datetime.now()
@ -200,20 +199,21 @@ class SafeEyesCore:
time_to_wait = self.postpone_duration
self.context['postponed'] = False
elif self.paused_time > -1 and self.break_queue.is_long_break():
# Safe Eyes was paused earlier and next break is long
elif self.context['state'] == State.RESTING and self.paused_time > -1:
# Safe Eyes was resting
paused_duration = int(current_timestamp - self.paused_time)
self.paused_time = -1
if paused_duration > self.break_queue.get_break().duration:
logging.info('Skip next long break due to the pause longer than break duration')
if paused_duration > self.break_queue.get_break(BreakType.LONG_BREAK).duration:
logging.info('Skip next long break due to the pause %ds longer than break duration', paused_duration)
# Skip the next long break
self.break_queue.next()
self.break_queue.reset()
if current_timestamp < self.scheduled_next_break_timestamp:
time_to_wait = round(self.scheduled_next_break_timestamp - current_timestamp)
self.scheduled_next_break_timestamp = -1
self.scheduled_next_break_time = current_time + datetime.timedelta(seconds=time_to_wait)
self.context['state'] = State.WAITING
utility.execute_main_thread(self.__fire_on_update_next_break, self.scheduled_next_break_time)
# Wait for the pre break warning period

View File

@ -258,12 +258,13 @@ class State(Enum):
"""
Possible states of Safe Eyes.
"""
START = 0,
WAITING = 1,
PRE_BREAK = 2,
BREAK = 3,
STOPPED = 4,
QUIT = 5
START = 0, # Starting scheduler
WAITING = 1, # User is working (waiting for next break)
PRE_BREAK = 2, # Preparing for break
BREAK = 3, # Break
STOPPED = 4, # Disabled
QUIT = 5, # Quitting
RESTING = 6 # Resting (natural break)
class EventHook:

View File

@ -20,12 +20,6 @@
"max": 3600,
"min": 5
},
{
"id": "interpret_idle_as_break",
"label": "Interpret idle time equivalent to upcoming break duration as a break",
"type": "BOOL",
"default": false
},
{
"id": "postpone_if_active",
"label": "Postpone the next break until the system becomes idle",

View File

@ -43,7 +43,6 @@ next_break_time = None
next_break_duration = 0
short_break_interval = 0
waiting_time = 2
interpret_idle_as_break = False
is_wayland_and_gnome = False
use_swayidle = False
@ -157,7 +156,6 @@ def init(ctx, safeeyes_config, plugin_config):
global short_break_interval
global long_break_duration
global waiting_time
global interpret_idle_as_break
global postpone_if_active
global is_wayland_and_gnome
global use_swayidle
@ -167,7 +165,6 @@ def init(ctx, safeeyes_config, plugin_config):
disable_safeeyes = context['api']['disable_safeeyes']
postpone = context['api']['postpone']
idle_time = plugin_config['idle_time']
interpret_idle_as_break = plugin_config['interpret_idle_as_break']
postpone_if_active = plugin_config['postpone_if_active']
short_break_interval = safeeyes_config.get(
'short_break_interval') * 60 # Convert to seconds
@ -197,18 +194,14 @@ def __start_idle_monitor():
smart_pause_activated = True
idle_start_time = datetime.datetime.now() - datetime.timedelta(seconds=system_idle_time)
logging.info('Pause Safe Eyes due to system idle')
disable_safeeyes(None)
elif system_idle_time < idle_time and context['state'] == State.STOPPED and idle_start_time is not None:
disable_safeeyes(None, True)
elif system_idle_time < idle_time and context['state'] == State.RESTING and idle_start_time is not None:
logging.info('Resume Safe Eyes due to user activity')
smart_pause_activated = False
idle_period = (datetime.datetime.now() - idle_start_time)
idle_seconds = idle_period.total_seconds()
context['idle_period'] = idle_seconds
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
logging.debug("Idle for %d seconds, long break %d", idle_seconds, long_break_duration)
enable_safe_eyes(-1, idle_seconds >= long_break_duration)
elif idle_seconds < short_break_interval:
if idle_seconds < short_break_interval:
# Credit back the idle time
if next_break_time is not None:
# This method runs in a thread since the start.

View File

@ -158,7 +158,7 @@ class SafeEyes:
if self.active:
logging.info("Stop Safe Eyes due to system suspend")
self.plugins_manager.stop()
self.safe_eyes_core.stop()
self.safe_eyes_core.stop(True)
else:
# Resume from sleep
if self.active and self.safe_eyes_core.has_breaks():
@ -239,14 +239,14 @@ class SafeEyes:
self.safe_eyes_core.start(scheduled_next_break_time, reset_breaks)
self.plugins_manager.start()
def disable_safeeyes(self, status=None):
def disable_safeeyes(self, status=None, is_resting = False):
"""
Listen to tray icon disable action and send the signal to core.
"""
if self.active:
self.active = False
self.plugins_manager.stop()
self.safe_eyes_core.stop()
self.safe_eyes_core.stop(is_resting)
if status is None:
status = _('Disabled until restart')
self._status = status