]> spindle.queued.net Git - midori/commitdiff
Implement proper menu positioning.
authorPrzemek Sitek <el.pescado@gazeta.pl>
Sat, 29 Mar 2008 21:38:59 +0000 (22:38 +0100)
committerChristian Dywan <christian@twotoasts.de>
Sat, 29 Mar 2008 21:38:59 +0000 (22:38 +0100)
Menu position is computed according to the widget position
and size as well as a hint indicating alignment to the
mouse pointer, left or right.

src/midori-browser.c
src/midori-webview.c
src/sokoke.c
src/sokoke.h
src/webSearch.c

index fd35e65872a8557e1885db51b5d03e1141766f76..2aa20f575b37239c047ef088ad527291d4add443 100644 (file)
@@ -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
index 2e1d299f051bff9f8f2eb55f3e29b208faafd23b..14fcec6212878f4599fa7fce7941994545c06e64 100644 (file)
@@ -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);
index 7f681996a908e5dcdb893412fefb029b53173dd1..41272465103531a1b26c1d34f2319b37b352cf00 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
 
  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)
index 74e751be2f3fd6824a4998ed0379aa7f8075533d..4424ea401113cbf4629a42cff874ed819c79518b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
 // 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*);
index 1f4d4f48b0f06e0131d710c923c8e366c1c70fac..c918953c22ffab87fa53d1182e22cf30f10d8b21 100644 (file)
@@ -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