entry accessible: Make work with almost-entries

This is not perfect, but gives a quick way to have
an accessible that can be used for password and
search entries.
This commit is contained in:
Matthias Clasen 2019-02-22 15:49:47 -05:00
parent 0e603a6646
commit bd99ae3767

View File

@ -26,6 +26,8 @@
#include "gtkpango.h"
#include "gtkentryaccessible.h"
#include "gtkentryprivate.h"
#include "gtksearchentryprivate.h"
#include "gtkpasswordentry.h"
#include "gtktextprivate.h"
#include "gtkcomboboxaccessible.h"
#include "gtkstylecontextprivate.h"
@ -407,7 +409,7 @@ gtk_entry_accessible_get_attributes (AtkObject *accessible)
GtkWidget *widget;
AtkAttributeSet *attributes;
AtkAttribute *placeholder_text;
const gchar *text;
char *text = NULL;
attributes = ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->get_attributes (accessible);
@ -415,13 +417,15 @@ gtk_entry_accessible_get_attributes (AtkObject *accessible)
if (widget == NULL)
return attributes;
text = gtk_entry_get_placeholder_text (GTK_ENTRY (widget));
if (GTK_IS_ENTRY (widget) || GTK_IS_SEARCH_ENTRY (widget))
g_object_get (widget, "placeholder-text", &text, NULL);
if (text == NULL)
return attributes;
placeholder_text = g_malloc (sizeof (AtkAttribute));
placeholder_text->name = g_strdup ("placeholder-text");
placeholder_text->value = g_strdup (text);
placeholder_text->value = text;
attributes = g_slist_append (attributes, placeholder_text);
@ -432,7 +436,7 @@ static void
gtk_entry_accessible_initialize (AtkObject *obj,
gpointer data)
{
GtkEntry *entry;
GtkWidget *widget;
GtkEntryAccessible *gtk_entry_accessible;
gint start_pos, end_pos;
@ -440,19 +444,19 @@ gtk_entry_accessible_initialize (AtkObject *obj,
gtk_entry_accessible = GTK_ENTRY_ACCESSIBLE (obj);
entry = GTK_ENTRY (data);
gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos);
widget = GTK_WIDGET (data);
gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), &start_pos, &end_pos);
gtk_entry_accessible->priv->cursor_position = end_pos;
gtk_entry_accessible->priv->selection_bound = start_pos;
/* Set up signal callbacks */
g_signal_connect_after (entry, "insert-text", G_CALLBACK (insert_text_cb), NULL);
g_signal_connect (entry, "delete-text", G_CALLBACK (delete_text_cb), NULL);
g_signal_connect_after (widget, "insert-text", G_CALLBACK (insert_text_cb), NULL);
g_signal_connect (widget, "delete-text", G_CALLBACK (delete_text_cb), NULL);
if (gtk_entry_get_visibility (entry))
obj->role = ATK_ROLE_TEXT;
else
if (GTK_IS_PASSWORD_ENTRY (widget))
obj->role = ATK_ROLE_PASSWORD_TEXT;
else
obj->role = ATK_ROLE_TEXT;
}
static void
@ -655,19 +659,20 @@ static gint
gtk_entry_accessible_get_n_children (AtkObject* obj)
{
GtkWidget *widget;
GtkEntry *entry;
gint count = 0;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return 0;
entry = GTK_ENTRY (widget);
if (GTK_IS_ENTRY (widget))
{
if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
count++;
if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
count++;
}
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
count++;
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
count++;
return count;
}
@ -678,29 +683,29 @@ gtk_entry_accessible_ref_child (AtkObject *obj,
GtkEntryAccessible *accessible = GTK_ENTRY_ACCESSIBLE (obj);
GtkEntryAccessiblePrivate *priv = accessible->priv;
GtkWidget *widget;
GtkEntry *entry;
GtkEntryIconPosition pos;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return NULL;
entry = GTK_ENTRY (widget);
if (!GTK_IS_ENTRY (widget))
return NULL;
switch (i)
{
case 0:
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
pos = GTK_ENTRY_ICON_PRIMARY;
else if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
else if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
pos = GTK_ENTRY_ICON_SECONDARY;
else
return NULL;
break;
case 1:
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_PRIMARY) == GTK_IMAGE_EMPTY)
if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) == GTK_IMAGE_EMPTY)
return NULL;
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY)
if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY)
return NULL;
pos = GTK_ENTRY_ICON_SECONDARY;
break;
@ -752,10 +757,8 @@ gtk_entry_accessible_init (GtkEntryAccessible *entry)
entry->priv->selection_bound = 0;
}
static gchar *
gtk_entry_accessible_get_text (AtkText *atk_text,
gint start_pos,
gint end_pos)
static GtkText *
get_text (AtkText *atk_text)
{
GtkWidget *widget;
@ -763,59 +766,82 @@ gtk_entry_accessible_get_text (AtkText *atk_text,
if (widget == NULL)
return NULL;
return gtk_text_get_display_text (gtk_entry_get_text_widget (GTK_ENTRY (widget)), start_pos, end_pos);
if (GTK_IS_ENTRY (widget))
return gtk_entry_get_text_widget (GTK_ENTRY (widget));
else if (GTK_IS_SEARCH_ENTRY (widget))
return gtk_search_entry_get_text_widget (GTK_SEARCH_ENTRY (widget));
else
return NULL; // FIXME;
}
static gchar *
gtk_entry_accessible_get_text_before_offset (AtkText *text,
gtk_entry_accessible_get_text (AtkText *atk_text,
gint start_pos,
gint end_pos)
{
GtkText *text;
text = get_text (atk_text);
if (text == NULL)
return NULL;
return gtk_text_get_display_text (text, start_pos, end_pos);
}
static gchar *
gtk_entry_accessible_get_text_before_offset (AtkText *atk_text,
gint offset,
AtkTextBoundary boundary_type,
gint *start_offset,
gint *end_offset)
{
GtkWidget *widget;
GtkText *text;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
text = get_text (atk_text);
if (text == NULL)
return NULL;
return _gtk_pango_get_text_before (gtk_text_get_layout (gtk_entry_get_text_widget (GTK_ENTRY (widget))),
return _gtk_pango_get_text_before (gtk_text_get_layout (text),
boundary_type, offset,
start_offset, end_offset);
}
static gchar *
gtk_entry_accessible_get_text_at_offset (AtkText *text,
gtk_entry_accessible_get_text_at_offset (AtkText *atk_text,
gint offset,
AtkTextBoundary boundary_type,
gint *start_offset,
gint *end_offset)
{
GtkWidget *widget;
GtkText *text;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
text = get_text (atk_text);
if (text == NULL)
return NULL;
return _gtk_pango_get_text_at (gtk_text_get_layout (gtk_entry_get_text_widget (GTK_ENTRY (widget))),
return _gtk_pango_get_text_at (gtk_text_get_layout (text),
boundary_type, offset,
start_offset, end_offset);
}
static gchar *
gtk_entry_accessible_get_text_after_offset (AtkText *text,
gtk_entry_accessible_get_text_after_offset (AtkText *atk_text,
gint offset,
AtkTextBoundary boundary_type,
gint *start_offset,
gint *end_offset)
{
GtkWidget *widget;
GtkText *text;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
text = get_text (atk_text);
if (text == NULL)
return NULL;
return _gtk_pango_get_text_after (gtk_text_get_layout (gtk_entry_get_text_widget (GTK_ENTRY (widget))),
return _gtk_pango_get_text_after (gtk_text_get_layout (text),
boundary_type, offset,
start_offset, end_offset);
}
@ -823,21 +849,22 @@ gtk_entry_accessible_get_text_after_offset (AtkText *text,
static gint
gtk_entry_accessible_get_character_count (AtkText *atk_text)
{
GtkWidget *widget;
gchar *text;
glong char_count;
GtkText *text;
char *display_text;
int char_count;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
text = get_text (atk_text);
if (text == NULL)
return 0;
text = gtk_text_get_display_text (gtk_entry_get_text_widget (GTK_ENTRY (widget)), 0, -1);
display_text = gtk_text_get_display_text (text, 0, -1);
char_count = 0;
if (text)
if (display_text)
{
char_count = g_utf8_strlen (text, -1);
g_free (text);
char_count = g_utf8_strlen (display_text, -1);
g_free (display_text);
}
return char_count;
@ -885,23 +912,24 @@ add_text_attribute (AtkAttributeSet *attributes,
}
static AtkAttributeSet *
gtk_entry_accessible_get_run_attributes (AtkText *text,
gtk_entry_accessible_get_run_attributes (AtkText *atk_text,
gint offset,
gint *start_offset,
gint *end_offset)
{
GtkWidget *widget;
GtkText *text;
AtkAttributeSet *attributes;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
text = get_text (atk_text);
if (text == NULL)
return NULL;
attributes = NULL;
attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
gtk_widget_get_direction (widget));
gtk_widget_get_direction (GTK_WIDGET (text)));
attributes = _gtk_pango_get_run_attributes (attributes,
gtk_text_get_layout (gtk_entry_get_text_widget (GTK_ENTRY (widget))),
gtk_text_get_layout (text),
offset,
start_offset,
end_offset);
@ -910,28 +938,29 @@ gtk_entry_accessible_get_run_attributes (AtkText *text,
}
static AtkAttributeSet *
gtk_entry_accessible_get_default_attributes (AtkText *text)
gtk_entry_accessible_get_default_attributes (AtkText *atk_text)
{
GtkWidget *widget;
GtkText *text;
AtkAttributeSet *attributes;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
text = get_text (atk_text);
if (text == NULL)
return NULL;
attributes = NULL;
attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
gtk_widget_get_direction (widget));
gtk_widget_get_direction (GTK_WIDGET (text)));
attributes = _gtk_pango_get_default_attributes (attributes,
gtk_text_get_layout (gtk_entry_get_text_widget (GTK_ENTRY (widget))));
gtk_text_get_layout (text));
attributes = _gtk_style_context_get_attributes (attributes,
gtk_widget_get_style_context (widget));
gtk_widget_get_style_context (GTK_WIDGET (text)));
return attributes;
}
static void
gtk_entry_accessible_get_character_extents (AtkText *text,
gtk_entry_accessible_get_character_extents (AtkText *atk_text,
gint offset,
gint *x,
gint *y,
@ -939,8 +968,6 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
gint *height,
AtkCoordType coords)
{
GtkWidget *widget;
GtkEntry *entry;
GtkText *textw;
PangoRectangle char_rect;
gchar *entry_text;
@ -949,12 +976,10 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
gint x_surface, y_surface;
GtkAllocation allocation;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
return;
textw = get_text (atk_text);
entry = GTK_ENTRY (widget);
textw = gtk_entry_get_text_widget (entry);
if (textw == NULL)
return;
gtk_text_get_layout_offsets (textw, &x_layout, &y_layout);
entry_text = gtk_text_get_display_text (textw, 0, -1);
@ -964,9 +989,9 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
pango_layout_index_to_pos (gtk_text_get_layout (textw), index, &char_rect);
pango_extents_to_pixels (&char_rect, NULL);
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_get_allocation (GTK_WIDGET (textw), &allocation);
surface = gtk_widget_get_surface (widget);
surface = gtk_widget_get_surface (GTK_WIDGET (textw));
gdk_surface_get_origin (surface, &x_surface, &y_surface);
*x = x_surface + allocation.x + x_layout + char_rect.x;
@ -990,8 +1015,6 @@ gtk_entry_accessible_get_offset_at_point (AtkText *atk_text,
gint y,
AtkCoordType coords)
{
GtkWidget *widget;
GtkEntry *entry;
GtkText *textw;
gchar *text;
gint index, x_layout, y_layout;
@ -1000,16 +1023,14 @@ gtk_entry_accessible_get_offset_at_point (AtkText *atk_text,
GdkSurface *surface;
glong offset;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
return -1;
textw = get_text (atk_text);
entry = GTK_ENTRY (widget);
textw = gtk_entry_get_text_widget (entry);
if (textw == NULL)
return 1;
gtk_text_get_layout_offsets (textw, &x_layout, &y_layout);
surface = gtk_widget_get_surface (widget);
surface = gtk_widget_get_surface (GTK_WIDGET (textw));
gdk_surface_get_origin (surface, &x_surface, &y_surface);
x_local = x - x_layout - x_surface;
@ -1158,21 +1179,22 @@ static gunichar
gtk_entry_accessible_get_character_at_offset (AtkText *atk_text,
gint offset)
{
GtkWidget *widget;
GtkText *textw;
gchar *text;
gchar *index;
gunichar result;
result = '\0';
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
textw = get_text (atk_text);
if (textw == NULL)
return 0;
if (!gtk_text_get_visibility (textw))
return result;
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
return result;
text = gtk_text_get_display_text (gtk_entry_get_text_widget (GTK_ENTRY (widget)), 0, -1);
text = gtk_text_get_display_text (textw, 0, -1);
if (offset < g_utf8_strlen (text, -1))
{
index = g_utf8_offset_to_pointer (text, offset);
@ -1218,7 +1240,7 @@ gtk_entry_accessible_set_text_contents (AtkEditableText *text,
if (!gtk_editable_get_editable (GTK_EDITABLE (widget)))
return;
gtk_entry_set_text (GTK_ENTRY (widget), string);
gtk_editable_set_text (GTK_EDITABLE (widget), string);
}
static void
@ -1400,14 +1422,19 @@ delete_text_cb (GtkEditable *editable,
gint end)
{
GtkEntryAccessible *accessible;
GtkText *textw;
accessible = GTK_ENTRY_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (editable)));
textw = get_text (ATK_TEXT (accessible));
if (textw == NULL)
return;
if (end < 0)
{
gchar *text;
text = gtk_text_get_display_text (gtk_entry_get_text_widget (GTK_ENTRY (editable)), 0, -1);
text = gtk_text_get_display_text (textw, 0, -1);
end = g_utf8_strlen (text, -1);
g_free (text);
}