~aperezdc/gtklock-dpms-module

2b1c928f9f3fe04cd53d8ec2b4a60452648eaa3d — Adrian Perez de Castro 9 months ago 147d397
Re-enable outputs on SIGINT and SIGTERM
1 files changed, 44 insertions(+), 2 deletions(-)

M module.c
M module.c => module.c +44 -2
@@ 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)))