Fix problems with "position" and "selection-bound" change notification

Added a "selection-bound" notify on clutter_text_clear_selection as it
changes the value.

Added utility function clutter_text_set_positions, in order to
change both cursor position and selection bound inside a
g_object_[freeze/thaw]_notify block

Added g_object_[freeze/thaw]_notify in other functions that changes
both cursor position and selection bound

Solves http://bugzilla.openedhand.com/show_bug.cgi?id=1955
This commit is contained in:
Alejandro Piñeiro 2010-01-25 16:13:58 +01:00 committed by Emmanuele Bassi
parent 579a9a2665
commit ecbb7ce41a

View File

@ -260,6 +260,7 @@ clutter_text_clear_selection (ClutterText *self)
if (priv->selection_bound != priv->position) if (priv->selection_bound != priv->position)
{ {
priv->selection_bound = priv->position; priv->selection_bound = priv->position;
g_object_notify (G_OBJECT (self), "selection-bound");
clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
} }
} }
@ -803,6 +804,7 @@ clutter_text_delete_selection (ClutterText *self)
priv->position = start_index; priv->position = start_index;
priv->selection_bound = start_index; priv->selection_bound = start_index;
/* Not required to be guarded by g_object_freeze/thaw_notify */
if (priv->position != old_position) if (priv->position != old_position)
g_object_notify (G_OBJECT (self), "position"); g_object_notify (G_OBJECT (self), "position");
@ -812,6 +814,21 @@ clutter_text_delete_selection (ClutterText *self)
return TRUE; return TRUE;
} }
/*
* Utility function to update both cursor position and selection bound
* at once
*/
static inline void
clutter_text_set_positions (ClutterText *self,
gint new_pos,
gint new_bound)
{
g_object_freeze_notify (G_OBJECT (self));
clutter_text_set_cursor_position (self, new_pos);
clutter_text_set_selection_bound (self, new_bound);
g_object_thaw_notify (G_OBJECT (self));
}
static inline void static inline void
clutter_text_set_text_internal (ClutterText *self, clutter_text_set_text_internal (ClutterText *self,
const gchar *text) const gchar *text)
@ -857,8 +874,7 @@ clutter_text_set_text_internal (ClutterText *self,
if (priv->n_bytes == 0) if (priv->n_bytes == 0)
{ {
clutter_text_set_cursor_position (self, -1); clutter_text_set_positions (self, -1, -1);
clutter_text_set_selection_bound (self, -1);
} }
clutter_text_dirty_cache (self); clutter_text_dirty_cache (self);
@ -1493,8 +1509,7 @@ clutter_text_button_press (ClutterActor *actor,
*/ */
if (priv->text == NULL || priv->text[0] == '\0') if (priv->text == NULL || priv->text[0] == '\0')
{ {
clutter_text_set_cursor_position (self, -1); clutter_text_set_positions (self, -1, -1);
clutter_text_set_selection_bound (self, -1);
return TRUE; return TRUE;
} }
@ -1519,8 +1534,7 @@ clutter_text_button_press (ClutterActor *actor,
*/ */
if (event->click_count == 1) if (event->click_count == 1)
{ {
clutter_text_set_cursor_position (self, offset); clutter_text_set_positions (self, offset, offset);
clutter_text_set_selection_bound (self, offset);
} }
else if (event->click_count == 2) else if (event->click_count == 2)
{ {
@ -1565,8 +1579,7 @@ clutter_text_motion (ClutterActor *actor,
clutter_text_set_cursor_position (self, offset); clutter_text_set_cursor_position (self, offset);
else else
{ {
clutter_text_set_cursor_position (self, offset); clutter_text_set_positions (self, offset, offset);
clutter_text_set_selection_bound (self, offset);
} }
return TRUE; return TRUE;
@ -1896,6 +1909,8 @@ clutter_text_real_move_left (ClutterText *self,
len = priv->n_chars; len = priv->n_chars;
g_object_freeze_notify (G_OBJECT (self));
if (pos != 0 && len != 0) if (pos != 0 && len != 0)
{ {
if (modifiers & CLUTTER_CONTROL_MASK) if (modifiers & CLUTTER_CONTROL_MASK)
@ -1919,6 +1934,8 @@ clutter_text_real_move_left (ClutterText *self,
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
g_object_thaw_notify (G_OBJECT (self));
return TRUE; return TRUE;
} }
@ -1935,6 +1952,8 @@ clutter_text_real_move_right (ClutterText *self,
len = priv->n_chars; len = priv->n_chars;
g_object_freeze_notify (G_OBJECT (self));
if (pos != -1 && len !=0) if (pos != -1 && len !=0)
{ {
if (modifiers & CLUTTER_CONTROL_MASK) if (modifiers & CLUTTER_CONTROL_MASK)
@ -1954,6 +1973,8 @@ clutter_text_real_move_right (ClutterText *self,
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
g_object_thaw_notify (G_OBJECT (self));
return TRUE; return TRUE;
} }
@ -1970,6 +1991,8 @@ clutter_text_real_move_up (ClutterText *self,
gint index_, trailing; gint index_, trailing;
gint x; gint x;
g_object_freeze_notify (G_OBJECT (self));
layout = clutter_text_get_layout (self); layout = clutter_text_get_layout (self);
if (priv->position == 0) if (priv->position == 0)
@ -2007,6 +2030,8 @@ clutter_text_real_move_up (ClutterText *self,
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
g_object_thaw_notify (G_OBJECT (self));
return TRUE; return TRUE;
} }
@ -2023,6 +2048,8 @@ clutter_text_real_move_down (ClutterText *self,
gint index_, trailing; gint index_, trailing;
gint x; gint x;
g_object_freeze_notify (G_OBJECT (self));
layout = clutter_text_get_layout (self); layout = clutter_text_get_layout (self);
if (priv->position == 0) if (priv->position == 0)
@ -2056,6 +2083,8 @@ clutter_text_real_move_down (ClutterText *self,
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
g_object_thaw_notify (G_OBJECT (self));
return TRUE; return TRUE;
} }
@ -2068,12 +2097,16 @@ clutter_text_real_line_start (ClutterText *self,
ClutterTextPrivate *priv = self->priv; ClutterTextPrivate *priv = self->priv;
gint position; gint position;
g_object_freeze_notify (G_OBJECT (self));
position = clutter_text_move_line_start (self, priv->position); position = clutter_text_move_line_start (self, priv->position);
clutter_text_set_cursor_position (self, position); clutter_text_set_cursor_position (self, position);
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
g_object_thaw_notify (G_OBJECT (self));
return TRUE; return TRUE;
} }
@ -2086,12 +2119,16 @@ clutter_text_real_line_end (ClutterText *self,
ClutterTextPrivate *priv = self->priv; ClutterTextPrivate *priv = self->priv;
gint position; gint position;
g_object_freeze_notify (G_OBJECT (self));
position = clutter_text_move_line_end (self, priv->position); position = clutter_text_move_line_end (self, priv->position);
clutter_text_set_cursor_position (self, position); clutter_text_set_cursor_position (self, position);
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
g_object_thaw_notify (G_OBJECT (self));
return TRUE; return TRUE;
} }
@ -2101,8 +2138,7 @@ clutter_text_real_select_all (ClutterText *self,
guint keyval, guint keyval,
ClutterModifierType modifiers) ClutterModifierType modifiers)
{ {
clutter_text_set_cursor_position (self, 0); clutter_text_set_positions (self, 0, self->priv->n_chars);
clutter_text_set_selection_bound (self, self->priv->n_chars);
return TRUE; return TRUE;
} }
@ -2151,15 +2187,13 @@ clutter_text_real_del_prev (ClutterText *self,
{ {
clutter_text_delete_text (self, len - 1, len); clutter_text_delete_text (self, len - 1, len);
clutter_text_set_cursor_position (self, -1); clutter_text_set_positions (self, -1, -1);
clutter_text_set_selection_bound (self, -1);
} }
else else
{ {
clutter_text_delete_text (self, pos - 1, pos); clutter_text_delete_text (self, pos - 1, pos);
clutter_text_set_cursor_position (self, pos - 1); clutter_text_set_positions (self, pos - 1, pos - 1);
clutter_text_set_selection_bound (self, pos - 1);
} }
} }
@ -3260,12 +3294,7 @@ clutter_text_set_selection (ClutterText *self,
start_pos = MIN (priv->n_chars, start_pos); start_pos = MIN (priv->n_chars, start_pos);
end_pos = MIN (priv->n_chars, end_pos); end_pos = MIN (priv->n_chars, end_pos);
g_object_freeze_notify (G_OBJECT (self)); clutter_text_set_positions (self, start_pos, end_pos);
clutter_text_set_cursor_position (self, start_pos);
clutter_text_set_selection_bound (self, end_pos);
g_object_thaw_notify (G_OBJECT (self));
} }
/** /**
@ -4349,8 +4378,7 @@ clutter_text_insert_unichar (ClutterText *self,
if (priv->position >= 0) if (priv->position >= 0)
{ {
clutter_text_set_cursor_position (self, priv->position + 1); clutter_text_set_positions (self, priv->position + 1, priv->position);
clutter_text_set_selection_bound (self, priv->position);
} }
g_string_free (new, TRUE); g_string_free (new, TRUE);
@ -4397,8 +4425,9 @@ clutter_text_insert_text (ClutterText *self,
if (position >= 0 && priv->position >= position) if (position >= 0 && priv->position >= position)
{ {
clutter_text_set_cursor_position (self, priv->position + g_utf8_strlen (text, -1)); clutter_text_set_positions (self,
clutter_text_set_selection_bound (self, priv->position); priv->position + g_utf8_strlen (text, -1),
priv->position);
} }
g_string_free (new, TRUE); g_string_free (new, TRUE);