summaryrefslogtreecommitdiff
path: root/gtk/gtktext.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-05-14 21:27:45 -0400
committerMatthias Clasen <mclasen@redhat.com>2020-05-15 14:11:53 -0400
commit8912a6eb757c39a6801358331fa81f8f52ebad8a (patch)
treeb410b78952f174bed33fd9d1fb63615eb20d3082 /gtk/gtktext.c
parent9b7a73268ea264f5674d04e129d9dabf680d3513 (diff)
downloadgtk+-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.c82
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);