forked from AuroraMiddleware/gtk
Fixed crashes when GtkEntry's internal buffer is not available (bug 588395)
To fix this I replaced the code that creates an internal buffer at init and construction time with code that creates a buffer at _get_buffer() time, this is the same as GtkTextView does and fixes the crashes for me.
This commit is contained in:
parent
7f83be8595
commit
51149246c0
136
gtk/gtkentry.c
136
gtk/gtkentry.c
@ -237,9 +237,6 @@ typedef enum
|
||||
*/
|
||||
static void gtk_entry_editable_init (GtkEditableClass *iface);
|
||||
static void gtk_entry_cell_editable_init (GtkCellEditableIface *iface);
|
||||
static GObject* gtk_entry_constructor (GType type,
|
||||
guint n_props,
|
||||
GObjectConstructParam *props);
|
||||
static void gtk_entry_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
@ -524,6 +521,8 @@ static void buffer_notify_max_length (GtkEntryBuffer *buffer,
|
||||
GtkEntry *entry);
|
||||
static void buffer_connect_signals (GtkEntry *entry);
|
||||
static void buffer_disconnect_signals (GtkEntry *entry);
|
||||
static GtkEntryBuffer *get_buffer (GtkEntry *entry);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
||||
@ -565,7 +564,6 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
gtk_object_class = (GtkObjectClass *)class;
|
||||
|
||||
gobject_class->constructor = gtk_entry_constructor;
|
||||
gobject_class->dispose = gtk_entry_dispose;
|
||||
gobject_class->finalize = gtk_entry_finalize;
|
||||
gobject_class->set_property = gtk_entry_set_property;
|
||||
@ -2023,7 +2021,7 @@ gtk_entry_get_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_MAX_LENGTH:
|
||||
g_value_set_int (value, gtk_entry_buffer_get_max_length (priv->buffer));
|
||||
g_value_set_int (value, gtk_entry_buffer_get_max_length (get_buffer (entry)));
|
||||
break;
|
||||
|
||||
case PROP_VISIBILITY:
|
||||
@ -2075,7 +2073,7 @@ gtk_entry_get_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_TEXT_LENGTH:
|
||||
g_value_set_uint (value, gtk_entry_buffer_get_length (priv->buffer));
|
||||
g_value_set_uint (value, gtk_entry_buffer_get_length (get_buffer (entry)));
|
||||
break;
|
||||
|
||||
case PROP_INVISIBLE_CHAR_SET:
|
||||
@ -2253,34 +2251,10 @@ find_invisible_char (GtkWidget *widget)
|
||||
return '*';
|
||||
}
|
||||
|
||||
static GObject*
|
||||
gtk_entry_constructor (GType type,
|
||||
guint n_props,
|
||||
GObjectConstructParam *props)
|
||||
{
|
||||
GObject *obj = G_OBJECT_CLASS (gtk_entry_parent_class)->constructor (type, n_props, props);
|
||||
GtkEntryPrivate *priv;
|
||||
GtkEntryBuffer *buffer;
|
||||
|
||||
if (obj != NULL)
|
||||
{
|
||||
priv = GTK_ENTRY_GET_PRIVATE (obj);
|
||||
if (!priv->buffer)
|
||||
{
|
||||
buffer = gtk_entry_buffer_new (NULL, 0);
|
||||
gtk_entry_set_buffer (GTK_ENTRY (obj), buffer);
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_init (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
GtkEntryBuffer *buffer;
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (entry, GTK_CAN_FOCUS);
|
||||
|
||||
@ -2320,13 +2294,6 @@ gtk_entry_init (GtkEntry *entry)
|
||||
g_signal_connect (entry->im_context, "delete-surrounding",
|
||||
G_CALLBACK (gtk_entry_delete_surrounding_cb), entry);
|
||||
|
||||
/* need to set a buffer here, so GtkEntry subclasses can do anything
|
||||
* in their init() functions, just as it used to be before
|
||||
* GtkEntryBuffer
|
||||
*/
|
||||
buffer = gtk_entry_buffer_new (NULL, 0);
|
||||
gtk_entry_set_buffer (entry, buffer);
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
static gint
|
||||
@ -2543,8 +2510,8 @@ gtk_entry_get_display_text (GtkEntry *entry,
|
||||
gint i;
|
||||
|
||||
priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
text = gtk_entry_buffer_get_text (priv->buffer);
|
||||
length = gtk_entry_buffer_get_length (priv->buffer);
|
||||
text = gtk_entry_buffer_get_text (get_buffer (entry));
|
||||
length = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
|
||||
if (end_pos < 0)
|
||||
end_pos = length;
|
||||
@ -4001,7 +3968,7 @@ gtk_entry_motion_notify (GtkWidget *widget,
|
||||
if (event->y < 0)
|
||||
tmp_pos = 0;
|
||||
else if (event->y >= height)
|
||||
tmp_pos = gtk_entry_buffer_get_length (priv->buffer);
|
||||
tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
else
|
||||
tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
|
||||
|
||||
@ -4319,13 +4286,12 @@ gtk_entry_get_chars (GtkEditable *editable,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (editable);
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
const gchar *text;
|
||||
gint text_length;
|
||||
gint start_index, end_index;
|
||||
|
||||
text = gtk_entry_buffer_get_text (priv->buffer);
|
||||
text_length = gtk_entry_buffer_get_length (priv->buffer);
|
||||
text = gtk_entry_buffer_get_text (get_buffer (entry));
|
||||
text_length = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
|
||||
if (end_pos < 0)
|
||||
end_pos = text_length;
|
||||
@ -4344,11 +4310,10 @@ gtk_entry_real_set_position (GtkEditable *editable,
|
||||
gint position)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (editable);
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
|
||||
guint length;
|
||||
|
||||
length = gtk_entry_buffer_get_length (priv->buffer);
|
||||
length = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
if (position < 0 || position > length)
|
||||
position = length;
|
||||
|
||||
@ -4372,10 +4337,9 @@ gtk_entry_set_selection_bounds (GtkEditable *editable,
|
||||
gint end)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (editable);
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
guint length;
|
||||
|
||||
length = gtk_entry_buffer_get_length (priv->buffer);
|
||||
length = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
if (start < 0)
|
||||
start = length;
|
||||
if (end < 0)
|
||||
@ -4704,23 +4668,21 @@ buffer_notify_max_length (GtkEntryBuffer *buffer,
|
||||
static void
|
||||
buffer_connect_signals (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
g_signal_connect (priv->buffer, "inserted-text", G_CALLBACK (buffer_inserted_text), entry);
|
||||
g_signal_connect (priv->buffer, "deleted-text", G_CALLBACK (buffer_deleted_text), entry);
|
||||
g_signal_connect (priv->buffer, "notify::text", G_CALLBACK (buffer_notify_text), entry);
|
||||
g_signal_connect (priv->buffer, "notify::length", G_CALLBACK (buffer_notify_length), entry);
|
||||
g_signal_connect (priv->buffer, "notify::max-length", G_CALLBACK (buffer_notify_max_length), entry);
|
||||
g_signal_connect (get_buffer (entry), "inserted-text", G_CALLBACK (buffer_inserted_text), entry);
|
||||
g_signal_connect (get_buffer (entry), "deleted-text", G_CALLBACK (buffer_deleted_text), entry);
|
||||
g_signal_connect (get_buffer (entry), "notify::text", G_CALLBACK (buffer_notify_text), entry);
|
||||
g_signal_connect (get_buffer (entry), "notify::length", G_CALLBACK (buffer_notify_length), entry);
|
||||
g_signal_connect (get_buffer (entry), "notify::max-length", G_CALLBACK (buffer_notify_max_length), entry);
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_disconnect_signals (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer, buffer_inserted_text, entry);
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer, buffer_deleted_text, entry);
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer, buffer_notify_text, entry);
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer, buffer_notify_length, entry);
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer, buffer_notify_max_length, entry);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_inserted_text, entry);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_deleted_text, entry);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_text, entry);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_length, entry);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_max_length, entry);
|
||||
}
|
||||
|
||||
/* Compute the X position for an offset that corresponds to the "more important
|
||||
@ -4794,7 +4756,7 @@ gtk_entry_move_cursor (GtkEntry *entry,
|
||||
case GTK_MOVEMENT_PARAGRAPH_ENDS:
|
||||
case GTK_MOVEMENT_BUFFER_ENDS:
|
||||
priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (priv->buffer);
|
||||
new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
break;
|
||||
case GTK_MOVEMENT_DISPLAY_LINES:
|
||||
case GTK_MOVEMENT_PARAGRAPHS:
|
||||
@ -4852,7 +4814,7 @@ gtk_entry_move_cursor (GtkEntry *entry,
|
||||
case GTK_MOVEMENT_PARAGRAPH_ENDS:
|
||||
case GTK_MOVEMENT_BUFFER_ENDS:
|
||||
priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (priv->buffer);
|
||||
new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
if (entry->current_pos == new_pos)
|
||||
gtk_widget_error_bell (GTK_WIDGET (entry));
|
||||
break;
|
||||
@ -4894,10 +4856,9 @@ gtk_entry_delete_from_cursor (GtkEntry *entry,
|
||||
gint count)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (entry);
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
gint start_pos = entry->current_pos;
|
||||
gint end_pos = entry->current_pos;
|
||||
gint old_n_bytes = gtk_entry_buffer_get_bytes (priv->buffer);
|
||||
gint old_n_bytes = gtk_entry_buffer_get_bytes (get_buffer (entry));
|
||||
|
||||
_gtk_entry_reset_im_context (entry);
|
||||
|
||||
@ -4963,7 +4924,7 @@ gtk_entry_delete_from_cursor (GtkEntry *entry,
|
||||
break;
|
||||
}
|
||||
|
||||
if (gtk_entry_buffer_get_bytes (priv->buffer) == old_n_bytes)
|
||||
if (gtk_entry_buffer_get_bytes (get_buffer (entry)) == old_n_bytes)
|
||||
gtk_widget_error_bell (GTK_WIDGET (entry));
|
||||
|
||||
gtk_entry_pend_cursor_blink (entry);
|
||||
@ -5848,7 +5809,6 @@ gtk_entry_get_cursor_locations (GtkEntry *entry,
|
||||
gint *weak_x)
|
||||
{
|
||||
DisplayMode mode = gtk_entry_get_display_mode (entry);
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
|
||||
/* Nothing to display at all, so no cursor is relevant */
|
||||
if (mode == DISPLAY_BLANK)
|
||||
@ -5880,7 +5840,7 @@ gtk_entry_get_cursor_locations (GtkEntry *entry,
|
||||
index += entry->preedit_length;
|
||||
else
|
||||
{
|
||||
gint preedit_len_chars = g_utf8_strlen (text, -1) - gtk_entry_buffer_get_length (priv->buffer);
|
||||
gint preedit_len_chars = g_utf8_strlen (text, -1) - gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
index += preedit_len_chars * g_unichar_to_utf8 (entry->invisible_char, NULL);
|
||||
}
|
||||
}
|
||||
@ -6084,11 +6044,10 @@ gtk_entry_move_logically (GtkEntry *entry,
|
||||
gint start,
|
||||
gint count)
|
||||
{
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
gint new_pos = start;
|
||||
guint length;
|
||||
|
||||
length = gtk_entry_buffer_get_length (priv->buffer);
|
||||
length = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
|
||||
/* Prevent any leak of information */
|
||||
if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL)
|
||||
@ -6131,11 +6090,10 @@ gtk_entry_move_forward_word (GtkEntry *entry,
|
||||
gint start,
|
||||
gboolean allow_whitespace)
|
||||
{
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
gint new_pos = start;
|
||||
guint length;
|
||||
|
||||
length = gtk_entry_buffer_get_length (priv->buffer);
|
||||
length = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
|
||||
/* Prevent any leak of information */
|
||||
if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL)
|
||||
@ -6279,7 +6237,7 @@ paste_received (GtkClipboard *clipboard,
|
||||
length = truncate_multiline (text);
|
||||
|
||||
/* only complete if the selection is at the end */
|
||||
popup_completion = (gtk_entry_buffer_get_length (priv->buffer) ==
|
||||
popup_completion = (gtk_entry_buffer_get_length (get_buffer (entry)) ==
|
||||
MAX (entry->current_pos, entry->selection_bound));
|
||||
|
||||
if (completion)
|
||||
@ -6609,11 +6567,28 @@ gtk_entry_new_with_max_length (gint max)
|
||||
max = CLAMP (max, 0, GTK_ENTRY_BUFFER_MAX_SIZE);
|
||||
|
||||
entry = g_object_new (GTK_TYPE_ENTRY, NULL);
|
||||
gtk_entry_buffer_set_max_length (GTK_ENTRY_GET_PRIVATE (entry)->buffer, max);
|
||||
gtk_entry_buffer_set_max_length (get_buffer (entry), max);
|
||||
|
||||
return GTK_WIDGET (entry);
|
||||
}
|
||||
|
||||
|
||||
static GtkEntryBuffer*
|
||||
get_buffer (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
|
||||
if (priv->buffer == NULL)
|
||||
{
|
||||
GtkEntryBuffer *buffer;
|
||||
buffer = gtk_entry_buffer_new (NULL, 0);
|
||||
gtk_entry_set_buffer (entry, buffer);
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
return priv->buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_get_buffer:
|
||||
* @entry: a #GtkEntry
|
||||
@ -6629,7 +6604,8 @@ GtkEntryBuffer*
|
||||
gtk_entry_get_buffer (GtkEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
|
||||
return GTK_ENTRY_GET_PRIVATE (entry)->buffer;
|
||||
|
||||
return get_buffer (entry);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6719,7 +6695,7 @@ gtk_entry_set_text (GtkEntry *entry,
|
||||
/* Actually setting the text will affect the cursor and selection;
|
||||
* if the contents don't actually change, this will look odd to the user.
|
||||
*/
|
||||
if (strcmp (gtk_entry_buffer_get_text (priv->buffer), text) == 0)
|
||||
if (strcmp (gtk_entry_buffer_get_text (get_buffer (entry)), text) == 0)
|
||||
return;
|
||||
|
||||
completion = gtk_entry_get_completion (entry);
|
||||
@ -6758,7 +6734,7 @@ gtk_entry_append_text (GtkEntry *entry,
|
||||
g_return_if_fail (text != NULL);
|
||||
priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
|
||||
tmp_pos = gtk_entry_buffer_get_length (priv->buffer);
|
||||
tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
gtk_editable_insert_text (GTK_EDITABLE (entry), text, -1, &tmp_pos);
|
||||
}
|
||||
|
||||
@ -7030,7 +7006,7 @@ G_CONST_RETURN gchar*
|
||||
gtk_entry_get_text (GtkEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
|
||||
return gtk_entry_buffer_get_text (GTK_ENTRY_GET_PRIVATE (entry)->buffer);
|
||||
return gtk_entry_buffer_get_text (get_buffer (entry));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7077,7 +7053,7 @@ gtk_entry_set_max_length (GtkEntry *entry,
|
||||
gint max)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||
gtk_entry_buffer_set_max_length (GTK_ENTRY_GET_PRIVATE (entry)->buffer, max);
|
||||
gtk_entry_buffer_set_max_length (get_buffer (entry), max);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7100,7 +7076,7 @@ gint
|
||||
gtk_entry_get_max_length (GtkEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0);
|
||||
return gtk_entry_buffer_get_max_length (GTK_ENTRY_GET_PRIVATE (entry)->buffer);
|
||||
return gtk_entry_buffer_get_max_length (get_buffer (entry));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7125,7 +7101,7 @@ guint16
|
||||
gtk_entry_get_text_length (GtkEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), 0);
|
||||
return gtk_entry_buffer_get_length (GTK_ENTRY_GET_PRIVATE (entry)->buffer);
|
||||
return gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -9524,7 +9500,7 @@ accept_completion_callback (GtkEntry *entry)
|
||||
|
||||
if (completion->priv->has_completion)
|
||||
gtk_editable_set_position (GTK_EDITABLE (entry),
|
||||
gtk_entry_buffer_get_length (GTK_ENTRY_GET_PRIVATE (entry)->buffer));
|
||||
gtk_entry_buffer_get_length (get_buffer (entry)));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user