[gtk/headless-seatless: 1/8] gtk: Handle seatless displays



commit 01acb9f116d26d2385aecbb177cb5099d6606943
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu May 14 21:27:45 2020 -0400

    gtk: Handle seatless displays
    
    If you run weston with the headless backend, you get a Wayland
    display with no seat, which is just fine by the protocol.
    
    gdk_display_get_default_seat() returns NULL in this case. Various
    widgets assume that we always have a seat with a keyboard and a
    pointer, since that is what X guarantees. Make things survive
    without that, so we can run the testsuite under a headless
    Wayland compositor.

 gdk/gdksurface.c               | 12 ++++---
 gtk/gtklabel.c                 | 80 ++++++++++++++++++++++++++---------------
 gtk/gtkpasswordentry.c         | 17 ++++++---
 gtk/gtkstylecontext.c          | 24 ++++++++++---
 gtk/gtktext.c                  | 82 +++++++++++++++++++++++++++---------------
 gtk/gtktextview.c              | 80 +++++++++++++++++++++++++----------------
 gtk/gtktooltip.c               | 29 +++++++++++----
 gtk/gtkwidget.c                | 12 ++++---
 gtk/gtkwindow.c                | 12 ++++---
 gtk/inspector/inspect-button.c |  7 +++-
 testsuite/gdk/seat.c           | 19 +++++++---
 11 files changed, 255 insertions(+), 119 deletions(-)
---
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index b6ee8f577a..4835c7ba42 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1746,10 +1746,14 @@ gdk_surface_hide (GdkSurface *surface)
       /* May need to break grabs on children */
       display = surface->display;
       seat = gdk_display_get_default_seat (display);
-
-      devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_ALL);
-      devices = g_list_prepend (devices, gdk_seat_get_keyboard (seat));
-      devices = g_list_prepend (devices, gdk_seat_get_pointer (seat));
+      if (seat)
+        {
+          devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_ALL);
+          devices = g_list_prepend (devices, gdk_seat_get_keyboard (seat));
+          devices = g_list_prepend (devices, gdk_seat_get_pointer (seat));
+        }
+      else
+        devices = NULL;
 
       for (d = devices; d; d = d->next)
         {
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 2aac9270d0..a66581cb48 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -4937,25 +4937,37 @@ gtk_label_get_single_line_mode  (GtkLabel *self)
  */
 static void
 get_better_cursor (GtkLabel *self,
-                  gint      index,
-                  gint      *x,
-                  gint      *y)
-{
-  GdkSeat *seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (self)));
-  GdkDevice *device = gdk_seat_get_keyboard (seat);
-  PangoDirection keymap_direction = gdk_device_get_direction (device);
-  PangoDirection cursor_direction = get_cursor_direction (self);
+                   int      index,
+                   int      *x,
+                   int      *y)
+{
+  GdkSeat *seat;
+  GdkDevice *keyboard;
+  PangoDirection keymap_direction;
+  PangoDirection cursor_direction;
   gboolean split_cursor;
   PangoRectangle strong_pos, weak_pos;
-  
+
+  seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (self)));
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  else
+    keyboard = NULL;
+  if (keyboard)
+    keymap_direction = gdk_device_get_direction (keyboard);
+  else
+    keymap_direction = PANGO_DIRECTION_LTR;
+
+  cursor_direction = get_cursor_direction (self);
+
   g_object_get (gtk_widget_get_settings (GTK_WIDGET (self)),
-               "gtk-split-cursor", &split_cursor,
-               NULL);
+                "gtk-split-cursor", &split_cursor,
+                NULL);
 
   gtk_label_ensure_layout (self);
-  
+
   pango_layout_get_cursor_pos (self->layout, index,
-                              &strong_pos, &weak_pos);
+                               &strong_pos, &weak_pos);
 
   if (split_cursor)
     {
@@ -4965,15 +4977,15 @@ get_better_cursor (GtkLabel *self,
   else
     {
       if (keymap_direction == cursor_direction)
-       {
-         *x = strong_pos.x / PANGO_SCALE;
-         *y = strong_pos.y / PANGO_SCALE;
-       }
+        {
+          *x = strong_pos.x / PANGO_SCALE;
+          *y = strong_pos.y / PANGO_SCALE;
+        }
       else
-       {
-         *x = weak_pos.x / PANGO_SCALE;
-         *y = weak_pos.y / PANGO_SCALE;
-       }
+        {
+          *x = weak_pos.x / PANGO_SCALE;
+          *y = weak_pos.y / PANGO_SCALE;
+        }
     }
 }
 
@@ -5041,16 +5053,26 @@ gtk_label_move_visually (GtkLabel *self,
                    NULL);
 
       if (split_cursor)
-       strong = TRUE;
+        strong = TRUE;
       else
-       {
-         GdkSeat *seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (self)));
-          GdkDevice *device = gdk_seat_get_keyboard (seat);
-         PangoDirection keymap_direction = gdk_device_get_direction (device);
+        {
+          GdkSeat *seat;
+          GdkDevice *keyboard;
+          PangoDirection keymap_direction;
+
+          seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (self)));
+          if (seat)
+            keyboard = gdk_seat_get_keyboard (seat);
+          else
+            keyboard = NULL;
+          if (keyboard)
+            keymap_direction = gdk_device_get_direction (keyboard);
+          else
+            keymap_direction = PANGO_DIRECTION_LTR;
+
+          strong = keymap_direction == get_cursor_direction (self);
+        }
 
-         strong = keymap_direction == get_cursor_direction (self);
-       }
-      
       if (count > 0)
        {
          pango_layout_move_cursor_visually (self->layout, strong, index, 0, 1, &new_index, &new_trailing);
diff --git a/gtk/gtkpasswordentry.c b/gtk/gtkpasswordentry.c
index d26bf75645..ab68a7dbd8 100644
--- a/gtk/gtkpasswordentry.c
+++ b/gtk/gtkpasswordentry.c
@@ -167,12 +167,20 @@ gtk_password_entry_realize (GtkWidget *widget)
 {
   GtkPasswordEntry *entry = GTK_PASSWORD_ENTRY (widget);
   GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry);
+  GdkSeat *seat;
 
   GTK_WIDGET_CLASS (gtk_password_entry_parent_class)->realize (widget);
 
-  priv->keyboard = gdk_seat_get_keyboard (gdk_display_get_default_seat (gtk_widget_get_display (widget)));
-  g_signal_connect (priv->keyboard, "notify::caps-lock-state", G_CALLBACK (caps_lock_state_changed), entry);
-  caps_lock_state_changed (priv->keyboard, NULL, widget);
+  seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
+  if (seat)
+    priv->keyboard = gdk_seat_get_keyboard (seat);
+
+  if (priv->keyboard)
+    {
+      g_signal_connect (priv->keyboard, "notify::caps-lock-state",
+                        G_CALLBACK (caps_lock_state_changed), entry);
+      caps_lock_state_changed (priv->keyboard, NULL, widget);
+    }
 }
 
 static void
@@ -496,7 +504,8 @@ gtk_password_entry_set_show_peek_icon (GtkPasswordEntry *entry,
                                             entry);
     }
 
-  caps_lock_state_changed (priv->keyboard, NULL, GTK_WIDGET (entry));
+  if (priv->keyboard)
+    caps_lock_state_changed (priv->keyboard, NULL, GTK_WIDGET (entry));
 
   g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_SHOW_PEEK_ICON]);
 }
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 7c40e4a055..0a11c83007 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -1151,6 +1151,7 @@ gtk_render_insertion_cursor (GtkStyleContext *context,
   float aspect_ratio;
   PangoRectangle strong_pos, weak_pos;
   PangoRectangle *cursor1, *cursor2;
+  GdkSeat *seat;
   GdkDevice *keyboard;
   PangoDirection keyboard_direction;
   PangoDirection direction2;
@@ -1165,8 +1166,15 @@ gtk_render_insertion_cursor (GtkStyleContext *context,
                 "gtk-cursor-aspect-ratio", &aspect_ratio,
                 NULL);
 
-  keyboard = gdk_seat_get_keyboard (gdk_display_get_default_seat (priv->display));
-  keyboard_direction = gdk_device_get_direction (keyboard);
+  seat = gdk_display_get_default_seat (priv->display);
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  else
+    keyboard = NULL;
+  if (keyboard)
+    keyboard_direction = gdk_device_get_direction (keyboard);
+  else
+    keyboard_direction = PANGO_DIRECTION_LTR;
 
   pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
 
@@ -1240,6 +1248,7 @@ gtk_snapshot_render_insertion_cursor (GtkSnapshot     *snapshot,
   float aspect_ratio;
   PangoRectangle strong_pos, weak_pos;
   PangoRectangle *cursor1, *cursor2;
+  GdkSeat *seat;
   GdkDevice *keyboard;
   PangoDirection keyboard_direction;
   PangoDirection direction2;
@@ -1254,8 +1263,15 @@ gtk_snapshot_render_insertion_cursor (GtkSnapshot     *snapshot,
                 "gtk-cursor-aspect-ratio", &aspect_ratio,
                 NULL);
 
-  keyboard = gdk_seat_get_keyboard (gdk_display_get_default_seat (priv->display));
-  keyboard_direction = gdk_device_get_direction (keyboard);
+  seat = gdk_display_get_default_seat (priv->display);
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  else
+    keyboard = NULL;
+  if (keyboard)
+    keyboard_direction = gdk_device_get_direction (keyboard);
+  else
+    keyboard_direction = PANGO_DIRECTION_LTR;
 
   pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
 
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index e12878fce9..4dc3664a0c 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -1920,7 +1920,7 @@ gtk_text_dispose (GObject *object)
   GtkText *self = GTK_TEXT (object);
   GtkTextPrivate *priv = gtk_text_get_instance_private (self);
   GdkSeat *seat;
-  GdkDevice *keyboard;
+  GdkDevice *keyboard = NULL;
   GtkWidget *chooser;
 
   priv->current_pos = priv->selection_bound = 0;
@@ -1949,8 +1949,10 @@ gtk_text_dispose (GObject *object)
     gtk_widget_unparent (chooser);
 
   seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (object)));
-  keyboard = gdk_seat_get_keyboard (seat);
-  g_signal_handlers_disconnect_by_func (keyboard, direction_changed, self);
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  if (keyboard)
+    g_signal_handlers_disconnect_by_func (keyboard, direction_changed, self);
 
   g_clear_pointer (&priv->selection_bubble, gtk_widget_unparent);
   g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
@@ -3129,13 +3131,18 @@ gtk_text_focus_in (GtkWidget *widget)
 {
   GtkText *self = GTK_TEXT (widget);
   GtkTextPrivate *priv = gtk_text_get_instance_private (self);
-  GdkSeat *seat;
-  GdkDevice *keyboard;
+  GdkSeat *seat = NULL;
+  GdkDevice *keyboard = NULL;
 
   gtk_widget_queue_draw (widget);
 
   seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
-  keyboard = gdk_seat_get_keyboard (seat);
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  if (keyboard)
+    g_signal_connect (keyboard, "notify::direction",
+                      G_CALLBACK (direction_changed), self);
+
 
   if (priv->editable)
     {
@@ -3143,9 +3150,6 @@ gtk_text_focus_in (GtkWidget *widget)
       gtk_im_context_focus_in (priv->im_context);
     }
 
-  g_signal_connect (keyboard, "notify::direction",
-                    G_CALLBACK (direction_changed), self);
-
   gtk_text_reset_blink_time (self);
   gtk_text_check_cursor_blink (self);
 }
@@ -3155,8 +3159,8 @@ gtk_text_focus_out (GtkWidget *widget)
 {
   GtkText *self = GTK_TEXT (widget);
   GtkTextPrivate *priv = gtk_text_get_instance_private (self);
-  GdkSeat *seat;
-  GdkDevice *keyboard;
+  GdkSeat *seat = NULL;
+  GdkDevice *keyboard = NULL;
 
   gtk_text_selection_bubble_popup_unset (self);
 
@@ -3166,7 +3170,10 @@ gtk_text_focus_out (GtkWidget *widget)
   gtk_widget_queue_draw (widget);
 
   seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
-  keyboard = gdk_seat_get_keyboard (seat);
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  if (keyboard)
+    g_signal_handlers_disconnect_by_func (keyboard, direction_changed, self);
 
   if (priv->editable)
     {
@@ -3175,8 +3182,6 @@ gtk_text_focus_out (GtkWidget *widget)
     }
 
   gtk_text_check_cursor_blink (self);
-
-  g_signal_handlers_disconnect_by_func (keyboard, direction_changed, self);
 }
 
 static gboolean
@@ -3656,15 +3661,21 @@ get_better_cursor_x (GtkText *self,
                      int      offset)
 {
   GtkTextPrivate *priv = gtk_text_get_instance_private (self);
-  GdkSeat *seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (self)));
-  GdkDevice *keyboard = gdk_seat_get_keyboard (seat);
-  PangoDirection direction = gdk_device_get_direction (keyboard);
+  GdkSeat *seat;
+  GdkDevice *keyboard = NULL;
+  PangoDirection direction = PANGO_DIRECTION_LTR;
   gboolean split_cursor;
   PangoLayout *layout = gtk_text_ensure_layout (self, TRUE);
   const char *text = pango_layout_get_text (layout);
   int index = g_utf8_offset_to_pointer (text, offset) - text;
   PangoRectangle strong_pos, weak_pos;
-  
+
+  seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (self)));
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  if (keyboard)
+    direction = gdk_device_get_direction (keyboard);
+
   g_object_get (gtk_widget_get_settings (GTK_WIDGET (self)),
                 "gtk-split-cursor", &split_cursor,
                 NULL);
@@ -4377,11 +4388,19 @@ gtk_text_create_layout (GtkText  *self,
         {
           if (gtk_widget_has_focus (widget))
             {
-              GdkDisplay *display = gtk_widget_get_display (widget);
-              GdkSeat *seat = gdk_display_get_default_seat (display);
-              GdkDevice *keyboard = gdk_seat_get_keyboard (seat);
-
-              if (gdk_device_get_direction (keyboard) == PANGO_DIRECTION_RTL)
+              GdkDisplay *display;
+              GdkSeat *seat;
+              GdkDevice *keyboard = NULL;
+              PangoDirection direction = PANGO_DIRECTION_LTR;
+
+              display = gtk_widget_get_display (widget);
+              seat = gdk_display_get_default_seat (display);
+              if (seat)
+                keyboard = gdk_seat_get_keyboard (seat);
+              if (keyboard)
+                direction = gdk_device_get_direction (keyboard);
+
+              if (direction == PANGO_DIRECTION_RTL)
                 pango_dir = PANGO_DIRECTION_RTL;
               else
                 pango_dir = PANGO_DIRECTION_LTR;
@@ -4941,14 +4960,21 @@ gtk_text_move_visually (GtkText *self,
         strong = TRUE;
       else
         {
-          GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (self));
-          GdkSeat *seat = gdk_display_get_default_seat (display);
-          GdkDevice *keyboard = gdk_seat_get_keyboard (seat);
-          PangoDirection direction = gdk_device_get_direction (keyboard);
+          GdkDisplay *display;
+          GdkSeat *seat;
+          GdkDevice *keyboard = NULL;
+          PangoDirection direction = PANGO_DIRECTION_LTR;
+
+          display = gtk_widget_get_display (GTK_WIDGET (self));
+          seat = gdk_display_get_default_seat (display);
+          if (seat)
+            keyboard = gdk_seat_get_keyboard (seat);
+          if (keyboard)
+            direction = gdk_device_get_direction (keyboard);
 
           strong = direction == priv->resolved_dir;
         }
-      
+
       if (count > 0)
         {
           pango_layout_move_cursor_visually (layout, strong, index, 0, 1, &new_index, &new_trailing);
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index c6cfcd5996..a6a02473ab 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -5524,9 +5524,14 @@ gtk_text_view_focus_in (GtkWidget *widget)
     }
 
   seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
-  keyboard = gdk_seat_get_keyboard (seat);
-  g_signal_connect (keyboard, "notify::direction",
-                    G_CALLBACK (direction_changed), text_view);
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  else
+    keyboard = NULL;
+
+  if (keyboard)
+    g_signal_connect (keyboard, "notify::direction",
+                      G_CALLBACK (direction_changed), text_view);
   gtk_text_view_check_keymap_direction (text_view);
 
   if (priv->editable)
@@ -5557,8 +5562,12 @@ gtk_text_view_focus_out (GtkWidget *widget)
     }
 
   seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
-  keyboard = gdk_seat_get_keyboard (seat);
-  g_signal_handlers_disconnect_by_func (keyboard, direction_changed, text_view);
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  else
+    keyboard = NULL;
+  if (keyboard)
+    g_signal_handlers_disconnect_by_func (keyboard, direction_changed, text_view);
   gtk_text_view_selection_bubble_popup_unset (text_view);
 
   text_view->priv->text_handles_enabled = FALSE;
@@ -7492,33 +7501,44 @@ static void
 gtk_text_view_check_keymap_direction (GtkTextView *text_view)
 {
   GtkTextViewPrivate *priv = text_view->priv;
+  GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (text_view));
+  GdkSeat *seat;
+  GdkDevice *keyboard;
+  PangoDirection direction;
+  GtkTextDirection new_cursor_dir;
+  GtkTextDirection new_keyboard_dir;
+  gboolean split_cursor;
 
-  if (priv->layout)
-    {
-      GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (text_view));
-      GdkSeat *seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (text_view)));
-      GdkDevice *keyboard = gdk_seat_get_keyboard (seat);
-      GtkTextDirection new_cursor_dir;
-      GtkTextDirection new_keyboard_dir;
-      gboolean split_cursor;
+  if (!priv->layout)
+    return;
 
-      g_object_get (settings,
-                   "gtk-split-cursor", &split_cursor,
-                   NULL);
-      
-      if (gdk_device_get_direction (keyboard) == PANGO_DIRECTION_RTL)
-       new_keyboard_dir = GTK_TEXT_DIR_RTL;
-      else
-       new_keyboard_dir  = GTK_TEXT_DIR_LTR;
-  
-      if (split_cursor)
-       new_cursor_dir = GTK_TEXT_DIR_NONE;
-      else
-       new_cursor_dir = new_keyboard_dir;
-      
-      gtk_text_layout_set_cursor_direction (priv->layout, new_cursor_dir);
-      gtk_text_layout_set_keyboard_direction (priv->layout, new_keyboard_dir);
-    }
+  seat = gdk_display_get_default_seat (gtk_widget_get_display (GTK_WIDGET (text_view)));
+  if (seat)
+    keyboard = gdk_seat_get_keyboard (seat);
+  else
+    keyboard = NULL;
+
+  if (keyboard)
+    direction = gdk_device_get_direction (keyboard);
+  else
+    direction = PANGO_DIRECTION_LTR;
+
+  g_object_get (settings,
+                "gtk-split-cursor", &split_cursor,
+                NULL);
+
+  if (direction == PANGO_DIRECTION_RTL)
+    new_keyboard_dir = GTK_TEXT_DIR_RTL;
+  else
+    new_keyboard_dir  = GTK_TEXT_DIR_LTR;
+
+  if (split_cursor)
+    new_cursor_dir = GTK_TEXT_DIR_NONE;
+  else
+    new_cursor_dir = new_keyboard_dir;
+
+  gtk_text_layout_set_cursor_direction (priv->layout, new_cursor_dir);
+  gtk_text_layout_set_keyboard_direction (priv->layout, new_keyboard_dir);
 }
 
 static void
diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c
index 4af709f19e..a6962641af 100644
--- a/gtk/gtktooltip.c
+++ b/gtk/gtktooltip.c
@@ -371,9 +371,10 @@ void
 gtk_tooltip_trigger_tooltip_query (GtkWidget *widget)
 {
   GdkDisplay *display;
-  double x, y;
-  GdkSurface *surface;
+  GdkSeat *seat;
   GdkDevice *device;
+  GdkSurface *surface;
+  double x, y;
   GtkWidget *toplevel;
   int dx, dy;
 
@@ -382,8 +383,15 @@ gtk_tooltip_trigger_tooltip_query (GtkWidget *widget)
   display = gtk_widget_get_display (widget);
 
   /* Trigger logic as if the mouse moved */
-  device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
-  surface = gdk_device_get_surface_at_position (device, &x, &y);
+  seat = gdk_display_get_default_seat (display);
+  if (seat)
+    device = gdk_seat_get_pointer (seat);
+  else
+    device = NULL;
+  if (device)
+    surface = gdk_device_get_surface_at_position (device, &x, &y);
+  else
+    surface = NULL;
   if (!surface)
     return;
 
@@ -673,6 +681,7 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
   gint x, y;
   GdkSurface *surface;
   GtkWidget *tooltip_widget;
+  GdkSeat *seat;
   GdkDevice *device;
   GtkTooltip *tooltip;
   gboolean return_value = FALSE;
@@ -684,9 +693,17 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
 
   surface = gtk_native_get_surface (GTK_NATIVE (tooltip->native));
 
-  device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
+  seat = gdk_display_get_default_seat (display);
+  if (seat)
+    device = gdk_seat_get_pointer (seat);
+  else
+    device = NULL;
+
+  if (device)
+    gdk_surface_get_device_position (surface, device, &px, &py, NULL);
+  else
+    px = py = 0;
 
-  gdk_surface_get_device_position (surface, device, &px, &py, NULL);
   x = round (px);
   y = round (py);
 
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index c314305071..a537530b80 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -7636,13 +7636,17 @@ _gtk_widget_list_devices (GtkWidget *widget,
       return NULL;
     }
 
-  result = g_ptr_array_new ();
   seat = gdk_display_get_default_seat (_gtk_widget_get_display (widget));
-  device = gdk_seat_get_pointer (seat);
-  if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
+  if (!seat)
     {
-      g_ptr_array_add (result, device);
+      *out_n_devices = 0;
+      return NULL;
     }
+  device = gdk_seat_get_pointer (seat);
+
+  result = g_ptr_array_new ();
+  if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
+    g_ptr_array_add (result, device);
 
   devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_ALL_POINTING);
   for (l = devices; l; l = l->next)
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index c8e51c5073..ddfb38792f 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -1578,8 +1578,9 @@ gtk_window_init (GtkWindow *window)
   gtk_widget_add_controller (GTK_WIDGET (window), GTK_EVENT_CONTROLLER (target));
 
   seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
-  g_signal_connect (seat, "device-removed",
-                    G_CALLBACK (device_removed_cb), window);
+  if (seat)
+    g_signal_connect (seat, "device-removed",
+                      G_CALLBACK (device_removed_cb), window);
 
   controller = gtk_event_controller_motion_new ();
   gtk_event_controller_set_propagation_phase (controller,
@@ -3726,6 +3727,7 @@ gtk_window_finalize (GObject *object)
 {
   GtkWindow *window = GTK_WINDOW (object);
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+  GdkSeat *seat;
 
   g_clear_pointer (&priv->extra_input_region, cairo_region_destroy);
   g_free (priv->title);
@@ -3742,9 +3744,9 @@ gtk_window_finalize (GObject *object)
       priv->keys_changed_handler = 0;
     }
 
-  g_signal_handlers_disconnect_by_func (gdk_display_get_default_seat (priv->display),
-                                        device_removed_cb,
-                                        window);
+  seat = gdk_display_get_default_seat (priv->display);
+  if (seat)
+    g_signal_handlers_disconnect_by_func (seat, device_removed_cb, window);
 
 #ifdef GDK_WINDOWING_X11
   g_signal_handlers_disconnect_by_func (gtk_settings_get_for_display (priv->display),
diff --git a/gtk/inspector/inspect-button.c b/gtk/inspector/inspect-button.c
index 64c198f2dc..5af4176418 100644
--- a/gtk/inspector/inspect-button.c
+++ b/gtk/inspector/inspect-button.c
@@ -229,11 +229,16 @@ void
 gtk_inspector_window_select_widget_under_pointer (GtkInspectorWindow *iw)
 {
   GdkDisplay *display;
+  GdkSeat *seat;
   GdkDevice *device;
   GtkWidget *widget;
 
   display = gtk_inspector_window_get_inspected_display (iw);
-  device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
+  seat = gdk_display_get_default_seat (display);
+  if (!seat)
+    return;
+
+  device = gdk_seat_get_pointer (seat);
 
   widget = find_widget_at_pointer (device);
 
diff --git a/testsuite/gdk/seat.c b/testsuite/gdk/seat.c
index e87c2b26a6..36a7da5d11 100644
--- a/testsuite/gdk/seat.c
+++ b/testsuite/gdk/seat.c
@@ -10,11 +10,12 @@ test_list_seats (void)
 
   display = gdk_display_get_default ();
   seat0 = gdk_display_get_default_seat (display);
-
-  g_assert_true (GDK_IS_SEAT (seat0));
+  if (seat0 != NULL)
+    g_assert_true (GDK_IS_SEAT (seat0));
 
   found_default = FALSE;
   list = gdk_display_list_seats (display);
+
   for (l = list; l; l = l->next)
     {
       seat = l->data;
@@ -25,9 +26,13 @@ test_list_seats (void)
       if (seat == seat0)
         found_default = TRUE;
     }
-  g_list_free (list);
 
-  g_assert_true (found_default);
+  if (seat0 != NULL)
+    g_assert_true (found_default);
+  else
+    g_assert_true (list == NULL);
+
+  g_list_free (list);
 }
 
 static void
@@ -42,6 +47,12 @@ test_default_seat (void)
   display = gdk_display_get_default ();
   seat0 = gdk_display_get_default_seat (display);
 
+  if (seat0 == NULL)
+    {
+      g_test_skip ("Display has no seats");
+      return;
+    }
+
   g_assert_true (GDK_IS_SEAT (seat0));
 
   caps = gdk_seat_get_capabilities (seat0);


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