/** * gtk_search_bar_handle_event: * @bar: a #GtkSearchBar * @event: a #GdkEvent containing key press events * * This function should be called when the top-level * window which contains the search bar received a key event. * * If the key event is handled by the search bar, the bar will * be shown, the entry populated with the entered text and %GDK_EVENT_STOP * will be returned. The caller should ensure that events are * not propagated further. * * If no entry has been connected to the search bar, using * gtk_search_bar_connect_entry(), this function will return * immediately with a warning. * * ## Showing the search bar on key presses * * |[<!-- language="C" --> * static gboolean * on_key_press_event (GtkWidget *widget, * GdkEvent *event, * gpointer user_data) * { * GtkSearchBar *bar = GTK_SEARCH_BAR (user_data); * return gtk_search_bar_handle_event (bar, event); * } * * g_signal_connect (window, * "key-press-event", * G_CALLBACK (on_key_press_event), * search_bar); * ]| * * Returns: %GDK_EVENT_STOP if the key press event resulted * in text being entered in the search entry (and revealing * the search bar if necessary), %GDK_EVENT_PROPAGATE otherwise. * * Since: 3.10 */ gboolean gtk_search_bar_handle_event (GtkSearchBar *bar, GdkEvent *event) { GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); guint keyval; gboolean handled; gboolean preedit_changed; guint preedit_change_id; gboolean res; char *old_text, *new_text; if (priv->entry == NULL) { g_warning ("The search bar does not have an entry connected to it. Call gtk_search_bar_connect_entry() to connect one."); return GDK_EVENT_PROPAGATE; } /* Exit early if the search bar is already shown, * the event doesn't contain a key press, * or the event is a navigation or space bar key press */ if (priv->reveal_child || !gdk_event_get_keyval (event, &keyval) || is_keynav_event (event, keyval) || keyval == GDK_KEY_space || keyval == GDK_KEY_Menu) return GDK_EVENT_PROPAGATE; if (!gtk_widget_get_realized (priv->entry)) gtk_widget_realize (priv->entry); handled = GDK_EVENT_PROPAGATE; preedit_changed = FALSE; preedit_change_id = g_signal_connect (priv->entry, "preedit-changed", G_CALLBACK (preedit_changed_cb), &preedit_changed); old_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry))); res = gtk_widget_event (priv->entry, event); new_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry))); g_signal_handler_disconnect (priv->entry, preedit_change_id); if ((res && g_strcmp0 (new_text, old_text) != 0) || preedit_changed) { handled = GDK_EVENT_STOP; gtk_revealer_set_reveal_child (GTK_REVEALER (priv->revealer), TRUE); } g_free (old_text); g_free (new_text); return handled; }
static gboolean window_keypress_handler (GtkWidget *window, GdkEvent *event, GsShell *shell) { GsShellPrivate *priv = gs_shell_get_instance_private (shell); GtkWidget *entry; guint keyval; gboolean handled; gboolean preedit_changed; guint preedit_change_id; gboolean res; g_autofree gchar *old_text = NULL; g_autofree gchar *new_text = NULL; if (gs_shell_get_mode (shell) != GS_SHELL_MODE_OVERVIEW && gs_shell_get_mode (shell) != GS_SHELL_MODE_SEARCH) return GDK_EVENT_PROPAGATE; if (!gdk_event_get_keyval (event, &keyval) || is_keynav_event (event, keyval) || keyval == GDK_KEY_space || keyval == GDK_KEY_Menu) return GDK_EVENT_PROPAGATE; entry = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_search")); handled = GDK_EVENT_PROPAGATE; preedit_changed = FALSE; preedit_change_id = g_signal_connect (entry, "preedit-changed", G_CALLBACK (preedit_changed_cb), &preedit_changed); old_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); res = gtk_widget_event (entry, event); new_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); g_signal_handler_disconnect (entry, preedit_change_id); if ((res && g_strcmp0 (new_text, old_text) != 0) || preedit_changed) { gtk_entry_grab_focus_without_selecting (GTK_ENTRY (entry)); handled = GDK_EVENT_STOP; } return handled; }