/* * gtkopenwithwidget.c: an open-with widget * * Copyright (C) 2004 Novell, Inc. * Copyright (C) 2007, 2010 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Authors: Dave Camp * Alexander Larsson * Cosimo Cecchi */ #include #include "gtkopenwithwidget.h" #include "gtkintl.h" #include "gtkmarshalers.h" #include "gtkopenwith.h" #include "gtkopenwithprivate.h" #include #include #include #include struct _GtkOpenWithWidgetPrivate { GAppInfo *selected_app_info; char *content_type; GtkOpenWithWidgetShowMode show_mode; GtkWidget *program_list; GtkListStore *program_list_store; GtkCellRenderer *padding_renderer; }; enum { COLUMN_APP_INFO, COLUMN_GICON, COLUMN_NAME, COLUMN_COMMENT, COLUMN_EXEC, COLUMN_HEADING, COLUMN_HEADING_TEXT, COLUMN_RECOMMENDED, NUM_COLUMNS }; enum { PROP_CONTENT_TYPE = 1, PROP_GFILE, PROP_SHOW_MODE, N_PROPERTIES }; enum { SIGNAL_APPLICATION_SELECTED, SIGNAL_APPLICATION_ACTIVATED, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0, }; static void gtk_open_with_widget_iface_init (GtkOpenWithIface *iface); G_DEFINE_TYPE_WITH_CODE (GtkOpenWithWidget, gtk_open_with_widget, GTK_TYPE_BOX, G_IMPLEMENT_INTERFACE (GTK_TYPE_OPEN_WITH, gtk_open_with_widget_iface_init)); static void refresh_and_emit_app_selected (GtkOpenWithWidget *self, GtkTreeSelection *selection) { GtkTreeModel *model; GtkTreeIter iter; GAppInfo *info = NULL; gboolean should_emit = FALSE; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { gtk_tree_model_get (model, &iter, COLUMN_APP_INFO, &info, -1); } if (info == NULL) return; if (self->priv->selected_app_info) { if (!g_app_info_equal (self->priv->selected_app_info, info)) { should_emit = TRUE; g_object_unref (self->priv->selected_app_info); self->priv->selected_app_info = info; } } else { should_emit = TRUE; self->priv->selected_app_info = info; } if (should_emit) g_signal_emit (self, signals[SIGNAL_APPLICATION_SELECTED], 0, self->priv->selected_app_info); } static gboolean path_is_heading (GtkTreeView *view, GtkTreePath *path) { GtkTreeIter iter; GtkTreeModel *model; gboolean res; model = gtk_tree_view_get_model (view); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, COLUMN_HEADING, &res, -1); return res; } static void program_list_selection_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) { GtkOpenWithWidget *self = user_data; GtkTreeSelection *selection; if (path_is_heading (view, path)) return; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list)); refresh_and_emit_app_selected (self, selection); g_signal_emit (self, signals[SIGNAL_APPLICATION_ACTIVATED], 0, self->priv->selected_app_info); } static void item_forget_association_cb (GtkMenuItem *item, gpointer user_data) { GtkOpenWithWidget *self = user_data; GtkTreePath *path = NULL; GtkTreeIter iter; GtkTreeModel *model; GAppInfo *info; gtk_tree_view_get_cursor (GTK_TREE_VIEW (self->priv->program_list), &path, NULL); model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->program_list)); if (path != NULL) { gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, COLUMN_APP_INFO, &info, -1); if (info != NULL && g_app_info_can_remove_supports_type (info)) g_app_info_remove_supports_type (info, self->priv->content_type, NULL); } _gtk_open_with_widget_refilter (self); } static GtkWidget * gtk_open_with_widget_build_popup_menu (GtkOpenWithWidget *self) { GtkWidget *menu; GtkWidget *item; menu = gtk_menu_new (); item = gtk_menu_item_new_with_label (_("Forget association")); g_signal_connect (item, "activate", G_CALLBACK (item_forget_association_cb), self); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); return menu; } static gboolean should_show_menu (GtkOpenWithWidget *self, GdkEventButton *event) { GtkTreeIter iter; GtkTreePath *path; GtkTreeModel *model; gboolean recommended, retval; GAppInfo *info; gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (self->priv->program_list), event->x, event->y, &path, NULL, NULL, NULL); model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->program_list)); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, COLUMN_RECOMMENDED, &recommended, COLUMN_APP_INFO, &info, -1); retval = recommended && (info != NULL); gtk_tree_path_free (path); if (info != NULL) g_object_unref (info); return retval; } static void do_popup_menu (GtkOpenWithWidget *self, GdkEventButton *event) { GtkWidget *menu; if (!should_show_menu (self, event)) return; menu = gtk_open_with_widget_build_popup_menu (self); gtk_menu_attach_to_widget (GTK_MENU (menu), self->priv->program_list, NULL); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time); } static gboolean program_list_button_press_event_cb (GtkWidget *treeview, GdkEventButton *event, gpointer user_data) { GtkOpenWithWidget *self = user_data; if (event->button == 3 && event->type == GDK_BUTTON_PRESS) do_popup_menu (self, event); return FALSE; } static gboolean gtk_open_with_search_equal_func (GtkTreeModel *model, int column, const char *key, GtkTreeIter *iter, gpointer user_data) { char *normalized_key; char *name, *normalized_name; char *path, *normalized_path; char *basename, *normalized_basename; gboolean ret; if (key != NULL) { normalized_key = g_utf8_casefold (key, -1); g_assert (normalized_key != NULL); ret = TRUE; gtk_tree_model_get (model, iter, COLUMN_NAME, &name, COLUMN_EXEC, &path, -1); if (name != NULL) { normalized_name = g_utf8_casefold (name, -1); g_assert (normalized_name != NULL); if (strncmp (normalized_name, normalized_key, strlen (normalized_key)) == 0) { ret = FALSE; } g_free (normalized_name); } if (ret && path != NULL) { normalized_path = g_utf8_casefold (path, -1); g_assert (normalized_path != NULL); basename = g_path_get_basename (path); g_assert (basename != NULL); normalized_basename = g_utf8_casefold (basename, -1); g_assert (normalized_basename != NULL); if (strncmp (normalized_path, normalized_key, strlen (normalized_key)) == 0 || strncmp (normalized_basename, normalized_key, strlen (normalized_key)) == 0) { ret = FALSE; } g_free (basename); g_free (normalized_basename); g_free (normalized_path); } g_free (name); g_free (path); g_free (normalized_key); return ret; } else { return TRUE; } } static gint gtk_open_with_sort_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) { gboolean a_recommended, b_recommended; gboolean a_heading, b_heading; gchar *a_name, *b_name, *a_casefold, *b_casefold; gint retval; /* this returns: * - <0 if a should show before b * - =0 if a is the same as b * - >0 if a should show after b */ gtk_tree_model_get (model, a, COLUMN_NAME, &a_name, COLUMN_RECOMMENDED, &a_recommended, COLUMN_HEADING, &a_heading, -1); gtk_tree_model_get (model, b, COLUMN_NAME, &b_name, COLUMN_RECOMMENDED, &b_recommended, COLUMN_HEADING, &b_heading, -1); /* the recommended one always wins */ if (a_recommended && !b_recommended) { retval = -1; goto out; } if (b_recommended && !a_recommended) { retval = 1; goto out; } /* they're both recommended or not, so if one is a heading, wins */ if (a_heading) { return -1; goto out; } if (b_heading) { return 1; goto out; } a_casefold = a_name != NULL ? g_utf8_casefold (a_name, -1) : NULL; b_casefold = b_name != NULL ? g_utf8_casefold (b_name, -1) : NULL; retval = g_strcmp0 (a_casefold, b_casefold); g_free (a_casefold); g_free (b_casefold); out: g_free (a_name); g_free (b_name); return retval; } static void heading_cell_renderer_func (GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer _user_data) { gboolean heading; gtk_tree_model_get (model, iter, COLUMN_HEADING, &heading, -1); g_object_set (cell, "visible", heading, NULL); } static void padding_cell_renderer_func (GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { gboolean heading; gtk_tree_model_get (model, iter, COLUMN_HEADING, &heading, -1); if (heading) g_object_set (cell, "visible", FALSE, "xpad", 0, "ypad", 0, NULL); else g_object_set (cell, "visible", TRUE, "xpad", 3, "ypad", 3, NULL); } static gboolean gtk_open_with_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer user_data) { GtkTreeIter iter; gboolean heading; gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, COLUMN_HEADING, &heading, -1); return !heading; } static gint compare_apps_func (gconstpointer a, gconstpointer b) { return !g_app_info_equal (G_APP_INFO (a), G_APP_INFO (b)); } static void gtk_open_with_widget_real_add_items (GtkOpenWithWidget *self) { GList *all_applications = NULL, *content_type_apps = NULL, *l; gboolean heading_added; gboolean show_recommended, show_headings, show_all; if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_RECOMMENDED) { show_all = FALSE; show_headings = FALSE; show_recommended = TRUE; } else if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_ALL) { show_all = TRUE; show_headings = FALSE; show_recommended = FALSE; } else { show_all = TRUE; show_headings = TRUE; show_recommended = TRUE; } if (show_recommended) content_type_apps = g_app_info_get_all_for_type (self->priv->content_type); if (show_all) all_applications = g_app_info_get_all (); heading_added = FALSE; for (l = content_type_apps; l != NULL; l = l->next) { GAppInfo *app = l->data; GtkTreeIter iter; if (!g_app_info_supports_uris (app) && !g_app_info_supports_files (app)) continue; if (!heading_added && show_headings) { gtk_list_store_append (self->priv->program_list_store, &iter); gtk_list_store_set (self->priv->program_list_store, &iter, COLUMN_HEADING_TEXT, _("Recommended Applications"), COLUMN_HEADING, TRUE, COLUMN_RECOMMENDED, TRUE, -1); heading_added = TRUE; } gtk_list_store_append (self->priv->program_list_store, &iter); gtk_list_store_set (self->priv->program_list_store, &iter, COLUMN_APP_INFO, app, COLUMN_GICON, g_app_info_get_icon (app), COLUMN_NAME, g_app_info_get_display_name (app), COLUMN_COMMENT, g_app_info_get_description (app), COLUMN_EXEC, g_app_info_get_executable, COLUMN_HEADING, FALSE, COLUMN_RECOMMENDED, TRUE, -1); } heading_added = FALSE; for (l = all_applications; l != NULL && show_all; l = l->next) { GAppInfo *app = l->data; GtkTreeIter iter; if (!g_app_info_supports_uris (app) && !g_app_info_supports_files (app)) continue; if (content_type_apps != NULL && g_list_find_custom (content_type_apps, app, (GCompareFunc) compare_apps_func)) continue; if (!heading_added && show_headings) { gtk_list_store_append (self->priv->program_list_store, &iter); gtk_list_store_set (self->priv->program_list_store, &iter, COLUMN_HEADING_TEXT, _("Other Applications"), COLUMN_HEADING, TRUE, COLUMN_RECOMMENDED, FALSE, -1); heading_added = TRUE; } gtk_list_store_append (self->priv->program_list_store, &iter); gtk_list_store_set (self->priv->program_list_store, &iter, COLUMN_APP_INFO, app, COLUMN_GICON, g_app_info_get_icon (app), COLUMN_NAME, g_app_info_get_display_name (app), COLUMN_COMMENT, g_app_info_get_description (app), COLUMN_EXEC, g_app_info_get_executable, COLUMN_HEADING, FALSE, COLUMN_RECOMMENDED, FALSE, -1); } if (content_type_apps != NULL) g_list_free_full (content_type_apps, g_object_unref); if (all_applications != NULL) g_list_free_full (all_applications, g_object_unref); } static void gtk_open_with_widget_add_items (GtkOpenWithWidget *self) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeModel *sort; /* create list store */ self->priv->program_list_store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_APP_INFO, G_TYPE_ICON, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_BOOLEAN); sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->priv->program_list_store)); /* populate the widget */ gtk_open_with_widget_real_add_items (self); gtk_tree_view_set_model (GTK_TREE_VIEW (self->priv->program_list), GTK_TREE_MODEL (sort)); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), COLUMN_NAME, GTK_SORT_ASCENDING); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort), COLUMN_NAME, gtk_open_with_sort_func, self, NULL); gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->priv->program_list), gtk_open_with_search_equal_func, NULL, NULL); column = gtk_tree_view_column_new (); /* initial padding */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); g_object_set (renderer, "xpad", (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_HEADINGS) ? 6 : 0, NULL); self->priv->padding_renderer = renderer; /* heading text renderer */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "text", COLUMN_HEADING_TEXT, NULL); g_object_set (renderer, "weight", PANGO_WEIGHT_BOLD, "weight-set", TRUE, "ypad", 6, "xpad", 0, NULL); gtk_tree_view_column_set_cell_data_func (column, renderer, heading_cell_renderer_func, NULL, NULL); /* padding renderer for non-heading cells */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_cell_data_func (column, renderer, padding_cell_renderer_func, NULL, NULL); /* app icon renderer */ renderer = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "gicon", COLUMN_GICON, NULL); /* app name renderer */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_attributes (column, renderer, "text", COLUMN_NAME, NULL); gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME); gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->program_list), column); } static void gtk_open_with_widget_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object); switch (property_id) { case PROP_CONTENT_TYPE: self->priv->content_type = g_value_dup_string (value); break; case PROP_SHOW_MODE: gtk_open_with_widget_set_show_mode (self, g_value_get_enum (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gtk_open_with_widget_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object); switch (property_id) { case PROP_CONTENT_TYPE: g_value_set_string (value, self->priv->content_type); break; case PROP_SHOW_MODE: g_value_set_enum (value, self->priv->show_mode); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gtk_open_with_widget_constructed (GObject *object) { GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object); g_assert (self->priv->content_type != NULL); if (G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->constructed != NULL) G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->constructed (object); gtk_open_with_widget_add_items (self); } static void gtk_open_with_widget_finalize (GObject *object) { GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object); g_free (self->priv->content_type); G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->finalize (object); } static void gtk_open_with_widget_dispose (GObject *object) { GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object); if (self->priv->selected_app_info != NULL) { g_object_unref (self->priv->selected_app_info); self->priv->selected_app_info = NULL; } G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->dispose (object); } static void gtk_open_with_widget_class_init (GtkOpenWithWidgetClass *klass) { GObjectClass *gobject_class; GParamSpec *pspec; gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = gtk_open_with_widget_dispose; gobject_class->finalize = gtk_open_with_widget_finalize; gobject_class->set_property = gtk_open_with_widget_set_property; gobject_class->get_property = gtk_open_with_widget_get_property; gobject_class->constructed = gtk_open_with_widget_constructed; g_object_class_override_property (gobject_class, PROP_CONTENT_TYPE, "content-type"); /** * GtkOpenWithWidget::show-mode: * * The #GtkOpenWithWidgetShowMode for this widget. **/ pspec = g_param_spec_enum ("show-mode", P_("The widget show mode"), P_("The show mode for this widget"), GTK_TYPE_OPEN_WITH_WIDGET_SHOW_MODE, GTK_OPEN_WITH_WIDGET_SHOW_MODE_HEADINGS, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_SHOW_MODE, pspec); signals[SIGNAL_APPLICATION_SELECTED] = g_signal_new ("application-selected", GTK_TYPE_OPEN_WITH_WIDGET, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GtkOpenWithWidgetClass, application_selected), NULL, NULL, _gtk_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_APP_INFO); signals[SIGNAL_APPLICATION_ACTIVATED] = g_signal_new ("application-activated", GTK_TYPE_OPEN_WITH_WIDGET, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GtkOpenWithWidgetClass, application_activated), NULL, NULL, _gtk_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_APP_INFO); g_type_class_add_private (klass, sizeof (GtkOpenWithWidgetPrivate)); } static void gtk_open_with_widget_init (GtkOpenWithWidget *self) { GtkWidget *scrolled_window; GtkTreeSelection *selection; self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_OPEN_WITH_WIDGET, GtkOpenWithWidgetPrivate); gtk_container_set_border_width (GTK_CONTAINER (self), 5); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request (scrolled_window, 400, 300); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); self->priv->program_list = gtk_tree_view_new (); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->priv->program_list), FALSE); gtk_container_add (GTK_CONTAINER (scrolled_window), self->priv->program_list); gtk_box_pack_start (GTK_BOX (self), scrolled_window, TRUE, TRUE, 0); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); gtk_tree_selection_set_select_function (selection, gtk_open_with_selection_func, self, NULL); g_signal_connect_swapped (selection, "changed", G_CALLBACK (refresh_and_emit_app_selected), self); g_signal_connect (self->priv->program_list, "row-activated", G_CALLBACK (program_list_selection_activated), self); g_signal_connect (self->priv->program_list, "button-press-event", G_CALLBACK (program_list_button_press_event_cb), self); } static GAppInfo * gtk_open_with_widget_get_app_info (GtkOpenWith *object) { GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object); if (self->priv->selected_app_info == NULL) return NULL; return g_object_ref (self->priv->selected_app_info); } static void gtk_open_with_widget_iface_init (GtkOpenWithIface *iface) { iface->get_app_info = gtk_open_with_widget_get_app_info; } void _gtk_open_with_widget_refilter (GtkOpenWithWidget *self) { if (self->priv->program_list_store != NULL) { gtk_list_store_clear (self->priv->program_list_store); /* don't add additional xpad if we don't have headings */ g_object_set (self->priv->padding_renderer, "visible", self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_HEADINGS, NULL); gtk_open_with_widget_real_add_items (self); } } GtkWidget * gtk_open_with_widget_new (const gchar *content_type) { return g_object_new (GTK_TYPE_OPEN_WITH_WIDGET, "content-type", content_type, NULL); } /** * gtk_open_with_widget_set_show_mode: * @self: a #GtkOpenWithWidget * @show_mode: the new show mode for this widget * * Sets the mode for the widget to show the list of applications. * See #GtkOpenWithWidgetShowMode for more details. * * Since: 3.0 **/ void gtk_open_with_widget_set_show_mode (GtkOpenWithWidget *self, GtkOpenWithWidgetShowMode show_mode) { g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self)); if (self->priv->show_mode != show_mode) { self->priv->show_mode = show_mode; g_object_notify (G_OBJECT (self), "show-mode"); _gtk_open_with_widget_refilter (self); } } /** * gtk_open_with_widget_get_show_mode: * @self: a #GtkOpenWithWidget * * Returns the current mode for the widget to show the list of applications. * See #GtkOpenWithWidgetShowMode for mode details. * * Returns: a #GtkOpenWithWidgetShowMode * * Since: 3.0 **/ GtkOpenWithWidgetShowMode gtk_open_with_widget_get_show_mode (GtkOpenWithWidget *self) { g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), FALSE); return self->priv->show_mode; }