[gnome-settings-daemon/wip/carlosg/logind-backlight-brightness] power: Use logind helper to change backlight brightness



commit cd051e6c7ccfb7e7b0ec440409c559b2e51284e8
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Nov 9 17:15:56 2019 +0100

    power: Use logind helper to change backlight brightness
    
    This is the favored method, over our own polkit helper, and over RandR.
    Since this helper does its own smart queueing of events, just forward them
    as fast as possible, and mark all tasks as completed ASAP on our side.
    
    However, as this is a recent logind feature (New in systemd 243), make this
    a soft runtime dependency, by checking first that the required DBus method
    exists. We forget about logind and go through the other methods if this one
    is not available.
    
    Closes: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/issues/429

 plugins/power/gsd-backlight.c | 67 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 60 insertions(+), 7 deletions(-)
---
diff --git a/plugins/power/gsd-backlight.c b/plugins/power/gsd-backlight.c
index 82f507b9..f4d60306 100644
--- a/plugins/power/gsd-backlight.c
+++ b/plugins/power/gsd-backlight.c
@@ -40,6 +40,8 @@ struct _GsdBacklight
         gint brightness_step;
 
 #ifdef __linux__
+        GDBusProxy *logind_proxy;
+
         GUdevClient *udev;
         GUdevDevice *udev_device;
 
@@ -59,6 +61,10 @@ enum {
         PROP_LAST,
 };
 
+#define SYSTEMD_DBUS_NAME                       "org.freedesktop.login1"
+#define SYSTEMD_DBUS_PATH                       "/org/freedesktop/login1/session/auto"
+#define SYSTEMD_DBUS_INTERFACE                  "org.freedesktop.login1.Session"
+
 static GParamSpec *props[PROP_LAST];
 
 static void     gsd_backlight_initable_iface_init (GInitableIface  *iface);
@@ -475,13 +481,26 @@ gsd_backlight_set_brightness_val_async (GsdBacklight *backlight,
         if (backlight->udev_device != NULL) {
                 BacklightHelperData *task_data;
 
-                task_data = g_new0 (BacklightHelperData, 1);
-                task_data->value = backlight->brightness_target;
-                g_task_set_task_data (task, task_data, backlight_task_data_destroy);
-
-                /* Task is set up now. Queue it and ensure we are working something. */
-                g_queue_push_tail (&backlight->tasks, task);
-                gsd_backlight_process_taskqueue (backlight);
+                if (backlight->logind_proxy) {
+                        g_dbus_proxy_call (backlight->logind_proxy,
+                                           "SetBrightness",
+                                           g_variant_new ("(ssu)",
+                                                          "backlight",
+                                                          g_udev_device_get_name (backlight->udev_device),
+                                                          backlight->brightness_target),
+                                           G_DBUS_CALL_FLAGS_NONE,
+                                           -1, NULL,
+                                           NULL, NULL);
+                        g_task_return_int (task, backlight->brightness_target);
+                } else {
+                        task_data = g_new0 (BacklightHelperData, 1);
+                        task_data->value = backlight->brightness_target;
+                        g_task_set_task_data (task, task_data, backlight_task_data_destroy);
+
+                        /* Task is set up now. Queue it and ensure we are working something. */
+                        g_queue_push_tail (&backlight->tasks, task);
+                        gsd_backlight_process_taskqueue (backlight);
+                }
 
                 return;
         }
@@ -799,6 +818,7 @@ gsd_backlight_initable_init (GInitable       *initable,
 {
         GsdBacklight *backlight = GSD_BACKLIGHT (initable);
         GnomeRROutput* output = NULL;
+        GError *logind_error = NULL;
 
         if (cancellable != NULL) {
                 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
@@ -807,6 +827,38 @@ gsd_backlight_initable_init (GInitable       *initable,
         }
 
 #ifdef __linux__
+        backlight->logind_proxy =
+                g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                               0,
+                                               NULL,
+                                               SYSTEMD_DBUS_NAME,
+                                               SYSTEMD_DBUS_PATH,
+                                               SYSTEMD_DBUS_INTERFACE,
+                                               NULL, &logind_error);
+        if (backlight->logind_proxy) {
+                /* Check that the SetBrightness method does exist */
+                g_dbus_proxy_call_sync (backlight->logind_proxy,
+                                        "SetBrightness", NULL,
+                                        G_DBUS_CALL_FLAGS_NONE, -1,
+                                        NULL, &logind_error);
+
+                if (g_error_matches (logind_error, G_DBUS_ERROR,
+                                     G_DBUS_ERROR_INVALID_ARGS)) {
+                        /* We are calling the method with no arguments, so
+                         * this is expected.
+                         */
+                        g_clear_error (&logind_error);
+                } else {
+                        /* Fail on anything else */
+                        g_clear_object (&backlight->logind_proxy);
+                }
+        }
+
+        if (logind_error) {
+                g_warning ("No logind found: %s", logind_error->message);
+                g_error_free (logind_error);
+        }
+
         /* Try finding a udev device. */
         if (gsd_backlight_udev_init (backlight))
                 goto found;
@@ -848,6 +900,7 @@ gsd_backlight_finalize (GObject *object)
 #ifdef __linux__
         g_assert (backlight->active_task == NULL);
         g_assert (g_queue_is_empty (&backlight->tasks));
+        g_clear_object (&backlight->logind_proxy);
         g_clear_object (&backlight->udev);
         g_clear_object (&backlight->udev_device);
         if (backlight->idle_update) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]