From 18529b7b95eab5ac073a9ef6fee8035dc9bcef13 Mon Sep 17 00:00:00 2001 From: Simon Gomizelj Date: Thu, 31 May 2012 12:39:59 -0400 Subject: [PATCH 1/6] Add an entry widge and overlay it over the vte. --- termite.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/termite.c b/termite.c index f68459f..b8b72c1 100644 --- a/termite.c +++ b/termite.c @@ -164,6 +164,26 @@ static void window_title_cb(VteTerminal *vte, GtkWindow *window) { } #endif +static gboolean position_overlay(GtkOverlay *overlay, GtkWidget *widget, GdkRectangle *alloc) { + GtkWidget *main_widget = gtk_bin_get_child(GTK_BIN(overlay)); + + GtkAllocation main_alloc; + main_alloc.x = 0; + main_alloc.y = 0; + main_alloc.width = gtk_widget_get_allocated_width(main_widget); + main_alloc.height = gtk_widget_get_allocated_height(main_widget); + + GtkRequisition req; + gtk_widget_get_preferred_size(widget, NULL, &req); + + alloc->x = 2 * main_alloc.width / 3 - req.width / 2; + alloc->y = 0; + alloc->width = MIN(main_alloc.width, req.width); + alloc->height = MIN(main_alloc.height, req.height); + + return TRUE; +} + int main(int argc, char **argv) { GError *error = NULL; @@ -195,6 +215,7 @@ int main(int argc, char **argv) { } #endif + GtkWidget *overlay = gtk_overlay_new(); GtkWidget *vte = vte_terminal_new(); char **command_argv; @@ -230,9 +251,16 @@ int main(int argc, char **argv) { return 1; } - gtk_container_add(GTK_CONTAINER(window), vte); + gtk_container_add(GTK_CONTAINER(overlay), vte); + gtk_container_add(GTK_CONTAINER(window), overlay); + + GtkWidget *entry = gtk_entry_new(); + gtk_widget_set_halign(entry, GTK_ALIGN_START); + gtk_widget_set_valign(entry, GTK_ALIGN_END); + gtk_overlay_add_overlay(GTK_OVERLAY(overlay), entry); g_signal_connect(vte, "child-exited", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(overlay, "get-child-position", G_CALLBACK(position_overlay), NULL); vte_terminal_set_scrollback_lines(VTE_TERMINAL(vte), scrollback_lines); vte_terminal_set_font_from_string(VTE_TERMINAL(vte), font); From 2df3250792846bffb8bcbc5d3b792e3c8be4c5fe Mon Sep 17 00:00:00 2001 From: Simon Gomizelj Date: Thu, 31 May 2012 21:31:09 -0400 Subject: [PATCH 2/6] Wrap the entry in a Gtk alignment and wire it up. Should be functionally equivalent to the old code. There are still some strange focus issues. --- termite.c | 85 ++++++++++++++++++++----------------------------------- 1 file changed, 31 insertions(+), 54 deletions(-) diff --git a/termite.c b/termite.c index b8b72c1..b932fcb 100644 --- a/termite.c +++ b/termite.c @@ -13,12 +13,11 @@ # define __attribute__(x) #endif -typedef struct search_dialog_info { +typedef struct search_panel_info { GtkWidget *vte; - GtkWidget *entry; + GtkBin *panel; bool reverse; - bool open; -} search_dialog_info; +} search_panel_info; static void search(VteTerminal *vte, const char *pattern, bool reverse) { GRegex *regex = vte_terminal_search_get_gregex(vte); @@ -34,49 +33,16 @@ static void search(VteTerminal *vte, const char *pattern, bool reverse) { vte_terminal_copy_primary(vte); } -static void search_response_cb(GtkWidget *dialog, gint response_id, search_dialog_info *info) { - if (response_id == GTK_RESPONSE_ACCEPT) { - search(VTE_TERMINAL(info->vte), gtk_entry_get_text(GTK_ENTRY(info->entry)), info->reverse); - } - gtk_widget_destroy(dialog); - info->open = false; -} - -static gboolean search_key_press_cb(__attribute__((unused)) GtkEntry *entry, GdkEventKey *event, GtkDialog *dialog) { +static gboolean search_key_press_cb(GtkEntry *entry, GdkEventKey *event, search_panel_info *info) { if (event->keyval == GDK_KEY_Return) { - gtk_dialog_response(dialog, GTK_RESPONSE_ACCEPT); + search(VTE_TERMINAL(info->vte), gtk_entry_get_text(GTK_ENTRY(entry)), info->reverse); + gtk_widget_hide(GTK_WIDGET(info->panel)); return TRUE; } return FALSE; } -static void open_search_dialog(GtkWidget *vte, bool reverse, search_dialog_info *info) { - info->reverse = reverse; - - if (info->open) { - return; - } - - info->open = true; - info->entry = gtk_entry_new(); - - GtkWidget *dialog, *content_area; - dialog = gtk_dialog_new_with_buttons("Search", - GTK_WINDOW(gtk_widget_get_toplevel(vte)), - GTK_DIALOG_DESTROY_WITH_PARENT, - NULL, - NULL); - - g_signal_connect(dialog, "response", G_CALLBACK(search_response_cb), info); - g_signal_connect(info->entry, "key-press-event", G_CALLBACK(search_key_press_cb), dialog); - - content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - gtk_container_add(GTK_CONTAINER(content_area), info->entry); - gtk_widget_show_all(dialog); - gtk_widget_grab_focus(GTK_WIDGET(info->entry)); -} - -static gboolean key_press_cb(GtkWidget *vte, GdkEventKey *event, search_dialog_info *info) { +static gboolean key_press_cb(GtkWidget *vte, GdkEventKey *event, search_panel_info *info) { const GdkModifierType modifiers = event->state & gtk_accelerator_get_default_mod_mask(); if (modifiers == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) { switch (gdk_keyval_to_lower(event->keyval)) { @@ -95,10 +61,12 @@ static gboolean key_press_cb(GtkWidget *vte, GdkEventKey *event, search_dialog_i vte_terminal_copy_primary(VTE_TERMINAL(vte)); return TRUE; case KEY(KEY_SEARCH): - open_search_dialog(vte, false, info); + info->reverse = false; + gtk_widget_show(GTK_WIDGET(info->panel)); return TRUE; case KEY(KEY_RSEARCH): - open_search_dialog(vte, true, info); + info->reverse = true; + gtk_widget_show(GTK_WIDGET(info->panel)); return TRUE; case KEY(KEY_URL): search(VTE_TERMINAL(vte), url_regex, false); @@ -164,7 +132,7 @@ static void window_title_cb(VteTerminal *vte, GtkWindow *window) { } #endif -static gboolean position_overlay(GtkOverlay *overlay, GtkWidget *widget, GdkRectangle *alloc) { +static gboolean position_overlay_cb(GtkOverlay *overlay, GtkWidget *widget, GdkRectangle *alloc) { GtkWidget *main_widget = gtk_bin_get_child(GTK_BIN(overlay)); GtkAllocation main_alloc; @@ -251,16 +219,29 @@ int main(int argc, char **argv) { return 1; } - gtk_container_add(GTK_CONTAINER(overlay), vte); - gtk_container_add(GTK_CONTAINER(window), overlay); + GtkWidget *alignment = gtk_alignment_new(0, 0, 1, 1); + gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 5, 5, 5, 5); + gtk_overlay_add_overlay(GTK_OVERLAY(overlay), alignment); GtkWidget *entry = gtk_entry_new(); gtk_widget_set_halign(entry, GTK_ALIGN_START); gtk_widget_set_valign(entry, GTK_ALIGN_END); - gtk_overlay_add_overlay(GTK_OVERLAY(overlay), entry); - g_signal_connect(vte, "child-exited", G_CALLBACK(gtk_main_quit), NULL); - g_signal_connect(overlay, "get-child-position", G_CALLBACK(position_overlay), NULL); + gtk_container_add(GTK_CONTAINER(alignment), entry); + gtk_container_add(GTK_CONTAINER(overlay), vte); + gtk_container_add(GTK_CONTAINER(window), overlay); + + search_panel_info info = { + .vte = vte, + .panel = GTK_BIN(alignment), + .reverse = false + }; + + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(vte, "child-exited", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(vte, "key-press-event", G_CALLBACK(key_press_cb), &info); + g_signal_connect(entry, "key-press-event", G_CALLBACK(search_key_press_cb), &info); + g_signal_connect(overlay, "get-child-position", G_CALLBACK(position_overlay_cb), NULL); vte_terminal_set_scrollback_lines(VTE_TERMINAL(vte), scrollback_lines); vte_terminal_set_font_from_string(VTE_TERMINAL(vte), font); @@ -301,11 +282,6 @@ int main(int argc, char **argv) { vte_terminal_set_colors(VTE_TERMINAL(vte), &foreground, &background, palette, 16); - search_dialog_info info = { .vte = vte, .open = false }; - - g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); - g_signal_connect(vte, "key-press-event", G_CALLBACK(key_press_cb), &info); - #ifdef CLICKABLE_URL int tmp = vte_terminal_match_add_gregex(VTE_TERMINAL(vte), g_regex_new(url_regex, @@ -329,6 +305,7 @@ int main(int argc, char **argv) { gtk_widget_grab_focus(vte); gtk_widget_show_all(window); + gtk_widget_hide(alignment); gtk_main(); return 0; } From 1b2e2a16970257dec31340d37eceb2284123d46e Mon Sep 17 00:00:00 2001 From: Simon Gomizelj Date: Thu, 31 May 2012 21:49:06 -0400 Subject: [PATCH 3/6] Use gtk_widget_grab_focus to deal with the focus issues. --- termite.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/termite.c b/termite.c index b932fcb..5a85fc4 100644 --- a/termite.c +++ b/termite.c @@ -15,6 +15,7 @@ typedef struct search_panel_info { GtkWidget *vte; + GtkWidget *entry; GtkBin *panel; bool reverse; } search_panel_info; @@ -37,6 +38,7 @@ static gboolean search_key_press_cb(GtkEntry *entry, GdkEventKey *event, search_ if (event->keyval == GDK_KEY_Return) { search(VTE_TERMINAL(info->vte), gtk_entry_get_text(GTK_ENTRY(entry)), info->reverse); gtk_widget_hide(GTK_WIDGET(info->panel)); + gtk_widget_grab_focus(info->vte); return TRUE; } return FALSE; @@ -63,10 +65,12 @@ static gboolean key_press_cb(GtkWidget *vte, GdkEventKey *event, search_panel_in case KEY(KEY_SEARCH): info->reverse = false; gtk_widget_show(GTK_WIDGET(info->panel)); + gtk_widget_grab_focus(info->entry); return TRUE; case KEY(KEY_RSEARCH): info->reverse = true; gtk_widget_show(GTK_WIDGET(info->panel)); + gtk_widget_grab_focus(info->entry); return TRUE; case KEY(KEY_URL): search(VTE_TERMINAL(vte), url_regex, false); @@ -233,6 +237,7 @@ int main(int argc, char **argv) { search_panel_info info = { .vte = vte, + .entry = entry, .panel = GTK_BIN(alignment), .reverse = false }; From a20410085683b4355992a77b219e729da277d352 Mon Sep 17 00:00:00 2001 From: Simon Gomizelj Date: Thu, 31 May 2012 22:27:10 -0400 Subject: [PATCH 4/6] Make the escape key hide the overlay again. --- termite.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/termite.c b/termite.c index 5a85fc4..c787a93 100644 --- a/termite.c +++ b/termite.c @@ -35,13 +35,20 @@ static void search(VteTerminal *vte, const char *pattern, bool reverse) { } static gboolean search_key_press_cb(GtkEntry *entry, GdkEventKey *event, search_panel_info *info) { - if (event->keyval == GDK_KEY_Return) { + gboolean ret = FALSE; + + if (event->keyval == GDK_KEY_Escape) { + ret = TRUE; + } else if (event->keyval == GDK_KEY_Return) { search(VTE_TERMINAL(info->vte), gtk_entry_get_text(GTK_ENTRY(entry)), info->reverse); + ret = TRUE; + } + + if (ret) { gtk_widget_hide(GTK_WIDGET(info->panel)); gtk_widget_grab_focus(info->vte); - return TRUE; } - return FALSE; + return ret; } static gboolean key_press_cb(GtkWidget *vte, GdkEventKey *event, search_panel_info *info) { From 578856ed9ed57ac9fa5e96dbeb99dd12a37d4571 Mon Sep 17 00:00:00 2001 From: Simon Gomizelj Date: Thu, 31 May 2012 22:27:24 -0400 Subject: [PATCH 5/6] Fix the overlay's position a set offset. 40 pixels from the right edge of the screen. --- termite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/termite.c b/termite.c index c787a93..2d04c88 100644 --- a/termite.c +++ b/termite.c @@ -155,7 +155,7 @@ static gboolean position_overlay_cb(GtkOverlay *overlay, GtkWidget *widget, GdkR GtkRequisition req; gtk_widget_get_preferred_size(widget, NULL, &req); - alloc->x = 2 * main_alloc.width / 3 - req.width / 2; + alloc->x = main_alloc.width - req.width - 40; alloc->y = 0; alloc->width = MIN(main_alloc.width, req.width); alloc->height = MIN(main_alloc.height, req.height); From 423537b97fc488b35c115c428439a41a43d5d699 Mon Sep 17 00:00:00 2001 From: Simon Gomizelj Date: Thu, 31 May 2012 22:31:15 -0400 Subject: [PATCH 6/6] Clean up position_overlay_cb. --- termite.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/termite.c b/termite.c index 2d04c88..70d19c4 100644 --- a/termite.c +++ b/termite.c @@ -144,21 +144,18 @@ static void window_title_cb(VteTerminal *vte, GtkWindow *window) { #endif static gboolean position_overlay_cb(GtkOverlay *overlay, GtkWidget *widget, GdkRectangle *alloc) { - GtkWidget *main_widget = gtk_bin_get_child(GTK_BIN(overlay)); + GtkWidget *vte = gtk_bin_get_child(GTK_BIN(overlay)); - GtkAllocation main_alloc; - main_alloc.x = 0; - main_alloc.y = 0; - main_alloc.width = gtk_widget_get_allocated_width(main_widget); - main_alloc.height = gtk_widget_get_allocated_height(main_widget); + int width = gtk_widget_get_allocated_width(vte); + int height = gtk_widget_get_allocated_height(vte); GtkRequisition req; gtk_widget_get_preferred_size(widget, NULL, &req); - alloc->x = main_alloc.width - req.width - 40; + alloc->x = width - req.width - 40; alloc->y = 0; - alloc->width = MIN(main_alloc.width, req.width); - alloc->height = MIN(main_alloc.height, req.height); + alloc->width = MIN(width, req.width); + alloc->height = MIN(height, req.height); return TRUE; }