diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-05-14 21:27:45 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-05-15 14:11:53 -0400 |
commit | 8912a6eb757c39a6801358331fa81f8f52ebad8a (patch) | |
tree | b410b78952f174bed33fd9d1fb63615eb20d3082 /gtk/gtktext.c | |
parent | 9b7a73268ea264f5674d04e129d9dabf680d3513 (diff) | |
download | gtk+-8912a6eb757c39a6801358331fa81f8f52ebad8a.tar.gz |
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.
Diffstat (limited to 'gtk/gtktext.c')
-rw-r--r-- | gtk/gtktext.c | 82 |
1 files changed, 54 insertions, 28 deletions
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); |