[Xfce4-commits] <thunar:master> Allow scrolling in the 'Open With' combo box (bug #3055).
Jannis Pohlmann
noreply at xfce.org
Sat Nov 13 16:08:01 CET 2010
Updating branch refs/heads/master
to 15db96fff4be9dbc4b45372fda756274eac3e42b (commit)
from a0706b2bd3d05dd076b3c03728cf59f7871d74f7 (commit)
commit 15db96fff4be9dbc4b45372fda756274eac3e42b
Author: Jannis Pohlmann <jannis at xfce.org>
Date: Sat Nov 13 16:04:28 2010 +0100
Allow scrolling in the 'Open With' combo box (bug #3055).
The open with button is now implemented as a subclass of GtkComboBox.
The original patch for this was written by Nick. It had to be rewritten
to apply against the new GIO codebase.
NEWS | 2 +
thunar/thunar-chooser-button.c | 504 +++++++++++++++++++++++-----------------
2 files changed, 289 insertions(+), 217 deletions(-)
diff --git a/NEWS b/NEWS
index 82e0d2d..dfe2a81 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@
- Make .desktop entries installed by Thunar validate against
desktop-file-utils 0.16 (bug #6655). Patch by Samuli Suominen.
- Fix missing instruction to load the sendto model (bug #6762).
+- Allow scrolling in the 'Open With' combo box of the file properties
+ dialog (bug #3055).
1.1.4
=====
diff --git a/thunar/thunar-chooser-button.c b/thunar/thunar-chooser-button.c
index ab8db20..9f9df25 100644
--- a/thunar/thunar-chooser-button.c
+++ b/thunar/thunar-chooser-button.c
@@ -42,57 +42,76 @@ enum
-static void thunar_chooser_button_finalize (GObject *object);
-static void thunar_chooser_button_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void thunar_chooser_button_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void thunar_chooser_button_activate (ThunarChooserButton *chooser_button,
- GtkWidget *item);
-static void thunar_chooser_button_activate_other (ThunarChooserButton *chooser_button);
-static void thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button,
- ThunarFile *file);
-static void thunar_chooser_button_pressed (ThunarChooserButton *chooser_button,
- GtkWidget *button);
+enum
+{
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_NAME,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_ICON,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_APPLICATION,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_SENSITIVE,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_STYLE,
+ THUNAR_CHOOSER_BUTTON_STORE_N_COLUMNS
+};
+
+
+
+static void thunar_chooser_button_finalize (GObject *object);
+static void thunar_chooser_button_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void thunar_chooser_button_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static gboolean thunar_chooser_button_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event);
+static void thunar_chooser_button_changed (GtkComboBox *combo_box);
+static void thunar_chooser_button_popup (ThunarChooserButton *chooser_button);
+static gint thunar_chooser_button_sort_applications (gconstpointer a,
+ gconstpointer b);
+static gboolean thunar_chooser_button_row_separator (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data);
+static void thunar_chooser_button_chooser_dialog (ThunarChooserButton *chooser_button);
+static void thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button,
+ ThunarFile *file);
struct _ThunarChooserButtonClass
{
- GtkHBoxClass __parent__;
+ GtkComboBoxClass __parent__;
};
struct _ThunarChooserButton
{
- GtkHBox __parent__;
+ GtkComboBox __parent__;
- GtkWidget *image;
- GtkWidget *label;
- GtkWidget *button;
-
- ThunarFile *file;
+ GtkListStore *store;
+ ThunarFile *file;
+ gboolean has_default_application;
};
-G_DEFINE_TYPE (ThunarChooserButton, thunar_chooser_button, GTK_TYPE_HBOX)
+G_DEFINE_TYPE (ThunarChooserButton, thunar_chooser_button, GTK_TYPE_COMBO_BOX)
static void
thunar_chooser_button_class_init (ThunarChooserButtonClass *klass)
{
- GObjectClass *gobject_class;
+ GObjectClass *gobject_class;
+ GtkWidgetClass *gtkwidget_class;
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = thunar_chooser_button_finalize;
gobject_class->get_property = thunar_chooser_button_get_property;
gobject_class->set_property = thunar_chooser_button_set_property;
+ gtkwidget_class = GTK_WIDGET_CLASS (klass);
+ gtkwidget_class->scroll_event = thunar_chooser_button_scroll_event;
+
/**
* ThunarChooserButton:file:
*
@@ -111,38 +130,49 @@ thunar_chooser_button_class_init (ThunarChooserButtonClass *klass)
static void
thunar_chooser_button_init (ThunarChooserButton *chooser_button)
{
- GtkWidget *separator;
- GtkWidget *arrow;
- GtkWidget *hbox;
-
- gtk_widget_push_composite_child ();
-
- chooser_button->button = gtk_button_new ();
- g_signal_connect_swapped (G_OBJECT (chooser_button->button), "pressed", G_CALLBACK (thunar_chooser_button_pressed), chooser_button);
- gtk_box_pack_start (GTK_BOX (chooser_button), chooser_button->button, TRUE, TRUE, 0);
- gtk_widget_show (chooser_button->button);
-
- hbox = gtk_hbox_new (FALSE, 4);
- gtk_container_add (GTK_CONTAINER (chooser_button->button), hbox);
- gtk_widget_show (hbox);
-
- chooser_button->image = gtk_image_new ();
- gtk_box_pack_start (GTK_BOX (hbox), chooser_button->image, FALSE, FALSE, 0);
- gtk_widget_show (chooser_button->image);
-
- chooser_button->label = g_object_new (GTK_TYPE_LABEL, "xalign", 0.0f, "yalign", 0.0f, NULL);
- gtk_box_pack_start (GTK_BOX (hbox), chooser_button->label, TRUE, TRUE, 0);
- gtk_widget_show (chooser_button->label);
-
- separator = g_object_new (GTK_TYPE_VSEPARATOR, "height-request", 16, NULL);
- gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0);
- gtk_widget_show (separator);
-
- arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
- gtk_widget_show (arrow);
-
- gtk_widget_pop_composite_child ();
+ GtkCellRenderer *renderer;
+
+ /* allocate a new store for the combo box */
+ chooser_button->store = gtk_list_store_new (THUNAR_CHOOSER_BUTTON_STORE_N_COLUMNS,
+ G_TYPE_STRING,
+ G_TYPE_ICON,
+ G_TYPE_OBJECT,
+ G_TYPE_BOOLEAN,
+ PANGO_TYPE_STYLE);
+ gtk_combo_box_set_model (GTK_COMBO_BOX (chooser_button),
+ GTK_TREE_MODEL (chooser_button->store));
+
+ g_signal_connect (chooser_button, "changed",
+ G_CALLBACK (thunar_chooser_button_changed), NULL);
+ g_signal_connect (chooser_button, "popup",
+ G_CALLBACK (thunar_chooser_button_popup), NULL);
+
+ /* set separator function */
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (chooser_button),
+ thunar_chooser_button_row_separator,
+ NULL, NULL);
+
+ /* add renderer for the application icon */
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (chooser_button), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (chooser_button), renderer,
+ "gicon",
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_ICON,
+ "sensitive",
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_SENSITIVE,
+ NULL);
+
+ /* add renderer for the application name */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (chooser_button), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (chooser_button), renderer,
+ "text",
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_NAME,
+ "sensitive",
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_SENSITIVE,
+ "style",
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_STYLE,
+ NULL);
}
@@ -155,6 +185,9 @@ thunar_chooser_button_finalize (GObject *object)
/* reset the "file" property */
thunar_chooser_button_set_file (chooser_button, NULL);
+ /* release the store */
+ g_object_unref (G_OBJECT (chooser_button->store));
+
(*G_OBJECT_CLASS (thunar_chooser_button_parent_class)->finalize) (object);
}
@@ -204,48 +237,147 @@ thunar_chooser_button_set_property (GObject *object,
+static gboolean
+thunar_chooser_button_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event)
+{
+ ThunarChooserButton *chooser_button = THUNAR_CHOOSER_BUTTON (widget);
+ GtkTreeIter iter;
+ GObject *application;
+ GtkTreeModel *model = GTK_TREE_MODEL (chooser_button->store);
+
+ g_return_val_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button), FALSE);
+
+ /* check if the next application in the store is valid if we scroll down,
+ * else drop the event so we don't popup the chooser dailog */
+ if (event->direction != GDK_SCROLL_UP
+ && gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)
+ && gtk_tree_model_iter_next (model, &iter))
+ {
+ gtk_tree_model_get (model, &iter,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_APPLICATION,
+ &application, -1);
+
+ if (application == NULL)
+ return FALSE;
+
+ g_object_unref (G_OBJECT (application));
+ }
+
+ return (*GTK_WIDGET_CLASS (thunar_chooser_button_parent_class)->scroll_event) (widget, event);
+}
+
+
+
static void
-thunar_chooser_button_activate (ThunarChooserButton *chooser_button,
- GtkWidget *item)
+thunar_chooser_button_changed (GtkComboBox *combo_box)
{
- const gchar *content_type;
- GAppInfo *app_info;
- GError *error = NULL;
+ ThunarChooserButton *chooser_button = THUNAR_CHOOSER_BUTTON (combo_box);
+ GtkTreeIter iter;
+ const gchar *content_type;
+ GAppInfo *app_info;
+ GError *error = NULL;
_thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button));
- _thunar_return_if_fail (GTK_IS_MENU_ITEM (item));
+ _thunar_return_if_fail (GTK_IS_LIST_STORE (chooser_button->store));
/* verify that we still have a valid file */
if (G_UNLIKELY (chooser_button->file == NULL))
return;
- /* determine the application that was set for the item */
- app_info = g_object_get_data (G_OBJECT (item), "app-info");
- if (G_UNLIKELY (app_info == NULL))
+ /* get the selected item in the combo box */
+ if (!gtk_combo_box_get_active_iter (combo_box, &iter))
return;
- /* determine the mime info for the file */
- content_type = thunar_file_get_content_type (chooser_button->file);
+ /* determine the application that was set for the item */
+ gtk_tree_model_get (GTK_TREE_MODEL (chooser_button->store), &iter,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_APPLICATION,
+ &app_info, -1);
- /* try to set application as default for these kind of file */
- if (!g_app_info_set_as_default_for_type (app_info, content_type, &error))
+ if (G_LIKELY (app_info != NULL))
{
- /* tell the user that it didn't work */
- thunar_dialogs_show_error (GTK_WIDGET (chooser_button), error, _("Failed to set default application for \"%s\""),
- thunar_file_get_display_name (chooser_button->file));
- g_error_free (error);
+ /* determine the mime info for the file */
+ content_type = thunar_file_get_content_type (chooser_button->file);
+
+ /* try to set application as default for these kind of file */
+ if (!g_app_info_set_as_default_for_type (app_info, content_type, &error))
+ {
+ /* tell the user that it didn't work */
+ thunar_dialogs_show_error (GTK_WIDGET (chooser_button), error,
+ _("Failed to set default application for \"%s\""),
+ thunar_file_get_display_name (chooser_button->file));
+ g_error_free (error);
+ }
+ else
+ {
+ /* emit "changed" on the file, so everybody updates its state */
+ thunar_file_changed (chooser_button->file);
+ }
+
+ /* release the application */
+ g_object_unref (app_info);
}
else
{
- /* emit "changed" on the file, so everybody updates its state */
- thunar_file_changed (chooser_button->file);
+ /* no application was found in the store, looks like the other... option */
+ thunar_chooser_button_chooser_dialog (chooser_button);
}
}
static void
-thunar_chooser_button_activate_other (ThunarChooserButton *chooser_button)
+thunar_chooser_button_popup (ThunarChooserButton *chooser_button)
+{
+ _thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button));
+
+ if (!chooser_button->has_default_application)
+ {
+ /* don't show the menu */
+ gtk_combo_box_popdown (GTK_COMBO_BOX (chooser_button));
+
+ /* open the chooser dialog if the filetype has no default action */
+ thunar_chooser_button_chooser_dialog (chooser_button);
+ }
+}
+
+
+
+static gint
+thunar_chooser_button_sort_applications (gconstpointer a,
+ gconstpointer b)
+{
+ _thunar_return_val_if_fail (G_IS_APP_INFO (a), -1);
+ _thunar_return_val_if_fail (G_IS_APP_INFO (b), -1);
+
+ return g_utf8_collate (g_app_info_get_name (G_APP_INFO (a)),
+ g_app_info_get_name (G_APP_INFO (b)));
+}
+
+
+
+static gboolean
+thunar_chooser_button_row_separator (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gchar *name;
+
+ /* determine the value of the "name" column */
+ gtk_tree_model_get (model, iter, THUNAR_CHOOSER_BUTTON_STORE_COLUMN_NAME, &name, -1);
+ if (G_LIKELY (name != NULL))
+ {
+ g_free (name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+static void
+thunar_chooser_button_chooser_dialog (ThunarChooserButton *chooser_button)
{
GtkWidget *toplevel;
GtkWidget *dialog;
@@ -262,7 +394,8 @@ thunar_chooser_button_activate_other (ThunarChooserButton *chooser_button)
exo_binding_new (G_OBJECT (chooser_button), "file", G_OBJECT (dialog), "file");
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_dialog_run (GTK_DIALOG (dialog));
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT)
+ thunar_chooser_button_file_changed (chooser_button, chooser_button->file);
gtk_widget_destroy (dialog);
}
@@ -273,169 +406,106 @@ thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button,
ThunarFile *file)
{
const gchar *content_type;
+ GtkTreeIter iter;
GAppInfo *app_info;
+ GList *app_infos;
+ GList *lp;
gchar *description;
+ guint i = 0;
_thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button));
_thunar_return_if_fail (chooser_button->file == file);
_thunar_return_if_fail (THUNAR_IS_FILE (file));
- /* determine the content type of the file */
- content_type = thunar_file_get_content_type (file);
+ /* clear the store */
+ gtk_list_store_clear (chooser_button->store);
- /* determine the default application for that content type */
- app_info = g_app_info_get_default_for_type (content_type, FALSE);
- if (G_LIKELY (app_info != NULL))
- {
- /* setup the image for the application */
- gtk_image_set_from_gicon (GTK_IMAGE (chooser_button->image),
- g_app_info_get_icon (app_info),
- GTK_ICON_SIZE_MENU);
+ /* reset the default application flag */
+ chooser_button->has_default_application = FALSE;
- /* setup the label for the application */
- gtk_label_set_attributes (GTK_LABEL (chooser_button->label), NULL);
- gtk_label_set_text (GTK_LABEL (chooser_button->label), g_app_info_get_name (app_info));
+ /* block the changed signal for a moment */
+ g_signal_handlers_block_by_func (chooser_button,
+ thunar_chooser_button_changed,
+ NULL);
- /* cleanup */
- g_object_unref (app_info);
- }
- else
- {
- /* no default application specified */
- gtk_label_set_attributes (GTK_LABEL (chooser_button->label), thunar_pango_attr_list_italic ());
- gtk_label_set_text (GTK_LABEL (chooser_button->label), _("No application selected"));
- gtk_image_set_from_pixbuf (GTK_IMAGE (chooser_button->image), NULL);
- }
+ /* determine the content type of the file */
+ content_type = thunar_file_get_content_type (file);
/* setup a useful tooltip for the button */
description = g_content_type_get_description (content_type);
- thunar_gtk_widget_set_tooltip (chooser_button->button,
+ thunar_gtk_widget_set_tooltip (GTK_WIDGET (chooser_button),
_("The selected application is used to open "
"this and other files of type \"%s\"."),
description);
g_free (description);
-}
-
-
-
-static void
-menu_position (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer chooser)
-{
- GtkRequisition chooser_request;
- GtkRequisition menu_request;
- GdkRectangle geometry;
- GdkScreen *screen;
- GtkWidget *toplevel = gtk_widget_get_toplevel (chooser);
- gint monitor;
- gint x0;
- gint y0;
- gtk_widget_translate_coordinates (GTK_WIDGET (chooser), toplevel, 0, 0, &x0, &y0);
-
- gtk_widget_size_request (GTK_WIDGET (chooser), &chooser_request);
- gtk_widget_size_request (GTK_WIDGET (menu), &menu_request);
-
- gdk_window_get_position (GTK_WIDGET (chooser)->window, x, y);
-
- *y += y0;
- *x += x0;
-
- /* verify the the menu is on-screen */
- screen = gtk_widget_get_screen (GTK_WIDGET (chooser));
- if (G_LIKELY (screen != NULL))
+ /* determine the default application for that content type */
+ app_info = g_app_info_get_default_for_type (content_type, FALSE);
+ if (G_LIKELY (app_info != NULL))
{
- monitor = gdk_screen_get_monitor_at_point (screen, *x, *y);
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
- if (*y + menu_request.height > geometry.y + geometry.height)
- *y -= menu_request.height - chooser_request.height;
- }
-
- *push_in = TRUE;
-}
-
-
-
-static void
-thunar_chooser_button_pressed (ThunarChooserButton *chooser_button,
- GtkWidget *button)
-{
- const gchar *content_type;
- GtkWidget *image;
- GtkWidget *item;
- GtkWidget *menu;
- GAppInfo *default_app_info;
- GList *app_infos;
- GList *lp;
-
- _thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button));
- _thunar_return_if_fail (chooser_button->button == button);
- _thunar_return_if_fail (GTK_IS_BUTTON (button));
-
- /* verify that we have a valid file */
- if (G_UNLIKELY (chooser_button->file == NULL))
- return;
-
- /* determine the content type for the file */
- content_type = thunar_file_get_content_type (chooser_button->file);
+ /* determine all applications that claim to be able to handle the file */
+ app_infos = g_app_info_get_all_for_type (content_type);
+ app_infos = g_list_sort (app_infos, thunar_chooser_button_sort_applications);
+
+ /* add all possible applications */
+ for (lp = app_infos, i = 0; lp != NULL; lp = lp->next, ++i)
+ {
+ /* insert the item into the store */
+ gtk_list_store_insert_with_values (chooser_button->store, &iter, i,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_NAME,
+ g_app_info_get_name (lp->data),
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_APPLICATION,
+ lp->data,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_ICON,
+ g_app_info_get_icon (lp->data),
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_SENSITIVE,
+ TRUE,
+ -1);
+
+ /* pre-select the default application */
+ if (g_app_info_equal (lp->data, app_info))
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (chooser_button), &iter);
+
+ /* release the application */
+ g_object_unref (lp->data);
+ }
+
+ /* release the application list */
+ g_list_free (app_infos);
+
+ /* release the default application */
+ g_object_unref (app_info);
- /* determine the default application */
- default_app_info = g_app_info_get_default_for_type (content_type, FALSE);
- if (G_UNLIKELY (default_app_info == NULL))
- {
- /* no default application, just popup the application chooser */
- thunar_chooser_button_activate_other (chooser_button);
- g_object_unref (default_app_info);
- return;
+ /* assume we have some applications in the list */
+ chooser_button->has_default_application = TRUE;
}
-
- /* determine all applications that claim to be able to handle the file */
- app_infos = g_app_info_get_all_for_type (content_type);
-
- /* allocate a new popup menu */
- menu = gtk_menu_new ();
-
- /* add the other possible applications */
- for (lp = app_infos; lp != NULL; lp = lp->next)
+ else
{
- item = gtk_image_menu_item_new_with_label (g_app_info_get_name (lp->data));
- g_object_set_data_full (G_OBJECT (item), I_("app-info"), lp->data, g_object_unref);
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_chooser_button_activate), chooser_button);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* setup the icon for the application */
- image = gtk_image_new_from_gicon (g_app_info_get_icon (lp->data), GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_show (image);
+ /* add the "No application selected" item and set as active */
+ gtk_list_store_insert_with_values (chooser_button->store, &iter, 0,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_NAME,
+ _("No application selected"),
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_STYLE,
+ PANGO_STYLE_ITALIC,
+ -1);
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (chooser_button), &iter);
}
- /* append a separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* release the applications list */
- g_list_free (app_infos);
-
- /* add the "Other Application..." choice */
- item = gtk_image_menu_item_new_with_mnemonic (_("_Other Application..."));
- g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_chooser_button_activate_other), chooser_button);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* make sure the menu has atleast the same width as the chooser */
- if (menu->allocation.width < button->allocation.width)
- gtk_widget_set_size_request (menu, button->allocation.width, -1);
-
- /* run the menu on the button's screen (takes over the floating reference of menu) */
- thunar_gtk_menu_run (GTK_MENU (menu), button, menu_position, button, 0, gtk_get_current_event_time ());
-
- /* yeppa, that's a requirement */
- gtk_button_released (GTK_BUTTON (button));
+ /* insert empty row that will appear as a separator */
+ gtk_list_store_insert_with_values (chooser_button->store, NULL, ++i, -1);
+
+ /* add the "Other Application..." option */
+ gtk_list_store_insert_with_values (chooser_button->store, NULL, ++i,
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_NAME,
+ _("Other Application..."),
+ THUNAR_CHOOSER_BUTTON_STORE_COLUMN_SENSITIVE,
+ TRUE,
+ -1);
+
+ /* unblock the changed signal */
+ g_signal_handlers_unblock_by_func (chooser_button,
+ thunar_chooser_button_changed,
+ NULL);
}
More information about the Xfce4-commits
mailing list