aboutsummaryrefslogtreecommitdiff
path: root/hildon/hildon-live-search.c
diff options
context:
space:
mode:
authorClaudio Saavedra <csaavedra@igalia.com>2009-11-04 17:21:08 +0200
committerClaudio Saavedra <csaavedra@igalia.com>2009-11-16 09:53:02 +0200
commit68b6d1740c32eb18103c62544db55a2044628457 (patch)
tree35169d4bcaf8c4f383a46316b016e9996f75dc69 /hildon/hildon-live-search.c
parentf12c43f0a623cfaa8db972f41c56bf44166099b0 (diff)
Major clean-up of the HildonLiveSearch event handling
Based on work by Xavier Claessens <xavier.claessens@collabora.co.uk>
Diffstat (limited to 'hildon/hildon-live-search.c')
-rw-r--r--hildon/hildon-live-search.c389
1 files changed, 24 insertions, 365 deletions
diff --git a/hildon/hildon-live-search.c b/hildon/hildon-live-search.c
index cec918a..3d29b6d 100644
--- a/hildon/hildon-live-search.c
+++ b/hildon/hildon-live-search.c
@@ -51,15 +51,7 @@ struct _HildonLiveSearchPrivate
GtkWidget *event_widget;
GHashTable *selection_map;
- GtkIMContext *im_context;
-
gulong key_press_id;
- gulong key_release_id;
- gulong realize_id;
- gulong unrealize_id;
- gulong focus_in_event_id;
- gulong focus_out_event_id;
- gulong on_entry_changed_id;
gulong destroy_id;
gchar *prefix;
@@ -79,12 +71,6 @@ enum
PROP_TEXT_COLUMN
};
-static void
-hildon_live_search_real_show (GtkWidget *widget);
-
-static void
-hildon_live_search_real_hide (GtkWidget *widget);
-
static gboolean
visible_func (GtkTreeModel *model,
GtkTreeIter *iter,
@@ -92,15 +78,6 @@ visible_func (GtkTreeModel *model,
/* Private implementation */
-static void
-grab_treeview_focus (HildonLiveSearchPrivate *priv)
-{
- if (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (priv->treeview)))
- gtk_im_context_focus_in (priv->im_context);
-
- gtk_widget_grab_focus (GTK_WIDGET (priv->treeview));
-}
-
static guint
hash_func (gconstpointer key)
{
@@ -262,12 +239,6 @@ selection_map_update_selection_from_map (HildonLiveSearchPrivate *priv)
}
}
-/*
- * Entry changed handler, called when the text entry is changed directly
- * (if it is focused) or indirectly (via #on_key_press_event which
- * captures key presses on the source widget). This will update the
- * filter as required.
- */
static void
on_entry_changed (GtkEntry *entry,
gpointer user_data)
@@ -300,35 +271,14 @@ on_entry_changed (GtkEntry *entry,
if (len < 1) {
selection_map_destroy (priv);
+ gtk_widget_hide (GTK_WIDGET (user_data));
+ } else {
+ gtk_widget_show (GTK_WIDGET (user_data));
}
g_free (old_prefix);
}
-static void
-adj_changed_cb (GtkAdjustment *adj, gpointer user_data)
-{
- GtkTreePath *path = NULL;
- GtkTreeView *view = user_data;
-
- gtk_tree_view_get_cursor (view, &path, NULL);
- if (path) {
- gtk_tree_view_scroll_to_cell (view, path, NULL, FALSE, 0.0f, 0.0f);
- }
- gtk_tree_path_free (path);
-
- g_object_disconnect (adj, "any_signal::changed", G_CALLBACK (adj_changed_cb), user_data, NULL);
-}
-
-static void
-scroll_to_focus (GtkTreeView *treeview)
-{
- GtkAdjustment *adj;
-
- adj = gtk_tree_view_get_vadjustment (treeview);
- g_signal_connect (G_OBJECT (adj), "changed", G_CALLBACK (adj_changed_cb), treeview);
-}
-
/**
* hildon_live_search_append_text:
* @livesearch: An #HildonLiveSearch widget
@@ -349,16 +299,6 @@ hildon_live_search_append_text (HildonLiveSearch *livesearch,
priv = GET_PRIVATE (livesearch);
- if (FALSE == GTK_WIDGET_MAPPED (livesearch)) {
- gunichar c;
-
- c = g_utf8_get_char_validated (utf8, strlen (utf8));
- if (g_unichar_isgraph (c))
- gtk_widget_show (GTK_WIDGET (livesearch));
- else
- return;
- }
-
editable = GTK_EDITABLE (priv->entry);
if (gtk_editable_get_selection_bounds (editable,
@@ -394,30 +334,12 @@ hildon_live_search_get_text (HildonLiveSearch *livesearch)
}
/*
- * IM commit handler. This receives the finalized utf8 input based on the
- * previous source widget key event(s) and manipules the entry. This
- * manipulation then calls #on_entry_changed.
- */
-static void
-on_im_context_commit (GtkIMContext *imcontext,
- gchar *utf8,
- gpointer user_data)
-{
- HildonLiveSearch *live_search;
-
- g_return_if_fail (HILDON_IS_LIVE_SEARCH (user_data));
-
- live_search = HILDON_LIVE_SEARCH (user_data);
- hildon_live_search_append_text (live_search, utf8);
-}
-
-/*
* Key press handler. This takes key presses from the source widget and
* manipulate the entry. This manipulation then calls #on_entry_changed.
*/
static gboolean
on_key_press_event (GtkWidget *widget,
- GdkEventKey *key,
+ GdkEventKey *event,
HildonLiveSearch *live_search)
{
HildonLiveSearchPrivate *priv;
@@ -425,153 +347,31 @@ on_key_press_event (GtkWidget *widget,
g_return_val_if_fail (HILDON_IS_LIVE_SEARCH (live_search), FALSE);
priv = GET_PRIVATE (live_search);
- /* Don't intercept control- presses.
- * Make an exception for ctr-space because it is the keyboard layout
- * switch */
- if (key->state & GDK_CONTROL_MASK &&
- key->keyval != GDK_space)
- return FALSE;
-
- /* Are we already visible, yet ? */
- if (GTK_WIDGET_MAPPED (live_search)) {
-
- /* Eat escape */
- if (key->keyval == GDK_Escape)
- return TRUE;
-
- /* Don't eat returns */
- if (key->keyval == GDK_Return)
- return FALSE;
- if (key->keyval == GDK_BackSpace) {
- GtkEditable *editable;
- int start, end;
-
- editable = GTK_EDITABLE (priv->entry);
- if (gtk_editable_get_selection_bounds (editable,
- &start,
- &end)) {
- gtk_editable_delete_text (editable, start, end);
- } else {
- int pos;
- pos = gtk_editable_get_position (editable);
- if (pos < 1)
- return TRUE;
- gtk_editable_delete_text (editable, pos - 1, pos);
- }
- scroll_to_focus (priv->treeview);
-
- return TRUE;
- }
- /* Does the entry have focus? */
- if (GTK_WIDGET_HAS_FOCUS (priv->entry))
- return FALSE;
-
- /* Run the key through the IM context filter to get the value */
- return gtk_im_context_filter_keypress (priv->im_context, key);
- }
-
- /* If the treeview is not visible, then don't bother */
- if (FALSE == GTK_WIDGET_MAPPED (priv->treeview))
- return FALSE;
-
- /* Return and space do not start searching. But ctr-space must still be
- * sent to switch the keyboard layout */
- if (key->keyval == GDK_Return ||
- (key->keyval == GDK_space &&
- !(key->state & GDK_CONTROL_MASK)))
- return FALSE;
-
- /* Run the key through the IM context filter to get the value */
- gtk_im_context_filter_keypress (priv->im_context, key);
+ /* If the entry is realized and has focus, it is enough to catch events.
+ * This assume that the toolbar is a child of the hook widget. */
+ gtk_widget_realize (priv->entry);
+ gtk_widget_grab_focus (priv->entry);
return FALSE;
}
-static gboolean
-on_key_release_event (GtkWidget *widget,
- GdkEventKey *key,
- HildonLiveSearch *live_search)
+static void
+on_hide_cb (GtkWidget *widget,
+ HildonLiveSearch *live_search)
{
HildonLiveSearchPrivate *priv;
- g_return_val_if_fail (HILDON_IS_LIVE_SEARCH (live_search), FALSE);
priv = GET_PRIVATE (live_search);
- /* Don't intercept control- presses */
- if (key->state & GDK_CONTROL_MASK)
- return FALSE;
- /* Are we already visible, yet ? */
- if (GTK_WIDGET_MAPPED (live_search)) {
- if (key->keyval == GDK_Escape) {
- gtk_widget_hide (GTK_WIDGET (live_search));
- return TRUE;
- }
-
- if (key->keyval == GDK_BackSpace) {
- const gchar *text = gtk_entry_get_text
- (GTK_ENTRY (priv->entry));
- glong len = g_utf8_strlen (text, -1);
-
- if (len <= 0) {
- gtk_widget_hide (GTK_WIDGET (live_search));
- return TRUE;
- }
- }
-
- /* Does the entry have focus? */
- if (GTK_WIDGET_HAS_FOCUS (priv->entry))
- return FALSE;
-
- /* Run the key through the IM context filter to get the
- value */
- return gtk_im_context_filter_keypress (priv->im_context, key);
+ if (priv->prefix) {
+ g_free (priv->prefix);
+ priv->prefix = NULL;
}
- /* If the treeview is not visible, then don't bother */
- if (FALSE == GTK_WIDGET_MAPPED (priv->treeview))
- return FALSE;
-
- /* Don't pop up fkb or the preview bar */
- if (key->keyval == GDK_Return ||
- key->keyval == GDK_space)
- return FALSE;
- /* Run the key through the IM context filter to get the value */
- gtk_im_context_filter_keypress (priv->im_context, key);
-
- return FALSE;
-}
-
-static void
-on_unmap (GtkWidget *widget,
- gpointer user_data)
-{
- HildonLiveSearchPrivate *priv;
-
- priv = GET_PRIVATE (user_data);
-
- hildon_gtk_im_context_hide (priv->im_context);
-}
-
-static void
-on_hook_widget_realize (GtkWidget *hook_widget,
- gpointer user_data)
-{
- HildonLiveSearchPrivate *priv;
-
- priv = GET_PRIVATE (user_data);
- gtk_im_context_set_client_window (priv->im_context,
- hook_widget->window);
-}
-
-static void
-on_hook_widget_unrealize (GtkWidget *hook_widget,
- gpointer user_data)
-{
- HildonLiveSearchPrivate *priv;
-
- priv = GET_PRIVATE (user_data);
- gtk_im_context_set_client_window (priv->im_context,
- NULL);
+ /* Remove text from the entry without calling on_entry_changed */
+ g_signal_handlers_block_by_func (priv->entry, on_entry_changed, live_search);
+ gtk_entry_set_text (GTK_ENTRY (priv->entry), "");
+ g_signal_handlers_unblock_by_func (priv->entry, on_entry_changed, live_search);
}
/* GObject methods */
@@ -624,12 +424,6 @@ hildon_live_search_dispose (GObject *object)
{
HildonLiveSearchPrivate *priv = GET_PRIVATE (object);
- if (priv->on_entry_changed_id) {
- g_signal_handler_disconnect (priv->entry,
- priv->on_entry_changed_id);
- priv->on_entry_changed_id = 0;
- }
-
hildon_live_search_widget_unhook (HILDON_LIVE_SEARCH (object));
if (priv->filter) {
@@ -648,11 +442,6 @@ hildon_live_search_dispose (GObject *object)
priv->visible_destroy = NULL;
}
- if (priv->im_context) {
- g_object_unref (priv->im_context);
- priv->im_context = NULL;
- }
-
G_OBJECT_CLASS (hildon_live_search_parent_class)->dispose (object);
}
@@ -660,7 +449,6 @@ static void
hildon_live_search_class_init (HildonLiveSearchClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
g_type_class_add_private (klass, sizeof (HildonLiveSearchPrivate));
@@ -668,9 +456,6 @@ hildon_live_search_class_init (HildonLiveSearchClass *klass)
object_class->set_property = hildon_live_search_set_property;
object_class->dispose = hildon_live_search_dispose;
- widget_class->show = hildon_live_search_real_show;
- widget_class->hide = hildon_live_search_real_hide;
-
g_object_class_install_property (object_class,
PROP_FILTER,
g_param_spec_object ("filter",
@@ -772,28 +557,14 @@ hildon_live_search_init (HildonLiveSearch *self)
gtk_toolbar_insert (GTK_TOOLBAR (self), close_button_container, -1);
- priv->on_entry_changed_id =
- g_signal_connect (G_OBJECT (priv->entry), "changed",
- G_CALLBACK (on_entry_changed), self);
-
- priv->im_context = gtk_im_multicontext_new();
-
- g_object_get (priv->im_context,
- "hildon-input-mode", &imode,
- NULL);
- g_object_set (priv->im_context,
- "hildon-input-mode", filter_input_mode (imode),
- NULL);
-
- g_signal_connect (G_OBJECT (priv->im_context), "commit",
- G_CALLBACK (on_im_context_commit), self);
+ g_signal_connect (G_OBJECT (close_button), "clicked",
+ G_CALLBACK (close_button_clicked_cb), self);
- g_signal_connect (G_OBJECT (self), "unmap",
- G_CALLBACK (on_unmap), self);
+ g_signal_connect (G_OBJECT (priv->entry), "changed",
+ G_CALLBACK (on_entry_changed), self);
- g_signal_connect (G_OBJECT (close_button), "clicked",
- G_CALLBACK (close_button_clicked_cb),
- self);
+ g_signal_connect (self, "hide",
+ G_CALLBACK (on_hide_cb), self);
gtk_widget_show_all (GTK_WIDGET (self));
gtk_widget_set_no_show_all (GTK_WIDGET (self), TRUE);
@@ -814,42 +585,6 @@ hildon_live_search_new (void)
return g_object_new (HILDON_TYPE_LIVE_SEARCH, NULL);
}
-static void
-hildon_live_search_real_show (GtkWidget *widget)
-{
- HildonLiveSearch *livesearch;
- HildonLiveSearchPrivate *priv;
-
- livesearch = HILDON_LIVE_SEARCH (widget);
- priv = GET_PRIVATE (livesearch);
-
- GTK_WIDGET_CLASS (hildon_live_search_parent_class)->show (widget);
-
- if (priv->treeview != NULL)
- grab_treeview_focus (priv);
-}
-
-static void
-hildon_live_search_real_hide (GtkWidget *widget)
-{
- HildonLiveSearch *livesearch;
- HildonLiveSearchPrivate *priv;
-
- livesearch = HILDON_LIVE_SEARCH (widget);
- priv = GET_PRIVATE (livesearch);
-
- gtk_editable_delete_text (GTK_EDITABLE (priv->entry), 0, -1);
-
- GTK_WIDGET_CLASS (hildon_live_search_parent_class)->hide (widget);
-
- if (priv->treeview != NULL) {
- if (GTK_WIDGET_MAPPED (priv->treeview))
- scroll_to_focus (priv->treeview);
-
- grab_treeview_focus (priv);
- }
-}
-
static gboolean
visible_func (GtkTreeModel *model,
GtkTreeIter *iter,
@@ -952,23 +687,6 @@ hildon_live_search_set_text_column (HildonLiveSearch *livesearch,
gtk_tree_model_filter_refilter (priv->filter);
}
-static gboolean
-on_hook_widget_focus_in_out_event (GtkWidget *widget,
- GdkEventFocus *focus,
- gpointer user_data)
-{
- HildonLiveSearchPrivate *priv;
-
- priv = GET_PRIVATE (user_data);
-
- if (focus->in) {
- gtk_im_context_focus_in (priv->im_context);
- } else {
- gtk_im_context_focus_out (priv->im_context);
- }
- return FALSE;
-}
-
static void
on_hook_widget_destroy (GtkObject *object,
gpointer user_data)
@@ -977,12 +695,6 @@ on_hook_widget_destroy (GtkObject *object,
priv = GET_PRIVATE (user_data);
- priv->key_press_id = 0;
- priv->key_release_id = 0;
- priv->realize_id = 0;
- priv->unrealize_id = 0;
- priv->focus_in_event_id = 0;
- priv->focus_out_event_id = 0;
priv->destroy_id = 0;
}
@@ -1010,40 +722,11 @@ hildon_live_search_widget_hook (HildonLiveSearch *livesearch,
g_return_if_fail (priv->event_widget == NULL);
priv->event_widget = hook_widget;
-
priv->treeview = kb_focus;
- if (priv->treeview != NULL)
- grab_treeview_focus (priv);
priv->key_press_id =
g_signal_connect (hook_widget, "key-press-event",
G_CALLBACK (on_key_press_event), livesearch);
- priv->key_release_id =
- g_signal_connect (hook_widget, "key-release-event",
- G_CALLBACK (on_key_release_event), livesearch);
- if (GTK_WIDGET_REALIZED (hook_widget)) {
- gtk_im_context_set_client_window (priv->im_context,
- hook_widget->window);
- priv->realize_id = 0;
- } else {
- priv->realize_id =
- g_signal_connect (G_OBJECT (hook_widget), "realize",
- G_CALLBACK (on_hook_widget_realize),
- livesearch);
- }
- priv->unrealize_id = g_signal_connect (G_OBJECT (hook_widget), "unrealize",
- G_CALLBACK (on_hook_widget_unrealize),
- livesearch);
-
- priv->focus_in_event_id =
- g_signal_connect (G_OBJECT (hook_widget), "focus-in-event",
- G_CALLBACK (on_hook_widget_focus_in_out_event),
- livesearch);
-
- priv->focus_out_event_id =
- g_signal_connect (G_OBJECT (hook_widget), "focus-out-event",
- G_CALLBACK (on_hook_widget_focus_in_out_event),
- livesearch);
priv->destroy_id =
g_signal_connect (G_OBJECT (hook_widget), "destroy",
@@ -1073,35 +756,11 @@ hildon_live_search_widget_unhook (HildonLiveSearch *livesearch)
g_signal_handler_disconnect (priv->event_widget, priv->key_press_id);
priv->key_press_id = 0;
}
- if (priv->key_release_id) {
- g_signal_handler_disconnect (priv->event_widget, priv->key_release_id);
- priv->key_release_id = 0;
- }
- if (priv->realize_id) {
- g_signal_handler_disconnect (priv->event_widget, priv->realize_id);
- priv->realize_id = 0;
- }
- if (priv->unrealize_id) {
- g_signal_handler_disconnect (priv->event_widget, priv->unrealize_id);
- priv->unrealize_id = 0;
- }
- if (priv->focus_in_event_id) {
- g_signal_handler_disconnect (priv->event_widget, priv->focus_in_event_id);
- priv->focus_in_event_id = 0;
- }
- if (priv->focus_out_event_id) {
- g_signal_handler_disconnect (priv->event_widget, priv->focus_out_event_id);
- priv->focus_out_event_id = 0;
- }
-
if (priv->destroy_id) {
g_signal_handler_disconnect (priv->event_widget, priv->destroy_id);
priv->destroy_id = 0;
}
- gtk_im_context_focus_out (priv->im_context);
- gtk_im_context_set_client_window (priv->im_context, NULL);
-
priv->event_widget = NULL;
priv->treeview = NULL;
}