Exemplo n.º 1
0
/**
 * 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;
}
Exemplo n.º 2
0
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;
}