[gnome-settings-daemon] wacom: Maintain per-device calibration notifications



commit a859aaa1c178bbbabd3cda2181c2813449dd93b9
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Dec 5 16:43:56 2013 +0100

    wacom: Maintain per-device calibration notifications
    
    All information around calibration notifications is now in a separate
    struct, set as GObject data on the GsdWacomDevice. On calibration checks,
    each device updates its notication as required. This fixes:
    
    1) The notification being possibly not shown if multiple in-screen devices
       are present. If the resolution changes on one monitor, but the device on
       the other monitor is checked last, the notification was then closed/removed.
    
    2) Older but still valid notifications disappearing if a second device needs
       calibration.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=700461

 plugins/wacom/gsd-wacom-manager.c |  174 ++++++++++++++++++++-----------------
 1 files changed, 93 insertions(+), 81 deletions(-)
---
diff --git a/plugins/wacom/gsd-wacom-manager.c b/plugins/wacom/gsd-wacom-manager.c
index 539c8d1..34110ab 100644
--- a/plugins/wacom/gsd-wacom-manager.c
+++ b/plugins/wacom/gsd-wacom-manager.c
@@ -97,6 +97,12 @@ static const gchar introspection_xml[] =
 "  </interface>"
 "</node>";
 
+typedef struct
+{
+        NotifyNotification *calibration_notification;
+        GsdWacomDevice     *device;
+        guint               notification_timeout_id;
+} GsdWacomDeviceCalibration;
 
 struct GsdWacomManagerPrivate
 {
@@ -117,10 +123,6 @@ struct GsdWacomManagerPrivate
         /* Help OSD window */
         GtkWidget *osd_window;
 
-        guint notification_timeout_src_id;
-        NotifyNotification *calibration_notification;
-        GsdWacomDevice *calibration_device;
-
         /* DBus */
         GDBusNodeInfo   *introspection_data;
         GDBusConnection *dbus_connection;
@@ -133,9 +135,6 @@ static void     gsd_wacom_manager_class_init  (GsdWacomManagerClass *klass);
 static void     gsd_wacom_manager_init        (GsdWacomManager      *wacom_manager);
 static void     gsd_wacom_manager_finalize    (GObject              *object);
 
-static void     on_notification_closed (NotifyNotification *notification,
-                                        GsdWacomManager    *manager);
-
 static gboolean osd_window_toggle_visibility (GsdWacomManager *manager,
                                               GsdWacomDevice  *device);
 
@@ -1099,7 +1098,8 @@ notify_unknown_device (GsdWacomManager *manager, const gchar *device_name)
         notify_notification_set_app_name (notification, _("Wacom Settings"));
         notify_notification_show (notification, NULL);
 
-        g_signal_connect (notification, "closed", G_CALLBACK (on_notification_closed), manager);
+        g_signal_connect (notification, "closed",
+                          G_CALLBACK (g_object_unref), NULL);
 
         g_free (msg_body);
 }
@@ -1580,8 +1580,7 @@ gsd_wacom_manager_idle_cb (GsdWacomManager *manager)
 }
 
 static gboolean
-check_need_for_calibration (GsdWacomManager *manager,
-                            GsdWacomDevice  *device)
+check_need_for_calibration (GsdWacomDevice  *device)
 {
         GSettings *settings;
         GVariant *variant;
@@ -1590,6 +1589,8 @@ check_need_for_calibration (GsdWacomManager *manager,
         gint monitor;
         GdkRectangle geometry;
 
+        g_debug ("Checking calibration for: %s", gsd_wacom_device_get_name (device));
+
         width = -1;
         height = -1;
 
@@ -1616,34 +1617,31 @@ check_need_for_calibration (GsdWacomManager *manager,
 }
 
 static void
-remove_notification (GsdWacomManager *manager)
+wacom_device_calibration_data_unset (GsdWacomDevice *device)
 {
-        g_clear_object (&manager->priv->calibration_notification);
-        manager->priv->calibration_device = NULL;
+        g_object_set_data (G_OBJECT (device),
+                           "gsd-wacom-calibration-data", NULL);
 }
 
 static void
-on_notification_closed (NotifyNotification *notification,
-                        GsdWacomManager    *manager)
+on_notification_closed (NotifyNotification        *notification,
+                        GsdWacomDeviceCalibration *data)
 {
-        if (notification == manager->priv->calibration_notification)
-                remove_notification (manager);
-        else
-                g_object_unref (notification);
+        wacom_device_calibration_data_unset (data->device);
 }
 
 static void
 on_notification_action (NotifyNotification *notification,
                         gchar              *action,
-                        gpointer            data)
+                        gpointer            user_data)
 {
         gboolean success;
         gchar *command;
         const gchar *device_name;
         GError *error = NULL;
-        GsdWacomManager *manager = GSD_WACOM_MANAGER (data);
+        GsdWacomDeviceCalibration *data = user_data;
 
-        device_name = gsd_wacom_device_get_name (manager->priv->calibration_device);
+        device_name = gsd_wacom_device_get_name (data->device);
 
         if (g_strcmp0 (action, "run-calibration") == 0) {
                 command = g_strdup_printf ("gnome-control-center wacom run-calibration \"%s\"",
@@ -1657,87 +1655,109 @@ on_notification_action (NotifyNotification *notification,
                 g_free (command);
         }
 
-        notify_notification_close (manager->priv->calibration_notification, NULL);
-        remove_notification (manager);
+        wacom_device_calibration_data_unset (data->device);
 }
 
 static void
-remove_calibration_notification (GsdWacomManager *manager)
+wacom_device_calibration_data_free (GsdWacomDeviceCalibration *data)
 {
-        GsdWacomManagerPrivate *priv;
-
-        priv = manager->priv;
+        if (data->notification_timeout_id)
+                g_source_remove (data->notification_timeout_id);
 
-        if (priv->calibration_notification) {
-                notify_notification_close (priv->calibration_notification, NULL);
-                g_clear_object (&priv->calibration_notification);
+        if (data->calibration_notification) {
+                notify_notification_close (data->calibration_notification, NULL);
+                g_object_unref (data->calibration_notification);
         }
-        if (manager->priv->notification_timeout_src_id > 0) {
-               g_source_remove (manager->priv->notification_timeout_src_id);
-               manager->priv->notification_timeout_src_id = 0;
-       }
-       manager->priv->calibration_device = NULL;
+
+        g_free (data);
 }
 
-static gboolean
-notify_need_for_calibration_real (gpointer data)
+static void
+wacom_device_calibration_data_update (GsdWacomDeviceCalibration *data)
 {
-        GsdWacomManager *manager = GSD_WACOM_MANAGER (data);
-        GsdWacomManagerPrivate *priv;
-        gchar *msg_body = NULL;
-
-        priv = manager->priv;
+        gchar *msg_body;
 
-        if (priv->calibration_notification) {
-                notify_notification_close (priv->calibration_notification, NULL);
-                g_clear_object (&priv->calibration_notification);
+        if (data->calibration_notification) {
+                notify_notification_close (data->calibration_notification, NULL);
+                g_object_unref (data->calibration_notification);
         }
+
         msg_body = g_strdup_printf (_("Tablet %s needs to be calibrated."),
-                                    gsd_wacom_device_get_name (priv->calibration_device));
-        priv->calibration_notification = notify_notification_new (_("Calibration needed"),
+                                    gsd_wacom_device_get_name (data->device));
+        data->calibration_notification = notify_notification_new (_("Calibration needed"),
                                                                   msg_body,
                                                                   NULL);
 
-        notify_notification_set_app_name (priv->calibration_notification,
+        notify_notification_set_app_name (data->calibration_notification,
                                           _("Wacom Settings"));
-        notify_notification_set_timeout (priv->calibration_notification,
+        notify_notification_set_timeout (data->calibration_notification,
                                          CALIBRATION_NOTIFICATION_TIMEOUT);
-        notify_notification_set_urgency (priv->calibration_notification,
+        notify_notification_set_urgency (data->calibration_notification,
                                          NOTIFY_URGENCY_NORMAL);
         /* TRANSLATORS: launches the calibration screen for the
            tablet in question */
-        notify_notification_add_action (priv->calibration_notification,
+        notify_notification_add_action (data->calibration_notification,
                                         "run-calibration",
                                         _("Calibrate"),
                                         on_notification_action,
-                                        manager,
+                                        data,
                                         NULL);
 
-        g_signal_connect (priv->calibration_notification,
+        g_signal_connect (data->calibration_notification,
                           "closed",
                           G_CALLBACK (on_notification_closed),
-                          manager);
+                          data);
 
-        notify_notification_show (priv->calibration_notification, NULL);
-
-        priv->notification_timeout_src_id = 0;
         g_free (msg_body);
-        return FALSE;
 }
 
-/* We need to have the notifications being shown from a
- * timeout function since when the monitor's size changes
- * we may get several calls to on_screen_changed_cb and
- * in the first call, the monitor's size is still not updated.
- */
+static GsdWacomDeviceCalibration *
+wacom_device_calibration_data_get (GsdWacomDevice *device)
+{
+        GsdWacomDeviceCalibration *data;
+
+        data = g_object_get_data (G_OBJECT (device), "gsd-wacom-calibration-data");
+
+        if (data)
+                return data;
+
+        data = g_new0 (GsdWacomDeviceCalibration, 1);
+        data->device = device;
+
+        g_object_set_data_full (G_OBJECT (device),
+                                "gsd-wacom-calibration-data", data,
+                                (GDestroyNotify) wacom_device_calibration_data_free);
+        return data;
+}
+
+static gboolean
+notify_need_for_calibration (gpointer user_data)
+{
+        GsdWacomDeviceCalibration *data = user_data;
+
+        notify_notification_show (data->calibration_notification, NULL);
+        data->notification_timeout_id = 0;
+
+        return G_SOURCE_REMOVE;
+}
+
 static void
-notify_need_for_calibration (GsdWacomManager *manager,
-                             GsdWacomDevice  *device)
+wacom_device_calibration_check (GsdWacomDevice  *device)
 {
-        manager->priv->calibration_device = device;
-        manager->priv->notification_timeout_src_id = g_timeout_add (SHOW_CALIBRATION_TIMEOUT,
-                                                                    notify_need_for_calibration_real,
-                                                                    manager);
+        if (check_need_for_calibration (device)) {
+                GsdWacomDeviceCalibration *data;
+
+                data = wacom_device_calibration_data_get (device);
+                wacom_device_calibration_data_update (data);
+
+                if (data->notification_timeout_id == 0) {
+                        data->notification_timeout_id = g_timeout_add (SHOW_CALIBRATION_TIMEOUT,
+                                                                       notify_need_for_calibration,
+                                                                       data);
+                }
+        } else {
+                wacom_device_calibration_data_unset (device);
+        }
 }
 
 /*
@@ -1772,14 +1792,10 @@ on_screen_changed_cb (GnomeRRScreen *rr_screen,
                settings = gsd_wacom_device_get_settings (device);
                /* Ignore touch devices as they do not share the same range of values for area */
                if (type != WACOM_TYPE_TOUCH) {
-                       if (gsd_wacom_device_is_screen_tablet (device) == FALSE)
+                       if (gsd_wacom_device_is_screen_tablet (device) == FALSE) {
                                set_keep_aspect (device, g_settings_get_boolean (settings, KEY_KEEP_ASPECT));
-                       else if (type == WACOM_TYPE_STYLUS) {
-                               remove_calibration_notification (manager);
-                               if (check_need_for_calibration (manager, device)) {
-                                       notify_need_for_calibration (manager,
-                                                                    device);
-                               }
+                        } else if (type == WACOM_TYPE_STYLUS) {
+                                wacom_device_calibration_check (device);
                        }
 
                        set_area (device, g_settings_get_value (settings, KEY_AREA));
@@ -1992,10 +2008,6 @@ gsd_wacom_manager_finalize (GObject *object)
         if (wacom_manager->priv->start_idle_id != 0)
                 g_source_remove (wacom_manager->priv->start_idle_id);
 
-        if (wacom_manager->priv->notification_timeout_src_id != 0)
-                g_source_remove (wacom_manager->priv->notification_timeout_src_id);
-        remove_notification (wacom_manager);
-
         g_clear_object (&wacom_manager->priv->shell_proxy);
 
         G_OBJECT_CLASS (gsd_wacom_manager_parent_class)->finalize (object);


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