diff --git a/src/midori-browser.c b/src/midori-browser.c index fd35e658..2aa20f57 100644 --- a/src/midori-browser.c +++ b/src/midori-browser.c @@ -865,7 +865,8 @@ midori_browser_menu_trash_activate_cb (GtkWidget* widget, menuitem = gtk_action_create_menu_item (action); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_widget_show (menuitem); - sokoke_widget_popup (widget, GTK_MENU (menu), NULL); + sokoke_widget_popup (widget, GTK_MENU (menu), NULL, + SOKOKE_MENU_POSITION_RIGHT); } static void @@ -1310,7 +1311,8 @@ _midori_panel_bookmarks_popup (GtkWidget* widget, _action_set_sensitive (browser, "BookmarkOpenTab", is_bookmark); _action_set_sensitive (browser, "BookmarkOpenWindow", is_bookmark); - sokoke_widget_popup (widget, GTK_MENU (priv->popup_bookmark), event); + sokoke_widget_popup (widget, GTK_MENU (priv->popup_bookmark), + event, SOKOKE_MENU_POSITION_CURSOR); } static gboolean @@ -1471,7 +1473,8 @@ midori_browser_bookmarkbar_folder_activate_cb (GtkToolItem* toolitem, // FIXME: We really *should* run the line below, but it won't work like that /*g_signal_connect (menu, "hide", G_CALLBACK (gtk_container_foreach), gtk_widget_destroy);*/ - sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu), NULL); + sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu), + NULL, SOKOKE_MENU_POSITION_LEFT); } static void diff --git a/src/midori-webview.c b/src/midori-webview.c index 2e1d299f..14fcec62 100644 --- a/src/midori-webview.c +++ b/src/midori-webview.c @@ -923,7 +923,7 @@ midori_web_view_get_proxy_tab_label (MidoriWebView* web_view) priv->tab_label = gtk_label_new (title); gtk_misc_set_alignment (GTK_MISC (priv->tab_label), 0.0, 0.5); // TODO: make the tab initially look "unvisited" until it's focused - gtk_box_pack_start (GTK_BOX (hbox), priv->tab_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), priv->tab_label, FALSE, TRUE, 0); priv->proxy_tab_label = event_box; _midori_web_view_update_tab_label_size (web_view); @@ -936,7 +936,7 @@ midori_web_view_get_proxy_tab_label (MidoriWebView* web_view) GtkWidget* image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); gtk_button_set_image (GTK_BUTTON(close_button), image); - gtk_box_pack_start (GTK_BOX (hbox), close_button, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0); gtk_widget_show_all (GTK_WIDGET (event_box)); if (!priv->close_button) gtk_widget_hide (close_button); diff --git a/src/sokoke.c b/src/sokoke.c index 7f681996..41272465 100644 --- a/src/sokoke.c +++ b/src/sokoke.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Christian Dywan + Copyright (C) 2007-2008 Christian Dywan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -69,12 +69,65 @@ void sokoke_tool_item_set_tooltip_text(GtkToolItem* toolitem, const gchar* text) gtk_tool_item_set_tooltip(toolitem, tooltips, text, NULL); } -void sokoke_widget_popup(GtkWidget* widget, GtkMenu* menu - , GdkEventButton* event) +typedef struct +{ + GtkWidget* widget; + SokokeMenuPos position; +} SokokePopupInfo; + +static void +sokoke_widget_popup_position_menu (GtkMenu* menu, + gint* x, + gint* y, + gboolean* push_in, + gpointer user_data) +{ + gint wx, wy; + gint menu_width; + GtkRequisition menu_req; + GtkRequisition widget_req; + SokokePopupInfo* info = user_data; + GtkWidget* widget = info->widget; + + // Retrieve size and position of both widget and menu + if (GTK_WIDGET_NO_WINDOW (widget)) + { + gdk_window_get_position (widget->window, &wx, &wy); + wx += widget->allocation.x; + wy += widget->allocation.y; + } + else + gdk_window_get_origin (widget->window, &wx, &wy); + gtk_widget_size_request (GTK_WIDGET (menu), &menu_req); + gtk_widget_size_request (widget, &widget_req); + menu_width = menu_req.width; + gint widget_height = widget_req.height; // Better than allocation.height + + // Calculate menu position + if (info->position == SOKOKE_MENU_POSITION_CURSOR) + ; // Do nothing? + else if (info->position == SOKOKE_MENU_POSITION_RIGHT) + { + *x = wx + widget->allocation.width - menu_width; + *y = wy + widget_height; + } else if (info->position == SOKOKE_MENU_POSITION_LEFT) + { + *x = wx; + *y = wy + widget_height; + } + + *push_in = TRUE; +} + + +void +sokoke_widget_popup (GtkWidget* widget, + GtkMenu* menu, + GdkEventButton* event, + SokokeMenuPos pos) { - // TODO: Provide a GtkMenuPositionFunc in case a keyboard invoked this int button, event_time; - if(event) + if (event) { button = event->button; event_time = event->time; @@ -82,19 +135,28 @@ void sokoke_widget_popup(GtkWidget* widget, GtkMenu* menu else { button = 0; - event_time = gtk_get_current_event_time(); + event_time = gtk_get_current_event_time (); } - if(!gtk_menu_get_attach_widget(menu)) - gtk_menu_attach_to_widget(menu, widget, NULL); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, button, event_time); + if (!gtk_menu_get_attach_widget(menu)) + gtk_menu_attach_to_widget (menu, widget, NULL); + + if (widget) + { + SokokePopupInfo info = { widget, pos }; + gtk_menu_popup (menu, NULL, NULL, + sokoke_widget_popup_position_menu, &info, + button, event_time); + } + else + gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, event_time); } typedef enum { - SOKOKE_DESKTOP_UNTESTED, - SOKOKE_DESKTOP_XFCE, - SOKOKE_DESKTOP_UNKNOWN + SOKOKE_DESKTOP_UNTESTED, + SOKOKE_DESKTOP_XFCE, + SOKOKE_DESKTOP_UNKNOWN } SokokeDesktop; static SokokeDesktop sokoke_get_desktop(void) diff --git a/src/sokoke.h b/src/sokoke.h index 74e751be..4424ea40 100644 --- a/src/sokoke.h +++ b/src/sokoke.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Christian Dywan + Copyright (C) 2007-2008 Christian Dywan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -17,6 +17,12 @@ // Many themes need this hack for small toolbars to work #define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON +typedef enum { + SOKOKE_MENU_POSITION_CURSOR = 0, + SOKOKE_MENU_POSITION_LEFT, + SOKOKE_MENU_POSITION_RIGHT +} SokokeMenuPos; + void sokoke_combo_box_add_strings(GtkComboBox*, const gchar*, ...); @@ -33,7 +39,7 @@ void sokoke_tool_item_set_tooltip_text(GtkToolItem*, const gchar*); void -sokoke_widget_popup(GtkWidget*, GtkMenu*, GdkEventButton*); +sokoke_widget_popup(GtkWidget*, GtkMenu*, GdkEventButton*, SokokeMenuPos pos); gpointer sokoke_xfce_header_new(const gchar*, const gchar*); diff --git a/src/webSearch.c b/src/webSearch.c index 1f4d4f48..c918953c 100644 --- a/src/webSearch.c +++ b/src/webSearch.c @@ -93,7 +93,8 @@ void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos menuitem = gtk_action_create_menu_item(action); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); gtk_widget_show(menuitem);*/ - sokoke_widget_popup(widget, GTK_MENU(menu), NULL); + sokoke_widget_popup(widget, GTK_MENU(menu), + NULL, SOKOKE_MENU_POSITION_LEFT); } static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column