04/23 Enhance app functionalities

This commit is contained in:
2026-04-23 16:54:24 -04:00
parent 64419a445a
commit f4eea48e4d
8 changed files with 427 additions and 45 deletions
+30 -2
View File
@@ -39,8 +39,12 @@ class App(tk.Tk):
self.current_user = None
self._idle_timer = None # after() handle for timeout
self._warning_timer = None # after() handle for 1-min warning
self._idle_last_reset = 0.0 # monotonic timestamp of last actual reset
# Bind all user activity events to reset the idle timer
# Bind all user activity events to reset the idle timer.
# <Motion> fires continuously — the handler throttles itself to at most
# once every 5 seconds so we don't schedule/cancel hundreds of after()
# handles per second during normal mouse movement.
for event in ("<Motion>", "<KeyPress>", "<ButtonPress>", "<MouseWheel>"):
self.bind_all(event, self._reset_idle_timer, add="+")
@@ -333,11 +337,35 @@ class App(tk.Tk):
# ─── Session Timeout ──────────────────────────────────────────────────────
# Minimum interval (seconds) between idle-timer resets triggered by
# continuous events like <Motion>. KeyPress / ButtonPress always reset
# immediately (they are infrequent by nature).
_IDLE_THROTTLE_S = 5.0
def _reset_idle_timer(self, event=None):
"""Cancel any pending timeout/warning timers and restart them."""
"""Cancel any pending timeout/warning timers and restart them.
Throttled for <Motion> events: the timer is only rescheduled if at
least _IDLE_THROTTLE_S seconds have elapsed since the last reset.
This prevents hundreds of after_cancel/after() calls per second
during normal mouse movement without affecting correctness.
"""
if not self.current_user:
return # not logged in — nothing to time out
import time
# Throttle continuous motion events; discrete actions always go through
if event and getattr(event, "type", None) is not None:
try:
# EventType.Motion == 6 in tkinter
if int(event.type) == 6:
now = time.monotonic()
if now - self._idle_last_reset < self._IDLE_THROTTLE_S:
return
self._idle_last_reset = now
except Exception:
pass
if self._idle_timer:
self.after_cancel(self._idle_timer)
if self._warning_timer: