chore(repo): baseline du fork input-remapper (upstream v2.2.1)

Le dépôt ne contenait que README.md ; ajout de l'intégralité du code
fonctionnel du fork comme socle stable de la branche de release.
L'état runtime d'orchestration (.ideai/) est exclu du suivi.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 00:47:12 +02:00
parent 1d790a78fb
commit 0ab77d2a64
257 changed files with 51859 additions and 0 deletions

View File

@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
# input-remapper - GUI for device specific keyboard mappings
# Copyright (C) 2025 sezanzeb <b8x45ygc9@mozmail.com>
#
# This file is part of input-remapper.
#
# input-remapper 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.
#
# input-remapper 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 input-remapper. If not, see <https://www.gnu.org/licenses/>.
"""Logging setup for input-remapper."""
from __future__ import annotations # needed for the TYPE_CHECKING import
import logging
import time
from typing import cast, Type, TYPE_CHECKING, List, Tuple
from evdev.ecodes import EV_ABS, EV_KEY, EV_REL, ABS_HAT0X, ABS_HAT0Y
from inputremapper.input_event import InputEvent
from inputremapper.logging.formatter import ColorfulFormatter
from inputremapper.installation_info import VERSION, COMMIT_HASH
if TYPE_CHECKING:
from inputremapper.injection.mapping_handler import MappingHandler
start = time.time()
class Logger(logging.Logger):
previous_abs_rel_log_time = 0.0
previous_write_debug_log = None
analog_log_threshold = 0.1 # s
def debug_mapping_handler(self, mapping_handler: MappingHandler) -> None:
"""Parse the structure of a mapping_handler and log it."""
if not self.isEnabledFor(logging.DEBUG):
return
lines_and_indent = self._build_mapping_handler_description_tree(mapping_handler)
for line in lines_and_indent:
indent = " "
msg = indent * line[1] + line[0]
self._log(logging.DEBUG, msg, args=())
def write(self, key, uinput) -> None:
"""Log that an event is being written
Parameters
----------
key
anything that can be string formatted, but usually a tuple of
(type, code, value) tuples
"""
# pylint: disable=protected-access
if not self.isEnabledFor(logging.DEBUG):
return
if isinstance(key, InputEvent):
if key.type not in [EV_ABS, EV_REL, EV_KEY]:
return
# Avoid spaming the terminal with tons of high-resolution logs
now = time.time()
if key.type in [EV_ABS, EV_REL] and key.code not in [ABS_HAT0X, ABS_HAT0Y]:
if now - self.previous_abs_rel_log_time < self.analog_log_threshold:
return
self.previous_abs_rel_log_time = now
str_key = repr(key)
str_key = str_key.replace(",)", ")")
msg = f'Writing {str_key} to "{uinput.name}"'
if msg == self.previous_write_debug_log:
# avoid some spam
return
self.previous_write_debug_log = msg
self._log(logging.DEBUG, msg, args=(), stacklevel=2)
def _build_mapping_handler_description_tree(
self,
mapping_handler: MappingHandler,
indent=0,
) -> List[Tuple[str, int]]:
lines_and_indent = [
(str(mapping_handler), indent),
]
mapping_handlers = mapping_handler.get_children()
for sub_handler in mapping_handlers:
sub_list = self._build_mapping_handler_description_tree(
sub_handler, indent + 1
)
lines_and_indent.extend(sub_list)
return lines_and_indent
def is_debug(self) -> bool:
"""True, if the logger is currently in DEBUG mode."""
return self.level <= logging.DEBUG
def log_info(self, name: str = "input-remapper") -> None:
"""Log version and name to the console."""
logger.info(
"%s %s %s https://github.com/sezanzeb/input-remapper",
name,
VERSION,
COMMIT_HASH,
)
if EVDEV_VERSION:
logger.info("python-evdev %s", EVDEV_VERSION)
if self.is_debug():
logger.warning(
"Debug level will log all your keystrokes! Do not post this "
"output in the internet if you typed in sensitive or private "
"information with your device!"
)
def update_verbosity(self, debug: bool) -> None:
"""Set the logging verbosity according to the settings object."""
if debug:
self.setLevel(logging.DEBUG)
else:
self.setLevel(logging.INFO)
for handler in self.handlers:
handler.setFormatter(ColorfulFormatter(debug))
@classmethod
def bootstrap_logger(cls: Type[Logger]) -> Logger:
# https://github.com/python/typeshed/issues/1801
logging.setLoggerClass(cls)
logger = cast(Logger, logging.getLogger("input-remapper"))
handler = logging.StreamHandler()
handler.setFormatter(ColorfulFormatter(False))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logging.getLogger("asyncio").setLevel(logging.WARNING)
return logger
logger = Logger.bootstrap_logger()
EVDEV_VERSION = None
try:
from importlib.metadata import version
EVDEV_VERSION = version("evdev")
except Exception as error:
logger.info("Could not figure out the evdev version")
logger.debug(error)
# check if the version is something like 1.5.0-beta or 1.5.0-beta.5
IS_BETA = "beta" in VERSION