Compare commits

...

9 Commits

Author SHA1 Message Date
DanyloTrofymov a189045971
Merge a3ce172bef into 137dd6b2ff 2025-10-14 22:29:25 -04:00
MistificaT0r 137dd6b2ff update Russian translation 2025-10-14 19:25:57 -04:00
DanyloTrofymov a3ce172bef
Merge pull request #1 from DanyloTrofymov/master
master to use_english
2025-08-19 13:00:22 +03:00
Danylo Trofymov 95ac6d5670 fix: merge conflict 2025-08-19 13:00:09 +03:00
DanyloTrofymov b465be2468 setup: fix 2024-04-23 14:55:52 +03:00
DanyloTrofymov 6d06cd9561 fix: ruff format 2024-04-23 14:49:21 +03:00
DanyloTrofymov d1796d2950 fix: ruff format 2024-04-23 14:46:43 +03:00
DanyloTrofymov 0dac92deb2
Update setup.py 2024-04-23 14:25:09 +03:00
DanyloTrofymov 6bfd6a7b94 switcher: added language switcher 2024-04-23 14:17:45 +03:00
8 changed files with 1135 additions and 1006 deletions

View File

@ -24,7 +24,6 @@ which is MIT licensed.
"""
from __future__ import annotations
import atexit
import ctypes
import logging

View File

@ -28,6 +28,7 @@ import subprocess
import sys
import time
import typing
import threading
from typing import Any
from typing import Dict
@ -46,6 +47,8 @@ if platform.system() in ("Darwin", "Windows"):
else:
import evdev
from . import language_switcher as _language_switcher
from .common import NamedInt
from .hidpp20 import SupportedFeature
from .special_keys import CONTROL
@ -57,7 +60,7 @@ if typing.TYPE_CHECKING:
from .base import HIDPPNotification
logger = logging.getLogger(__name__)
switcher = _language_switcher.LanguageSwitcher()
#
# See docs/rules.md for documentation
#
@ -1550,7 +1553,22 @@ def process_notification(device, notification: HIDPPNotification, feature) -> No
thumb_wheel_displacement = 0
thumb_wheel_displacement += signed(notification.data[0:2])
GLib.idle_add(evaluate_rules, feature, notification, device)
def switch_and_evaluate(feature, notification, device):
done_switching = threading.Event()
def switch_language():
switcher.evaluate()
done_switching.set()
def evaluate_rules():
done_switching.wait() # Wait until the language has been switched
rules.evaluate(feature, notification, device, True)
switcher.set_previous_language()
GLib.idle_add(switch_language)
GLib.idle_add(evaluate_rules)
GLib.idle_add(switch_and_evaluate, feature, notification, device)
_XDG_CONFIG_HOME = os.environ.get("XDG_CONFIG_HOME") or os.path.expanduser(os.path.join("~", ".config"))

View File

@ -0,0 +1,82 @@
import logging
import subprocess
from xkbgroup import X11Error
from xkbgroup import XKeyboard
logger = logging.getLogger(__name__)
# it would be better to use xkbgroup to switch language, but I don't know how to work with it
class LanguageSwitcher:
def __init__(self):
self.xkb = None
try:
self.xkb = XKeyboard()
except X11Error as e:
logger.error(f"Cannot initialize XKeyboard: {e}")
self.previous_layout = None
def get_current_layout(self):
"""Gets the current keyboard layout (language)."""
try:
result = subprocess.run(["setxkbmap", "-query"], capture_output=True, text=True)
for line in result.stdout.splitlines():
if "layout:" in line:
return line.split(":")[1].strip()
except Exception as e:
logger.error(f"Failed to get current keyboard layout: {e}")
return None
def get_current_language(self):
"""Gets the current keyboard layout (language)."""
try:
# xkb used because setxkbmap shows only layout, but not language. So we need to use xkb to check current language
return self.xkb.group_symbol
except Exception as e:
logger.error(f"Failed to get current keyboard layout: {e}")
return None
def remember_layout(self, language):
"""Remembers the previous language."""
self.previous_layout = language
logger.debug(f"Remembered language: {self.previous_layout}")
# switch to english using setxkbmap because xkbgroup switching seems to be asynctounous and I don't know how work with it
# you can use xkbgroup to switch to english. just remember previous_language instead of layout
# and use self.xkb.group_symbol = "us", self.xkb.group_symbol = previous_language
def switch_language_to_english(self):
"""Switches the keyboard layout to English."""
try:
subprocess.run(["setxkbmap", "us"], check=True)
logger.debug("Switched keyboard layout to English.")
except subprocess.CalledProcessError as e:
logger.error(f"Failed to switch to English layout: {e}")
def set_previous_language(self):
"""Sets the keyboard layout back to the previously remembered language."""
if self.previous_layout:
try:
subprocess.run(["setxkbmap", self.previous_layout], check=True)
logger.debug(f"Restored keyboard layout to {self.previous_layout}.")
except subprocess.CalledProcessError as e:
logger.error(f"Failed to restore previous layout: {e}")
finally:
self.previous_layout = None
else:
logger.warning("No previous language was remembered.")
def evaluate(self):
"""Evaluate the current language and switch to English if it's not already English."""
if not self.xkb:
logger.warning("X11 display not accessible. Skipping get_current_language.")
return None
current_language = self.get_current_language()
logger.debug(f"Current language: {current_language}")
if current_language != "us":
current_layout = self.get_current_layout()
logger.debug(f"Current layout: {current_layout}")
self.remember_layout(current_layout)
self.switch_language_to_english()

View File

@ -90,7 +90,6 @@ def process_receiver_notification(receiver: Receiver, notification: HIDPPNotific
Notification.RAW_INPUT,
Notification.POWER,
]
logger.warning(f"{receiver}: unhandled notification {notification}")

View File

@ -678,7 +678,6 @@ class FeatureRWMap(FeatureRW):
reply = device.feature_request(self.feature, self.write_fnid, key_bytes, data_bytes, no_reply=self.no_reply)
return reply if not self.no_reply else True
class ActionSettingRW:
"""Special RW class for settings that turn on and off special processing when a key or button is depressed"""

1017
po/ru.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -77,6 +77,7 @@ setup(
'dbus-python ; platform_system=="Linux"',
"PyGObject",
"typing_extensions",
"xkbgroup",
],
extras_require={
"report-descriptor": ["hid-parser"],