Merge 5dcfe196f4
into a3ca7b7639
This commit is contained in:
commit
db058ed917
|
@ -5,7 +5,7 @@
|
||||||
"version": "0.0.3"
|
"version": "0.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"python_modules": [],
|
"python_modules": ["pywayland"],
|
||||||
"shell_commands": [],
|
"shell_commands": [],
|
||||||
"operating_systems": [],
|
"operating_systems": [],
|
||||||
"desktop_environments": [],
|
"desktop_environments": [],
|
||||||
|
|
|
@ -25,6 +25,11 @@ def validate(plugin_config, plugin_settings):
|
||||||
command = "dbus-send"
|
command = "dbus-send"
|
||||||
elif utility.DESKTOP_ENVIRONMENT == "sway":
|
elif utility.DESKTOP_ENVIRONMENT == "sway":
|
||||||
command = "swayidle"
|
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:
|
else:
|
||||||
command = "xprintidle"
|
command = "xprintidle"
|
||||||
if not utility.command_exist(command):
|
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
|
is_wayland_and_gnome = False
|
||||||
|
|
||||||
use_swayidle = False
|
use_swayidle = False
|
||||||
|
use_ext_idle_notify = False
|
||||||
swayidle_process = None
|
swayidle_process = None
|
||||||
swayidle_lock = threading.Lock()
|
swayidle_lock = threading.Lock()
|
||||||
swayidle_idle = 0
|
swayidle_idle = 0
|
||||||
swayidle_active = 0
|
swayidle_active = 0
|
||||||
|
|
||||||
|
ext_idle_notify_lock = threading.Lock()
|
||||||
|
ext_idle_notification_obj = None
|
||||||
|
|
||||||
|
# swayidle
|
||||||
def __swayidle_running():
|
def __swayidle_running():
|
||||||
return (swayidle_process is not None and
|
return (swayidle_process is not None and
|
||||||
swayidle_process.poll() is None)
|
swayidle_process.poll() is None)
|
||||||
|
@ -88,6 +93,33 @@ def __swayidle_idle_time():
|
||||||
return idle_time
|
return idle_time
|
||||||
return 0
|
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():
|
def __gnome_wayland_idle_time():
|
||||||
"""
|
"""
|
||||||
Determine system idle time in seconds, specifically for gnome with wayland.
|
Determine system idle time in seconds, specifically for gnome with wayland.
|
||||||
|
@ -119,6 +151,8 @@ def __system_idle_time():
|
||||||
return __gnome_wayland_idle_time()
|
return __gnome_wayland_idle_time()
|
||||||
elif use_swayidle:
|
elif use_swayidle:
|
||||||
return __swayidle_idle_time()
|
return __swayidle_idle_time()
|
||||||
|
elif use_ext_idle_notify:
|
||||||
|
return __ext_idle_idle_time()
|
||||||
# Convert to seconds
|
# Convert to seconds
|
||||||
return int(subprocess.check_output(['xprintidle']).decode('utf-8')) / 1000
|
return int(subprocess.check_output(['xprintidle']).decode('utf-8')) / 1000
|
||||||
except BaseException:
|
except BaseException:
|
||||||
|
@ -159,6 +193,7 @@ def init(ctx, safeeyes_config, plugin_config):
|
||||||
global postpone_if_active
|
global postpone_if_active
|
||||||
global is_wayland_and_gnome
|
global is_wayland_and_gnome
|
||||||
global use_swayidle
|
global use_swayidle
|
||||||
|
global use_ext_idle_notify
|
||||||
logging.debug('Initialize Smart Pause plugin')
|
logging.debug('Initialize Smart Pause plugin')
|
||||||
context = ctx
|
context = ctx
|
||||||
enable_safeeyes = context['api']['enable_safeeyes']
|
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
|
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']
|
||||||
use_swayidle = context['desktop'] == 'sway'
|
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():
|
def __start_idle_monitor():
|
||||||
|
@ -245,6 +281,9 @@ def on_stop():
|
||||||
idle_condition.notify_all()
|
idle_condition.notify_all()
|
||||||
idle_condition.release()
|
idle_condition.release()
|
||||||
|
|
||||||
|
if use_ext_idle_notify:
|
||||||
|
__stop_ext_idle_monitor()
|
||||||
|
|
||||||
|
|
||||||
def update_next_break(break_obj, dateTime):
|
def update_next_break(break_obj, dateTime):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue