Commit Graph
10 Commits
Author SHA1 Message Date
3b08a85ad1 Recover monitors Hyprland brought up with no mode (#6701)
A monitor powered off when the machine boots — a smart strip cutting AC, the PC
coming back on its own — still answers DDC, but with a partial EDID that carries
no video modes. Hyprland takes the connector as present and brings the monitor
up at 0x0. Powering it on afterwards changes nothing: the connector never
dropped at DRM level, so no hotplug fires, nothing re-reads the EDID, and the
screen stays black until a reboot.

Only a reload re-reads it. Forcing a DRM re-probe would work too but needs root,
and the kernel's cached mode list stays empty without one, so there is nothing
cheaper to poll: the reload is both the fix and the only way to learn whether it
was needed. Poll only while a monitor is in that state, back off from three
seconds to a minute, and stop as soon as one reports a mode — the machine can
sit black all night, and powering the monitor on fires no event to stop on.

Nothing will ask again if this loop gives up, so an unreadable answer is not
taken for a healthy monitor. It is also not waited on forever: a compositor that
stays silent has gone, and with it the session and any reason to keep asking.

Reloading on our own schedule means minding the reload guard, which exists to
keep Hyprland out of package-owned config mid-transaction, and which only
disables the automatic reloads. The guard can now be asked, and recovery holds
off while a transaction is in flight.

A reload lands a monitor at 0x0 the same way a boot does, so configreloaded is
watched alongside the hotplug events. The recovery's own reload comes back
through it, and a lock keeps that from stacking a second loop. Contention waits
rather than drops: a trigger arriving while a loop is exiting is the last one
that will come, and one arriving while a loop is running is answered by its next
pass anyway.

Mirrors are dropped from `hyprctl monitors`, so the check asks for all of them
and filters the disabled ones itself. Monitors turned off on purpose sit at 0x0
too, and re-applying config would fight the user over those.

The existing poll here recovers internal panels on docked laptops and never runs
on a desktop, which is where this happens.

Reported in #6668.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 13:26:24 +02:00
David Heinemeier HanssonandClaude Fable 5 d548b730e0 Only run the clamshell poll while docked, not for every laptop
The reconciliation poll (added in "Fix clamshell display recovery") is a
backstop for lid transitions the Hyprland switch binds can miss across
suspend/resume. But the internal panel is only ever disabled while the
laptop is docked — lid shut with an external monitor active — so the poll
has nothing to reconcile when undocked. Running it 24/7 on every laptop
wakes the CPU every 2s for no reason, which is exactly the case where
battery matters most.

Start the poll when an external monitor is present and stop it when the
last one goes away (driven by the socat monitor-add/remove watch), gated
on omarchy-hw-laptop. Undocked laptops and desktops now never poll; a
docked laptop keeps the 2s recovery poll. Switch the event reader from a
pipe to process substitution so it runs in the main shell and can manage
the poll's lifetime.

Desktop verified: no poll runs even with external monitors attached. The
docked-laptop start/stop path needs a check on real laptop hardware.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 08:15:09 -07:00
David Heinemeier HanssonandClaude Fable 5 63f147ef85 Only run the clamshell poll on laptops
omarchy-hyprland-monitor-watch ran poll_clamshell_state() every 2s for
the whole session, and each pass forks omarchy-hyprland-monitor-clamshell
plus its hyprctl/jq/monitor-* children. Clamshell (lid) handling can only
ever apply to a machine with a lid, so on desktops and VMs this was pure
churn — the single largest remaining source of idle process wakeups
(~3 forks/sec on an otherwise idle desktop).

Gate the poll behind a new omarchy-hw-laptop helper (lid button, or a
laptop DMI chassis type as a fallback). The event-driven socat watch on
Hyprland monitor add/remove is unchanged, so monitor hotplug still
reconciles everywhere; only the periodic lid poll is now laptop-only.

Verified on a desktop: steady-state omarchy-hyprland-* forks drop from
~3/sec to zero, socat watch still present.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 08:09:07 -07:00
David Heinemeier Hansson aa7350ab60 Fix clamshell display recovery 2026-06-23 09:23:29 +02:00
David Heinemeier Hansson ee65304b92 Handle clamshell monitor hotplug 2026-06-22 21:48:35 +02:00
David Heinemeier Hansson 8f6e815c78 Recover internal monitor before sleep
Run internal monitor toggle recovery before the sleep lock path and retry recovery after Hyprland monitor removal events. This gives dock/lid-close races time to settle before suspend or external-display reconnects leave the session without a safe internal display fallback.
2026-06-21 15:42:24 +02:00
d2a4cc0c4d Add omarchy CLI (#5477)
* Add omarchy CLI

* Remove outdated or internal

* Add bash completions for command

* Add omarchy command documentation

* Add missing docs

* Correct to what's now right

* Fix tests

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
2026-05-01 17:40:22 +02:00
35789cc102 Add laptop display mirror toggle + hotkey (#5462)
* Add check for active external monitors before disabling internal display

Co-authored-by: Copilot <copilot@github.com>

* Revert "Add check for active external monitors before disabling internal display"

This reverts commit e20b3da87e3df0f084c0bca232a61ba58fab4cdc.

* feat(hyprland): add toggle for internal monitor mirroring

- Implement `omarchy-hyprland-monitor-internal-mirror` to dynamically mirror the internal eDP display to external monitor.
- Update `omarchy-hyprland-monitor-internal` to prevent disabling the laptop screen if mirroring is currently active.
- Add "Mirror Display" toggle to omarchy hardware Menu

* Ensure there is also a laptop monitor available to mirror before we do it

* Fix toggle use

* Recover from mirror mode gracefully

* Add hotkey to mirroring

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: David Heinemeier Hansson <david@hey.com>
2026-04-29 20:19:32 +02:00
David Heinemeier Hansson cd3e683fef Combine into one script with options 2026-04-22 13:35:20 +02:00
David Heinemeier Hansson d6aaf30e43 Ensure internal display is turned back on if the external one is disconnected 2026-04-19 17:11:48 +02:00