gatelock v0.3.0. Every change here works around a Tk *default*, not an application mistake -- which is why they belong in the shared backend rather than being fixed four times. On a lock surface these are not accessibility niceties. The lockers hold a global input grab with VT switching disabled, so a control the keyboard cannot reach, or a button clipped off the bottom of the screen, is a bricked machine. LockConfig gains a type scale, a spacing scale and a focus-ring token: - font() applies Tk's sign convention. Tk encodes the unit in the SIGN of the font size -- positive is points, negative is pixels -- so passing the design system's px values straight through rendered every string ~30% oversized (measured: body at 16pt has a 26px linespace where 16px gives 20). That alone pushed diet_guard's meal gate to 866px of content inside a 739px pane on a 1366x768 screen. - focus_kwargs() sets highlightcolor, the *focused* ring. Tk's default is a 1px BLACK ring, invisible against the palette's #211D1B background. Note highlightbackground is the UNfocused ring: setting only that one inverts the affordance, which is what diet_guard was doing. _keyboard.py collects three Tk defaults that each make a form unusable: - tk.Text traps Tab (inserts a literal tab and refocuses itself) and no-ops Shift-Tab; the only exits are the undocumented Ctrl+Tab / Ctrl+Shift+Tab. - tk.Button binds <space> on X11 but never <Return>, so the key a user reaches for to submit does nothing. - Escape needs binding at the toplevel to work wherever focus happens to sit. _scrollable.py adds ScrollableSurface, a viewport that content can actually be reached in: - A place()-centred frame takes its *requested* size and is clipped SYMMETRICALLY, so overflow removes the heading and the submit button at the same time, with no scrollbar and no hint anything is missing. - A bare tk.Canvas has no class key bindings, so ::tk::FocusOK rejects it as a focus stop and the only way to scroll is dragging the thumb with a pointer. - Canvas clipping does not unmap children, so scrolled-out fields stay in the tab ring while Tk never scrolls to follow focus -- Tab lands on fields the user can neither see nor reveal. - A Canvas holds content in a canvas *item*, so it never propagates the content's requested size; a toplevel told to size itself has nothing to grow to. _request_content_size() fixes that, clamped to the display. center_when_fits keeps short screens looking exactly as they did, so the viewport can replace a centred frame without a visual change. A scrollable dialog Toplevel is deliberately NOT the mechanism: on an override-redirect lock surface a second toplevel steals the Tk grab, which the recovery tick then kills -- the 2026-07-26 failure where a frozen sport selector logged a walk as table tennis. unified-design-system gains the two rule families this implements (pointer-free operability, 1366x768 usable / 1024x600 graceful), a focus-ring token, and the px/pt sign convention written down so it cannot recur. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| crdt_sync_dart | ||
| crdt-sync | ||
| gatelock | ||
| guard-lib | ||
| scripts | ||
| unified-design-system | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
utils
Shared libraries used across kuhyx's other projects. Each subdirectory is a
formerly-standalone repo, folded in here with full commit history preserved
(see each subdirectory's own git log for its pre-merge history).
crdt_sync_dart/
Dart/Flutter CRDT sync library (pub package name: crdt_sync, not published
to pub.dev — consumed via a git dependency). Mirrors crdt-sync (below)
module-for-module and test-for-test. Consumed by diet_guard's app,
screen-locker's workout_app, wake_alarm's phone_app, and todo (whose
notes are stored in the v0.2.0 LogStore).
Consume via:
dependencies:
crdt_sync:
git:
url: https://github.com/kuhyx/utils
ref: crdt_sync_dart-v0.2.0
path: crdt_sync_dart
crdt-sync/
Python CRDT sync library (package: crdt_sync, not published to PyPI). Same
design as crdt_sync_dart (HLC clocks, per-field LWW, sticky-delete
tombstones). Consumed by diet-guard and screen-locker.
Consume via:
crdt-sync @ git+https://github.com/kuhyx/utils@crdt-sync-v0.2.0#subdirectory=crdt-sync
guard-lib/
Bash tamper-resistance primitives (guardctl: chattr + bind-mount + systemd
watcher + pacman hooks). Not a package — installed by running
guard-lib/install.sh as root, which copies files onto the system
(/usr/local/bin, /usr/local/lib/guard-lib, systemd units, pacman hooks).
Consumed by steam-backlog-enforcer (expects a guard-lib/install.sh
sibling clone) and referenced by screen-locker.
gatelock/
Python lock-window + HMAC log-integrity backend (package: gatelock, not
published to PyPI). Consumed via pip by screen-locker, diet-guard, and
wake-alarm:
gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.1.0#subdirectory=gatelock
unified-design-system/
Not a package — the frozen design tokens (colors, spacing, type, radius,
shadow policy) and per-stack (Flutter/web/Tkinter) implementation patterns
that keep every one of kuhy's repos visually identical, plus annotated
component references (components.html, button.html). Read
unified-design-system/README.md and
tokens.md before touching any theme/CSS/style file in any repo. The
unified-design-system Claude Code skill is a thin pointer here, not a
duplicate.