utils/gatelock/README.md
Krzysztof kuhy Rudnicki 68ec316b28
Some checks failed
dependency freshness / dependencies on newest stable (push) Waiting to run
file length / file-length (push) Waiting to run
gatelock pre-commit / pre-commit (push) Waiting to run
gatelock tests / test (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
palette drift / palette (push) Waiting to run
shared gate tests / gate unit tests (push) Waiting to run
freedays pre-commit / pre-commit (push) Has been cancelled
freedays tests / test (push) Has been cancelled
gatelock 0.8.0: LockConfig as behaviour + GrabPolicy + theme records; pylint at 10
LockConfig was one 35-field record: the lock's behaviour, the grab
policy, nine colours, a type scale and a spacing scale, flat. It is
now the seven behavioural knobs plus four nested records --
GrabPolicy(kind, disable_vt, retry_ms, log_every, preempt_weaker_holder),
LockPalette, LockTypography and LockSpacing -- each overridden as a
unit. Breaking for every constructor that passed grab=/disable_vt=/
grab_retry_ms=/preempt_weaker_holder= or a colour, and for every read
of config.<colour>; hence the minor bump. screen-locker, leetcode-guard
and diet-guard follow in their own commits.

The two fail-open guards in the recovery loop carry per-line
suppressions: catching everything is the property they exist for, and
the check stays live for the next careless except. That was the last
finding, so the gate now says 10.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHCbkJWXHjtTUaqvnHRAqA
2026-09-12 19:36:31 +02:00

76 lines
2.5 KiB
Markdown

# gatelock
Shared fullscreen lock-window + HMAC log-integrity backend, extracted from
three personal automation tools that each independently implemented "lock the
screen with a blocking overlay until a condition is met":
[diet_guard](https://github.com/kuhyx/testsAndMisc/tree/main/python_pkg/diet_guard),
[wake_alarm](https://github.com/kuhyx/testsAndMisc/tree/main/python_pkg/wake_alarm),
and [screen-locker](https://github.com/kuhyx/screen-locker).
## Why
All three reimplemented the same tkinter fullscreen mechanics (overrideredirect,
input grab, VT-switch disable) at different levels of maturity, and the
HMAC-signed-state module had already been hand-copied between two of them
because they live in separate repos. `gatelock` is the one place that logic
now lives.
## Install
```bash
pip install "gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.1.1#subdirectory=gatelock"
```
## Usage
```python
import tkinter as tk
from gatelock import GateRoot, LockConfig, LockWindow
class MyGate:
def __init__(self, *, demo_mode: bool) -> None:
self.root = GateRoot()
self.root.on_callback_error = self._handle_callback_error
config = LockConfig(mode="soft" if demo_mode else "hard")
self._lock = LockWindow(self.root, config, hooks=self)
self._lock.setup()
# ... build your widgets ...
self._lock.grab_input()
def on_focus_ready(self) -> None:
self.my_entry.focus_force()
def on_callback_error(self) -> None:
self.close()
def on_close(self) -> None:
... # release any hardware/state held while locked
def close(self) -> None:
self._lock.close()
def run(self) -> None:
self._lock.run()
```
`LockConfig`'s `mode` preset bundles the common combination ("soft" = topmost
only, typeable, WM-escapable; "hard" = overrideredirect + global grab +
VT-disable). `overrideredirect` and the `grab=GrabPolicy(kind=..., disable_vt=...,
retry_ms=...)` axes can be set explicitly to reproduce a consumer's exact prior
behavior where it diverges from the preset. Colours, type scale and spacing are
the `palette`, `typography` and `spacing` records (`gatelock.LockPalette` etc.),
overridden as a unit.
`gatelock.log_integrity` ports the HMAC-signed state module used by all three
projects; `DEFAULT_HMAC_KEY_FILE` (`/etc/workout-locker/hmac.key`) is
unchanged so existing signed history keeps verifying.
## Development
```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pytest
pre-commit install && pre-commit install --hook-type pre-push
```