[gnome-control-center/wip/carlosg/tablet-calibration-ui-mapping] wacom: Use Mutter's input mapping interface to show calibration UI




commit 92b784f561f887982d42ebca46910fcb58c5506f
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Sep 1 13:58:18 2022 +0200

    wacom: Use Mutter's input mapping interface to show calibration UI
    
    When the "Automatic" mapping is chosen for a display-attached tablet device,
    Mutter is in charge of applying the heuristics to map the tablet device to
    its most likely attached display.
    
    When that happens, the Wacom panel does not know better (or anything)
    to show the calibration UI than picking a GdkMonitor and hoping for the
    best.
    
    To improve this situation, Mutter has been added a D-Bus interface so it
    is possible to query it for the output that a tablet device is mapped to.
    This commit adds the support for this interface, so that the Wacom panel
    does know to pick the right GdkMonitor to fullscreen the calibration UI on.

 panels/wacom/cc-wacom-page.c  | 67 ++++++++++++++++++++++++++++++++-----------
 panels/wacom/cc-wacom-panel.c | 37 ++++++++++++++++++++++++
 panels/wacom/cc-wacom-panel.h |  2 ++
 panels/wacom/test-wacom.c     |  8 ++++++
 4 files changed, 98 insertions(+), 16 deletions(-)
---
diff --git a/panels/wacom/cc-wacom-page.c b/panels/wacom/cc-wacom-page.c
index ad4c569ed..696d71d0e 100644
--- a/panels/wacom/cc-wacom-page.c
+++ b/panels/wacom/cc-wacom-page.c
@@ -235,6 +235,28 @@ run_calibration (CcWacomPage *page,
        return FALSE;
 }
 
+static GdkMonitor *
+find_monitor_at_point (GdkDisplay *display,
+                      gint        x,
+                      gint        y)
+{
+       GListModel *monitors;
+       int i;
+
+       monitors = gdk_display_get_monitors (display);
+
+       for (i = 0; i < g_list_model_get_n_items (monitors); i++) {
+               g_autoptr(GdkMonitor) m = g_list_model_get_item (monitors, i);
+               GdkRectangle geometry;
+
+               gdk_monitor_get_geometry (m, &geometry);
+               if (gdk_rectangle_contains_point (&geometry, x, y))
+                       return g_steal_pointer (&m);
+       }
+
+       return NULL;
+}
+
 static void
 calibrate (CcWacomPage *page)
 {
@@ -243,12 +265,12 @@ calibrate (CcWacomPage *page)
        g_autofree GVariant **tmp = NULL;
        g_autofree gdouble *calibration = NULL;
        gsize ncal;
-       g_autoptr(GdkMonitor) monitor = NULL;
-  GListModel *monitors;
        GdkDisplay *display;
+       g_autoptr(GdkMonitor) monitor = NULL;
        g_autoptr(GnomeRRScreen) rr_screen = NULL;
        GnomeRROutput *output;
        g_autoptr(GError) error = NULL;
+       GDBusProxy *input_mapping_proxy;
        gint x, y;
 
        display = gdk_display_get_default ();
@@ -259,20 +281,33 @@ calibrate (CcWacomPage *page)
        }
 
        output = cc_wacom_device_get_output (page->stylus, rr_screen);
-       gnome_rr_output_get_position (output, &x, &y);
-
-  monitors = gdk_display_get_monitors (display);
-  for (i = 0; i < g_list_model_get_n_items (monitors); i++) {
-    g_autoptr(GdkMonitor) m = g_list_model_get_item (monitors, i);
-    GdkRectangle geometry;
-
-    gdk_monitor_get_geometry (m, &geometry);
-    if (gdk_rectangle_contains_point (&geometry, x, y))
-      {
-        monitor = g_steal_pointer (&m);
-        break;
-      }
-  }
+       input_mapping_proxy = cc_wacom_panel_get_input_mapping_bus_proxy (page->panel);
+
+       if (output) {
+               gnome_rr_output_get_position (output, &x, &y);
+               monitor = find_monitor_at_point (display, x, y);
+       } else if (input_mapping_proxy) {
+               GsdDevice *gsd_device;
+               GVariant *mapping;
+
+               gsd_device = cc_wacom_device_get_device (page->stylus);
+
+               if (gsd_device) {
+                       mapping = g_dbus_proxy_call_sync (input_mapping_proxy,
+                                                         "GetDeviceMapping",
+                                                         g_variant_new ("(o)", gsd_device_get_device_file 
(gsd_device)),
+                                                         G_DBUS_CALL_FLAGS_NONE,
+                                                         -1,
+                                                         NULL,
+                                                         NULL);
+                       if (mapping) {
+                               gint x, y, width, height;
+
+                               g_variant_get (mapping, "((iiii))", &x, &y, &width, &height);
+                               monitor = find_monitor_at_point (display, x, y);
+                       }
+               }
+       }
 
        if (!monitor) {
                /* The display the tablet should be mapped to could not be located.
diff --git a/panels/wacom/cc-wacom-panel.c b/panels/wacom/cc-wacom-panel.c
index 9b50c7b36..36aca068f 100644
--- a/panels/wacom/cc-wacom-panel.c
+++ b/panels/wacom/cc-wacom-panel.c
@@ -70,6 +70,7 @@ struct _CcWacomPanel
 
        /* DBus */
        GDBusProxy    *proxy;
+       GDBusProxy    *input_mapping_proxy;
 };
 
 CC_PANEL_REGISTER (CcWacomPanel, cc_wacom_panel)
@@ -288,6 +289,7 @@ cc_wacom_panel_dispose (GObject *object)
 
        g_clear_pointer (&self->devices, g_hash_table_unref);
        g_clear_object (&self->proxy);
+       g_clear_object (&self->input_mapping_proxy);
        g_clear_pointer (&self->pages, g_hash_table_unref);
        g_clear_pointer (&self->stylus_pages, g_hash_table_unref);
        g_clear_handle_id (&self->mock_stylus_id, g_source_remove);
@@ -664,6 +666,23 @@ got_osd_proxy_cb (GObject      *source_object,
        }
 }
 
+static void
+got_input_mapping_proxy_cb (GObject      *source_object,
+                           GAsyncResult *res,
+                           gpointer      data)
+{
+       g_autoptr(GError) error = NULL;
+       CcWacomPanel *self;
+
+       self = CC_WACOM_PANEL (data);
+       self->input_mapping_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+
+       if (self->input_mapping_proxy == NULL) {
+               g_printerr ("Error creating input mapping proxy: %s\n", error->message);
+               return;
+       }
+}
+
 static void
 cc_wacom_panel_init (CcWacomPanel *self)
 {
@@ -688,6 +707,16 @@ cc_wacom_panel_init (CcWacomPanel *self)
                                  got_osd_proxy_cb,
                                  self);
 
+       g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                 G_DBUS_PROXY_FLAGS_NONE,
+                                 NULL,
+                                 "org.gnome.Shell",
+                                 "/org/gnome/Mutter/InputMapping",
+                                 "org.gnome.Mutter.InputMapping",
+                                 cc_panel_get_cancellable (CC_PANEL (self)),
+                                 got_input_mapping_proxy_cb,
+                                 self);
+
        self->devices = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
        self->pages = g_hash_table_new (NULL, NULL);
        self->stylus_pages = g_hash_table_new (NULL, NULL);
@@ -714,3 +743,11 @@ cc_wacom_panel_get_gsd_wacom_bus_proxy (CcWacomPanel *self)
 
        return self->proxy;
 }
+
+GDBusProxy *
+cc_wacom_panel_get_input_mapping_bus_proxy (CcWacomPanel *self)
+{
+       g_return_val_if_fail (CC_IS_WACOM_PANEL (self), NULL);
+
+       return self->input_mapping_proxy;
+}
diff --git a/panels/wacom/cc-wacom-panel.h b/panels/wacom/cc-wacom-panel.h
index 55bf1f96e..68f46aadc 100644
--- a/panels/wacom/cc-wacom-panel.h
+++ b/panels/wacom/cc-wacom-panel.h
@@ -37,4 +37,6 @@ void  cc_wacom_panel_set_osd_visibility (CcWacomPanel *self,
 
 GDBusProxy * cc_wacom_panel_get_gsd_wacom_bus_proxy (CcWacomPanel *self);
 
+GDBusProxy * cc_wacom_panel_get_input_mapping_bus_proxy (CcWacomPanel *self);
+
 G_END_DECLS
diff --git a/panels/wacom/test-wacom.c b/panels/wacom/test-wacom.c
index ef95aeb57..5e4cf7e7a 100644
--- a/panels/wacom/test-wacom.c
+++ b/panels/wacom/test-wacom.c
@@ -21,6 +21,14 @@ cc_wacom_panel_get_gsd_wacom_bus_proxy (CcWacomPanel *self)
        return NULL;
 }
 
+GDBusProxy *
+cc_wacom_panel_get_input_mapping_bus_proxy (CcWacomPanel *self)
+{
+       g_message ("Should get the mutter input mapping dbus proxy here");
+
+       return NULL;
+}
+
 static void
 add_page (GList *devices,
          GtkWidget *notebook)


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