backend: add signals for reporting suspend and resume

This commit adds "suspending" and "resuming" signals
to MetaBackend.

It's preliminary work needed for tracking when to purge
and recreate all textures (needed by nvidia).
This commit is contained in:
Ray Strode 2019-01-10 10:47:19 -05:00
parent 76c34858d1
commit 4ac2899576

View File

@ -26,6 +26,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <gio/gunixfdlist.h>
#include <clutter/clutter-mutter.h> #include <clutter/clutter-mutter.h>
#include <meta/meta-backend.h> #include <meta/meta-backend.h>
#include <meta/main.h> #include <meta/main.h>
@ -60,7 +62,8 @@ enum
KEYMAP_CHANGED, KEYMAP_CHANGED,
KEYMAP_LAYOUT_GROUP_CHANGED, KEYMAP_LAYOUT_GROUP_CHANGED,
LAST_DEVICE_CHANGED, LAST_DEVICE_CHANGED,
SUSPENDING,
RESUMING,
N_SIGNALS N_SIGNALS
}; };
@ -550,6 +553,20 @@ meta_backend_class_init (MetaBackendClass *klass)
0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_INT); G_TYPE_NONE, 1, G_TYPE_INT);
signals[SUSPENDING] =
g_signal_new ("suspending",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[RESUMING] =
g_signal_new ("resuming",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS"); mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0; stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
@ -584,15 +601,66 @@ lid_is_closed_changed_cb (UpClient *client,
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ()); meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
} }
static void
inhibit_sleep (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
g_autoptr (GVariant) fd_variant = NULL;
g_autoptr (GUnixFDList) fd_list = NULL;
g_autoptr (GError) error = NULL;
int handle, fd;
if (priv->inhibit_sleep_fd >= 0)
return;
if (!login1_manager_call_inhibit_sync (priv->logind_proxy,
"sleep",
"Display Server",
"Prepare for suspend",
"delay",
NULL,
&fd_variant,
&fd_list,
priv->cancellable,
&error))
{
g_warning ("Failed to inhibit sleep: %s", error->message);
return;
}
handle = g_variant_get_handle (fd_variant);
fd = g_unix_fd_list_get (fd_list, handle, &error);
if (fd < 0)
{
g_warning ("Failed to fetch sleep inhibitor fd: %s", error->message);
return;
}
priv->inhibit_sleep_fd = fd;
}
static void
uninhibit_sleep (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
close (priv->inhibit_sleep_fd);
priv->inhibit_sleep_fd = -1;
}
static void static void
prepare_for_sleep_cb (MetaBackend *backend, prepare_for_sleep_cb (MetaBackend *backend,
gboolean suspending) gboolean suspending)
{ {
gboolean suspending; if (suspending) {
g_signal_emit (backend, signals[SUSPENDING], 0);
g_variant_get (parameters, "(b)", &suspending); uninhibit_sleep (backend);
if (suspending)
return; return;
}
inhibit_sleep (backend);
g_signal_emit (backend, signals[RESUMING], 0);
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ()); meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
} }
@ -619,6 +687,7 @@ system_bus_gotten_cb (GObject *object,
GAsyncResult *res, GAsyncResult *res,
gpointer user_data) gpointer user_data)
{ {
MetaBackend *backend = META_BACKEND (user_data);
MetaBackendPrivate *priv; MetaBackendPrivate *priv;
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
GDBusConnection *bus; GDBusConnection *bus;
@ -630,15 +699,21 @@ system_bus_gotten_cb (GObject *object,
priv = meta_backend_get_instance_private (user_data); priv = meta_backend_get_instance_private (user_data);
priv->system_bus = bus; priv->system_bus = bus;
priv->logind_proxy = get_logind_proxy (priv->cancellable, &error); priv->logind_proxy = get_logind_proxy (priv->cancellable, &error);
priv->inhibit_sleep_fd = -1;
if (!priv->logind_proxy) if (!priv->logind_proxy)
g_warning ("Failed to get logind proxy: %s", error->message); {
g_warning ("Failed to get logind proxy: %s", error->message);
g_signal_connect_object (priv->logind_proxy, }
"prepare-for-sleep", else
G_CALLBACK (prepare_for_sleep_cb), {
user_data, inhibit_sleep (backend);
G_CONNECT_SWAPPED); g_signal_connect_object (priv->logind_proxy,
"prepare-for-sleep",
G_CALLBACK (prepare_for_sleep_cb),
user_data,
G_CONNECT_SWAPPED);
}
} }
static gboolean static gboolean