Implement proper menu positioning.
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.
This commit is contained in:
parent
173b05dd78
commit
b01eb78c9d
5 changed files with 92 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
86
src/sokoke.c
86
src/sokoke.c
|
@ -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)
|
||||
|
|
10
src/sokoke.h
10
src/sokoke.h
|
@ -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
|
||||
|
@ -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*);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue