[gnome-disk-utility/wip/mdraid] Fix menu placement
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility/wip/mdraid] Fix menu placement
- Date: Thu, 20 Sep 2012 20:09:59 +0000 (UTC)
commit ce65865d82dad326c502db435dc04877b893baf2
Author: David Zeuthen <zeuthen gmail com>
Date: Thu Sep 20 16:07:47 2012 -0400
Fix menu placement
This involves using GtkMenuButton and also making it work for
GtkToolButton by implementing a GtkMenuPositionFunc ourselves for the
toolbar case (GtkMenuToolButton contains an extra arrow we do not
want).
Signed-off-by: David Zeuthen <zeuthen gmail com>
data/ui/disks.ui | 3 +-
src/disks/gduwindow.c | 96 ++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 82 insertions(+), 17 deletions(-)
---
diff --git a/data/ui/disks.ui b/data/ui/disks.ui
index b84a48e..7ca32cc 100644
--- a/data/ui/disks.ui
+++ b/data/ui/disks.ui
@@ -596,7 +596,8 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="devtab-drive-generic-button">
+ <object class="GtkMenuButton" id="devtab-drive-generic-button">
+ <property name="menu">generic-drive-menu</property>
<property name="use_action_appearance">False</property>
<property name="related_action">devtab-drive-action-generic</property>
<property name="visible">True</property>
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index 9e54756..04bec2b 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -63,6 +63,8 @@ struct _GduWindow
GtkWidget *volume_grid;
+ GtkWidget *toolbutton_generic_menu;
+
GtkWidget *main_hpane;
GtkWidget *details_notebook;
GtkWidget *device_scrolledwindow;
@@ -154,6 +156,7 @@ static const struct {
goffset offset;
const gchar *name;
} widget_mapping[] = {
+ {G_STRUCT_OFFSET (GduWindow, toolbutton_generic_menu), "toolbutton-generic-menu"},
{G_STRUCT_OFFSET (GduWindow, main_hpane), "main-hpane"},
{G_STRUCT_OFFSET (GduWindow, device_scrolledwindow), "device-tree-scrolledwindow"},
{G_STRUCT_OFFSET (GduWindow, device_toolbar), "device-tree-add-remove-toolbar"},
@@ -335,7 +338,6 @@ static void on_devtab_action_deactivate_swap_activated (GtkAction *action, gpoin
static void on_devtab_drive_action_raid_start_activated (GtkAction *action, gpointer user_data);
static void on_devtab_drive_action_raid_stop_activated (GtkAction *action, gpointer user_data);
static void on_devtab_drive_action_eject_activated (GtkAction *action, gpointer user_data);
-static void on_devtab_drive_action_generic_activated (GtkAction *action, gpointer user_data);
static void on_generic_drive_menu_item_view_smart (GtkMenuItem *menu_item,
gpointer user_data);
@@ -1243,10 +1245,6 @@ gdu_window_constructed (GObject *object)
"activate",
G_CALLBACK (on_devtab_action_deactivate_swap_activated),
window);
- g_signal_connect (window->devtab_drive_action_generic,
- "activate",
- G_CALLBACK (on_devtab_drive_action_generic_activated),
- window);
/* drive actions */
g_signal_connect (window->devtab_drive_action_raid_start,
@@ -3469,25 +3467,91 @@ on_devtab_action_unmount_activated (GtkAction *action,
/* ---------------------------------------------------------------------------------------------------- */
static void
-on_devtab_action_generic_activated (GtkAction *action,
- gpointer user_data)
+generic_menu_position_func (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
{
GduWindow *window = GDU_WINDOW (user_data);
- update_all (window);
- gtk_menu_popup (GTK_MENU (window->generic_menu),
- NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
-}
+ GtkWidget *align_widget;
+ GtkRequisition menu_req;
+ GtkTextDirection direction;
+ GdkRectangle monitor;
+ gint monitor_num;
+ GdkScreen *screen;
+ GdkWindow *gdk_window;
+ GtkAllocation allocation, arrow_allocation;
+ GtkAlign align;
+ GtkWidget *toplevel;
+
+ align_widget = window->toolbutton_generic_menu;
+ align = gtk_widget_get_halign (GTK_WIDGET (menu));
+ direction = gtk_widget_get_direction (align_widget);
+ gdk_window = gtk_widget_get_window (align_widget);
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (menu),
+ &menu_req,
+ NULL);
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (menu));
+ gtk_window_set_type_hint (GTK_WINDOW (toplevel), GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (menu));
+ monitor_num = gdk_screen_get_monitor_at_window (screen, gdk_window);
+ if (monitor_num < 0)
+ monitor_num = 0;
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
+
+ gtk_widget_get_allocation (align_widget, &allocation);
+ gtk_widget_get_allocation (align_widget, &arrow_allocation);
+
+ gdk_window_get_origin (gdk_window, x, y);
+ *x += allocation.x;
+ *y += allocation.y;
+
+ /* treat the default align value like START */
+ if (align == GTK_ALIGN_FILL)
+ align = GTK_ALIGN_START;
+
+ if (align == GTK_ALIGN_CENTER)
+ *x -= (menu_req.width - allocation.width) / 2;
+ else if ((align == GTK_ALIGN_START && direction == GTK_TEXT_DIR_LTR) ||
+ (align == GTK_ALIGN_END && direction == GTK_TEXT_DIR_RTL))
+ *x += MAX (allocation.width - menu_req.width, 0);
+ else if (menu_req.width > allocation.width)
+ *x -= menu_req.width - allocation.width;
+
+ if ((*y + arrow_allocation.height + menu_req.height) <= monitor.y + monitor.height)
+ *y += arrow_allocation.height;
+ else if ((*y - menu_req.height) >= monitor.y)
+ *y -= menu_req.height;
+ else if (monitor.y + monitor.height - (*y + arrow_allocation.height) > *y)
+ *y += arrow_allocation.height;
+ else
+ *y -= menu_req.height;
-/* ---------------------------------------------------------------------------------------------------- */
+ *push_in = FALSE;
+}
static void
-on_devtab_drive_action_generic_activated (GtkAction *action,
- gpointer user_data)
+on_devtab_action_generic_activated (GtkAction *action,
+ gpointer user_data)
{
GduWindow *window = GDU_WINDOW (user_data);
+ GdkEventButton *event = NULL;
+
update_all (window);
- gtk_menu_popup (GTK_MENU (window->generic_drive_menu),
- NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ());
+
+ gtk_menu_popup_for_device (GTK_MENU (window->generic_menu),
+ event != NULL ? event->device : NULL,
+ NULL, /* parent_menu_shell */
+ NULL, /* parent_menu_item */
+ generic_menu_position_func,
+ window,
+ NULL, /* user_data GDestroyNotify */
+ event != NULL ? event->button : 0,
+ event != NULL ? event->time : gtk_get_current_event_time ());
}
/* ---------------------------------------------------------------------------------------------------- */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]