Skip to content

Commit 1feb867

Browse files
committed
stuff
1 parent b038e27 commit 1feb867

File tree

5 files changed

+68
-18
lines changed

5 files changed

+68
-18
lines changed

inputremapper/bin/input_remapper_gtk.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
import gi
3131

32+
from inputremapper.bin.process_utils import ProcessUtils
33+
3234
gi.require_version("Gtk", "3.0")
3335
gi.require_version("GLib", "2.0")
3436
gi.require_version("GtkSource", "4")
@@ -109,6 +111,12 @@ def main() -> Tuple[
109111
# by the user.
110112
reader_client = ReaderClient(message_broker, _Groups())
111113

114+
if ProcessUtils.count_python_processes("input-remapper-gtk") >= 2:
115+
logger.warning(
116+
"Another input-remapper GUI is already running. "
117+
"This can cause problems while recording keys"
118+
)
119+
112120
if not options.without_reader_service:
113121
try:
114122
ReaderService.pkexec_reader_service()

inputremapper/bin/input_remapper_reader_service.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@
2525
import os
2626
import signal
2727
import sys
28+
import time
2829
from argparse import ArgumentParser
2930

31+
from inputremapper.bin.process_utils import ProcessUtils
3032
from inputremapper.groups import _Groups
33+
from inputremapper.gui.reader_service import ReaderService
3134
from inputremapper.injection.global_uinputs import GlobalUInputs, FrontendUInput
3235
from inputremapper.logging.logger import logger
3336

@@ -47,8 +50,19 @@ def main() -> None:
4750

4851
logger.update_verbosity(options.debug)
4952

50-
# import input-remapper stuff after setting the log verbosity
51-
from inputremapper.gui.reader_service import ReaderService
53+
if ProcessUtils.count_python_processes("input-remapper-reader-service") >= 2:
54+
logger.warning(
55+
"Another input-remapper-reader-service process is already running. "
56+
"This can cause problems while recording keys"
57+
)
58+
59+
if os.getuid() != 0:
60+
logger.warning("The reader-service usually needs elevated privileges")
61+
62+
if not ReaderService.pipes_exist():
63+
while not ReaderService.pipes_exist():
64+
time.sleep(1)
65+
logger.debug("Waiting for pipes to be created")
5266

5367
def on_exit():
5468
"""Don't remain idle and alive when the GUI exits via ctrl+c."""

inputremapper/bin/process_utils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import psutil
2+
3+
4+
class ProcessUtils:
5+
@staticmethod
6+
def count_python_processes(name: str) -> int:
7+
# This is somewhat complicated, because there might also be a "sudo <name>"
8+
# process.
9+
count = 0
10+
pids = psutil.pids()
11+
for pid in pids:
12+
try:
13+
process = psutil.Process(pid)
14+
cmdline = process.cmdline()
15+
if len(cmdline) >= 2 and "python" in cmdline[0] and name in cmdline[1]:
16+
count += 1
17+
except Exception:
18+
pass
19+
20+
return count

inputremapper/gui/reader_client.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
CMD_TERMINATE,
4646
CMD_REFRESH_GROUPS,
4747
CMD_STOP_READING,
48-
get_pipe_paths,
4948
ReaderService,
5049
)
5150
from inputremapper.gui.utils import CTX_ERROR
@@ -120,8 +119,8 @@ def _send_command(self, command: str):
120119

121120
def connect(self):
122121
"""Connect to the reader-service."""
123-
results_pipe = Pipe(get_pipe_paths()[0])
124-
commands_pipe = Pipe(get_pipe_paths()[1])
122+
results_pipe = Pipe(ReaderService.get_pipe_paths()[0])
123+
commands_pipe = Pipe(ReaderService.get_pipe_paths()[1])
125124
return results_pipe, commands_pipe
126125

127126
def attach_to_events(self):

inputremapper/gui/reader_service.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
import sys
4747
import time
4848
from collections import defaultdict
49-
from typing import Set, List
49+
from typing import Set, List, Tuple
5050

5151
import evdev
5252
from evdev.ecodes import EV_KEY, EV_ABS, EV_REL, REL_HWHEEL, REL_WHEEL
@@ -80,14 +80,6 @@
8080
MSG_STATUS = "status"
8181

8282

83-
def get_pipe_paths():
84-
"""Get the path where the pipe can be found."""
85-
return (
86-
f"/tmp/input-remapper-{UserUtils.home}/reader-results",
87-
f"/tmp/input-remapper-{UserUtils.home}/reader-commands",
88-
)
89-
90-
9183
class ReaderService:
9284
"""Service that only reads events and is supposed to run as root.
9385
@@ -114,13 +106,13 @@ class ReaderService:
114106
_maximum_lifetime: int = 60 * 15
115107
_timeout_tolerance: int = 60
116108

117-
def __init__(self, groups: _Groups, global_uinputs: GlobalUInputs):
109+
def __init__(self, groups: _Groups, global_uinputs: GlobalUInputs) -> None:
118110
"""Construct the reader-service and initialize its communication pipes."""
119111
self._start_time = time.time()
120112
self.groups = groups
121113
self.global_uinputs = global_uinputs
122-
self._results_pipe = Pipe(get_pipe_paths()[0])
123-
self._commands_pipe = Pipe(get_pipe_paths()[1])
114+
self._results_pipe = Pipe(self.get_pipe_paths()[0])
115+
self._commands_pipe = Pipe(self.get_pipe_paths()[1])
124116
self._pipe = multiprocessing.Pipe()
125117

126118
self._tasks: Set[asyncio.Task] = set()
@@ -129,7 +121,24 @@ def __init__(self, groups: _Groups, global_uinputs: GlobalUInputs):
129121
self._results_pipe.send({"type": MSG_STATUS, "message": "ready"})
130122

131123
@staticmethod
132-
def is_running():
124+
def get_pipe_paths() -> Tuple[str, str]:
125+
"""Get the path where the pipe can be found."""
126+
return (
127+
f"/tmp/input-remapper-{UserUtils.home}/reader-results",
128+
f"/tmp/input-remapper-{UserUtils.home}/reader-commands",
129+
)
130+
131+
@staticmethod
132+
def pipes_exist() -> bool:
133+
# Just checking for one of the 4 files (results, commands both read and write)
134+
# should be enough I guess.
135+
path = f"{ReaderService.get_pipe_paths()[0]}r"
136+
# Use os.path.exists, not lexists or islink, because broken links are bad.
137+
# New pipes and symlinks need to be made.
138+
return os.path.exists(path)
139+
140+
@staticmethod
141+
def is_running() -> bool:
133142
"""Check if the reader-service is running."""
134143
try:
135144
subprocess.check_output(["pgrep", "-f", "input-remapper-reader-service"])

0 commit comments

Comments
 (0)