{"id":50970680,"url":"https://github.com/isene/spot","last_synced_at":"2026-06-19T02:01:25.665Z","repository":{"id":365764397,"uuid":"1273536704","full_name":"isene/spot","owner":"isene","description":"Presenter spotlight overlay for Linux — pure x86_64 assembly, ~14 KB. Click-through, screen-share-safe, follows the pointer via SHAPE.","archived":false,"fork":false,"pushed_at":"2026-06-18T19:02:45.000Z","size":72,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-18T20:23:41.524Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Assembly","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/isene.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-18T16:08:47.000Z","updated_at":"2026-06-18T19:02:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/isene/spot","commit_stats":null,"previous_names":["isene/spot"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/isene/spot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isene%2Fspot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isene%2Fspot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isene%2Fspot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isene%2Fspot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/isene","download_url":"https://codeload.github.com/isene/spot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isene%2Fspot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34514285,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-19T02:01:23.805Z","updated_at":"2026-06-19T02:01:25.659Z","avatar_url":"https://github.com/isene.png","language":"Assembly","funding_links":[],"categories":["Assembly"],"sub_categories":[],"readme":"# spot - Pure Assembly Presenter Spotlight\n\n\u003cimg src=\"img/spot.svg\" align=\"left\" width=\"150\" height=\"150\"\u003e\n\n![Version](https://img.shields.io/badge/version-0.3.0-blue)\n![Assembly](https://img.shields.io/badge/language-x86__64%20Assembly-purple)\n![License](https://img.shields.io/badge/license-Unlicense-green)\n![Platform](https://img.shields.io/badge/platform-Linux%20x86__64-blue)\n![Dependencies](https://img.shields.io/badge/dependencies-none-brightgreen)\n![Binary](https://img.shields.io/badge/binary-~22KB-orange)\n![Startup](https://img.shields.io/badge/startup-~1ms-ff6600)\n![Idle](https://img.shields.io/badge/idle%20cost-0%20W-brightgreen)\n![Suite](https://img.shields.io/badge/suite-CHasm-9333ea)\n\nPresenter overlays for the [CHasm](https://github.com/isene/chasm)\ndesktop suite. Three modes from one binary: **spotlight** (dimmed\nscreen, circular hole follows the cursor), **draw** (click-drag to\nannotate), **highlight** (click-drag a rectangle that stays bright\nwhile the surround stays dim). Works on every workspace and over\nscreen-share (Teams, Discord, Meet capture the composited framebuffer,\nwhich includes us).\n\nSingle static ~21 KB ELF, no libc, pure x86_64 NASM. X11 wire protocol\n+ SHAPE extension over a Unix socket. Every key passes through to the\nfocused application — type, click, navigate slides while the overlay\nis up. Toggle via the launch key (a second press kills it).\n\n\u003cbr clear=\"left\"/\u003e\n\n## Modes\n\n| Mode | Status | Bound to |\n|------|--------|----------|\n| **spotlight** | ✓ shipped (v0.1.0) | `Mod4+Shift+s` (tile) |\n| **draw** (annotate) | ✓ shipped (v0.2.0) | `Mod4+Shift+d` (tile) |\n| **highlight** (drag-rect) | ✓ shipped (v0.3.0) | `Mod4+Shift+h` (tile) |\n\n## Install\n\n```bash\ngit clone https://github.com/isene/spot.git\ncd spot\nmake\nsudo make install\n```\n\nAdd toggle bindings to `~/.tilerc` (same key launches and kills):\n\n```\nbind Mod4+Shift+s   exec sh -c 'pkill -x spot || exec spot'\nbind Mod4+Shift+d   exec sh -c 'pkill -x spot || exec spot draw'\nbind Mod4+Shift+h   exec sh -c 'pkill -x spot || exec spot highlight'\n```\n\nFirst press launches spot; second press kills it. Esc and every other\nkey passes through to whatever application has focus in **spotlight**\nmode — type into the terminal, click in the slides, anything underneath\nstays interactive while the spotlight is up.\n\nIn **draw** mode, click-drag draws strokes onto a frozen snapshot of the\nscreen. Configure colour and width via env vars:\n\n```\nbind Mod4+Shift+d   exec sh -c 'pkill -x spot || env SPOT_COLOR=00cc44 SPOT_WIDTH=5 exec spot draw'\n```\n\n| Env | Default | Effect |\n|-----|---------|--------|\n| `SPOT_DIM`   | `80`     | spotlight surround brightness (0-100) |\n| `SPOT_COLOR` | `ff0000` | draw stroke colour (hex `RRGGBB`, optional `#`) |\n| `SPOT_WIDTH` | `3`      | draw stroke width in pixels |\n\n## Configuration\n\n`SPOT_DIM=\u003c0..100\u003e` env var controls the surround brightness:\n\n| Value | Effect |\n|-------|--------|\n| `100` | pure black surround |\n| `80`  | default — `#333333` |\n| `50`  | medium gray `#808080` |\n| `0`   | white surround |\n\n```\nbind Mod4+Shift+s   exec env SPOT_DIM=70 spot\n```\n\nv0.1.3+ shows the **actual screen content darkened** (not a solid colour).\nAt startup, spot does `XGetImage` on root, multiplies every R/G/B channel\nby `(100 - SPOT_DIM) / 100`, and uploads the result as the overlay's\nback pixmap. No compositor needed — the snapshot is just bytes on the\nserver side, painted as the window background.\n\nCaveat: it's a **snapshot**. If something behind spot animates / scrolls\n/ repaints while spot is running, the dimmed surround stays as it was at\nstartup. Fine for presenting static slides. Less great for live demos\nwhere windows below are updating; in that case, exit spot and re-launch.\n\n## How it works\n\n- **Snapshot pipeline**, shared by all three modes: `XGetImage` on root\n  at startup, walk every pixel through a 256-byte LUT that scales each\n  R/G/B channel by `(100 - SPOT_DIM) / 100`, `PutImage` the result into\n  a server-side pixmap. That pixmap becomes the overlay's\n  `CW_BACK_PIXMAP`, so the X server paints the surround for free.\n- **Override-redirect InputOutput window** covers the root. No window\n  manager involvement, no focus changes.\n- **Spotlight**: SHAPE input region empty (clicks pass through), SHAPE\n  bounding region = ~564 per-row rectangles approximating a circle of\n  radius 140 px. A precomputed `circle_hw[]` table holds the horizontal\n  half-width per row (built in ~140 iterations at startup, then static).\n  Cursor tracking polls `XQueryPointer` at 30 Hz; on actual motion one\n  `SHAPE Rectangles` request rewrites the bound. Still cursor = zero\n  requests, zero CPU.\n- **Draw**: GC on the pixmap with the user's colour, line-width, round\n  caps + joins. ButtonPress records the stroke origin; each Motion\n  event sends a `PolyLine` onto the pixmap and a `ClearArea` over the\n  segment's bounding box (padded for the round caps) to refresh just\n  that slice of the window.\n- **Highlight**: same pixmap, no input pass-through (we own the\n  pointer). Drag rectangles trigger four-rect SHAPE bounding updates —\n  top, bottom, left, right bars around the user's hole, live as you\n  drag.\n- **No keyboard grab.** Every key passes through to the focused\n  application underneath. The launch keybinding doubles as a kill —\n  `pkill -x spot || exec spot ...` toggles cleanly.\n\n## Goals (CHasm rules in priority order)\n\n1. **No wasted CPU.** Single SHAPE-rect request per cursor motion event.\n   No animation loops, no compositor wakeups.\n2. **Lightning fast.** ~1 ms cold start (one syscall to connect, four to\n   create + map + grab + flush). Instantaneous show / hide.\n3. **More battery.** Idle: not running. Active + still cursor: not\n   redrawing. Active + moving: one X request per ≥1 px delta.\n\n## License\n\n[Unlicense](https://unlicense.org/) - public domain.\n\n## Credits\n\nCreated by Geir Isene (https://isene.org) with pair-programming via Claude Code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisene%2Fspot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fisene%2Fspot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisene%2Fspot/lists"}