diff --git a/README.md b/README.md index 6256bd3..baf00e1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Python X11 transcription daemon that records audio, runs Whisper, logs the trans - `soundfile` (libsndfile) - `faster-whisper` - Tray icon deps: `gtk3` -- Python deps: `pillow`, `python-xlib`, `faster-whisper`, `PyGObject`, `i3ipc`, `sounddevice`, `soundfile` +- Python deps: `pillow`, `python-xlib`, `faster-whisper`, `PyGObject`, `sounddevice`, `soundfile` System packages (example names): `portaudio`/`libportaudio2` and `libsndfile`. @@ -84,11 +84,6 @@ AI provider: - Generic OpenAI-compatible chat API at `ai_base_url` (base URL only; the app uses `/v1/chat/completions`) -Context capture (i3 only): - -- The focused window at hotkey time is stored via i3 IPC. -- If focus changes before injection, the workflow aborts (interpreted as a cancel). - Control: ```bash diff --git a/pyproject.toml b/pyproject.toml index 811b853..76c6345 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ dependencies = [ "pillow", "python-xlib", "PyGObject", - "i3ipc", "sounddevice", "soundfile", ] diff --git a/src/context.py b/src/context.py deleted file mode 100644 index 09ab567..0000000 --- a/src/context.py +++ /dev/null @@ -1,43 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass - -import i3ipc - - -@dataclass -class Context: - window_id: int - app_id: str - klass: str - instance: str - title: str - - -class I3Provider: - def __init__(self): - self._conn = i3ipc.Connection() - - def _focused(self): - return self._conn.get_tree().find_focused() - - def capture(self) -> Context: - node = self._focused() - return Context( - window_id=node.id, - app_id=node.app_id or "", - klass=node.window_class or "", - instance=node.window_instance or "", - title=node.name or "", - ) - - def is_same_focus(self, ctx: Context) -> bool: - node = self._focused() - return bool(node and node.id == ctx.window_id) - - def focus_window(self, window_id: int) -> bool: - try: - self._conn.command(f"[con_id={window_id}] focus") - return True - except Exception: - return False diff --git a/src/leld.py b/src/leld.py index 6566bc5..43123a2 100755 --- a/src/leld.py +++ b/src/leld.py @@ -13,7 +13,6 @@ from config import Config, load, redacted_dict from recorder import start_recording, stop_recording from stt import FasterWhisperSTT, STTConfig from aiprocess import AIConfig, build_processor -from context import I3Provider from inject import inject from x11_hotkey import listen from tray import run_tray @@ -35,8 +34,6 @@ class Daemon: self.proc = None self.record = None self.timer = None - self.context = None - self.context_provider = I3Provider() self.stt = FasterWhisperSTT( STTConfig( model=cfg.transcribing.get("model", "base"), @@ -75,23 +72,6 @@ class Daemon: except Exception as exc: logging.error("record start failed: %s", exc) return - try: - if self.context_provider: - self.context = self.context_provider.capture() - except Exception as exc: - logging.error("context capture failed: %s", exc) - self.context = None - if self.context: - logging.info( - "context: id=%s app_id=%s class=%s instance=%s title=%s", - self.context.window_id, - self.context.app_id, - self.context.klass, - self.context.instance, - self.context.title, - ) - else: - logging.info("context: none") self.proc = proc self.record = record self.state = State.RECORDING @@ -179,11 +159,6 @@ class Daemon: try: self.set_state(State.OUTPUTTING) logging.info("outputting started") - if self.context_provider and self.context: - if not self.context_provider.is_same_focus(self.context): - logging.info("focus changed, aborting injection") - self.set_state(State.IDLE) - return backend = self.cfg.injection.get("backend", "clipboard") inject(text, backend) except Exception as exc: @@ -191,16 +166,6 @@ class Daemon: finally: self.set_state(State.IDLE) - def _context_json(self, ctx): - if not ctx: - return None - return { - "window_id": ctx.window_id, - "app_id": ctx.app_id, - "class": ctx.klass, - "instance": ctx.instance, - "title": ctx.title, - } def stop_recording(self): with self.lock: diff --git a/uv.lock b/uv.lock index 23044d4..c35c48a 100644 --- a/uv.lock +++ b/uv.lock @@ -373,18 +373,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/ae/2f6d96b4e6c5478d87d606a1934b5d436c4a2bce6bb7c6fdece891c128e3/huggingface_hub-1.4.1-py3-none-any.whl", hash = "sha256:9931d075fb7a79af5abc487106414ec5fba2c0ae86104c0c62fd6cae38873d18", size = 553326, upload-time = "2026-02-06T09:20:00.728Z" }, ] -[[package]] -name = "i3ipc" -version = "2.2.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "python-xlib" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/f3/dfab70c888d85d3e933ff4d6b351aaed0ae137a29c896e03e364de3bec94/i3ipc-2.2.1.tar.gz", hash = "sha256:e880d7d7147959ead5cb34764f08b97b41385b36eb8256e8af1ce163dbcccce8", size = 47760, upload-time = "2020-04-05T17:25:08.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/30/294b07ddeccb58855c890c3ef3a951c3b0c1e2d089666d548b6a9edc39fb/i3ipc-2.2.1-py3-none-any.whl", hash = "sha256:c0b898223d50d42c90c818deb5033d1304c582755547dee7d15df3e3781bc690", size = 26591, upload-time = "2020-04-05T17:25:07.338Z" }, -] - [[package]] name = "idna" version = "3.11" @@ -400,7 +388,6 @@ version = "0.0.0" source = { virtual = "." } dependencies = [ { name = "faster-whisper" }, - { name = "i3ipc" }, { name = "pillow" }, { name = "pygobject" }, { name = "python-xlib" }, @@ -411,7 +398,6 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "faster-whisper" }, - { name = "i3ipc" }, { name = "pillow" }, { name = "pygobject" }, { name = "python-xlib" },