- Idle is handled in the shell instead of hypridle: the screen dims slowly at 4 minutes, locks at 5, powers down at 6, and suspends at 15 on battery. Idle inhibitors hold every stage off; Super+Shift+I does the same by hand and puts a cup on the rail. - The shell draws the wallpaper (backdrop/), so hyprpaper is gone. The picture is drawn a little larger than the screen and drifts with the workspace a beat after the windows, and dims a shade while windows are open. The path lives in quickshell/wallpaper. - The lock screen and power menu say "Take your time." instead of the NieR slogan. - hyprpaper is no longer launched twice, the media module keeps the player that played last instead of an empty browser tab, and grouped windows show thin untitled tabs with their place in the group (2/3) in the bar title. - qt6ct uses Darkly; the package list gains adw-gtk-theme and darkly-bin.
107 lines
3.5 KiB
Lua
107 lines
3.5 KiB
Lua
-- Presentation mode: every external output shows the laptop panel.
|
|
--
|
|
-- Toggled from lua/binds/shell.lua. Mirroring is just a `mirror` field on the
|
|
-- monitor rule, so switching it off clears that field and re-applies the specs
|
|
-- from lua/monitors.lua to put the Samsung back where it belongs.
|
|
--
|
|
-- Anything plugged in while mirroring is on gets mirrored too, which is the
|
|
-- usual order at a talk: press the key, then find the HDMI cable.
|
|
|
|
local monitors = require("lua/monitors")
|
|
|
|
local M = {}
|
|
|
|
local function notify(text)
|
|
hl.notification.create({ text = text, timeout = 3000 })
|
|
end
|
|
|
|
-- The panel is off while docked with the lid shut, see lua/lid.lua. Mirroring
|
|
-- a disabled output would leave every screen black.
|
|
local function builtin()
|
|
for _, mon in ipairs(hl.get_monitors()) do
|
|
if mon.name == monitors.laptop then
|
|
return mon
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-- A mirroring output drops out of hl.get_monitors(), so the only place left
|
|
-- to find it is the panel's own `mirrors` list. That list is also the state:
|
|
-- a Lua flag would reset on every config reload while the outputs stay
|
|
-- mirrored.
|
|
local function mirroring(panel)
|
|
local names = {}
|
|
for _, mon in ipairs(panel and panel.mirrors or {}) do
|
|
table.insert(names, mon.name)
|
|
end
|
|
return names
|
|
end
|
|
|
|
-- Outputs keep their own mode while mirroring, and the panel image gets
|
|
-- rescaled to fit it every frame. The Dells at 1920x1200 flicker with that,
|
|
-- so match the panel's resolution; Hyprland falls back to the preferred mode
|
|
-- if the output cannot do it.
|
|
local function mirror_all(panel)
|
|
local mode = panel.width .. "x" .. panel.height
|
|
for _, mon in ipairs(monitors.externals_present()) do
|
|
hl.monitor({ output = mon.name, mirror = monitors.laptop, mode = mode, position = "auto" })
|
|
end
|
|
end
|
|
|
|
-- The bar, popouts and wallpaper stay on the outputs they were created for,
|
|
-- so respawn the shell the same way lua/autostart.lua starts it.
|
|
local function restart_clients()
|
|
hl.exec_cmd("sh -c 'qs kill; exec uwsm app -- qs'")
|
|
end
|
|
|
|
-- hl.monitor() only takes effect after the calling handler returns, so
|
|
-- anything that has to see the new layout goes on a timer.
|
|
local function later(fn)
|
|
hl.timer(fn, { timeout = 500, type = "oneshot" })
|
|
end
|
|
|
|
-- Clearing `mirror` alone brings the image back, but Hyprland never
|
|
-- re-announces the output to clients: hyprpaper and Quickshell keep seeing
|
|
-- only the panel, however often they restart. Cycling the output through
|
|
-- disabled makes it a fresh wl_output. Undeclared outputs get their auto
|
|
-- defaults back, apply_external() then overrides what lua/monitors.lua knows
|
|
-- better.
|
|
local function unmirror_all(names)
|
|
for _, name in ipairs(names) do
|
|
hl.monitor({ output = name, mirror = "", disabled = true })
|
|
end
|
|
later(function()
|
|
for _, name in ipairs(names) do
|
|
hl.monitor({ output = name, disabled = false, mode = "preferred", position = "auto" })
|
|
end
|
|
monitors.apply_external()
|
|
later(restart_clients)
|
|
end)
|
|
end
|
|
|
|
function M.toggle()
|
|
local panel = builtin()
|
|
local mirrored = mirroring(panel)
|
|
|
|
if #mirrored > 0 then
|
|
unmirror_all(mirrored)
|
|
notify("Mirroring off")
|
|
elseif panel then
|
|
mirror_all(panel)
|
|
later(restart_clients)
|
|
notify("Mirroring " .. monitors.laptop .. " to all screens")
|
|
else
|
|
notify("Laptop panel is off, open the lid first")
|
|
end
|
|
end
|
|
|
|
hl.on("monitor.added", function()
|
|
local panel = builtin()
|
|
if #mirroring(panel) > 0 then
|
|
mirror_all(panel)
|
|
end
|
|
end)
|
|
|
|
return M
|