Fix actions on sub widgets

this also broke somewhere along the line. I couldn't find it spelled
out in CHANGELOG and this feels like a workaround, but that's all I
got right now.

hey at least I could get rid of the escape-key workaround!
This commit is contained in:
Jeff Epler 2025-04-21 08:49:54 +02:00
parent 82b2e979f0
commit 9f35490cd5

View file

@ -30,8 +30,6 @@ import pyotp
import platformdirs import platformdirs
import tomllib import tomllib
from textual._ansi_sequences import ANSI_SEQUENCES_KEYS
from textual.keys import Keys
from typing import TypeGuard # use `typing_extensions` for Python 3.9 and below from typing import TypeGuard # use `typing_extensions` for Python 3.9 and below
# workaround for pyperclip being un-typed # workaround for pyperclip being un-typed
@ -54,12 +52,6 @@ def is_str_list(val: Any) -> TypeGuard[list[str]]:
return all(isinstance(x, str) for x in val) return all(isinstance(x, str) for x in val)
# Monkeypatch escape key as meaning "F9", WFM
# ignore typing here because ANSI_SEQUENCES_KEYS is a Mapping[] which is read-only as
# far as mypy is concerned.
ANSI_SEQUENCES_KEYS["\x1b\x1b"] = (Keys.F9,) # type: ignore
# Copied from pyotp with the issuer mismatch check removed and HTOP support removed # Copied from pyotp with the issuer mismatch check removed and HTOP support removed
def parse_uri(uri: str) -> pyotp.TOTP: def parse_uri(uri: str) -> pyotp.TOTP:
""" """
@ -134,7 +126,26 @@ def parse_uri(uri: str) -> pyotp.TOTP:
default_conffile = platformdirs.user_config_path("ttotp") / "settings.toml" default_conffile = platformdirs.user_config_path("ttotp") / "settings.toml"
class TOTPLabel(Label, can_focus=True): class _common_actions:
app: Any # avoid mypy diagnostics about properties of self.app
def action_focus_next(self) -> None:
self.app.screen.focus_next()
def action_focus_previous(self) -> None:
self.app.screen.focus_previous()
def action_copy(self) -> None:
self.app.action_copy()
def action_show(self) -> None:
self.app.action_show()
def action_clear_search(self) -> None:
self.app.action_clear_search()
class TOTPLabel(_common_actions, Label, can_focus=True, inherit_bindings=True):
otp: "TOTPData" otp: "TOTPData"
BINDINGS = [ BINDINGS = [
@ -179,12 +190,12 @@ class TOTPLabel(Label, can_focus=True):
self.shown = False self.shown = False
class SearchInput(Input, can_focus=False): class SearchInput(_common_actions, Input, can_focus=False):
BINDINGS = [ BINDINGS = [
Binding("up", "focus_previous", show=False), Binding("up", "focus_previous", show=False),
Binding("down", "focus_next", show=False), Binding("down", "focus_next", show=False),
Binding("ctrl+a", "clear_search", "Show all", show=True), Binding("ctrl+a", "clear_search", "Show all", show=True),
Binding("F9", "clear_search", show=True), Binding("escape", "clear_search", show=True),
] ]
def on_focus(self) -> None: def on_focus(self) -> None:
@ -275,6 +286,7 @@ class TTOTP(App[None]):
.otp-value { width: 9; } .otp-value { width: 9; }
.otp-hidden { display: none; } .otp-hidden { display: none; }
.otp-name { text-wrap: nowrap; text-overflow: ellipsis; } .otp-name { text-wrap: nowrap; text-overflow: ellipsis; }
.otp-name:focus { background: red; }
TOTPLabel { width: 1fr; height: 1; padding: 0 1; } TOTPLabel { width: 1fr; height: 1; padding: 0 1; }
Horizontal:focus-within { background: $primary-background; } Horizontal:focus-within { background: $primary-background; }
Bar > .bar--bar { color: $success; } Bar > .bar--bar { color: $success; }