From 7fafe08ddd93145b93b9f95a423ed2af8d9f9369 Mon Sep 17 00:00:00 2001 From: Andrej Kacian Date: Fri, 9 Mar 2018 19:24:44 +0100 Subject: [PATCH] Change how main window's keyboard accelerators are bypassed when quicksearch has focus. Instead of artificially forwarding the keypress to quicksearch (only when Shift is pressed), we emit a new "key-press-event" signal directly to the quicksearch entry, and block the original signal before it reaches the accelerator handling. Closes bug #3984: Copy-paste in find/filter field works incorrectly --- src/gtk/quicksearch.c | 65 +++++++++++-------------------------------- src/gtk/quicksearch.h | 2 +- src/mainwindow.c | 33 +++++----------------- 3 files changed, 25 insertions(+), 75 deletions(-) diff --git a/src/gtk/quicksearch.c b/src/gtk/quicksearch.c index 3242aa798..272c221bb 100644 --- a/src/gtk/quicksearch.c +++ b/src/gtk/quicksearch.c @@ -332,7 +332,18 @@ static void searchbar_changed_cb(GtkWidget *widget, QuickSearch *qs) static gboolean searchbar_pressed(GtkWidget *widget, GdkEventKey *event, QuickSearch *quicksearch) { - if (event && (event->keyval == GDK_KEY_Escape)) { + if (event != NULL && (event->keyval == GDK_KEY_ISO_Left_Tab)) { + /* Shift+Tab moves focus "back" */ + gtk_widget_grab_focus(quicksearch->search_type_opt); + return TRUE; + } + if (event != NULL && (event->keyval == GDK_KEY_Tab)) { + /* Just Tab moves focus "forwards" */ + gtk_widget_grab_focus(quicksearch->clear_search); + return TRUE; + } + + if (event != NULL && (event->keyval == GDK_KEY_Escape)) { gchar *str; quicksearch->in_typing = FALSE; @@ -869,6 +880,11 @@ GtkWidget *quicksearch_get_widget(QuickSearch *quicksearch) return quicksearch->hbox_search; } +GtkWidget *quicksearch_get_entry(QuickSearch *quicksearch) +{ + return gtk_bin_get_child(GTK_BIN(quicksearch->search_string_entry)); +} + void quicksearch_show(QuickSearch *quicksearch) { MainWindow *mainwin = mainwindow_get_mainwindow(); @@ -989,53 +1005,6 @@ gboolean quicksearch_is_running(QuickSearch *quicksearch) return quicksearch->running; } -void quicksearch_pass_key(QuickSearch *quicksearch, guint val, GdkModifierType mod) -{ - GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry)))); - glong curpos = gtk_editable_get_position(GTK_EDITABLE(entry)); - guint32 c; - char *str = g_strdup(gtk_entry_get_text(entry)); - char *begin = str; - char *end = NULL; - char *new = NULL; - char key[7] = ""; - gint char_len = 0; - - if (gtk_editable_get_selection_bounds(GTK_EDITABLE(entry), NULL, NULL)) { - /* remove selection */ - gtk_editable_delete_selection(GTK_EDITABLE(entry)); - curpos = gtk_editable_get_position(GTK_EDITABLE(entry)); - /* refresh string */ - g_free(str); - str = g_strdup(gtk_entry_get_text(entry)); - begin = str; - } - - if (!(c = gdk_keyval_to_unicode(val))) { - g_free(str); - return; - } - char_len = g_unichar_to_utf8(c, key); - if (char_len < 0) - return; - key[char_len] = '\0'; - if (curpos < g_utf8_strlen(str, -1)) { - gchar *stop = g_utf8_offset_to_pointer(begin, curpos); - end = g_strdup(g_utf8_offset_to_pointer(str, curpos)); - *stop = '\0'; - new = g_strdup_printf("%s%s%s", begin, key, end); - gtk_entry_set_text(entry, new); - g_free(end); - } else { - new = g_strdup_printf("%s%s", begin, key); - gtk_entry_set_text(entry, new); - } - g_free(str); - g_free(new); - gtk_editable_set_position(GTK_EDITABLE(entry), curpos+1); - -} - gboolean quicksearch_is_in_typing(QuickSearch *quicksearch) { return quicksearch->in_typing; diff --git a/src/gtk/quicksearch.h b/src/gtk/quicksearch.h index c1a26bfac..9aada6e1f 100644 --- a/src/gtk/quicksearch.h +++ b/src/gtk/quicksearch.h @@ -30,6 +30,7 @@ typedef void (*QuickSearchExecuteCallback) (QuickSearch *quicksearch, gpointer d QuickSearch *quicksearch_new(); GtkWidget *quicksearch_get_widget(QuickSearch *quicksearch); +GtkWidget *quicksearch_get_entry(QuickSearch *quicksearch); void quicksearch_show(QuickSearch *quicksearch); void quicksearch_hide(QuickSearch *quicksearch); void quicksearch_set(QuickSearch *quicksearch, AdvancedSearchType type, const gchar *matchstring); @@ -45,7 +46,6 @@ gboolean quicksearch_run_on_folder(QuickSearch* quicksearch, FolderItem *folderI gboolean quicksearch_is_running(QuickSearch *quicksearch); gboolean quicksearch_has_focus(QuickSearch *quicksearch); -void quicksearch_pass_key(QuickSearch *quicksearch, guint val, GdkModifierType mod); gboolean quicksearch_is_fast(QuickSearch *quicksearch); gboolean quicksearch_is_in_typing(QuickSearch *quicksearch); void quicksearch_relayout(QuickSearch *quicksearch); diff --git a/src/mainwindow.c b/src/mainwindow.c index 367e4a03a..20bc40f9a 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -30,6 +30,7 @@ #include "folderview.h" #include "folder_item_prefs.h" #include "foldersel.h" +#include "quicksearch.h" #include "summaryview.h" #include "summary_search.h" #include "messageview.h" @@ -921,27 +922,8 @@ static GtkRadioActionEntry mainwin_radio_dec_entries[] = }; static gboolean offline_ask_sync = TRUE; -static guint lastkey; static gboolean is_obscured = FALSE; -static gboolean main_window_accel_activate (GtkAccelGroup *accelgroup, - GObject *arg1, - guint value, - GdkModifierType mod, - gpointer user_data) -{ - MainWindow *mainwin = (MainWindow *)user_data; - - if (mainwin->summaryview && - mainwin->summaryview->quicksearch && - quicksearch_has_focus(mainwin->summaryview->quicksearch) && - (mod == 0 || mod == GDK_SHIFT_MASK)) { - quicksearch_pass_key(mainwin->summaryview->quicksearch, lastkey, mod); - return TRUE; - } - return FALSE; -} - #define N_COLOR_LABELS colorlabel_get_color_count() static void mainwindow_colorlabel_menu_item_activate_item_cb(GtkMenuItem *menu_item, @@ -1379,14 +1361,16 @@ static gboolean mainwindow_key_pressed (GtkWidget *widget, GdkEventKey *event, gpointer data) { MainWindow *mainwin = (MainWindow*) data; - + if (!mainwin || !event) return FALSE; if (quicksearch_has_focus(mainwin->summaryview->quicksearch)) { - lastkey = event->keyval; - return FALSE; + GtkWidget *entry = + quicksearch_get_entry(mainwin->summaryview->quicksearch); + g_signal_emit_by_name(entry, "key-press-event", event, data); + return TRUE; } switch (event->keyval) { @@ -2174,10 +2158,7 @@ MainWindow *main_window_create() #define ADD_MENU_ACCEL_GROUP_TO_WINDOW(menu,win) \ gtk_window_add_accel_group \ (GTK_WINDOW(win), \ - gtk_ui_manager_get_accel_group(gtkut_ui_manager())); \ - g_signal_connect(G_OBJECT(gtk_ui_manager_get_accel_group(gtkut_ui_manager())), \ - "accel_activate", \ - G_CALLBACK(main_window_accel_activate), mainwin); + gtk_ui_manager_get_accel_group(gtkut_ui_manager())); ADD_MENU_ACCEL_GROUP_TO_WINDOW(summaryview->popupmenu, mainwin->window); -- 2.25.1