Refactor idle module

- Get rid of sleepy.py, handle everything in idle.py
- Introduce one Monitor class that handles everything
This commit is contained in:
Philipp Hörist 2018-05-21 02:20:30 +02:00
parent 2e5d966f1d
commit c5df74c509
10 changed files with 212 additions and 257 deletions

View file

@ -276,8 +276,8 @@ def detect_dependencies():
# IDLE # IDLE
try: try:
from gajim.common import sleepy from gajim.common import idle
if sleepy.SUPPORTED: if idle.Monitor.is_available():
_dependencies['IDLE'] = True _dependencies['IDLE'] = True
except Exception: except Exception:
pass pass

View file

@ -61,6 +61,7 @@ from gajim.common import app
from gajim.common import gpg from gajim.common import gpg
from gajim.common import passwords from gajim.common import passwords
from gajim.common import i18n from gajim.common import i18n
from gajim.common import idle
from gajim.common.connection_handlers import * from gajim.common.connection_handlers import *
from gajim.common.contacts import GC_Contact from gajim.common.contacts import GC_Contact
from gajim.gtkgui_helpers import get_action from gajim.gtkgui_helpers import get_action
@ -596,7 +597,7 @@ class CommonConnection:
idle_time = None idle_time = None
if auto: if auto:
if app.is_installed('IDLE') and app.config.get('autoaway'): if app.is_installed('IDLE') and app.config.get('autoaway'):
idle_sec = int(app.interface.sleeper.getIdleSec()) idle_sec = idle.Monitor.get_idle_sec()
idle_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', idle_time = time.strftime('%Y-%m-%dT%H:%M:%SZ',
time.gmtime(time.time() - idle_sec)) time.gmtime(time.time() - idle_sec))
app.nec.push_incoming_event(BeforeChangeShowEvent(None, app.nec.push_incoming_event(BeforeChangeShowEvent(None,
@ -2025,8 +2026,8 @@ class Connection(CommonConnection, ConnectionHandlers):
if signed: if signed:
p.setTag(nbxmpp.NS_SIGNED + ' x').setData(signed) p.setTag(nbxmpp.NS_SIGNED + ' x').setData(signed)
if idle_time: if idle_time:
idle = p.setTag('idle', namespace=nbxmpp.NS_IDLE) idle_node = p.setTag('idle', namespace=nbxmpp.NS_IDLE)
idle.setAttr('since', idle_time) idle_node.setAttr('since', idle_time)
if self.connection: if self.connection:
self.connection.send(p) self.connection.send(p)
self.priority = priority self.priority = priority
@ -2761,11 +2762,11 @@ class Connection(CommonConnection, ConnectionHandlers):
self.add_lang(p) self.add_lang(p)
if auto: if auto:
if app.is_installed('IDLE') and app.config.get('autoaway'): if app.is_installed('IDLE') and app.config.get('autoaway'):
idle_sec = int(app.interface.sleeper.getIdleSec()) idle_sec = idle.Monitor.get_idle_sec()
idle_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', idle_time = time.strftime('%Y-%m-%dT%H:%M:%SZ',
time.gmtime(time.time() - idle_sec)) time.gmtime(time.time() - idle_sec))
idle = p.setTag('idle', namespace=nbxmpp.NS_IDLE) idle_node = p.setTag('idle', namespace=nbxmpp.NS_IDLE)
idle.setAttr('since', idle_time) idle_node.setAttr('since', idle_time)
# send instantly so when we go offline, status is sent to gc before we # send instantly so when we go offline, status is sent to gc before we
# disconnect from jabber server # disconnect from jabber server
self.connection.send(p) self.connection.send(p)

View file

@ -48,6 +48,7 @@ from gajim.common import app
from gajim.common import dataforms from gajim.common import dataforms
from gajim.common import jingle_xtls from gajim.common import jingle_xtls
from gajim.common import configpaths from gajim.common import configpaths
from gajim.common import idle
from gajim.common.caps_cache import muc_caps_cache from gajim.common.caps_cache import muc_caps_cache
from gajim.common.commands import ConnectionCommands from gajim.common.commands import ConnectionCommands
from gajim.common.pubsub import ConnectionPubSub from gajim.common.pubsub import ConnectionPubSub
@ -1730,7 +1731,7 @@ ConnectionHTTPUpload):
'send_idle_time'): 'send_idle_time'):
iq_obj = obj.stanza.buildReply('result') iq_obj = obj.stanza.buildReply('result')
qp = iq_obj.setQuery() qp = iq_obj.setQuery()
qp.attrs['seconds'] = int(app.interface.sleeper.getIdleSec()) qp.attrs['seconds'] = idle.Monitor.get_idle_sec()
else: else:
iq_obj = obj.stanza.buildReply('error') iq_obj = obj.stanza.buildReply('error')
err = nbxmpp.ErrorNode(name=nbxmpp.NS_STANZAS + \ err = nbxmpp.ErrorNode(name=nbxmpp.NS_STANZAS + \

View file

@ -106,6 +106,12 @@ class JIDConstant(IntEnum):
NORMAL_TYPE = 0 NORMAL_TYPE = 0
ROOM_TYPE = 1 ROOM_TYPE = 1
@unique
class IdleState(IntEnum):
UNKNOWN = 0
XA = 1
AWAY = 2
AWAKE = 3
SSLError = { SSLError = {
2: _("Unable to get issuer certificate"), 2: _("Unable to get issuer certificate"),

View file

@ -1,30 +1,35 @@
## src/common/idle.py #
## # Copyright (C) 2003-2014 Yann Leboulanger <asterix AT lagaule.org>
## (C) 2008 Thorsten P. 'dGhvcnN0ZW5wIEFUIHltYWlsIGNvbQ==\n'.decode("base64") # Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com>
## # Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
## This file is part of Gajim. # Copyright (C) 2008 Mateusz Biliński <mateusz AT bilinski.it>
## # Copyright (C) 2008 Thorsten P. 'dGhvcnN0ZW5wIEFUIHltYWlsIGNvbQ==\n'.decode("base64")
## Gajim is free software; you can redistribute it and/or modify # Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
## it under the terms of the GNU General Public License as published #
## by the Free Software Foundation; version 3 only. # This file is part of Gajim.
## #
## Gajim is distributed in the hope that it will be useful, # Gajim is free software; you can redistribute it and/or modify
## but WITHOUT ANY WARRANTY; without even the implied warranty of # it under the terms of the GNU General Public License as published
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # by the Free Software Foundation; version 3 only.
## GNU General Public License for more details. #
## # Gajim is distributed in the hope that it will be useful,
## You should have received a copy of the GNU General Public License # but WITHOUT ANY WARRANTY; without even the implied warranty of
## along with Gajim. If not, see <http://www.gnu.org/licenses/>. # 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 Gajim. If not, see <http://www.gnu.org/licenses/>.
import sys
import ctypes import ctypes
import ctypes.util import ctypes.util
import logging import logging
from gi.repository import Gio from gi.repository import Gio
from gi.repository import GLib from gi.repository import GLib
log = logging.getLogger('gajim.c.idle') from gajim.common.const import IdleState
idle_monitor = None log = logging.getLogger('gajim.c.idle')
class DBusGnomeIdleMonitor: class DBusGnomeIdleMonitor:
@ -52,38 +57,41 @@ class DBusGnomeIdleMonitor:
def _get_idle_sec_fail(self): def _get_idle_sec_fail(self):
(idle_time,) = self.dbus_gnome_proxy.call_sync( (idle_time,) = self.dbus_gnome_proxy.call_sync(
'GetIdletime', 'GetIdletime',
None, None,
Gio.DBusCallFlags.NO_AUTO_START, Gio.DBusCallFlags.NO_AUTO_START,
-1, -1,
None None
) )
return int(idle_time / 1000) return int(idle_time / 1000)
def get_idle_sec(self): def get_idle_sec(self):
try: try:
self.last_idle_time = self._get_idle_sec_fail() self.last_idle_time = self._get_idle_sec_fail()
except GLib.Error as e: except GLib.Error as error:
log.warning( log.warning(
'org.gnome.Mutter.IdleMonitor.GetIdletime() failed: %s', 'org.gnome.Mutter.IdleMonitor.GetIdletime() failed: %s',
repr(e)) error)
return self.last_idle_time return self.last_idle_time
def is_extended_away(self):
class XScreenSaverInfo(ctypes.Structure): return False
_fields_ = [
('window', ctypes.c_ulong),
('state', ctypes.c_int),
('kind', ctypes.c_int),
('til_or_since', ctypes.c_ulong),
('idle', ctypes.c_ulong),
('eventMask', ctypes.c_ulong)
]
class XssIdleMonitor: class XssIdleMonitor:
def __init__(self): def __init__(self):
class XScreenSaverInfo(ctypes.Structure):
_fields_ = [
('window', ctypes.c_ulong),
('state', ctypes.c_int),
('kind', ctypes.c_int),
('til_or_since', ctypes.c_ulong),
('idle', ctypes.c_ulong),
('eventMask', ctypes.c_ulong)
]
XScreenSaverInfo_p = ctypes.POINTER(XScreenSaverInfo) XScreenSaverInfo_p = ctypes.POINTER(XScreenSaverInfo)
display_p = ctypes.c_void_p display_p = ctypes.c_void_p
@ -91,7 +99,7 @@ class XssIdleMonitor:
c_int_p = ctypes.POINTER(ctypes.c_int) c_int_p = ctypes.POINTER(ctypes.c_int)
libX11path = ctypes.util.find_library('X11') libX11path = ctypes.util.find_library('X11')
if libX11path == None: if libX11path is None:
raise OSError('libX11 could not be found.') raise OSError('libX11 could not be found.')
libX11 = ctypes.cdll.LoadLibrary(libX11path) libX11 = ctypes.cdll.LoadLibrary(libX11path)
libX11.XOpenDisplay.restype = display_p libX11.XOpenDisplay.restype = display_p
@ -100,60 +108,151 @@ class XssIdleMonitor:
libX11.XDefaultRootWindow.argtypes = display_p, libX11.XDefaultRootWindow.argtypes = display_p,
libXsspath = ctypes.util.find_library('Xss') libXsspath = ctypes.util.find_library('Xss')
if libXsspath == None: if libXsspath is None:
raise OSError('libXss could not be found.') raise OSError('libXss could not be found.')
self.libXss = ctypes.cdll.LoadLibrary(libXsspath) self.libXss = ctypes.cdll.LoadLibrary(libXsspath)
self.libXss.XScreenSaverQueryExtension.argtypes = display_p, c_int_p, c_int_p self.libXss.XScreenSaverQueryExtension.argtypes = display_p, c_int_p, c_int_p
self.libXss.XScreenSaverAllocInfo.restype = XScreenSaverInfo_p self.libXss.XScreenSaverAllocInfo.restype = XScreenSaverInfo_p
self.libXss.XScreenSaverQueryInfo.argtypes = (display_p, xid, XScreenSaverInfo_p) self.libXss.XScreenSaverQueryInfo.argtypes = (
display_p, xid, XScreenSaverInfo_p)
self.dpy_p = libX11.XOpenDisplay(None) self.dpy_p = libX11.XOpenDisplay(None)
if self.dpy_p == None: if self.dpy_p is None:
raise OSError('Could not open X Display.') raise OSError('Could not open X Display.')
_event_basep = ctypes.c_int() _event_basep = ctypes.c_int()
_error_basep = ctypes.c_int() _error_basep = ctypes.c_int()
if self.libXss.XScreenSaverQueryExtension(self.dpy_p, ctypes.byref(_event_basep), extension = self.libXss.XScreenSaverQueryExtension(
ctypes.byref(_error_basep)) == 0: self.dpy_p, ctypes.byref(_event_basep), ctypes.byref(_error_basep))
if extension == 0:
raise OSError('XScreenSaver Extension not available on display.') raise OSError('XScreenSaver Extension not available on display.')
self.xss_info_p = self.libXss.XScreenSaverAllocInfo() self.xss_info_p = self.libXss.XScreenSaverAllocInfo()
if self.xss_info_p == None: if self.xss_info_p is None:
raise OSError('XScreenSaverAllocInfo: Out of Memory.') raise OSError('XScreenSaverAllocInfo: Out of Memory.')
self.rootwindow = libX11.XDefaultRootWindow(self.dpy_p) self.rootwindow = libX11.XDefaultRootWindow(self.dpy_p)
def get_idle_sec(self): def get_idle_sec(self):
if self.libXss.XScreenSaverQueryInfo( info = self.libXss.XScreenSaverQueryInfo(
self.dpy_p, self.dpy_p, self.rootwindow, self.xss_info_p)
self.rootwindow, if info == 0:
self.xss_info_p) == 0: return info
return 0 return int(self.xss_info_p.contents.idle / 1000)
def is_extended_away(self):
return False
class WindowsIdleMonitor:
OpenInputDesktop = ctypes.windll.user32.OpenInputDesktop
CloseDesktop = ctypes.windll.user32.CloseDesktop
SystemParametersInfo = ctypes.windll.user32.SystemParametersInfoW
GetTickCount = ctypes.windll.kernel32.GetTickCount
GetLastInputInfo = ctypes.windll.user32.GetLastInputInfo
def __init__(self):
class LASTINPUTINFO(ctypes.Structure):
_fields_ = [('cbSize', ctypes.c_uint), ('dwTime', ctypes.c_uint)]
self.lastInputInfo = LASTINPUTINFO()
self.lastInputInfo.cbSize = ctypes.sizeof(self.lastInputInfo)
def get_idle_sec(self):
self.GetLastInputInfo(ctypes.byref(self.lastInputInfo))
return float(self.GetTickCount() - self.lastInputInfo.dwTime) / 1000
def is_extended_away(self):
# Check if Screen Saver is running
# 0x72 is SPI_GETSCREENSAVERRUNNING
saver_runing = ctypes.c_int(0)
info = self.SystemParametersInfo(0x72, 0, ctypes.byref(saver_runing), 0)
if info and saver_runing.value:
return True
# Check if Screen is locked
desk = self.OpenInputDesktop(0, False, 0)
if not desk:
return True
self.CloseDesktop(desk)
return False
class IdleMonitor:
def __init__(self):
self.set_interval()
self._state = IdleState.AWAKE
self._idle_monitor = self._get_idle_monitor()
def set_interval(self, away_interval=60, xa_interval=120):
log.info('Set interval: away: %s, xa: %s',
away_interval, xa_interval)
self._away_interval = away_interval
self._xa_interval = xa_interval
def is_available(self):
return self._idle_monitor is not None
def state(self):
if not self.is_available():
return IdleState.UNKNOWN
return self._state
def is_xa(self):
return self.state == IdleState.XA
def is_away(self):
return self.state == IdleState.AWAY
def is_awake(self):
return self.state == IdleState.AWAKE
def is_unknown(self):
return self.state == IdleState.UNKNOWN
def _get_idle_monitor(self):
if sys.platform == 'win32':
return WindowsIdleMonitor()
try:
return DBusGnomeIdleMonitor()
except GLib.Error as error:
log.info('Idle time via D-Bus not available: %s', error)
try:
return XssIdleMonitor()
except OSError as error:
log.info('Idle time via XScreenSaverInfo '
'not available: %s', error)
def get_idle_sec(self):
return self._idle_monitor.get_idle_sec()
def poll(self):
"""
Check to see if we should change state
"""
if not self.is_available():
return False
if self._idle_monitor.is_extended_away():
log.info('Extended Away: Screensaver or Locked Screen')
self._state = IdleState.XA
return True
idle_time = self.get_idle_sec()
log.info('Idle time: %s', idle_time)
# xa is stronger than away so check for xa first
if idle_time > self._xa_interval:
self._state = IdleState.XA
elif idle_time > self._away_interval:
self._state = IdleState.AWAY
else: else:
return int(self.xss_info_p.contents.idle / 1000) self._state = IdleState.AWAKE
return True
def getIdleSec(): Monitor = IdleMonitor()
"""
Return the idle time in seconds
"""
if idle_monitor is None:
return 0
else:
return idle_monitor.get_idle_sec()
try:
idle_monitor = DBusGnomeIdleMonitor()
except GLib.Error as e:
log.info("Idle time via D-Bus not available: %s", repr(e))
try:
idle_monitor = XssIdleMonitor()
except OSError as e:
log.info("Idle time via XScreenSaverInfo not available: %s", repr(e))
raise Exception('No supported idle monitor found')
if __name__ == '__main__':
import time
time.sleep(2.1)
print(getIdleSec())

View file

@ -1,147 +0,0 @@
# -*- coding:utf-8 -*-
## src/common/sleepy.py
##
## Copyright (C) 2003-2014 Yann Leboulanger <asterix AT lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com>
## Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
## Copyright (C) 2008 Mateusz Biliński <mateusz AT bilinski.it>
##
## This file is part of Gajim.
##
## Gajim 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; version 3 only.
##
## Gajim 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 Gajim. If not, see <http://www.gnu.org/licenses/>.
##
from gajim.common import app
import os
import logging
log = logging.getLogger('gajim.c.sleepy')
STATE_UNKNOWN = 'OS probably not supported'
STATE_XA = 'extended away'
STATE_AWAY = 'away'
STATE_AWAKE = 'awake'
SUPPORTED = True
try:
if os.name == 'nt':
import ctypes
GetTickCount = ctypes.windll.kernel32.GetTickCount
GetLastInputInfo = ctypes.windll.user32.GetLastInputInfo
class LASTINPUTINFO(ctypes.Structure):
_fields_ = [('cbSize', ctypes.c_uint), ('dwTime', ctypes.c_uint)]
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo)
# one or more of these may not be supported before XP.
OpenInputDesktop = ctypes.windll.user32.OpenInputDesktop
CloseDesktop = ctypes.windll.user32.CloseDesktop
SystemParametersInfo = ctypes.windll.user32.SystemParametersInfoW
else: # unix
from gajim.common import idle
except Exception:
log.warning('Unable to load idle module')
SUPPORTED = False
class SleepyWindows:
def __init__(self, away_interval = 60, xa_interval = 120):
self.away_interval = away_interval
self.xa_interval = xa_interval
self.state = STATE_AWAKE # assume we are awake
def getIdleSec(self):
GetLastInputInfo(ctypes.byref(lastInputInfo))
idleDelta = float(GetTickCount() - lastInputInfo.dwTime) / 1000
return idleDelta
def poll(self):
"""
Check to see if we should change state
"""
if not SUPPORTED:
return False
# screen saver, in windows >= XP
saver_runing = ctypes.c_int(0)
# 0x72 is SPI_GETSCREENSAVERRUNNING
if SystemParametersInfo(0x72, 0, ctypes.byref(saver_runing), 0) and \
saver_runing.value:
self.state = STATE_XA
return True
desk = OpenInputDesktop(0, False, 0)
if not desk:
# Screen locked
self.state = STATE_XA
return True
CloseDesktop(desk)
idleTime = self.getIdleSec()
# xa is stronger than away so check for xa first
if idleTime > self.xa_interval:
self.state = STATE_XA
elif idleTime > self.away_interval:
self.state = STATE_AWAY
else:
self.state = STATE_AWAKE
return True
def getState(self):
return self.state
def setState(self, val):
self.state = val
class SleepyUnix:
def __init__(self, away_interval = 60, xa_interval = 120):
global SUPPORTED
self.away_interval = away_interval
self.xa_interval = xa_interval
self.state = STATE_AWAKE # assume we are awake
def getIdleSec(self):
return idle.getIdleSec()
def poll(self):
"""
Check to see if we should change state
"""
if not SUPPORTED:
return False
idleTime = self.getIdleSec()
# xa is stronger than away so check for xa first
if idleTime > self.xa_interval:
self.state = STATE_XA
elif idleTime > self.away_interval:
self.state = STATE_AWAY
else:
self.state = STATE_AWAKE
return True
def getState(self):
return self.state
def setState(self, val):
self.state = val
if os.name == 'nt':
Sleepy = SleepyWindows
else:
Sleepy = SleepyUnix

View file

@ -40,7 +40,7 @@ from gi.repository import GObject
from gi.repository import GLib from gi.repository import GLib
from gajim.common import config as c_config from gajim.common import config as c_config
from gajim.common import sleepy from gajim.common import idle
from gajim.common.i18n import Q_ from gajim.common.i18n import Q_
from gajim import gtkgui_helpers from gajim import gtkgui_helpers
@ -353,7 +353,7 @@ class PreferencesWindow:
self.auto_xa_message_entry.set_text(st) self.auto_xa_message_entry.set_text(st)
self.auto_xa_message_entry.set_sensitive(app.config.get('autoxa')) self.auto_xa_message_entry.set_sensitive(app.config.get('autoxa'))
if not sleepy.SUPPORTED: if not idle.Monitor.is_available():
self.xml.get_object('autoaway_table').set_sensitive(False) self.xml.get_object('autoaway_table').set_sensitive(False)
# ask_status when online / offline # ask_status when online / offline
@ -925,9 +925,8 @@ class PreferencesWindow:
def on_auto_away_time_spinbutton_value_changed(self, widget): def on_auto_away_time_spinbutton_value_changed(self, widget):
aat = widget.get_value_as_int() aat = widget.get_value_as_int()
app.config.set('autoawaytime', aat) app.config.set('autoawaytime', aat)
app.interface.sleeper = sleepy.Sleepy( idle.Monitor.set_interval(app.config.get('autoawaytime') * 60,
app.config.get('autoawaytime') * 60, app.config.get('autoxatime') * 60)
app.config.get('autoxatime') * 60)
def on_auto_away_message_entry_changed(self, widget): def on_auto_away_message_entry_changed(self, widget):
app.config.set('autoaway_message', widget.get_text()) app.config.set('autoaway_message', widget.get_text())
@ -939,9 +938,8 @@ class PreferencesWindow:
def on_auto_xa_time_spinbutton_value_changed(self, widget): def on_auto_xa_time_spinbutton_value_changed(self, widget):
axt = widget.get_value_as_int() axt = widget.get_value_as_int()
app.config.set('autoxatime', axt) app.config.set('autoxatime', axt)
app.interface.sleeper = sleepy.Sleepy( idle.Monitor.set_interval(app.config.get('autoawaytime') * 60,
app.config.get('autoawaytime') * 60, app.config.get('autoxatime') * 60)
app.config.get('autoxatime') * 60)
def on_auto_xa_message_entry_changed(self, widget): def on_auto_xa_message_entry_changed(self, widget):
app.config.set('autoxa_message', widget.get_text()) app.config.set('autoxa_message', widget.get_text())

View file

@ -163,8 +163,8 @@ class FeaturesWindow:
return app.is_installed('GSPELL') return app.is_installed('GSPELL')
def idle_available(self): def idle_available(self):
from gajim.common import sleepy from gajim.common import idle
return sleepy.SUPPORTED return idle.Monitor.is_available()
def pycrypto_available(self): def pycrypto_available(self):
return app.is_installed('PYCRYPTO') return app.is_installed('PYCRYPTO')
@ -181,4 +181,3 @@ class FeaturesWindow:
def gupnp_igd_available(self): def gupnp_igd_available(self):
return app.is_installed('UPNP') return app.is_installed('UPNP')

View file

@ -79,7 +79,7 @@ from gajim.filetransfers_window import FileTransfersWindow
from gajim.atom_window import AtomWindow from gajim.atom_window import AtomWindow
from gajim.session import ChatControlSession from gajim.session import ChatControlSession
from gajim.common import sleepy from gajim.common import idle
from nbxmpp import idlequeue from nbxmpp import idlequeue
from nbxmpp import Hashes2 from nbxmpp import Hashes2
@ -1114,13 +1114,13 @@ class Interface:
app.logger.insert_jid(obj.conn.get_own_jid().getStripped()) app.logger.insert_jid(obj.conn.get_own_jid().getStripped())
account = obj.conn.name account = obj.conn.name
app.block_signed_in_notifications[account] = True app.block_signed_in_notifications[account] = True
state = self.sleeper.getState()
connected = obj.conn.connected connected = obj.conn.connected
if state != sleepy.STATE_UNKNOWN and connected in (2, 3):
if idle.Monitor.is_unknown() and connected in (2, 3):
# we go online or free for chat, so we activate auto status # we go online or free for chat, so we activate auto status
app.sleeper_state[account] = 'online' app.sleeper_state[account] = 'online'
elif not ((state == sleepy.STATE_AWAY and connected == 4) or \ elif not ((idle.Monitor.is_away() and connected == 4) or \
(state == sleepy.STATE_XA and connected == 5)): (idle.Monitor.is_xa() and connected == 5)):
# If we are autoaway/xa and come back after a disconnection, do # If we are autoaway/xa and come back after a disconnection, do
# nothing # nothing
# Else disable autoaway # Else disable autoaway
@ -2239,15 +2239,15 @@ class Interface:
""" """
Check idle status and change that status if needed Check idle status and change that status if needed
""" """
if not self.sleeper.poll(): if not idle.Monitor.poll():
# idle detection is not supported in that OS # idle detection is not supported in that OS
return False # stop looping in vain return False # stop looping in vain
state = self.sleeper.getState()
for account in app.connections: for account in app.connections:
if account not in app.sleeper_state or \ if account not in app.sleeper_state or \
not app.sleeper_state[account]: not app.sleeper_state[account]:
continue continue
if state == sleepy.STATE_AWAKE: if idle.Monitor.is_awake():
if app.sleeper_state[account] in ('autoaway', 'autoxa'): if app.sleeper_state[account] in ('autoaway', 'autoxa'):
# we go online # we go online
self.roster.send_status(account, 'online', self.roster.send_status(account, 'online',
@ -2261,7 +2261,7 @@ class Interface:
app.status_before_autoaway[account]) app.status_before_autoaway[account])
app.status_before_autoaway[account] = '' app.status_before_autoaway[account] = ''
app.sleeper_state[account] = 'off' app.sleeper_state[account] = 'off'
elif state == sleepy.STATE_AWAY and app.config.get('autoaway'): elif idle.Monitor.is_away() and app.config.get('autoaway'):
if app.sleeper_state[account] == 'online': if app.sleeper_state[account] == 'online':
# we save out online status # we save out online status
app.status_before_autoaway[account] = \ app.status_before_autoaway[account] = \
@ -2288,7 +2288,7 @@ class Interface:
self.roster.send_status(account, app.SHOW_LIST[connected], self.roster.send_status(account, app.SHOW_LIST[connected],
app.status_before_autoaway[account], auto=True) app.status_before_autoaway[account], auto=True)
app.sleeper_state[account] = 'idle' app.sleeper_state[account] = 'idle'
elif state == sleepy.STATE_XA and \ elif idle.Monitor.is_xa() and \
app.sleeper_state[account] in ('online', 'autoaway', app.sleeper_state[account] in ('online', 'autoaway',
'autoaway-forced') and app.config.get('autoxa'): 'autoaway-forced') and app.config.get('autoxa'):
# we go extended away [we pass True to auto param] # we go extended away [we pass True to auto param]
@ -2913,9 +2913,8 @@ class Interface:
self.show_vcard_when_connect = [] self.show_vcard_when_connect = []
self.sleeper = sleepy.Sleepy( idle.Monitor.set_interval(app.config.get('autoawaytime') * 60,
app.config.get('autoawaytime') * 60, # make minutes to seconds app.config.get('autoxatime') * 60)
app.config.get('autoxatime') * 60)
gtkgui_helpers.make_jabber_state_images() gtkgui_helpers.make_jabber_state_images()

View file

@ -46,7 +46,6 @@ import locale
from enum import IntEnum, unique from enum import IntEnum, unique
from gajim.common import sleepy
from gajim import history_window from gajim import history_window
from gajim import dialogs from gajim import dialogs
from gajim import vcard from gajim import vcard
@ -62,6 +61,7 @@ from gajim.common.const import AvatarSize
from gajim.common import app from gajim.common import app
from gajim.common import helpers from gajim.common import helpers
from gajim.common import idle
from gajim.common.exceptions import GajimGeneralException from gajim.common.exceptions import GajimGeneralException
from gajim.common import i18n from gajim.common import i18n
if app.is_installed('GEOCLUE'): if app.is_installed('GEOCLUE'):
@ -2125,8 +2125,7 @@ class RosterWindow:
def send_status_continue(self, account, status, txt, auto, to): def send_status_continue(self, account, status, txt, auto, to):
if app.account_is_connected(account) and not to: if app.account_is_connected(account) and not to:
if status == 'online' and app.interface.sleeper.getState() != \ if status == 'online' and not idle.Monitor.is_unknown():
sleepy.STATE_UNKNOWN:
app.sleeper_state[account] = 'online' app.sleeper_state[account] = 'online'
elif app.sleeper_state[account] not in ('autoaway', 'autoxa') or \ elif app.sleeper_state[account] not in ('autoaway', 'autoxa') or \
status == 'offline': status == 'offline':