Merge pull request #452 from lopsided98/hidpp-4.5-fixes

Fix errors related to sleep and power on/off (especially HID++ >=2.0 devices).

Closes #414 by @SonicFrog who originally came up with a similar fix for the connection notice.
This commit is contained in:
Peter Wu 2018-08-11 16:26:25 +02:00 committed by GitHub
commit 336b778398
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 29 additions and 18 deletions

View File

@ -150,7 +150,7 @@ class EventsListener(_threading.Thread):
# replace the handle with a threaded one
self.receiver.handle = _ThreadedHandle(self, self.receiver.path, self.receiver.handle)
# get the right low-level handle for this thead
# get the right low-level handle for this thread
ihandle = int(self.receiver.handle)
if _log.isEnabledFor(_INFO):
_log.info("started with %s (%d)", self.receiver, ihandle)

View File

@ -164,14 +164,14 @@ def _process_hidpp10_notification(device, status, n):
assert wpid == device.wpid, "%s wpid mismatch, got %s" % (device, wpid)
flags = ord(n.data[:1]) & 0xF0
link_encrypyed = bool(flags & 0x20)
link_encrypted = bool(flags & 0x20)
link_established = not (flags & 0x40)
if _log.isEnabledFor(_DEBUG):
sw_present = bool(flags & 0x10)
has_payload = bool(flags & 0x80)
_log.debug("%s: %s connection notification: software=%s, encrypted=%s, link=%s, payload=%s",
device, protocol_name, sw_present, link_encrypyed, link_established, has_payload)
status[_K.LINK_ENCRYPTED] = link_encrypyed
device, protocol_name, sw_present, link_encrypted, link_established, has_payload)
status[_K.LINK_ENCRYPTED] = link_encrypted
status.changed(active=link_established)
else:
_log.warn("%s: connection notification with unknown protocol %02X: %s", device.number, n.address, n)

View File

@ -67,10 +67,11 @@ def attach_to(device, changed_callback):
assert device
assert changed_callback
if device.kind is None:
device.status = ReceiverStatus(device, changed_callback)
else:
device.status = DeviceStatus(device, changed_callback)
if not hasattr(device, 'status') or device.status is None:
if device.kind is None:
device.status = ReceiverStatus(device, changed_callback)
else:
device.status = DeviceStatus(device, changed_callback)
#
#

View File

@ -18,6 +18,7 @@
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from __future__ import absolute_import, division, print_function, unicode_literals
import time
from logging import getLogger, INFO as _INFO
_log = getLogger(__name__)
@ -181,11 +182,20 @@ class ReceiverListener(_listener.EventsListener):
return
# a device notification
assert n.devnumber > 0 and n.devnumber <= self.receiver.max_devices
assert 0 < n.devnumber <= self.receiver.max_devices
already_known = n.devnumber in self.receiver
if n.sub_id == 0x41:
already_known = False
# FIXME: hacky fix for kernel/hardware race condition
# If the device was just turned on or woken up from sleep, it may not
# be ready to receive commands. The "payload" bit of the wireless
# status notification seems to tell us this. If this is the case, we
# must wait a short amount of time to avoid causing a broken pipe
# error.
device_ready = not bool(ord(n.data[0:1]) & 0x80) or n.sub_id != 0x41
if not device_ready:
time.sleep(0.01)
if n.sub_id == 0x41 and not already_known:
dev = self.receiver.register_new_device(n.devnumber, n)
else:
dev = self.receiver[n.devnumber]
@ -194,7 +204,8 @@ class ReceiverListener(_listener.EventsListener):
_log.warn("%s: received %s for invalid device %d: %r", self.receiver, n, n.devnumber, dev)
return
if not already_known:
# Apply settings every time the device connects
if n.sub_id == 0x41:
if _log.isEnabledFor(_INFO):
_log.info("%s triggered new device %s (%s)", n, dev, dev.kind)
# If there are saved configs, bring the device's settings up-to-date.
@ -213,8 +224,7 @@ class ReceiverListener(_listener.EventsListener):
if _log.isEnabledFor(_INFO):
_log.info("%s: pairing detected new device", self.receiver)
self.receiver.status.new_device = dev
elif dev:
if dev.online is None:
elif dev.online is None:
dev.ping()
def __str__(self):

View File

@ -75,7 +75,7 @@ def error_dialog(reason, object):
#
_task_runner = None
def async(function, *args, **kwargs):
def ui_async(function, *args, **kwargs):
if _task_runner:
_task_runner(function, *args, **kwargs)
@ -90,7 +90,7 @@ def _startup(app, startup_hook):
if _log.isEnabledFor(_DEBUG):
_log.debug("startup registered=%s, remote=%s", app.get_is_registered(), app.get_is_remote())
from solaar.async import TaskRunner as _TaskRunner
from solaar.tasks import TaskRunner as _TaskRunner
global _task_runner
_task_runner = _TaskRunner('AsyncUI')
_task_runner.start()

View File

@ -23,7 +23,7 @@ from gi.repository import Gtk, GLib
from threading import Timer as _Timer
from solaar.i18n import _
from solaar.ui import async as _ui_async
from solaar.ui import ui_async as _ui_async
from logitech_receiver.settings import KIND as _SETTING_KIND
#

View File

@ -31,7 +31,7 @@ from solaar import NAME
from solaar.i18n import _
from gettext import ngettext
# from solaar import __version__ as VERSION
from solaar.ui import async as _ui_async
from solaar.ui import ui_async as _ui_async
from logitech_receiver import hidpp10 as _hidpp10
from logitech_receiver.common import NamedInts as _NamedInts, NamedInt as _NamedInt
from logitech_receiver.status import KEYS as _K