@@ 8,6 8,7 @@
#include <gmodule.h>
#include <gtk/gtk.h>
#include <gdk/gdkwayland.h>
+#include <glib-unix.h>
#include "wlr-output-power-management-v1.h"
struct Window {
@@ 41,6 42,8 @@ typedef struct {
struct wl_list link;
} DpmsOutput;
+static unsigned s_sigint_handler = 0;
+static unsigned s_sigterm_handler = 0;
static unsigned s_power_off_timeout = 0;
static struct zwlr_output_power_manager_v1 *s_power_manager = NULL;
static struct wl_list s_outputs;
@@ 111,15 114,22 @@ output_create_with_gdk_monitor(GdkMonitor *monitor)
}
static void
-populate_outputs(const GArray *windows)
+destroy_outputs(void)
{
DpmsOutput *output, *tmp_output;
wl_list_for_each_safe(output, tmp_output, &s_outputs, link)
output_destroy(g_steal_pointer(&output));
+}
+
+static void
+populate_outputs(const GArray *windows)
+{
+ destroy_outputs();
for (unsigned i = 0; i < windows->len; i++) {
struct Window *window = g_array_index(windows, struct Window*, i);
- if ((output = output_by_gdk_monitor(window->monitor)))
+ DpmsOutput *output = output_by_gdk_monitor(window->monitor);
+ if (output)
continue; // Already in the list.
output = output_create_with_gdk_monitor(window->monitor);
@@ 195,6 205,33 @@ on_idle_hide(struct GtkLock *gtklock)
g_debug("%s: timeout #%u started.", G_STRFUNC, s_power_off_timeout);
}
+static void
+handle_after_signal_idle(void *data)
+{
+ int signum = GPOINTER_TO_INT(data);
+ g_debug("%s: Re-raising signal %d.", G_STRFUNC, signum);
+ raise(signum);
+}
+
+static gboolean
+handle_signal(void *data)
+{
+ g_clear_handle_id(&s_sigint_handler, g_source_remove);
+ g_clear_handle_id(&s_sigterm_handler, g_source_remove);
+
+ if (s_power_manager) {
+ g_debug("%s: Re-powering outputs before exiting.", G_STRFUNC);
+ set_outputs_powered(TRUE);
+ destroy_outputs();
+ }
+
+ // We cannot re-raise the signal immediately because we need to let the
+ // compositor do its job and gtklock needs to consume pending Wayland
+ // events before terminating.
+ g_idle_add_once(handle_after_signal_idle, data);
+ return G_SOURCE_REMOVE;
+}
+
G_MODULE_EXPORT void
on_output_change(struct GtkLock *gtklock)
{
@@ 220,6 257,11 @@ on_output_change(struct GtkLock *gtklock)
if (!s_power_manager)
return;
+ if (!s_sigint_handler)
+ s_sigint_handler = g_unix_signal_add(SIGINT, handle_signal, GINT_TO_POINTER(SIGINT));
+ if (!s_sigterm_handler)
+ s_sigterm_handler = g_unix_signal_add(SIGTERM, handle_signal, GINT_TO_POINTER(SIGTERM));
+
populate_outputs(gtklock->windows);
if (!gtklock->use_idle_hide || !gtklock->hidden || g_application_get_is_busy(G_APPLICATION(gtklock->app)))