Skip to content

Instantly share code, notes, and snippets.

@Deminder
Last active June 17, 2023 12:09
Show Gist options
  • Save Deminder/6839fad736865cb3acabab409f9b09a1 to your computer and use it in GitHub Desktop.
Save Deminder/6839fad736865cb3acabab409f9b09a1 to your computer and use it in GitHub Desktop.
Inhibit screensaver: mpv flatpak on GNOME wayland (workaround)
-- ~/.var/app/io.mpv.Mpv/config/mpv/scripts/inhibit-screensaver.lua
--
-- Workaround for inhibiting screensaver for io.mpv.Mpv flatpak (if not paused)
-- Issue: [vo/gpu/wayland] GNOME's wayland compositor lacks support for the idle inhibit protocol. This means the screen can blank during playback.
-- Until this is merged: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/111
-- Non-flatpak version: https://gist.github.com/crazygolem/a7d3a2d3c0cee5d072c0cbbbdee69286
--
-- NOTE: if mpv does not exit cleanly (e.g. with SIGKILL), an orphan process will keep inhibiting the screensaver
--
-- Arch: x86_64
-- REQUIRED: flatpak override --user --talk-name=org.gnome.SessionManager io.mpv.Mpv
require 'mp.msg'
inhibits = {
video={reason="Playing video", inhibit="suspend:idle", proc=nil},
audio={reason="Playing audio", inhibit="suspend", proc=nil}
}
props = {pause=0, stop_screensaver=0, window_minimized=0, mute=0}
function inhibit(kind)
inhibits[kind].proc = mp.command_native_async({
name = "subprocess",
playback_only = false,
capture_stdout = true,
args = { "/run/host/lib64/ld-linux-x86-64.so.2",
"--library-path", "/run/host/lib64",
"/run/host/usr/bin/gnome-session-inhibit",
"--app-id", "io.mpv.Mpv",
"--reason", inhibits[kind].reason,
"--inhibit", inhibits[kind].inhibit,
"--inhibit-only"
}}, function(success, result, error)
mp.msg.verbose('gnome-session-inhibit stopped for ' .. kind)
if result ~= nil and #result.stdout ~= 0 then
mp.msg.debug(result.stdout)
end
inhibits[kind].proc = nil
end)
end
function maybe_toggle_inhibit(kind, paused, should_inhibit)
local proc = inhibits[kind].proc
if paused or not should_inhibit then
-- uninhibit screensaver
if proc ~= nil then
mp.msg.verbose('stop gnome-session-inhibit for ' .. kind)
mp.abort_async_command(proc)
end
elseif should_inhibit then
-- inhibit screensaver
if proc == nil then
mp.msg.verbose('start gnome-session-inhibit for ' .. kind)
inhibit(kind)
end
end
end
function update(name, value)
props[name:gsub("-", "_")] = value
maybe_toggle_inhibit("video",
props.pause,
props.stop_screensaver and not props.window_minimized)
maybe_toggle_inhibit("audio",
props.pause,
props.stop_screensaver and not props.mute)
end
for prop,_ in pairs(props) do
mpv_prop = prop:gsub("_", "-")
props[prop] = mp.get_property_bool(mpv_prop)
mp.observe_property(mpv_prop, "bool", update)
end
-- ~/.var/app/io.mpv.Mpv/config/mpv/scripts/inhibit-screensaver.lua
--
-- [Heartbeat] version: if you are worried about mpv not exiting normally (orphan process)
--
-- Workaround for inhibiting screensaver for io.mpv.Mpv flatpak (if not paused)
--
-- Arch: x86_64
-- REQUIRED: flatpak override --user --talk-name=org.gnome.SessionManager io.mpv.Mpv
require 'mp.msg'
inhibits = {
video={reason="Playing video", inhibit="suspend:idle", do_inhibit=false, dead=true},
audio={reason="Playing audio", inhibit="suspend", do_inhibit=false, dead=true}
}
props = {pause=0, stop_screensaver=0, window_minimized=0, mute=0}
function inhibit(kind)
local active = inhibits[kind].do_inhibit
if active then
mp.command_native({ name = "subprocess",
playback_only = false,
detach = true,
args = { "/run/host/lib64/ld-linux-x86-64.so.2",
"--library-path", "/run/host/lib64",
"/run/host/usr/bin/gnome-session-inhibit",
"--app-id", "io.mpv.Mpv",
"--reason", inhibits[kind].reason,
"--inhibit", inhibits[kind].inhibit,
"sleep", "1"
}})
end
inhibits[kind].dead = not active
end
function heartbeat()
inhibit("video")
inhibit("audio")
end
function maybe_toggle_inhibit(kind, paused, should_inhibit)
active = inhibits[kind].do_inhibit
if paused or not should_inhibit then
-- uninhibit screensaver
if active then
mp.msg.verbose('stop gnome-session-inhibit for ' .. kind)
inhibits[kind].do_inhibit = false
end
elseif should_inhibit then
-- inhibit screensaver
if not active then
mp.msg.verbose('start gnome-session-inhibit for ' .. kind)
inhibits[kind].do_inhibit = true
if inhibits[kind].dead then
heartbeat()
end
end
end
end
function update(name, value)
props[name:gsub("-", "_")] = value
maybe_toggle_inhibit("video",
props.pause,
props.stop_screensaver and not props.window_minimized)
maybe_toggle_inhibit("audio",
props.pause,
props.stop_screensaver and not props.mute)
end
for prop,_ in pairs(props) do
mpv_prop = prop:gsub("_", "-")
props[prop] = mp.get_property_bool(mpv_prop)
mp.observe_property(mpv_prop, "bool", update)
end
-- lowest screensaver setting 60 sec => heatbeat 59 seconds is enough
mp.add_periodic_timer(59, heartbeat)
@Deminder
Copy link
Author

Deminder commented Jan 14, 2022

Allow io.mpv.Mpv to talk to the session-manager dbus-destination:

flatpak override --user --talk-name=org.gnome.SessionManager io.mpv.Mpv

Then install this script with lazy-inhibit:

curl -o ~/.var/app/io.mpv.Mpv/config/mpv/scripts/inhibit-screensaver.lua https://gist.githubusercontent.com/Deminder/6839fad736865cb3acabab409f9b09a1/raw/5c7d606733074aed8de3e542743229852fc34337/inhibit-screensaver.lua

or with heartbeat-inhibit:

curl -o ~/.var/app/io.mpv.Mpv/config/mpv/scripts/inhibit-screensaver.lua https://gist.githubusercontent.com/Deminder/6839fad736865cb3acabab409f9b09a1/raw/5c7d606733074aed8de3e542743229852fc34337/inhibit-with-heartbeat.lua

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment