Skip to content

Commit

Permalink
Fixed non-returning method decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasBoss committed Dec 22, 2022
1 parent 1ed7d89 commit 51a24b1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 45 deletions.
67 changes: 24 additions & 43 deletions inputremapper/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
import asyncio
import atexit
import functools
import inspect
import json
import os
import sys
import time
import tracemalloc
import typing
from pathlib import PurePath
from typing import Protocol, Dict, Optional, Callable
from typing import Protocol, Dict, Optional

from dbus_next.aio import MessageBus
from dbus_next import BusType, service, RequestNameReply
Expand All @@ -52,6 +54,7 @@
from inputremapper.injection.macros.macro import macro_variables
from inputremapper.injection.global_uinputs import global_uinputs

tracemalloc.start()

BUS_NAME = "inputremapper.Control"
PATH_NAME = "/inputremapper/Control"
Expand Down Expand Up @@ -152,6 +155,18 @@ def hello(self, out: str) -> str:
...


def method(name: str = None, disabled: bool = False):
# this is a workaround for https://github.com/altdesktop/python-dbus-next/issues/119
@typing.no_type_check_decorator
def fixed_decorator(fn):
# we don't actually decorate the function
# dbus-next only cares about the __dict__
fn.__dict__ = service.method(name, disabled)(fn).__dict__
return fn

return fixed_decorator


class Daemon(service.ServiceInterface):
"""Starts injecting keycodes based on the configuration.
Expand All @@ -163,40 +178,6 @@ class Daemon(service.ServiceInterface):
on its own.
"""

# https://dbus.freedesktop.org/doc/dbus-specification.html#type-system
dbus = f"""
<node>
<interface name='{BUS_NAME}'>
<method name='stop_injecting'>
<arg type='s' name='group_key' direction='in'/>
</method>
<method name='get_state'>
<arg type='s' name='group_key' direction='in'/>
<arg type='s' name='response' direction='out'/>
</method>
<method name='start_injecting'>
<arg type='s' name='group_key' direction='in'/>
<arg type='s' name='preset' direction='in'/>
<arg type='b' name='response' direction='out'/>
</method>
<method name='stop_all'>
</method>
<method name='set_config_dir'>
<arg type='s' name='config_dir' direction='in'/>
</method>
<method name='autoload'>
</method>
<method name='autoload_single'>
<arg type='s' name='group_key' direction='in'/>
</method>
<method name='hello'>
<arg type='s' name='out' direction='in'/>
<arg type='s' name='response' direction='out'/>
</method>
</interface>
</node>
"""

def __init__(self):
"""Constructs the daemon."""
logger.debug("Creating daemon")
Expand Down Expand Up @@ -313,7 +294,7 @@ async def refresh(self, group_key: Optional[str] = None):
groups.refresh()
self.refreshed_devices_at = now

@service.method()
@method()
def stop_injecting(self, group_key: "s"):
"""Stop injecting the preset mappings for a single device."""
if self.injectors.get(group_key) is None:
Expand All @@ -326,13 +307,13 @@ def stop_injecting(self, group_key: "s"):
self.injectors[group_key].stop_injecting()
self.autoload_history.forget(group_key)

@service.method()
@method()
def get_state(self, group_key: "s") -> "s":
"""Get the injectors state."""
injector = self.injectors.get(group_key)
return injector.get_state() if injector else InjectorState.UNKNOWN

@service.method()
@method()
def set_config_dir(self, config_dir: "s"):
"""All future operations will use this config dir.
Expand Down Expand Up @@ -393,7 +374,7 @@ async def _autoload(self, group_key: str):
await self.start_injecting(group.key, preset)
self.autoload_history.remember(group.key, preset)

@service.method()
@method()
async def autoload_single(self, group_key: "s"):
"""Inject the configured autoload preset for the device.
Expand All @@ -420,7 +401,7 @@ async def autoload_single(self, group_key: "s"):

await self._autoload(group_key)

@service.method()
@method()
async def autoload(self):
"""Load all autoloaded presets for the current config_dir.
Expand All @@ -444,7 +425,7 @@ async def autoload(self):
for group_key, _ in autoload_presets:
await self._autoload(group_key)

@service.method()
@method()
async def start_injecting(self, group_key: "s", preset: "s") -> "b":
"""Start injecting the preset for the device.
Expand Down Expand Up @@ -535,14 +516,14 @@ async def start_injecting(self, group_key: "s", preset: "s") -> "b":

return True

@service.method()
@method()
def stop_all(self):
"""Stop all injections."""
logger.info("Stopping all injections")
for group_key in list(self.injectors.keys()):
self.stop_injecting(group_key)

@service.method()
@method()
def hello(self, out: "s") -> "s":
"""Used for tests."""
logger.info('Received "%s" from client', out)
Expand Down
17 changes: 15 additions & 2 deletions inputremapper/injection/injector.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,21 @@ def _create_forwarding_device(self, source: evdev.InputDevice) -> evdev.UInput:
raise e
return forward_to

def is_alive(self) -> bool:
"""used in tests, can probably be removed, previously defined by the
multiprocessing.Process superclass"""
return self._alive

async def run(self) -> None:
self._alive = True
try:
await self._run()
except:
self._alive = False
raise
self._alive = False

async def _run(self) -> None:
"""The injection worker that keeps injecting until terminated.
Stuff is non-blocking by using asyncio in order to do multiple things
Expand All @@ -386,7 +400,6 @@ async def run(self) -> None:
Use this function as starting point in a process. It creates
the loops needed to read and map events and keeps running them.
"""
self._alive = True
logger.info('Starting injecting the preset for "%s"', self.group.key)

# create a new event loop, because somehow running an infinite loop
Expand Down Expand Up @@ -414,6 +427,7 @@ async def run(self) -> None:
# maybe the preset was empty or something
logger.error("Did not grab any device")
self._msg_pipe[0].send(InjectorState.NO_GRAB)
self._alive = False
return

numlock_state = is_numlock_on()
Expand Down Expand Up @@ -465,4 +479,3 @@ async def run(self) -> None:
logger.debug("OSError for ungrab on %s: %s", source.path, str(error))

self._msg_pipe[0].send(InjectorState.STOPPED)
self._alive = False

0 comments on commit 51a24b1

Please sign in to comment.