Merge 5dcfe196f4
into a3ca7b7639
This commit is contained in:
commit
db058ed917
|
@ -5,7 +5,7 @@
|
|||
"version": "0.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"python_modules": [],
|
||||
"python_modules": ["pywayland"],
|
||||
"shell_commands": [],
|
||||
"operating_systems": [],
|
||||
"desktop_environments": [],
|
||||
|
|
|
@ -25,6 +25,11 @@ def validate(plugin_config, plugin_settings):
|
|||
command = "dbus-send"
|
||||
elif utility.DESKTOP_ENVIRONMENT == "sway":
|
||||
command = "swayidle"
|
||||
elif utility.IS_WAYLAND:
|
||||
if not utility.module_exist("pywayland"):
|
||||
return _("Please install the Python module '%s'") % "pywayland"
|
||||
# no command needed with pywayland
|
||||
return None
|
||||
else:
|
||||
command = "xprintidle"
|
||||
if not utility.command_exist(command):
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
# Safe Eyes is a utility to remind you to take break frequently
|
||||
# to protect your eyes from eye strain.
|
||||
|
||||
# Copyright (C) 2017 Gobinath
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file is heavily inspired by https://github.com/juienpro/easyland/blob/efc26a0b22d7bdbb0f8436183428f7036da4662a/src/easyland/idle.py
|
||||
|
||||
import logging
|
||||
import threading
|
||||
import datetime
|
||||
|
||||
from pywayland.client import Display
|
||||
from pywayland.protocol.wayland.wl_seat import WlSeat
|
||||
from pywayland.protocol.ext_idle_notify_v1 import (
|
||||
ExtIdleNotificationV1,
|
||||
ExtIdleNotifierV1
|
||||
)
|
||||
|
||||
|
||||
class ExtIdleNotify:
|
||||
_idle_notifier = None
|
||||
_seat = None
|
||||
_notification = None
|
||||
_notifier_set = False
|
||||
_running = True
|
||||
_thread = None
|
||||
|
||||
_idle_since = None
|
||||
|
||||
def __init__(self):
|
||||
self._display = Display()
|
||||
self._display.connect()
|
||||
|
||||
def stop(self):
|
||||
self._running = False
|
||||
self._notification.destroy()
|
||||
self._notification = None
|
||||
self._seat = None
|
||||
self._thread.join()
|
||||
|
||||
def run(self):
|
||||
self._thread = threading.Thread(target=self._run, name="ExtIdleNotify", daemon=False)
|
||||
self._thread.start()
|
||||
|
||||
def _run(self):
|
||||
reg = self._display.get_registry()
|
||||
reg.dispatcher['global'] = self._global_handler
|
||||
|
||||
while self._running:
|
||||
self._display.dispatch(block=True)
|
||||
|
||||
self._display.disconnect()
|
||||
|
||||
def _global_handler(self, reg, id_num, iface_name, version):
|
||||
if iface_name == 'wl_seat':
|
||||
self._seat = reg.bind(id_num, WlSeat, version)
|
||||
if iface_name == "ext_idle_notifier_v1":
|
||||
self._idle_notifier = reg.bind(id_num, ExtIdleNotifierV1, version)
|
||||
|
||||
if self._idle_notifier and self._seat and not self._notifier_set:
|
||||
self._notifier_set = True
|
||||
timeout_sec = 1
|
||||
self._notification = self._idle_notifier.get_idle_notification(timeout_sec * 1000, self._seat)
|
||||
self._notification.dispatcher['idled'] = self._idle_notifier_handler
|
||||
self._notification.dispatcher['resumed'] = self._idle_notifier_resume_handler
|
||||
|
||||
def _idle_notifier_handler(self, notification):
|
||||
self._idle_since = datetime.datetime.now()
|
||||
|
||||
def _idle_notifier_resume_handler(self, notification):
|
||||
self._idle_since = None
|
||||
|
||||
def get_idle_time_seconds(self):
|
||||
if self._idle_since is None:
|
||||
return 0
|
||||
|
||||
result = datetime.datetime.now() - self._idle_since
|
||||
return result.total_seconds()
|
||||
|
||||
|
|
@ -46,11 +46,16 @@ waiting_time = 2
|
|||
is_wayland_and_gnome = False
|
||||
|
||||
use_swayidle = False
|
||||
use_ext_idle_notify = False
|
||||
swayidle_process = None
|
||||
swayidle_lock = threading.Lock()
|
||||
swayidle_idle = 0
|
||||
swayidle_active = 0
|
||||
|
||||
ext_idle_notify_lock = threading.Lock()
|
||||
ext_idle_notification_obj = None
|
||||
|
||||
# swayidle
|
||||
def __swayidle_running():
|
||||
return (swayidle_process is not None and
|
||||
swayidle_process.poll() is None)
|
||||
|
@ -88,6 +93,33 @@ def __swayidle_idle_time():
|
|||
return idle_time
|
||||
return 0
|
||||
|
||||
# ext idle
|
||||
def __start_ext_idle_monitor():
|
||||
global ext_idle_notification_obj
|
||||
|
||||
from .ext_idle_notify import ExtIdleNotify
|
||||
|
||||
ext_idle_notification_obj = ExtIdleNotify()
|
||||
ext_idle_notification_obj.run()
|
||||
|
||||
def __stop_ext_idle_monitor():
|
||||
global ext_idle_notification_obj
|
||||
|
||||
with ext_idle_notify_lock:
|
||||
if ext_idle_notification_obj is not None:
|
||||
ext_idle_notification_obj.stop()
|
||||
ext_idle_notification_obj = None;
|
||||
|
||||
def __ext_idle_idle_time():
|
||||
global ext_idle_notification_obj
|
||||
with ext_idle_notify_lock:
|
||||
if ext_idle_notification_obj is None:
|
||||
__start_ext_idle_monitor()
|
||||
else:
|
||||
return ext_idle_notification_obj.get_idle_time_seconds()
|
||||
return 0
|
||||
|
||||
# gnome
|
||||
def __gnome_wayland_idle_time():
|
||||
"""
|
||||
Determine system idle time in seconds, specifically for gnome with wayland.
|
||||
|
@ -119,6 +151,8 @@ def __system_idle_time():
|
|||
return __gnome_wayland_idle_time()
|
||||
elif use_swayidle:
|
||||
return __swayidle_idle_time()
|
||||
elif use_ext_idle_notify:
|
||||
return __ext_idle_idle_time()
|
||||
# Convert to seconds
|
||||
return int(subprocess.check_output(['xprintidle']).decode('utf-8')) / 1000
|
||||
except BaseException:
|
||||
|
@ -159,6 +193,7 @@ def init(ctx, safeeyes_config, plugin_config):
|
|||
global postpone_if_active
|
||||
global is_wayland_and_gnome
|
||||
global use_swayidle
|
||||
global use_ext_idle_notify
|
||||
logging.debug('Initialize Smart Pause plugin')
|
||||
context = ctx
|
||||
enable_safeeyes = context['api']['enable_safeeyes']
|
||||
|
@ -172,6 +207,7 @@ def init(ctx, safeeyes_config, plugin_config):
|
|||
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']
|
||||
use_swayidle = context['desktop'] == 'sway'
|
||||
use_ext_idle_notify = context['is_wayland'] and not use_swayidle and not is_wayland_and_gnome
|
||||
|
||||
|
||||
def __start_idle_monitor():
|
||||
|
@ -245,6 +281,9 @@ def on_stop():
|
|||
idle_condition.notify_all()
|
||||
idle_condition.release()
|
||||
|
||||
if use_ext_idle_notify:
|
||||
__stop_ext_idle_monitor()
|
||||
|
||||
|
||||
def update_next_break(break_obj, dateTime):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue