Skip to content

Add a tile mode to the bundled YouTube web app - #9265

Open
Vegasq wants to merge 1 commit into
omacom:quattrofrom
Vegasq:youtube-tile-extension
Open

Add a tile mode to the bundled YouTube web app#9265
Vegasq wants to merge 1 commit into
omacom:quattrofrom
Vegasq:youtube-tile-extension

Conversation

@Vegasq

@Vegasq Vegasq commented Aug 30, 2026

Copy link
Copy Markdown

The problem

Omarchy ships YouTube as a web app — Super + Shift + Y in default/hypr/bindings/applications.lua, an applications/YouTube.desktop, and dedicated window rules in default/hypr/apps/browser.lua. It launches as chromium --app=https://youtube.com/, so it is an ordinary window in the tiling layout.

But YouTube only knows two sizes: embedded in the page, or fullscreen. Fullscreen goes through the Fullscreen API, which makes Hyprland promote the window to cover the whole monitor — it leaves the tile entirely. There is no way to say "just fill this tile with the video", which is the thing you actually want in a tiling session.

The change

screenrecording-2026-08-30_17-31-45_trimmed.mp4

A fourth bundled Chromium extension, next to WhatsApp Slim — which exists for the same reason. Omarchy ships the web app, so Omarchy fixes the web app.

Tile mode lifts #movie_player out of the page as a viewport-sized fixed element: the video fills the window edge to edge while the window stays exactly where the tiling layout put it. No Fullscreen API, no layout change.

Key Action
f Toggle tile mode
Shift + F Real fullscreen, unchanged
z Zoom to fill — crop to the tile instead of letterboxing
Esc Leave tile mode
Alt + S Settings

z earns its place: a tile is rarely 16:9, so a letterboxed video leaves black bars down two sides.

Two implementation notes worth flagging for review:

  • Hiding is structural, not enumerated. It walks up from the player and hides each ancestor's siblings, so masthead, live chat, the theater-mode metadata row, engagement panels and endscreens are all covered without naming any of them. Enumerating surfaces in CSS meant a new bug for every page variant, and it rots whenever YouTube renames a container.
  • Settings live behind Alt + S because an --app window has no toolbar, and therefore no extension popup.

Scope: deliberately layout only

The extension this is extracted from also repaints YouTube with the active Omarchy palette. That half is left out on purpose, for two reasons:

  1. It works by overriding YouTube's internal --yt-spec-* design tokens, which is exactly the surface that moves under a redesign. Tile mode is CSS positioning and key handling, which is far more durable — and a bundled extension is a maintenance commitment.
  2. It cannot work from a bundled copy anyway. The palette is generated into the extension directory by a theme-set hook, and $OMARCHY_PATH is root-owned and pacman-managed, so a user-run hook has nowhere to write and an upgrade would clobber it regardless. Doing it properly needs a native messaging host, like copy-url and yt-dlp have. That is a reasonable follow-up, but it does not belong in the same change as the layout fix.

So there are no --omy-* variables anywhere in this extension, and a test asserts that stays true.

Details

  • manifest.json pins a key, matching all three existing bundled extensions, so the id does not drift with the load path.
  • migrations/1788118063.sh adds the extension to existing browser flag files — config/chromium-flags.conf does not reach users who already have a copy in ~/.config. It follows migrations/1785543725.sh, which did the same for WhatsApp Slim.
  • Only permission is storage, for the settings.

Verification

./test/cli passes. ./test/shell passes; the six failures on my machine (bar-icon-geometry, config, snapper, theme-install-guards, unowned-system-paths, windows-vm-mount-boundary) fail identically on a clean checkout — they are environment checks against an unlinked tree.

New test/shell.d/chromium-youtube-tile-test.sh covers the derived extension id, that the flags file loads it, that a migration exists, that no palette variables crept in, and that the content script parses.

Verified in a real --app window on a ThinkPad X280 running Omarchy 4.0.1, against a live YouTube page:

  • Tile mode engages automatically; hyprctl reports the window still at its tiled geometry with fullscreen: 0, and the video fills it edge to edge.
  • Alt + S renders the settings overlay over the tiled player.
  • z crops a 4:3 video to fill a 941×509 tile instead of letterboxing it.
  • No content-script errors in the Chromium log.

Provenance

Extracted from omarchy-youtube, which I wrote; MIT, and mine to relicense into this tree. It is also on the Chrome Web Store, but a bundled copy is better for a shipped web app — no install step, no store account, and it tracks the repo.

Happy to cut anything here that reads as too much for a default, including the settings overlay — tile mode itself is the part that matters.

Omarchy ships YouTube as a web app: a Super + Shift + Y binding, a desktop
entry, and its own Hyprland window rules. It launches as
`chromium --app=https://youtube.com/`, so it is an ordinary window in the
tiling layout.

YouTube only knows two sizes, though: embedded in the page, or fullscreen.
Fullscreen goes through the Fullscreen API, which makes Hyprland promote the
window to cover the monitor — it leaves the tile entirely. There is no way to
say "just fill this tile with the video", which is what you actually want in a
tiling session.

This adds that missing state as a fourth bundled Chromium extension, alongside
WhatsApp Slim, which exists for the same reason: Omarchy ships the web app, so
Omarchy fixes the web app. Tile mode lifts the player out of the page as a
viewport-sized fixed element, so the video fills the window while the window
stays exactly where the layout put it. No Fullscreen API, no layout change.

  f          toggle tile mode
  Shift + F  real fullscreen, unchanged
  z          zoom to fill — crop to the tile instead of letterboxing
  Esc        leave tile mode
  Alt + S    settings

Rather than enumerate the surfaces to hide — a new bug for every page variant —
it walks up from the player and hides each ancestor's siblings, so masthead,
live chat, engagement panels and endscreens are all covered without naming any
of them. The settings live behind a key because an --app window has no toolbar
and therefore no extension popup.

The migration adds the extension to existing browser flag files, which the
default chromium-flags.conf does not reach once it has been copied into
~/.config.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013k1Ygomw5M3d5SPbbnqUzs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant