[Xfce4-commits] <thunar:master> Create pull-down history buttons and remove arrows.
Nick Schermer
noreply at xfce.org
Wed Oct 24 21:06:01 CEST 2012
Updating branch refs/heads/master
to 7df35529827eda827755df91600c86eaffabcc07 (commit)
from 2259bddaf7f3ebac98b38cdca709463a7ebf3f33 (commit)
commit 7df35529827eda827755df91600c86eaffabcc07
Author: Nick Schermer <nick at xfce.org>
Date: Wed Oct 24 21:03:56 2012 +0200
Create pull-down history buttons and remove arrows.
This is common for most users since web browsers do the same.
You can popup the menu with a right-click, hold for 500ms or
pull-down (click and drag downwards).
thunar/thunar-history-action.c | 219 +++++++++++++++++++++++++++++++++++++---
1 files changed, 205 insertions(+), 14 deletions(-)
diff --git a/thunar/thunar-history-action.c b/thunar/thunar-history-action.c
index f4a613e..148b918 100644
--- a/thunar/thunar-history-action.c
+++ b/thunar/thunar-history-action.c
@@ -28,7 +28,9 @@
static GtkWidget *thunar_history_action_create_tool_item (GtkAction *action);
static void thunar_history_action_show_menu (GtkWidget *tool_item,
- ThunarHistoryAction *history_action);
+ ThunarHistoryAction *history_action,
+ guint button,
+ guint32 timestamp);
@@ -40,6 +42,8 @@ struct _ThunarHistoryActionClass
struct _ThunarHistoryAction
{
GtkAction __parent__;
+
+ guint popup_delay;
};
@@ -79,20 +83,169 @@ thunar_history_action_init (ThunarHistoryAction *actions_changed)
+static gboolean
+thunar_history_action_popup_delayed (gpointer data)
+{
+ GtkWidget *button = GTK_WIDGET (data);
+ ThunarHistoryAction *history_action;
+
+ history_action = g_object_get_data (G_OBJECT (button), I_("thunar-history-action"));
+
+ GDK_THREADS_ENTER ();
+ thunar_history_action_show_menu (button, history_action, 3, 0);
+ GDK_THREADS_LEAVE ();
+
+ history_action->popup_delay = 0;
+
+ return FALSE;
+}
+
+
+
+static gboolean
+thunar_history_action_button_press_event (GtkWidget *toggle_button,
+ GdkEventButton *event,
+ GtkWidget *tool_item)
+{
+ ThunarHistoryAction *history_action;
+
+ _thunar_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
+ _thunar_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
+
+ history_action = g_object_get_data (G_OBJECT (toggle_button), I_("thunar-history-action"));
+
+ if (event->button == 1)
+ {
+ /* shouldn't happen, but stop pending timeout */
+ if (history_action->popup_delay != 0)
+ g_source_remove (history_action->popup_delay);
+
+ /* schedule a popup for button press */
+ history_action->popup_delay = g_timeout_add (500, thunar_history_action_popup_delayed, toggle_button);
+ }
+ else if (event->button == 3)
+ {
+ /* directy show the menu */
+ thunar_history_action_show_menu (toggle_button, history_action,
+ event->button, event->time);
+ }
+
+ return FALSE;
+}
+
+
+
+static gboolean
+thunar_history_action_button_release_event (GtkWidget *toggle_button,
+ GdkEventButton *event,
+ GtkWidget *tool_item)
+{
+ ThunarHistoryAction *history_action;
+
+ _thunar_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
+ _thunar_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
+
+ if (event->button == 1)
+ {
+ history_action = g_object_get_data (G_OBJECT (toggle_button), I_("thunar-history-action"));
+ if (history_action->popup_delay != 0)
+ {
+ /* stop timeout */
+ g_source_remove (history_action->popup_delay);
+ history_action->popup_delay = 0;
+
+ /* activate event */
+ gtk_action_activate (GTK_ACTION (history_action));
+ }
+ }
+
+ /* bit of a strange trick to get the button untoggeled */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button),
+ gtk_widget_is_sensitive (toggle_button));
+
+ return FALSE;
+}
+
+
+
+static gboolean
+thunar_history_action_leave_notify_event (GtkWidget *toggle_button,
+ GdkEventCrossing *event,
+ ThunarHistoryAction *history_action)
+{
+
+ GtkAllocation alloc;
+
+ _thunar_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
+ _thunar_return_val_if_fail (THUNAR_IS_HISTORY_ACTION (history_action), FALSE);
+
+ if (history_action->popup_delay != 0)
+ {
+ /* stop the timeout */
+ g_source_remove (history_action->popup_delay);
+ history_action->popup_delay = 0;
+
+ /* if the user dragged to the bottom, directly popup the menu */
+ gtk_widget_get_allocation (toggle_button, &alloc);
+ if (event->x >= 0
+ && event->x < alloc.width
+ && event->y >= alloc.height)
+ {
+ thunar_history_action_show_menu (toggle_button, history_action,
+ 3, event->time);
+ }
+ }
+
+ return FALSE;
+}
+
+
+
+static void
+thunar_history_action_activate (GtkWidget *toggle_button,
+ ThunarHistoryAction *history_action)
+{
+ _thunar_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+ _thunar_return_if_fail (THUNAR_IS_HISTORY_ACTION (history_action));
+
+ /* activate event (only key events trigger this function) */
+ gtk_action_activate (GTK_ACTION (history_action));
+
+ /* activate, so the code deactivates a bit later... */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), TRUE);
+}
+
+
+
static GtkWidget*
thunar_history_action_create_tool_item (GtkAction *action)
{
GtkWidget *tool_item;
+ GtkWidget *button;
+ GtkWidget *icon;
_thunar_return_val_if_fail (THUNAR_IS_HISTORY_ACTION (action), NULL);
/* allocate the tool item with an empty menu */
- tool_item = g_object_new (GTK_TYPE_MENU_TOOL_BUTTON,
- "menu", gtk_menu_new (),
- NULL);
+ tool_item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
+ gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
+
+ button = gtk_toggle_button_new ();
+ gtk_container_add (GTK_CONTAINER (tool_item), button);
+ gtk_button_set_relief (GTK_BUTTON (button), gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (tool_item)));
+ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
+ gtk_widget_show (button);
+
+ icon = gtk_image_new_from_stock (gtk_action_get_stock_id (action), gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (tool_item)));
+ gtk_container_add (GTK_CONTAINER (button), icon);
+ gtk_widget_show (icon);
+
+ g_object_set_data (G_OBJECT (button), I_("thunar-history-action"), action);
- /* be sure to be informed before the menu is shown */
- g_signal_connect (G_OBJECT (tool_item), "show-menu", G_CALLBACK (thunar_history_action_show_menu), action);
+ g_signal_connect (G_OBJECT (button), "button-press-event", G_CALLBACK (thunar_history_action_button_press_event), tool_item);
+ g_signal_connect (G_OBJECT (button), "button-release-event", G_CALLBACK (thunar_history_action_button_release_event), tool_item);
+ g_signal_connect (G_OBJECT (button), "leave-notify-event", G_CALLBACK (thunar_history_action_leave_notify_event), action);
+ g_signal_connect (G_OBJECT (button), "activate", G_CALLBACK (thunar_history_action_activate), action);
return tool_item;
}
@@ -100,25 +253,63 @@ thunar_history_action_create_tool_item (GtkAction *action)
static void
-thunar_history_action_show_menu (GtkWidget *tool_item,
- ThunarHistoryAction *history_action)
+thunar_history_action_position_menu (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+ GtkWidget *button = GTK_WIDGET (user_data);
+ GtkAllocation alloc;
+
+ gdk_window_get_origin (gtk_widget_get_window (button), x, y);
+
+ gtk_widget_get_allocation (button, &alloc);
+ *x += alloc.x;
+ *y += alloc.y + alloc.height;
+ *push_in = FALSE;
+}
+
+
+
+static void
+thunar_history_action_menu_deactivate (GtkWidget *toggle_button)
+{
+ /* untoggle the button */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), FALSE);
+}
+
+
+
+static void
+thunar_history_action_show_menu (GtkWidget *toggle_button,
+ ThunarHistoryAction *history_action,
+ guint button,
+ guint32 timestamp)
{
GtkWidget *menu;
- _thunar_return_if_fail (GTK_IS_MENU_TOOL_BUTTON (tool_item));
+ _thunar_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
_thunar_return_if_fail (THUNAR_IS_HISTORY_ACTION (history_action));
/* allocate a new menu for the action */
menu = gtk_menu_new ();
-
- /* setup the appropriate screen for the menu */
- gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (tool_item));
+ gtk_menu_attach_to_widget (GTK_MENU (menu), toggle_button, NULL);
+ g_signal_connect_swapped (G_OBJECT (menu), "deactivate",
+ G_CALLBACK (thunar_history_action_menu_deactivate), toggle_button);
/* generate the menu items */
g_signal_emit_by_name (G_OBJECT (history_action), "show-menu", menu);
- /* setup the menu for the tool item */
- gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), menu);
+ /* toggle the button */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), TRUE);
+
+ /* show menu */
+ gtk_menu_popup (GTK_MENU (menu),
+ NULL, NULL,
+ thunar_history_action_position_menu, toggle_button,
+ button,
+ timestamp ? timestamp : gtk_get_current_event_time ());
}
More information about the Xfce4-commits
mailing list