backend: Remove direct upower-glib usage

Monitor whether UPower is running ourselves. That allows us to keep the
same value for "lid-is-closed" throughout the process of UPower
restarting, preventing unwanted monitor re-configuration through the process.

Fixes another screen black out when UPower restarts and the laptop lid
is closed.
This commit is contained in:
Bastien Nocera 2018-04-17 11:43:24 +02:00 committed by Jonas Ådahl
parent 951219650f
commit fa9e330f2c
3 changed files with 97 additions and 18 deletions

View File

@ -88,7 +88,6 @@ MUTTER_PC_MODULES="
cairo >= 1.10.0
gsettings-desktop-schemas >= 3.21.4
json-glib-1.0
upower-glib >= 0.99.0
gnome-desktop-3.0
xcomposite >= 0.2
xcursor

View File

@ -29,7 +29,6 @@
#include <glib-object.h>
#include <xkbcommon/xkbcommon.h>
#include <libupower-glib/upower.h>
#include <meta/meta-backend.h>
#include <meta/meta-idle-monitor.h>

View File

@ -112,7 +112,8 @@ struct _MetaBackendPrivate
MetaPointerConstraint *client_pointer_constraint;
MetaDnd *dnd;
UpClient *up_client;
guint upower_watch_id;
GDBusProxy *upower_proxy;
gboolean lid_is_closed;
guint sleep_signal_id;
@ -144,12 +145,14 @@ meta_backend_finalize (GObject *object)
g_clear_object (&priv->dbus_session_watcher);
#endif
g_clear_object (&priv->up_client);
if (priv->sleep_signal_id)
g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
if (priv->upower_watch_id)
g_bus_unwatch_name (priv->upower_watch_id);
g_cancellable_cancel (priv->cancellable);
g_clear_object (&priv->cancellable);
g_clear_object (&priv->system_bus);
g_clear_object (&priv->upower_proxy);
if (priv->device_update_idle_id)
g_source_remove (priv->device_update_idle_id);
@ -511,9 +514,6 @@ meta_backend_real_is_lid_closed (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
if (!priv->up_client)
return FALSE;
return priv->lid_is_closed;
}
@ -524,15 +524,25 @@ meta_backend_is_lid_closed (MetaBackend *backend)
}
static void
lid_is_closed_changed_cb (UpClient *client,
GParamSpec *pspec,
gpointer user_data)
upower_properties_changed (GDBusProxy *proxy,
GVariant *changed_properties,
GStrv invalidated_properties,
gpointer user_data)
{
MetaBackend *backend = user_data;
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
GVariant *v;
gboolean lid_is_closed;
lid_is_closed = up_client_get_lid_is_closed (priv->up_client);
v = g_variant_lookup_value (changed_properties,
"LidIsClosed",
G_VARIANT_TYPE_BOOLEAN);
if (!v)
return;
lid_is_closed = g_variant_get_boolean (v);
g_variant_unref (v);
if (lid_is_closed == priv->lid_is_closed)
return;
@ -546,6 +556,77 @@ lid_is_closed_changed_cb (UpClient *client,
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
}
static void
upower_ready_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
MetaBackend *backend;
MetaBackendPrivate *priv;
GDBusProxy *proxy;
GError *error = NULL;
GVariant *v;
proxy = g_dbus_proxy_new_finish (res, &error);
if (!proxy)
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
g_warning ("Failed to create UPower proxy: %s", error->message);
g_error_free (error);
return;
}
backend = META_BACKEND (user_data);
priv = meta_backend_get_instance_private (backend);
priv->upower_proxy = proxy;
g_signal_connect (proxy, "g-properties-changed",
G_CALLBACK (upower_properties_changed), backend);
v = g_dbus_proxy_get_cached_property (proxy, "LidIsClosed");
if (!v)
return;
priv->lid_is_closed = g_variant_get_boolean (v);
g_variant_unref (v);
if (priv->lid_is_closed)
{
g_signal_emit (backend, signals[LID_IS_CLOSED_CHANGED], 0,
priv->lid_is_closed);
}
}
static void
upower_appeared (GDBusConnection *connection,
const gchar *name,
const gchar *name_owner,
gpointer user_data)
{
MetaBackend *backend = META_BACKEND (user_data);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
g_dbus_proxy_new (connection,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.freedesktop.UPower",
"/org/freedesktop/UPower",
"org.freedesktop.UPower",
priv->cancellable,
upower_ready_cb,
backend);
}
static void
upower_vanished (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
MetaBackend *backend = META_BACKEND (user_data);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
g_clear_object (&priv->upower_proxy);
}
static void
meta_backend_constructed (GObject *object)
{
@ -557,13 +638,13 @@ meta_backend_constructed (GObject *object)
if (backend_class->is_lid_closed != meta_backend_real_is_lid_closed)
return;
priv->up_client = up_client_new ();
if (priv->up_client)
{
g_signal_connect (priv->up_client, "notify::lid-is-closed",
G_CALLBACK (lid_is_closed_changed_cb), NULL);
priv->lid_is_closed = up_client_get_lid_is_closed (priv->up_client);
}
priv->upower_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
"org.freedesktop.UPower",
G_BUS_NAME_WATCHER_FLAGS_NONE,
upower_appeared,
upower_vanished,
backend,
NULL);
}
static void