[Xfce4-commits] <design:master> Add spawning.
Nick Schermer
noreply at xfce.org
Thu Jun 2 18:34:01 CEST 2011
Updating branch refs/heads/master
to ffe975f45f55522520bf6050180025e81fe93449 (commit)
from 90c7e1988188c36b6df779f0f71076054b590208 (commit)
commit ffe975f45f55522520bf6050180025e81fe93449
Author: Nick Schermer <nick at xfce.org>
Date: Thu Jun 2 18:31:55 2011 +0200
Add spawning.
.../merge-with-xfrun/demo-code/c/appfinder-model.c | 170 ++++++++--
.../merge-with-xfrun/demo-code/c/appfinder-model.h | 18 +-
.../demo-code/c/appfinder-window.c | 344 +++++++++++++++++---
.../merge-with-xfrun/demo-code/c/main.c | 3 +
4 files changed, 455 insertions(+), 80 deletions(-)
diff --git a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c
index 4bdc7d9..9e6f104 100644
--- a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c
+++ b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c
@@ -5,6 +5,7 @@
#include <memory.h>
#include <string.h>
#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
#include <garcon/garcon.h>
#include "appfinder-model.h"
@@ -176,6 +177,8 @@ xfce_appfinder_model_finalize (GObject *object)
g_free (model->filter_category);
g_free (model->filter_string);
+ g_message ("model cleared");
+
(*G_OBJECT_CLASS (xfce_appfinder_model_parent_class)->finalize) (object);
}
@@ -204,7 +207,6 @@ xfce_appfinder_model_get_column_type (GtkTreeModel *tree_model,
switch (column)
{
case XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT:
- case XFCE_APPFINDER_MODEL_COLUMN_KEY:
case XFCE_APPFINDER_MODEL_COLUMN_ICON_NAME:
return G_TYPE_STRING;
@@ -274,10 +276,15 @@ xfce_appfinder_model_get_value (GtkTreeModel *tree_model,
g_return_if_fail (iter->stamp == model->stamp);
item = ITER_GET_DATA (iter);
- g_return_if_fail (item->item == NULL || GARCON_IS_MENU_ITEM (item->item));
+ g_return_if_fail (GARCON_IS_MENU_ITEM (item->item));
switch (column)
{
+ case XFCE_APPFINDER_MODEL_COLUMN_VISIBLE:
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, item->visible);
+ break;
+
case XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT:
if (item->abstract == NULL
&& item->item != NULL)
@@ -304,27 +311,11 @@ xfce_appfinder_model_get_value (GtkTreeModel *tree_model,
g_value_set_object (value, item->pixbuf);
break;
- case XFCE_APPFINDER_MODEL_COLUMN_KEY:
- if (item->key == NULL
- && item->item)
- {
- name = garcon_menu_item_get_name (item->item);
- item->key = g_utf8_normalize (name, -1, G_NORMALIZE_ALL);
- }
-
- g_value_init (value, G_TYPE_STRING);
- g_value_set_static_string (value, item->key);
- break;
-
case XFCE_APPFINDER_MODEL_COLUMN_ICON_NAME:
g_value_init (value, G_TYPE_STRING);
g_value_set_static_string (value, garcon_menu_item_get_icon_name (item->item));
break;
- case XFCE_APPFINDER_MODEL_COLUMN_VISIBLE:
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, item->visible);
- break;
default:
g_assert_not_reached ();
@@ -533,6 +524,36 @@ xfce_appfinder_model_item_free (gpointer data)
+static gchar *
+xfce_appfinder_model_item_key (GarconMenuItem *item)
+{
+ const gchar *value;
+ GString *str;
+ gchar *normalized;
+ gchar *casefold;
+
+ str = g_string_sized_new (128);
+
+ value = garcon_menu_item_get_name (item);
+ if (value != NULL)
+ g_string_append (str, value);
+ g_string_append_c (str, '\n');
+
+ value = garcon_menu_item_get_comment (item);
+ if (value != NULL)
+ g_string_append (str, value);
+
+ normalized = g_utf8_normalize (str->str, str->len, G_NORMALIZE_ALL);
+ casefold = g_utf8_casefold (normalized, -1);
+ g_free (normalized);
+
+ g_string_free (str, TRUE);
+
+ return casefold;
+}
+
+
+
static gboolean
xfce_appfinder_model_collect_items (XfceAppfinderModel *model,
GarconMenu *menu,
@@ -542,6 +563,7 @@ xfce_appfinder_model_collect_items (XfceAppfinderModel *model,
GarconMenuDirectory *directory;
ModelItem *item;
gboolean has_items = FALSE;
+ gchar *category_collated = NULL;
g_return_val_if_fail (GARCON_IS_MENU (menu), FALSE);
@@ -552,7 +574,11 @@ xfce_appfinder_model_collect_items (XfceAppfinderModel *model,
return FALSE;
if (category == NULL)
- category = garcon_menu_directory_get_name (directory);
+ {
+ category = garcon_menu_directory_get_name (directory);
+ category_collated = g_utf8_collate_key (category, -1);
+ category = category_collated;
+ }
}
/* collect all the elements in this menu and its sub menus */
@@ -567,8 +593,7 @@ xfce_appfinder_model_collect_items (XfceAppfinderModel *model,
item = g_slice_new0 (ModelItem);
item->visible = TRUE;
item->item = li->data;
- if (category != NULL)
- item->category = g_utf8_collate_key (category, -1);
+ item->category = g_strdup (category);
model->collect_items = g_slist_prepend (model->collect_items, item);
@@ -582,6 +607,8 @@ xfce_appfinder_model_collect_items (XfceAppfinderModel *model,
}
g_list_free (elements);
+ g_free (category_collated);
+
if (directory != NULL
&& has_items)
model->collect_categories = g_slist_prepend (model->collect_categories, directory);
@@ -651,12 +678,18 @@ xfce_appfinder_model_filter_idle (gpointer data)
visible = TRUE;
if (model->filter_category != NULL
- && g_strcmp0 (model->filter_category, item->category) != 0)
- visible = FALSE;
+ && (item->category == NULL
+ || strcmp (model->filter_category, item->category) != 0))
+ {
+ visible = FALSE;
+ }
+ else if (model->filter_string != NULL)
+ {
+ if (item->key == NULL)
+ item->key = xfce_appfinder_model_item_key (item->item);
- /*if (visible
- && model->filter_string != NULL)
- visible = FALSE;*/
+ visible = strstr (item->key, model->filter_string) != NULL;
+ }
if (item->visible != visible)
{
@@ -728,16 +761,99 @@ void
xfce_appfinder_model_filter_string (XfceAppfinderModel *model,
const gchar *seach_string)
{
+ gchar *normalized;
+
g_return_if_fail (XFCE_IS_APPFINDER_MODEL (model));
g_free (model->filter_string);
- model->filter_string = g_strdup (seach_string);
+
+ if (seach_string != NULL && *seach_string != '\0')
+ {
+ normalized = g_utf8_normalize (seach_string, -1, G_NORMALIZE_ALL);
+ model->filter_string = g_utf8_casefold (normalized, -1);
+ g_free (normalized);
+ }
+ else
+ {
+ model->filter_string = NULL;
+ }
xfce_appfinder_model_filter (model);
}
+gboolean
+xfce_appfinder_model_execute (XfceAppfinderModel *model,
+ GtkTreeIter *iter,
+ GdkScreen *screen,
+ GError **error)
+{
+ const gchar *command, *p;
+ GarconMenuItem *item;
+ ModelItem *mitem;
+ GString *string;
+ gboolean succeed = FALSE;
+ gchar **argv;
+
+ g_return_val_if_fail (XFCE_IS_APPFINDER_MODEL (model), FALSE);
+ g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ mitem = ITER_GET_DATA (iter);
+ item = mitem->item;
+ g_return_val_if_fail (GARCON_IS_MENU_ITEM (item), FALSE);
+
+ command = garcon_menu_item_get_command (item);
+ if (command == NULL || *command == '\0')
+ {
+ g_set_error_literal (error, 0, 0, _("Application has no command"));
+ return FALSE;
+ }
+
+ string = g_string_sized_new (100);
+
+ if (garcon_menu_item_requires_terminal (item))
+ g_string_append (string, "exo-open --launch TerminalEmulator ");
+
+ /* expand the field codes */
+ for (p = command; *p != '\0'; ++p)
+ {
+ if (G_UNLIKELY (p[0] == '%' && p[1] != '\0'))
+ {
+ switch (*++p)
+ {
+ case '%':
+ g_string_append_c (string, '%');
+ break;
+
+ /* skip all the other %? values for now we don't have dnd anyways */
+ }
+ }
+ else
+ {
+ g_string_append_c (string, *p);
+ }
+ }
+
+ if (g_shell_parse_argv (string->str, NULL, &argv, error))
+ {
+ succeed = xfce_spawn_on_screen (screen, garcon_menu_item_get_path (item),
+ argv, NULL, G_SPAWN_SEARCH_PATH,
+ garcon_menu_item_supports_startup_notification (item),
+ gtk_get_current_event_time (),
+ garcon_menu_item_get_icon_name (item),
+ error);
+
+ g_strfreev (argv);
+ }
+
+ g_string_free (string, TRUE);
+
+ return succeed;
+}
+
+
GdkPixbuf *
xfce_appfinder_model_load_pixbuf (const gchar *icon_name,
gint size)
diff --git a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h
index 2cf37e9..b54ca13 100644
--- a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h
+++ b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h
@@ -26,7 +26,6 @@ enum
{
XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT,
XFCE_APPFINDER_MODEL_COLUMN_ICON,
- XFCE_APPFINDER_MODEL_COLUMN_KEY,
XFCE_APPFINDER_MODEL_COLUMN_ICON_NAME,
XFCE_APPFINDER_MODEL_COLUMN_VISIBLE,
XFCE_APPFINDER_MODEL_N_COLUMNS,
@@ -38,14 +37,19 @@ GType xfce_appfinder_model_get_type (void) G_GNUC_CONS
XfceAppfinderModel *xfce_appfinder_model_new (void) G_GNUC_MALLOC;
-void xfce_appfinder_model_filter_category (XfceAppfinderModel *model,
- const gchar *category);
+void xfce_appfinder_model_filter_category (XfceAppfinderModel *model,
+ const gchar *category);
-void xfce_appfinder_model_filter_string (XfceAppfinderModel *model,
- const gchar *seach_string);
+void xfce_appfinder_model_filter_string (XfceAppfinderModel *model,
+ const gchar *seach_string);
-GdkPixbuf *xfce_appfinder_model_load_pixbuf (const gchar *icon_name,
- gint size) G_GNUC_MALLOC;
+gboolean xfce_appfinder_model_execute (XfceAppfinderModel *model,
+ GtkTreeIter *iter,
+ GdkScreen *screen,
+ GError **error);
+
+GdkPixbuf *xfce_appfinder_model_load_pixbuf (const gchar *icon_name,
+ gint size) G_GNUC_MALLOC;
G_END_DECLS
diff --git a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c
index 397b122..f203667 100644
--- a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c
+++ b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c
@@ -4,6 +4,8 @@
#include <string.h>
#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+#include <gdk/gdkkeysyms.h>
#include "appfinder-window.h"
#include "appfinder-model.h"
@@ -12,15 +14,29 @@
static void xfce_appfinder_window_finalize (GObject *object);
+static gboolean xfce_appfinder_window_key_press_event (GtkWidget *widget,
+ GdkEventKey *event);
+static gboolean xfce_appfinder_window_delete_event (GtkWidget *widget,
+ GdkEventAny *event);
static void xfce_appfinder_window_set_padding (GtkWidget *entry,
GtkWidget *align);
-static GtkWidget *xfce_appfinder_window_buttonbox (void);
+static void xfce_appfinder_window_entry_changed (XfceAppfinderWindow *window);
+static void xfce_appfinder_window_entry_activate (GtkEditable *entry,
+ XfceAppfinderWindow *window);
+static gboolean xfce_appfinder_window_entry_key_press_event (GtkWidget *entry,
+ GdkEventKey *event,
+ XfceAppfinderWindow *window);
static void xfce_appfinder_window_entry_icon_released (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
GdkEvent *event,
XfceAppfinderWindow *window);
static void xfce_appfinder_window_category_changed (GtkTreeSelection *selection,
XfceAppfinderWindow *window);
+static void xfce_appfinder_window_item_changed (XfceAppfinderWindow *window);
+static void xfce_appfinder_window_row_activated (XfceAppfinderWindow *window);
+static void xfce_appfinder_window_execute (XfceAppfinderWindow *window);
+
+
struct _XfceAppfinderWindowClass
{
@@ -37,10 +53,13 @@ struct _XfceAppfinderWindow
GtkWidget *paned;
GtkWidget *entry;
- GtkWidget *vbox;
- GtkWidget *bbox1;
- GtkWidget *bbox2;
GtkWidget *image;
+ GtkWidget *treeview;
+
+ GtkWidget *bbox;
+ GtkWidget *button_launch;
+ GtkWidget *bin_collapsed;
+ GtkWidget *bin_expanded;
};
@@ -52,10 +71,15 @@ G_DEFINE_TYPE (XfceAppfinderWindow, xfce_appfinder_window, GTK_TYPE_WINDOW)
static void
xfce_appfinder_window_class_init (XfceAppfinderWindowClass *klass)
{
- GObjectClass *gobject_class;
+ GObjectClass *gobject_class;
+ GtkWidgetClass *gtkwidget_class;
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = xfce_appfinder_window_finalize;
+
+ gtkwidget_class = GTK_WIDGET_CLASS (klass);
+ gtkwidget_class->key_press_event = xfce_appfinder_window_key_press_event;
+ gtkwidget_class->delete_event = xfce_appfinder_window_delete_event;
}
@@ -76,6 +100,9 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
GtkCellRenderer *renderer;
GtkTreeModel *filter_model;
GtkTreeSelection *selection;
+ GtkWidget *bbox;
+ GtkWidget *button;
+ GtkTreePath *path;
window->model = xfce_appfinder_model_new ();
window->category_model = xfce_appfinder_category_model_new ();
@@ -86,9 +113,8 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
gtk_window_set_title (GTK_WINDOW (window), _("Application Finder"));
gtk_window_set_default_size (GTK_WINDOW (window), 500 /* todo, remember */, -1);
gtk_window_set_icon_name (GTK_WINDOW (window), GTK_STOCK_EXECUTE);
- g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (gtk_main_quit), NULL);
- window->vbox = vbox = gtk_vbox_new (FALSE, 6);
+ vbox = gtk_vbox_new (FALSE, 6);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_widget_show (vbox);
@@ -117,10 +143,15 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
gtk_container_add (GTK_CONTAINER (align), entry);
g_signal_connect (G_OBJECT (entry), "icon-release", G_CALLBACK (xfce_appfinder_window_entry_icon_released), window);
g_signal_connect (G_OBJECT (entry), "realize", G_CALLBACK (xfce_appfinder_window_set_padding), align);
+ g_signal_connect_swapped (G_OBJECT (entry), "changed", G_CALLBACK (xfce_appfinder_window_entry_changed), window);
+ g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (xfce_appfinder_window_entry_activate), window);
+ g_signal_connect (G_OBJECT (entry), "key-press-event", G_CALLBACK (xfce_appfinder_window_entry_key_press_event), window);
+ gtk_entry_set_icon_tooltip_text (GTK_ENTRY (window->entry), GTK_ENTRY_ICON_SECONDARY, _("Toggle view mode"));
gtk_widget_show (entry);
- window->bbox1 = xfce_appfinder_window_buttonbox ();
- gtk_box_pack_start (GTK_BOX (vbox2), window->bbox1, FALSE, TRUE, 0);
+ window->bin_collapsed = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ gtk_box_pack_start (GTK_BOX (vbox2), window->bin_collapsed, FALSE, TRUE, 0);
+ gtk_widget_show (window->bin_collapsed);
window->paned = pane = gtk_hpaned_new ();
gtk_box_pack_start (GTK_BOX (vbox), pane, TRUE, TRUE, 0);
@@ -134,12 +165,19 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
sidepane = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window->category_model));
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (sidepane), FALSE);
+ gtk_tree_view_set_enable_search (GTK_TREE_VIEW (sidepane), FALSE);
+ g_signal_connect_swapped (GTK_TREE_VIEW (sidepane), "start-interactive-search", G_CALLBACK (gtk_widget_grab_focus), entry);
gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (sidepane),
xfce_appfinder_category_model_row_separator_func, NULL, NULL);
gtk_container_add (GTK_CONTAINER (scroll), sidepane);
gtk_widget_show (sidepane);
+ path = gtk_tree_path_new_first ();
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (sidepane), path, NULL, FALSE);
+ gtk_tree_path_free (path);
+
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidepane));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
g_signal_connect (G_OBJECT (selection), "changed",
G_CALLBACK (xfce_appfinder_window_category_changed), window);
@@ -160,34 +198,57 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_paned_add2 (GTK_PANED (pane), scroll);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_show (scroll);
filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (window->model), NULL);
gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), XFCE_APPFINDER_MODEL_COLUMN_VISIBLE);
- treeview = gtk_tree_view_new_with_model (filter_model);
+ window->treeview = treeview = gtk_tree_view_new_with_model (filter_model);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+ gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE);
+ g_signal_connect_swapped (GTK_TREE_VIEW (treeview), "row-activated", G_CALLBACK (xfce_appfinder_window_row_activated), window);
+ g_signal_connect_swapped (GTK_TREE_VIEW (treeview), "start-interactive-search", G_CALLBACK (gtk_widget_grab_focus), entry);
/* gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), XFCE_RUN_MODEL_COLUMN_TOOLTIP); */
gtk_container_add (GTK_CONTAINER (scroll), treeview);
gtk_widget_show (treeview);
g_object_unref (G_OBJECT (filter_model));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ g_signal_connect_swapped (G_OBJECT (selection), "changed",
+ G_CALLBACK (xfce_appfinder_window_item_changed), window);
+
renderer = gtk_cell_renderer_pixbuf_new ();
- column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
- "pixbuf", XFCE_APPFINDER_MODEL_COLUMN_ICON,
- NULL);
+ column = gtk_tree_view_column_new_with_attributes (NULL, renderer, "pixbuf", XFCE_APPFINDER_MODEL_COLUMN_ICON, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), GTK_TREE_VIEW_COLUMN (column));
renderer = gtk_cell_renderer_text_new ();
- g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
- "markup", XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT,
- NULL);
+ column = gtk_tree_view_column_new_with_attributes (NULL, renderer, "markup", XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), GTK_TREE_VIEW_COLUMN (column));
- window->bbox2 = xfce_appfinder_window_buttonbox ();
- gtk_box_pack_start (GTK_BOX (vbox), window->bbox2, FALSE, TRUE, 0);
+ window->bin_expanded = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ gtk_box_pack_start (GTK_BOX (vbox), window->bin_expanded, FALSE, TRUE, 0);
+ gtk_widget_show (window->bin_expanded);
+
+ window->bbox = bbox = gtk_hbutton_box_new ();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 6);
+ gtk_widget_show (bbox);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ gtk_container_add (GTK_CONTAINER (bbox), button);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_widget_show (button);
+
+ window->button_launch = button = gtk_button_new_with_mnemonic ("La_unch");
+ gtk_container_add (GTK_CONTAINER (bbox), button);
+ g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (xfce_appfinder_window_execute), window);
+ gtk_widget_set_sensitive (button, FALSE);
+ gtk_widget_show (button);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_EXECUTE, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ gtk_widget_show (image);
g_message ("constructed window");
}
@@ -207,6 +268,32 @@ xfce_appfinder_window_finalize (GObject *object)
+static gboolean
+xfce_appfinder_window_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_Escape)
+ {
+ gtk_main_quit ();
+ return TRUE;
+ }
+
+ return (*GTK_WIDGET_CLASS (xfce_appfinder_window_parent_class)->key_press_event) (widget, event);
+}
+
+
+
+static gboolean
+xfce_appfinder_window_delete_event (GtkWidget *widget,
+ GdkEventAny *event)
+{
+ /* destroy the window after the main loop */
+ gtk_main_quit ();
+ return TRUE;
+}
+
+
+
static void
xfce_appfinder_window_set_padding (GtkWidget *entry,
GtkWidget *align)
@@ -219,32 +306,64 @@ xfce_appfinder_window_set_padding (GtkWidget *entry,
-static GtkWidget *
-xfce_appfinder_window_buttonbox (void)
+/* TODO idle */
+static void
+xfce_appfinder_window_entry_changed (XfceAppfinderWindow *window)
{
+ const gchar *text;
- GtkWidget *image;
- GtkWidget *button;
- GtkWidget *bbox;
+ text = gtk_entry_get_text (GTK_ENTRY (window->entry));
- bbox = gtk_hbutton_box_new ();
- gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
- gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 6);
+ if (gtk_widget_get_visible (window->paned))
+ xfce_appfinder_model_filter_string (window->model, text);
+ else
+ gtk_widget_set_sensitive (window->button_launch, text != NULL && *text != '\0');
+}
- button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
- gtk_container_add (GTK_CONTAINER (bbox), button);
- g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtk_main_quit), NULL);
- gtk_widget_show (button);
- button = gtk_button_new_with_mnemonic ("La_unch");
- gtk_container_add (GTK_CONTAINER (bbox), button);
- gtk_widget_show (button);
- image = gtk_image_new_from_stock (GTK_STOCK_EXECUTE, GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (GTK_BUTTON (button), image);
- gtk_widget_show (image);
+static void
+xfce_appfinder_window_entry_activate (GtkEditable *entry,
+ XfceAppfinderWindow *window)
+{
+ GtkTreePath *path;
- return bbox;
+ if (gtk_widget_get_visible (window->paned))
+ {
+ if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (window->treeview), &path, NULL))
+ {
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (window->treeview), path, NULL, FALSE);
+ gtk_tree_path_free (path);
+ }
+
+ gtk_widget_grab_focus (window->treeview);
+ }
+ else if (gtk_widget_get_sensitive (window->button_launch))
+ {
+ gtk_button_clicked (GTK_BUTTON (window->button_launch));
+ }
+}
+
+
+
+static gboolean
+xfce_appfinder_window_entry_key_press_event (GtkWidget *entry,
+ GdkEventKey *event,
+ XfceAppfinderWindow *window)
+{
+ gboolean expand;
+
+ if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down)
+ {
+ expand = (event->keyval == GDK_KEY_Down);
+ if (gtk_widget_get_visible (window->paned) != expand)
+ {
+ xfce_appfinder_window_set_expanded (window, expand);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
}
@@ -284,6 +403,120 @@ xfce_appfinder_window_category_changed (GtkTreeSelection *selection,
+static void
+xfce_appfinder_window_item_changed (XfceAppfinderWindow *window)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gboolean can_launch;
+ GtkTreeSelection *selection;
+
+ if (!gtk_widget_get_visible (window->paned))
+ return;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
+ can_launch = gtk_tree_selection_get_selected (selection, &model, &iter);
+ gtk_widget_set_sensitive (window->button_launch, can_launch);
+ if (can_launch)
+ {
+ /* TODO? */
+ }
+}
+
+
+
+
+static void
+xfce_appfinder_window_row_activated (XfceAppfinderWindow *window)
+{
+ if (gtk_widget_get_sensitive (window->button_launch))
+ gtk_button_clicked (GTK_BUTTON (window->button_launch));
+}
+
+
+
+static void
+xfce_appfinder_window_execute (XfceAppfinderWindow *window)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter, orig;
+ GError *error = NULL;
+ gboolean result = FALSE;
+ GdkScreen *screen;
+ const gchar *text;
+ GdkModifierType state;
+ gboolean in_terminal = FALSE;
+ gchar *cmdline, *tmp;
+ const gchar *exo_open_prefix[] = { "file://", "http://", "https://" };
+ guint i;
+
+ if (!gtk_widget_get_sensitive (window->button_launch))
+ return;
+
+ screen = gtk_window_get_screen (GTK_WINDOW (window));
+ if (gtk_widget_get_visible (window->paned))
+ {
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &orig, &iter);
+ result = xfce_appfinder_model_execute (window->model, &orig, screen, &error);
+ }
+ }
+ else
+ {
+ if (gtk_get_current_event_state (&state)
+ && (state & GDK_CONTROL_MASK) != 0)
+ in_terminal = TRUE;
+
+ text = gtk_entry_get_text (GTK_ENTRY (window->entry));
+ cmdline = xfce_expand_variables (text, NULL);
+
+ if (g_str_has_prefix (text, "#"))
+ {
+ /* open manual page in the terminal */
+ tmp = g_strconcat ("man ", cmdline + 1, NULL);
+ g_free (cmdline);
+ cmdline = tmp;
+ in_terminal = TRUE;
+ }
+
+ result = xfce_spawn_command_line_on_screen (screen, cmdline, in_terminal, FALSE, &error);
+ if (!result)
+ {
+ /* TODO instead check the exo exit code */
+ /* check if this is something exo-open can handle */
+ for (i = 0; !result && i < G_N_ELEMENTS (exo_open_prefix); i++)
+ if (g_str_has_prefix (cmdline, exo_open_prefix[i]))
+ result = TRUE;
+
+ if (result)
+ {
+ /* try to spawn again */
+ tmp = g_strconcat ("exo-open ", cmdline, NULL);
+ result = xfce_spawn_command_line_on_screen (screen, tmp, FALSE, FALSE, &error);
+ g_free (tmp);
+ }
+ }
+
+ g_free (cmdline);
+ }
+
+ gtk_entry_set_icon_from_stock (GTK_ENTRY (window->entry), GTK_ENTRY_ICON_PRIMARY,
+ result ? NULL : GTK_STOCK_DIALOG_ERROR);
+ gtk_entry_set_icon_tooltip_text (GTK_ENTRY (window->entry), GTK_ENTRY_ICON_PRIMARY,
+ error != NULL ? error->message : NULL);
+
+ if (error != NULL)
+ g_error_free (error);
+
+ if (result)
+ gtk_main_quit ();
+}
+
+
+
GtkWidget *
xfce_appfinder_window_new (void)
{
@@ -296,9 +529,13 @@ void
xfce_appfinder_window_set_expanded (XfceAppfinderWindow *window,
gboolean expanded)
{
- GdkGeometry hints;
- gint width;
+ GdkGeometry hints;
+ gint width;
+ GtkWidget *parent;
+ g_message ("set expand = %s", expanded ? "true" : "false");
+
+ /* force window geomentry */
if (expanded)
{
gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL, NULL, 0);
@@ -312,12 +549,27 @@ xfce_appfinder_window_set_expanded (XfceAppfinderWindow *window,
gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL, &hints, GDK_HINT_MAX_SIZE);
}
+ /* repack the button box */
+ g_object_ref (G_OBJECT (window->bbox));
+ parent = gtk_widget_get_parent (window->bbox);
+ if (parent != NULL)
+ gtk_container_remove (GTK_CONTAINER (parent), window->bbox);
+ if (expanded)
+ gtk_container_add (GTK_CONTAINER (window->bin_expanded), window->bbox);
+ else
+ gtk_container_add (GTK_CONTAINER (window->bin_collapsed), window->bbox);
+ gtk_widget_set_visible (window->bin_expanded, expanded);
+ gtk_widget_set_visible (window->bin_collapsed, !expanded);
+ g_object_unref (G_OBJECT (window->bbox));
+
+ /* show/hide pane with treeviews */
gtk_widget_set_visible (window->paned, expanded);
- gtk_widget_set_visible (window->bbox1, !expanded);
- gtk_widget_set_visible (window->bbox2, expanded);
+
+ /* toggle icon */
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (window->entry), GTK_ENTRY_ICON_SECONDARY,
expanded ? GTK_STOCK_GO_UP : GTK_STOCK_GO_DOWN);
- gtk_entry_set_icon_tooltip_text (GTK_ENTRY (window->entry), GTK_ENTRY_ICON_SECONDARY,
- expanded ? _("Collapse the icon views")
- : _("Show all applications"));
+
+ /* update state */
+ xfce_appfinder_window_entry_changed (window);
+ xfce_appfinder_window_item_changed (window);
}
diff --git a/xfce4-appfinder/merge-with-xfrun/demo-code/c/main.c b/xfce4-appfinder/merge-with-xfrun/demo-code/c/main.c
index f847999..d7a8fa1 100644
--- a/xfce4-appfinder/merge-with-xfrun/demo-code/c/main.c
+++ b/xfce4-appfinder/merge-with-xfrun/demo-code/c/main.c
@@ -78,5 +78,8 @@ main (gint argc, gchar **argv)
gtk_main ();
+ gtk_widget_hide (window);
+ gtk_widget_destroy (window);
+
return EXIT_SUCCESS;
}
More information about the Xfce4-commits
mailing list