diff --git a/src/system/session_manager.vala b/src/system/session_manager.vala index ebb74b7..164c12a 100644 --- a/src/system/session_manager.vala +++ b/src/system/session_manager.vala @@ -25,12 +25,28 @@ namespace Singularity { */ public signal void session_ending(); + private Subprocess? lockscreen_process = null; + + public bool locked { get; private set; default = false; } + public void lock_screen() { + if (lockscreen_process != null) return; + // 1. Native singularity-lockscreen (ext-session-lock-v1 + PAM) string? lockscreen = find_singularity_binary("singularity-lockscreen"); if (lockscreen != null) { try { - Process.spawn_command_line_async(lockscreen); + var process = new Subprocess(SubprocessFlags.NONE, lockscreen); + lockscreen_process = process; + locked = true; + process.wait_async.begin(null, (obj, res) => { + try { + process.wait_async.end(res); + } catch (Error e) { } + if (lockscreen_process != process) return; + lockscreen_process = null; + locked = false; + }); return; } catch (Error e) { warning("singularity-lockscreen failed: %s", e.message); diff --git a/tests/power_test.vala b/tests/power_test.vala index 52dc591..d561056 100644 --- a/tests/power_test.vala +++ b/tests/power_test.vala @@ -227,6 +227,33 @@ private void test_charge_limit() { assert(replaced.charge_limit_available); } +private void test_lock_screen_single_instance() { + string count = Path.build_filename(fixture_root, "lock-starts"); + string release = Path.build_filename(fixture_root, "lock-release"); + script("singularity-lockscreen", + "echo x >> '%s'\nwhile [ ! -e '%s' ]; do sleep 0.05; done\n".printf(count, release)); + Environment.set_variable("PATH", + Path.build_filename(fixture_root, "bin") + ":" + (Environment.get_variable("PATH") ?? "/usr/bin:/bin"), true); + + var session = Singularity.SessionManager.get_default(); + session.lock_screen(); + session.lock_screen(); + assert(session.locked); + wait_for(() => read_file(count) != ""); + assert(read_file(count) == "x"); + + write_file(release, ""); + wait_for(() => !session.locked); + assert(!session.locked); + FileUtils.remove(release); + + session.lock_screen(); + wait_for(() => read_file(count) == "x\nx"); + assert(read_file(count) == "x\nx"); + write_file(release, ""); + wait_for(() => !session.locked); +} + public static int main(string[] args) { Test.init(ref args); try { @@ -238,5 +265,6 @@ public static int main(string[] args) { Test.add_func("/power/command-suspend", test_command_suspend); Test.add_func("/power/battery-scan", test_battery_scan); Test.add_func("/power/charge-limit", test_charge_limit); + Test.add_func("/power/lock-screen-single-instance", test_lock_screen_single_instance); return Test.run(); }