From a98003674be06798ad4e7a6c59b99ee8674ea1fe Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 9 May 2020 19:38:26 +0100 Subject: GTK: Add transient popup behaviour for local history too Signed-off-by: Daniel Silverstone --- frontends/gtk/local_history.c | 35 ++++++++++++++++++- frontends/gtk/local_history.h | 5 +++ frontends/gtk/res/localhistory.gtk2.ui | 1 + frontends/gtk/res/localhistory.gtk3.ui | 1 + frontends/gtk/scaffolding.c | 6 ++++ frontends/gtk/scaffolding.h | 7 ++++ frontends/gtk/toolbar.c | 64 ++++++++++++++++++++++++++++++---- frontends/gtk/toolbar.h | 6 ++++ frontends/gtk/window.c | 6 ++++ frontends/gtk/window.h | 7 ++++ 10 files changed, 131 insertions(+), 7 deletions(-) (limited to 'frontends') diff --git a/frontends/gtk/local_history.c b/frontends/gtk/local_history.c index 010fa3126..0d59c468a 100644 --- a/frontends/gtk/local_history.c +++ b/frontends/gtk/local_history.c @@ -35,6 +35,7 @@ #include "gtk/resources.h" #include "gtk/corewindow.h" #include "gtk/local_history.h" +#include "gtk/scaffolding.h" struct nsgtk_local_history_window { struct nsgtk_corewindow core; @@ -158,6 +159,12 @@ nsgtk_local_history_init(struct browser_window *bw, ncwin->wnd = GTK_WINDOW(gtk_builder_get_object(ncwin->builder, "wndHistory")); + /* Configure for transient behaviour */ + gtk_window_set_type_hint(GTK_WINDOW(ncwin->wnd), + GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU); + gtk_window_set_modal(GTK_WINDOW(ncwin->wnd), TRUE); + + ncwin->core.scrolled = GTK_SCROLLED_WINDOW( gtk_builder_get_object(ncwin->builder, "HistoryScrolled")); @@ -171,6 +178,16 @@ nsgtk_local_history_init(struct browser_window *bw, "delete_event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); + /* Ditto if we lose the grab */ + g_signal_connect(G_OBJECT(ncwin->wnd), + "grab-broken-event", + G_CALLBACK(gtk_widget_hide_on_delete), + ncwin); + /* Handle button press events */ + g_signal_connect(G_OBJECT(ncwin->wnd), + "button-press-event", + G_CALLBACK(gtk_widget_hide_on_delete), + ncwin); ncwin->core.draw = nsgtk_local_history_draw; ncwin->core.key = nsgtk_local_history_key; @@ -206,7 +223,11 @@ nserror nsgtk_local_history_present(GtkWindow *parent, int width, height; res = nsgtk_local_history_init(bw, &local_history_window); if (res == NSERROR_OK) { + gtk_window_group_add_window(gtk_window_get_group(parent), + local_history_window->wnd); gtk_window_set_transient_for(local_history_window->wnd, parent); + gtk_window_set_screen(local_history_window->wnd, + gtk_widget_get_screen(GTK_WIDGET(parent))); gtk_window_get_size(parent, &prnt_width, &prnt_height); @@ -224,7 +245,11 @@ nserror nsgtk_local_history_present(GtkWindow *parent, } gtk_window_resize(local_history_window->wnd, width, height); - gtk_window_present(local_history_window->wnd); + /* Attempt to place the window in the right place */ + nsgtk_scaffolding_position_local_history(nsgtk_current_scaffolding()); + + gtk_widget_show(GTK_WIDGET(local_history_window->wnd)); + gtk_widget_grab_focus(GTK_WIDGET(local_history_window->wnd)); local_history_scroll_to_cursor(local_history_window->session); } @@ -269,3 +294,11 @@ nserror nsgtk_local_history_destroy(void) return res; } + +/* exported function documented gtk/history.h */ +void nsgtk_local_history_set_position(int x, int y) +{ + NSLOG(netsurf, INFO, "x=%d y=%d", x, y); + + gtk_window_move(local_history_window->wnd, x, y); +} diff --git a/frontends/gtk/local_history.h b/frontends/gtk/local_history.h index 605405ddf..c5b447194 100644 --- a/frontends/gtk/local_history.h +++ b/frontends/gtk/local_history.h @@ -33,6 +33,11 @@ struct browser_window; */ nserror nsgtk_local_history_present(GtkWindow *parent, struct browser_window *bw); +/** + * set the local history window position. + */ +void nsgtk_local_history_set_position(int x, int y); + /** * hide the local history window from being visible. * diff --git a/frontends/gtk/res/localhistory.gtk2.ui b/frontends/gtk/res/localhistory.gtk2.ui index 9512b6289..2003ed69a 100644 --- a/frontends/gtk/res/localhistory.gtk2.ui +++ b/frontends/gtk/res/localhistory.gtk2.ui @@ -2,6 +2,7 @@ + GTK_WINDOW_POPUP False NetSurf Local History center diff --git a/frontends/gtk/res/localhistory.gtk3.ui b/frontends/gtk/res/localhistory.gtk3.ui index 0e2bedbac..9a36a91a7 100644 --- a/frontends/gtk/res/localhistory.gtk3.ui +++ b/frontends/gtk/res/localhistory.gtk3.ui @@ -2,6 +2,7 @@ + GTK_WINDOW_POPUP False NetSurf Local History center diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c index 0c8fd333d..c35eef921 100644 --- a/frontends/gtk/scaffolding.c +++ b/frontends/gtk/scaffolding.c @@ -1581,3 +1581,9 @@ nserror nsgtk_scaffolding_position_page_info(struct nsgtk_scaffolding *gs, { return nsgtk_window_position_page_info(gs->top_level, win); } + +/* exported interface documented in gtk/scaffolding.h */ +nserror nsgtk_scaffolding_position_local_history(struct nsgtk_scaffolding *gs) +{ + return nsgtk_window_position_local_history(gs->top_level); +} diff --git a/frontends/gtk/scaffolding.h b/frontends/gtk/scaffolding.h index 95cd51a2a..87d4f3bd6 100644 --- a/frontends/gtk/scaffolding.h +++ b/frontends/gtk/scaffolding.h @@ -65,6 +65,13 @@ nserror nsgtk_scaffolding_toolbar_context_menu(struct nsgtk_scaffolding *gs); nserror nsgtk_scaffolding_position_page_info(struct nsgtk_scaffolding *gs, struct nsgtk_pi_window *win); +/** + * Position the local-history popup in the right place + * + * \param gs The scaffolding to position relative to + */ +nserror nsgtk_scaffolding_position_local_history(struct nsgtk_scaffolding *gs); + /** * open the burger menu */ diff --git a/frontends/gtk/toolbar.c b/frontends/gtk/toolbar.c index 9a57b67ee..d08973293 100644 --- a/frontends/gtk/toolbar.c +++ b/frontends/gtk/toolbar.c @@ -3800,15 +3800,34 @@ nserror nsgtk_toolbar_update(struct nsgtk_toolbar *tb) return res; } -/* exported interface documented in toolbar.h */ -nserror nsgtk_toolbar_position_page_info(struct nsgtk_toolbar *tb, - struct nsgtk_pi_window *win) +/** + * Find the correct location for popping up a window for the chosen item. + * + * \param tb The toolbar to select from + * \param item_idx The toolbar item to select from + * \param out_x Filled with an appropriate X coordinate + * \param out_y Filled with an appropriate Y coordinate + */ +static nserror +nsgtk_toolbar_get_icon_window_position(struct nsgtk_toolbar *tb, + int item_idx, + int *out_x, + int *out_y) { - struct nsgtk_toolbar_item *item = &tb->items[URL_BAR_ITEM]; - GtkWidget *widget = GTK_WIDGET(gtk_bin_get_child(GTK_BIN(item->button))); + struct nsgtk_toolbar_item *item = &tb->items[item_idx]; + GtkWidget *widget = GTK_WIDGET(item->button); GtkAllocation alloc; gint rootx, rooty, x, y; + switch (item_idx) { + case URL_BAR_ITEM: + widget = GTK_WIDGET(gtk_bin_get_child(GTK_BIN(item->button))); + break; + default: + /* Nothing to do here */ + break; + } + nsgtk_widget_get_allocation(widget, &alloc); if (gtk_widget_translate_coordinates(widget, @@ -3822,7 +3841,40 @@ nserror nsgtk_toolbar_position_page_info(struct nsgtk_toolbar *tb, gtk_window_get_position(GTK_WINDOW(gtk_widget_get_toplevel(widget)), &rootx, &rooty); - nsgtk_page_info_set_position(win, rootx + x + 4, rooty + y + 4); + *out_x = rootx + x + 4; + *out_y = rooty + y + 4; + + return NSERROR_OK; +} + +nserror nsgtk_toolbar_position_page_info(struct nsgtk_toolbar *tb, + struct nsgtk_pi_window *win) +{ + nserror res; + int x, y; + + res = nsgtk_toolbar_get_icon_window_position(tb, URL_BAR_ITEM, &x, &y); + if (res != NSERROR_OK) { + return res; + } + + nsgtk_page_info_set_position(win, x, y); + + return NSERROR_OK; +} + +/* exported interface documented in toolbar.h */ +nserror nsgtk_toolbar_position_local_history(struct nsgtk_toolbar *tb) +{ + nserror res; + int x, y; + + res = nsgtk_toolbar_get_icon_window_position(tb, HISTORY_BUTTON, &x, &y); + if (res != NSERROR_OK) { + return res; + } + + nsgtk_local_history_set_position(x, y); return NSERROR_OK; } diff --git a/frontends/gtk/toolbar.h b/frontends/gtk/toolbar.h index 15740b52b..4ecca9f02 100644 --- a/frontends/gtk/toolbar.h +++ b/frontends/gtk/toolbar.h @@ -126,6 +126,12 @@ nserror nsgtk_toolbar_show(struct nsgtk_toolbar *tb, bool show); nserror nsgtk_toolbar_position_page_info(struct nsgtk_toolbar *tb, struct nsgtk_pi_window *win); +/** + * position the local history window appropriately + * + * \param tb The toolbar to position relative to + */ +nserror nsgtk_toolbar_position_local_history(struct nsgtk_toolbar *tb); /** * Initialise customization of toolbar entries diff --git a/frontends/gtk/window.c b/frontends/gtk/window.c index 601177d6f..f0a53a66f 100644 --- a/frontends/gtk/window.c +++ b/frontends/gtk/window.c @@ -1684,3 +1684,9 @@ nserror nsgtk_window_position_page_info(struct gui_window *gw, { return nsgtk_toolbar_position_page_info(gw->toolbar, win); } + +/* exported interface documented in window.h */ +nserror nsgtk_window_position_local_history(struct gui_window *gw) +{ + return nsgtk_toolbar_position_local_history(gw->toolbar); +} diff --git a/frontends/gtk/window.h b/frontends/gtk/window.h index 36166d811..a43e0b197 100644 --- a/frontends/gtk/window.h +++ b/frontends/gtk/window.h @@ -106,4 +106,11 @@ nserror nsgtk_window_item_activate(struct gui_window *gw, nsgtk_toolbar_button i nserror nsgtk_window_position_page_info(struct gui_window *gw, struct nsgtk_pi_window *win); +/** + * position local_history appropriately + * + * \param gw The gui window handle to position relative to + */ +nserror nsgtk_window_position_local_history(struct gui_window *gw); + #endif /* NETSURF_GTK_WINDOW_H */ -- cgit v1.2.3