[gtk+] Fixed crashes when GtkEntry's internal buffer is not available (bug 588395)
- From: Tristan Van Berkom <tvb src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+] Fixed crashes when GtkEntry's internal buffer is not available (bug 588395)
- Date: Fri, 17 Jul 2009 03:53:30 +0000 (UTC)
commit 51149246c04ba21010892c5e349564ef9893c926
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Thu Jul 16 23:19:03 2009 -0400
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.
gtk/gtkentry.c | 136 +++++++++++++++++++++++---------------------------------
1 files changed, 56 insertions(+), 80 deletions(-)
---
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index d82d687..c490f4d 100644
--- a/gtk/gtkentry.c
+++ b/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;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]