[gnome-control-center/wip/carlosg/ekr-loves-27qhd: 1/4] wacom: Let CcWacomPage track pad devices



commit ebea9faf5b77fca9552b48ac152c5a48a2c247b6
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Dec 5 14:17:17 2019 +0100

    wacom: Let CcWacomPage track pad devices
    
    This puts stylus/pad tracking on 2 separate levels. The CcWacomPanel
    will look for styli, and treat them as "device leaders", adding a
    CcWacomPage for them.
    
    The CcWacomPage will then track the related pad, and update the
    "Map buttons..." action visibility according to it.
    
    This simplifies tablet page creation (eg. have it completed in one
    step), and decouples the device grouping logic from CcWacomPanel,
    which will be useful in future commits.

 panels/wacom/cc-wacom-page.c           |  87 +++++++++++-----
 panels/wacom/cc-wacom-page.h           |   7 +-
 panels/wacom/cc-wacom-panel.c          | 176 +++++++++++----------------------
 panels/wacom/gnome-wacom-properties.ui |   2 +-
 panels/wacom/test-wacom.c              |   5 +-
 5 files changed, 119 insertions(+), 158 deletions(-)
---
diff --git a/panels/wacom/cc-wacom-page.c b/panels/wacom/cc-wacom-page.c
index ab52a8471..c037ff88b 100644
--- a/panels/wacom/cc-wacom-page.c
+++ b/panels/wacom/cc-wacom-page.c
@@ -87,6 +87,9 @@ struct _CcWacomPage
        GtkWidget      *dialog;
 
        GCancellable   *cancellable;
+
+       /* To reach other grouped devices */
+       GsdDeviceManager *manager;
 };
 
 G_DEFINE_TYPE (CcWacomPage, cc_wacom_page, GTK_TYPE_BOX)
@@ -119,8 +122,8 @@ enum {
 };
 
 static void
-update_tablet_ui (CcWacomPage *page,
-                 int          layout);
+set_page_layout (CcWacomPage *page,
+                int          layout);
 
 static int
 get_layout_type (CcWacomDevice *device)
@@ -504,7 +507,7 @@ display_mapping_dialog_closed (GtkDialog   *dialog,
        page->dialog = NULL;
        page->mapping = NULL;
        layout = get_layout_type (page->stylus);
-       update_tablet_ui (page, layout);
+       set_page_layout (page, layout);
 }
 
 static void
@@ -717,6 +720,7 @@ cc_wacom_page_dispose (GObject *object)
        g_clear_pointer (&self->dialog, gtk_widget_destroy);
        g_clear_object (&self->builder);
        g_clear_object (&self->header_group);
+       g_clear_object (&self->pad);
 
        self->panel = NULL;
 
@@ -865,8 +869,8 @@ has_monitor (CcWacomPage *page)
 }
 
 static void
-update_tablet_ui (CcWacomPage *page,
-                 int          layout)
+set_page_layout (CcWacomPage *page,
+                int          layout)
 {
        WacomIntegrationFlags integration_flags;
 
@@ -878,9 +882,6 @@ update_tablet_ui (CcWacomPage *page,
                remove_mouse_link (page);
        }
 
-       /* Hide the pad buttons if no pad is present */
-       gtk_widget_set_visible (WID ("map-buttons-button"), page->pad != NULL);
-
        switch (layout) {
        case LAYOUT_NORMAL:
                remove_left_handed (page);
@@ -912,44 +913,63 @@ update_tablet_ui (CcWacomPage *page,
        }
 }
 
-gboolean
-cc_wacom_page_update_tools (CcWacomPage   *page,
-                           CcWacomDevice *stylus,
-                           CcWacomDevice *pad)
+static void
+update_pad_availability (CcWacomPage *page)
 {
-       int layout;
-       gboolean changed;
+       gtk_widget_set_visible (WID ("map-buttons-button"), page->pad != NULL);
+}
 
-       /* Type of layout */
-       layout = get_layout_type (stylus);
+static void
+check_add_pad (CcWacomPage *page,
+              GsdDevice   *gsd_device)
+{
+       CcWacomDevice *wacom_device;
 
-       changed = (page->stylus != stylus || page->pad != pad);
-       if (!changed)
-               return FALSE;
+       if ((gsd_device_get_device_type (gsd_device) & GSD_DEVICE_TYPE_PAD) == 0)
+               return;
 
-       page->stylus = stylus;
-       page->pad = pad;
+       wacom_device = cc_wacom_device_new (gsd_device);
+       if (!wacom_device)
+               return;
 
-       update_tablet_ui (CC_WACOM_PAGE (page), layout);
+       if (g_strcmp0 (cc_wacom_device_get_name (page->stylus),
+                      cc_wacom_device_get_name (wacom_device)) != 0) {
+               g_object_unref (wacom_device);
+               return;
+       }
 
-       return TRUE;
+       g_set_object (&page->pad, wacom_device);
+       update_pad_availability (page);
+}
+
+static void
+check_remove_pad (CcWacomPage *page,
+                 GsdDevice   *gsd_device)
+{
+       if ((gsd_device_get_device_type (gsd_device) & GSD_DEVICE_TYPE_PAD) == 0)
+               return;
+
+       if (page->pad && cc_wacom_device_get_device (page->pad) == gsd_device)
+               page->pad = NULL;
+       update_pad_availability (page);
 }
 
 GtkWidget *
 cc_wacom_page_new (CcWacomPanel  *panel,
-                  CcWacomDevice *stylus,
-                  CcWacomDevice *pad)
+                  CcWacomDevice *stylus)
 {
+       g_autoptr (GList) pads = NULL;
        CcWacomPage *page;
+       GList *l;
 
        g_return_val_if_fail (CC_IS_WACOM_DEVICE (stylus), NULL);
-       g_return_val_if_fail (!pad || CC_IS_WACOM_DEVICE (pad), NULL);
 
        page = g_object_new (CC_TYPE_WACOM_PAGE, NULL);
 
        page->panel = panel;
+       page->stylus = stylus;
 
-       cc_wacom_page_update_tools (page, stylus, pad);
+       set_page_layout (page, get_layout_type (stylus));
 
        /* FIXME move this to construct */
        page->wacom_settings  = cc_wacom_device_get_settings (stylus);
@@ -966,6 +986,19 @@ cc_wacom_page_new (CcWacomPanel  *panel,
        /* Tablet icon */
        set_icon_name (page, "image-tablet", cc_wacom_device_get_icon_name (stylus));
 
+       /* Listen to changes in related/paired pads */
+       page->manager = gsd_device_manager_get ();
+       g_signal_connect_object (G_OBJECT (page->manager), "device-added",
+                                G_CALLBACK (check_add_pad), page,
+                                G_CONNECT_SWAPPED);
+       g_signal_connect_object (G_OBJECT (page->manager), "device-removed",
+                                G_CALLBACK (check_remove_pad), page,
+                                G_CONNECT_SWAPPED);
+
+       pads = gsd_device_manager_list_devices (page->manager, GSD_DEVICE_TYPE_PAD);
+       for (l = pads; l ; l = l->next)
+               check_add_pad (page, l->data);
+
        return GTK_WIDGET (page);
 }
 
diff --git a/panels/wacom/cc-wacom-page.h b/panels/wacom/cc-wacom-page.h
index cd3a6ae39..56b32ac87 100644
--- a/panels/wacom/cc-wacom-page.h
+++ b/panels/wacom/cc-wacom-page.h
@@ -30,12 +30,7 @@ G_BEGIN_DECLS
 G_DECLARE_FINAL_TYPE (CcWacomPage, cc_wacom_page, CC, WACOM_PAGE, GtkBox)
 
 GtkWidget * cc_wacom_page_new (CcWacomPanel  *panel,
-                              CcWacomDevice *stylus,
-                              CcWacomDevice *pad);
-
-gboolean cc_wacom_page_update_tools (CcWacomPage   *page,
-                                    CcWacomDevice *stylus,
-                                    CcWacomDevice *pad);
+                              CcWacomDevice *stylus);
 
 void cc_wacom_page_set_navigation (CcWacomPage *page,
                                   GtkNotebook *notebook,
diff --git a/panels/wacom/cc-wacom-panel.c b/panels/wacom/cc-wacom-panel.c
index c0c15b3aa..4c5d46b76 100644
--- a/panels/wacom/cc-wacom-panel.c
+++ b/panels/wacom/cc-wacom-panel.c
@@ -54,7 +54,7 @@ struct _CcWacomPanel
        GtkWidget        *test_draw_area;
        GtkWidget        *test_button;
        GHashTable       *devices; /* key=GsdDevice, value=CcWacomDevice */
-       GHashTable       *pages; /* key=device name, value=GtkWidget */
+       GHashTable       *pages; /* key=CcWacomDevice, value=GtkWidget */
        GHashTable       *stylus_pages; /* key=CcWacomTool, value=GtkWidget */
        GsdDeviceManager *manager;
        guint             device_added_id;
@@ -120,23 +120,39 @@ cc_wacom_panel_static_init_func (void)
        update_visibility (manager, NULL, NULL);
 }
 
+static CcWacomDevice *
+lookup_wacom_device (CcWacomPanel *self,
+                    const gchar  *name)
+{
+       GHashTableIter iter;
+       CcWacomDevice *wacom_device;
+
+       g_hash_table_iter_init (&iter, self->devices);
+       while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &wacom_device)) {
+               if (strcmp (cc_wacom_device_get_name (wacom_device), name) == 0)
+                       return wacom_device;
+       }
+
+       return NULL;
+}
+
 static CcWacomPage *
 set_device_page (CcWacomPanel *self, const gchar *device_name)
 {
        CcWacomPage *page;
+       CcWacomDevice *wacom_device;
        gint current;
 
        if (device_name == NULL)
                return NULL;
 
-       /* Choose correct device */
-       page = g_hash_table_lookup (self->pages, device_name);
-
-       if (page == NULL) {
+       wacom_device = lookup_wacom_device (self, device_name);
+       if (!wacom_device) {
                g_warning ("Failed to find device '%s', supplied in the command line.", device_name);
-               return page;
+               return NULL;
        }
 
+       page = g_hash_table_lookup (self->pages, wacom_device);
        current = gtk_notebook_page_num (GTK_NOTEBOOK (self->tablet_notebook), GTK_WIDGET (page));
        gtk_notebook_set_current_page (GTK_NOTEBOOK (self->tablet_notebook), current);
 
@@ -495,107 +511,13 @@ cc_wacom_panel_class_init (CcWacomPanelClass *klass)
 }
 
 static void
-remove_page (GtkNotebook *notebook,
-            GtkWidget   *widget)
+update_current_page (CcWacomPanel  *self)
 {
-       int num_pages, i;
+       int num_pages;
 
-       num_pages = gtk_notebook_get_n_pages (notebook);
-       g_return_if_fail (num_pages > 1);
-       for (i = 1; i < num_pages; i++) {
-               if (gtk_notebook_get_nth_page (notebook, i) == widget) {
-                       gtk_notebook_remove_page (notebook, i);
-                       return;
-               }
-       }
-}
-
-static void
-update_current_page (CcWacomPanel  *self,
-                    CcWacomDevice *removed_device)
-{
-       GHashTable *ht;
-       g_autoptr(GList) tablets = NULL;
-       GList *l;
-       gboolean changed;
-       GHashTableIter iter;
-       GsdDevice *gsd_device;
-       CcWacomDevice *device;
-
-       changed = FALSE;
-
-       ht = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
-
-       if (removed_device) {
-               Tablet *tablet = g_new0 (Tablet, 1);
-               tablet->name = cc_wacom_device_get_name (removed_device);
-               g_hash_table_insert (ht, (gpointer) tablet->name, tablet);
-       }
-
-       g_hash_table_iter_init (&iter, self->devices);
-
-       while (g_hash_table_iter_next (&iter, (gpointer*) &gsd_device,
-                                      (gpointer*) &device)) {
-               Tablet *tablet;
-               GsdDeviceType device_type;
-
-               device_type = gsd_device_get_device_type (gsd_device);
-               tablet = g_hash_table_lookup (ht, cc_wacom_device_get_name (device));
-               if (tablet == NULL) {
-                       tablet = g_new0 (Tablet, 1);
-                       tablet->name = cc_wacom_device_get_name (device);
-                       g_hash_table_insert (ht, (gpointer) tablet->name, tablet);
-               }
-
-               if (device_type & GSD_DEVICE_TYPE_PAD) {
-                       tablet->pad = device;
-               } else if (device_type & GSD_DEVICE_TYPE_TABLET) {
-                       tablet->stylus = device;
-               }
-       }
-
-       /* We now have a list of Tablet structs,
-        * see which ones are full tablets */
-       tablets = g_hash_table_get_values (ht);
-       for (l = tablets; l; l = l->next) {
-               Tablet *tablet;
-               GtkWidget *page;
-
-               tablet = l->data;
-               if (tablet->stylus == NULL) {
-                       page = g_hash_table_lookup (self->pages, tablet->name);
-                       if (page != NULL) {
-                               remove_page (GTK_NOTEBOOK (self->tablet_notebook), page);
-                               g_hash_table_remove (self->pages, tablet->name);
-
-                               changed = TRUE;
-                       }
-                       continue;
-               }
-               /* this code is called once the stylus is set up, but the pad does not exist yet */
-               page = g_hash_table_lookup (self->pages, tablet->name);
-               if (page == NULL) {
-                       page = cc_wacom_page_new (self, tablet->stylus, tablet->pad);
-                       cc_wacom_page_set_navigation (CC_WACOM_PAGE (page), GTK_NOTEBOOK 
(self->tablet_notebook), TRUE);
-                       gtk_widget_show (page);
-                       gtk_notebook_append_page (GTK_NOTEBOOK (self->tablet_notebook), page, NULL);
-                       g_hash_table_insert (self->pages, g_strdup (tablet->name), page);
-
-                       changed = TRUE;
-               } else {
-                       cc_wacom_page_update_tools (CC_WACOM_PAGE (page), tablet->stylus, tablet->pad);
-               }
-       }
-
-       g_hash_table_destroy (ht);
-
-       if (changed == TRUE) {
-               int num_pages;
-
-               num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (self->tablet_notebook));
-               if (num_pages > 1)
-                       gtk_notebook_set_current_page (GTK_NOTEBOOK (self->tablet_notebook), 1);
-       }
+       num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (self->tablet_notebook));
+       if (num_pages > 1)
+               gtk_notebook_set_current_page (GTK_NOTEBOOK (self->tablet_notebook), 1);
 
        update_test_button (self);
 }
@@ -606,6 +528,9 @@ add_known_device (CcWacomPanel *self,
 {
        CcWacomDevice *device;
        GsdDeviceType device_type;
+       g_autoptr(GList) tools = NULL;
+       GtkWidget *page;
+       GList *l;
 
        device_type = gsd_device_get_device_type (gsd_device);
 
@@ -613,7 +538,9 @@ add_known_device (CcWacomPanel *self,
                return;
 
        if ((device_type &
-            (GSD_DEVICE_TYPE_TOUCHSCREEN | GSD_DEVICE_TYPE_TOUCHPAD)) != 0) {
+            (GSD_DEVICE_TYPE_PAD |
+             GSD_DEVICE_TYPE_TOUCHSCREEN |
+             GSD_DEVICE_TYPE_TOUCHPAD)) != 0) {
                return;
        }
 
@@ -623,17 +550,17 @@ add_known_device (CcWacomPanel *self,
 
        g_hash_table_insert (self->devices, gsd_device, device);
 
-       /* Only trigger tool lookup on pen devices */
-       if ((device_type & GSD_DEVICE_TYPE_TABLET) != 0) {
-               g_autoptr(GList) tools = NULL;
-               GList *l;
+       tools = cc_tablet_tool_map_list_tools (self->tablet_tool_map, device);
 
-               tools = cc_tablet_tool_map_list_tools (self->tablet_tool_map, device);
-
-               for (l = tools; l != NULL; l = l->next) {
-                       add_stylus (self, l->data);
-               }
+       for (l = tools; l != NULL; l = l->next) {
+               add_stylus (self, l->data);
        }
+
+       page = cc_wacom_page_new (self, device);
+       cc_wacom_page_set_navigation (CC_WACOM_PAGE (page), GTK_NOTEBOOK (self->tablet_notebook), TRUE);
+       gtk_widget_show (page);
+       gtk_notebook_append_page (GTK_NOTEBOOK (self->tablet_notebook), page, NULL);
+       g_hash_table_insert (self->pages, device, page);
 }
 
 static void
@@ -641,15 +568,22 @@ device_removed_cb (GsdDeviceManager *manager,
                   GsdDevice        *gsd_device,
                   CcWacomPanel     *self)
 {
-       g_autoptr(CcWacomDevice) device = NULL;
+       CcWacomDevice *device;
+       GtkWidget *page;
 
        device = g_hash_table_lookup (self->devices, gsd_device);
        if (!device)
                return;
 
-       g_hash_table_steal (self->devices, gsd_device);
-       update_current_page (self, device);
+       page = g_hash_table_lookup (self->pages, device);
+       if (page) {
+               g_hash_table_remove (self->pages, device);
+               gtk_widget_destroy (page);
+       }
+
+       g_hash_table_remove (self->devices, gsd_device);
        check_remove_stylus_pages (self);
+       update_current_page (self);
 }
 
 static void
@@ -658,7 +592,7 @@ device_added_cb (GsdDeviceManager *manager,
                 CcWacomPanel     *self)
 {
        add_known_device (self, device);
-       update_current_page (self, NULL);
+       update_current_page (self);
 }
 
 static gboolean
@@ -828,7 +762,7 @@ cc_wacom_panel_init (CcWacomPanel *self)
                          G_CALLBACK (link_activated), self);
 
        self->devices = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
-       self->pages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+       self->pages = g_hash_table_new (NULL, NULL);
        self->stylus_pages = g_hash_table_new (NULL, NULL);
 
        self->manager = gsd_device_manager_get ();
@@ -842,7 +776,7 @@ cc_wacom_panel_init (CcWacomPanel *self)
        for (l = devices; l ; l = l->next)
                add_known_device (self, l->data);
 
-       update_current_page (self, NULL);
+       update_current_page (self);
 }
 
 GDBusProxy *
diff --git a/panels/wacom/gnome-wacom-properties.ui b/panels/wacom/gnome-wacom-properties.ui
index 4ac842410..8679bd26e 100644
--- a/panels/wacom/gnome-wacom-properties.ui
+++ b/panels/wacom/gnome-wacom-properties.ui
@@ -308,7 +308,7 @@
                           <object class="GtkButton" id="map-buttons-button">
                             <property name="label" translatable="yes">Map Buttons…</property>
                             <property name="use_action_appearance">False</property>
-                            <property name="visible">True</property>
+                            <property name="visible">False</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
                           </object>
diff --git a/panels/wacom/test-wacom.c b/panels/wacom/test-wacom.c
index 16821b230..a8d4f6948 100644
--- a/panels/wacom/test-wacom.c
+++ b/panels/wacom/test-wacom.c
@@ -26,19 +26,18 @@ add_page (GList *devices,
          GtkWidget *notebook)
 {
        GtkWidget *widget;
-       CcWacomDevice *stylus, *eraser, *pad;
+       CcWacomDevice *stylus = NULL;
        GList *l;
 
        if (devices == NULL)
                return;
 
-       stylus = eraser = pad = NULL;
        for (l = devices; l ; l = l->next) {
                stylus = l->data;
        }
        g_list_free (devices);
 
-       widget = cc_wacom_page_new (NULL, stylus, pad);
+       widget = cc_wacom_page_new (NULL, stylus);
        cc_wacom_page_set_navigation (CC_WACOM_PAGE (widget), GTK_NOTEBOOK (notebook), FALSE);
        gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, NULL);
        gtk_widget_show (widget);


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