1#!/usr/local/bin/python3.8 2# vim:fileencoding=utf-8 3# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net> 4 5from functools import update_wrapper 6from typing import TYPE_CHECKING, Callable, Generic, NamedTuple, TypeVar, Union 7 8_T = TypeVar('_T') 9 10 11class ParsedShortcut(NamedTuple): 12 mods: int 13 key_name: str 14 15 16class Edges(NamedTuple): 17 left: int = 0 18 top: int = 0 19 right: int = 0 20 bottom: int = 0 21 22 23class FloatEdges(NamedTuple): 24 left: float = 0 25 top: float = 0 26 right: float = 0 27 bottom: float = 0 28 29 30class ScreenGeometry(NamedTuple): 31 xstart: float 32 ystart: float 33 xnum: int 34 ynum: int 35 dx: float 36 dy: float 37 38 39class WindowGeometry(NamedTuple): 40 left: int 41 top: int 42 right: int 43 bottom: int 44 xnum: int 45 ynum: int 46 spaces: Edges = Edges() 47 48 49class SingleKey(NamedTuple): 50 mods: int = 0 51 is_native: bool = False 52 key: int = -1 53 54 55class MouseEvent(NamedTuple): 56 button: int = 0 57 mods: int = 0 58 repeat_count: int = 1 59 grabbed: bool = False 60 61 62ConvertibleToNumbers = Union[str, bytes, int, float] 63 64 65if TYPE_CHECKING: 66 class RunOnce(Generic[_T]): 67 68 def __init__(self, func: Callable[[], _T]): ... 69 def __call__(self) -> _T: ... 70 def set_override(self, val: _T) -> None: ... 71 def clear_override(self) -> None: ... 72else: 73 class RunOnce: 74 75 def __init__(self, f): 76 self._override = RunOnce 77 self._cached_result = RunOnce 78 update_wrapper(self, f) 79 80 def __call__(self): 81 if self._override is not RunOnce: 82 return self._override 83 if self._cached_result is RunOnce: 84 self._cached_result = self.__wrapped__() 85 return self._cached_result 86 87 def set_override(self, val): 88 self._override = val 89 90 def clear_override(self): 91 self._override = RunOnce 92 93 94def run_once(f: Callable[[], _T]) -> RunOnce: 95 return RunOnce(f) 96 97 98if TYPE_CHECKING: 99 from typing import Literal 100 ActionGroup = Literal['cp', 'sc', 'win', 'tab', 'mouse', 'mk', 'lay', 'misc'] 101else: 102 ActionGroup = str 103 104 105class ActionSpec(NamedTuple): 106 group: str 107 doc: str 108 109 110def ac(group: ActionGroup, doc: str) -> Callable[[_T], _T]: 111 def w(f: _T) -> _T: 112 setattr(f, 'action_spec', ActionSpec(group, doc)) 113 return f 114 return w 115