[Xfce4-commits] <xfce4-panel:devel> Add most of the launchercode from svn trunk back in the experimental branch.
Nick Schermer
nick at xfce.org
Tue Aug 11 20:28:37 CEST 2009
Updating branch refs/heads/devel
to 7de46a62f3e69d5fa01ff689125554df9dc7bc1f (commit)
from eab2c2dd87ef1f7696a0aecfc8da9d9d1d4eabae (commit)
commit 7de46a62f3e69d5fa01ff689125554df9dc7bc1f
Author: Nick Schermer <nick at xfce.org>
Date: Thu Mar 5 22:21:01 2009 +0100
Add most of the launchercode from svn trunk back in the experimental branch.
plugins/launcher/launcher-dialog.c | 19 +-
plugins/launcher/launcher-dialog.glade | 13 +-
plugins/launcher/launcher-dialog.h | 2 +-
plugins/launcher/launcher.c | 974 +++++++++++++++++++++++++++----
plugins/launcher/launcher.h | 30 +-
5 files changed, 886 insertions(+), 152 deletions(-)
diff --git a/plugins/launcher/launcher-dialog.c b/plugins/launcher/launcher-dialog.c
index 528e113..9b1c55c 100644
--- a/plugins/launcher/launcher-dialog.c
+++ b/plugins/launcher/launcher-dialog.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (C) 2008-2009 Nick Schermer <nick at xfce.org>
- *
+ *
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
@@ -38,10 +38,10 @@
typedef struct
{
- LauncherPlugin *plugin;
- GtkBuilder *builder;
- guint idle_populate_id;
- XfconfChannel *channel;
+ XfceLauncherPlugin *plugin;
+ GtkBuilder *builder;
+ guint idle_populate_id;
+ XfconfChannel *channel;
}
LauncherPluginDialog;
@@ -175,7 +175,7 @@ launcher_dialog_add_populate_model_idle (gpointer user_data)
panel_return_val_if_fail (GTK_IS_BUILDER (dialog->builder), FALSE);
GDK_THREADS_ENTER ();
-
+
/* initialize the menu library */
xfce_menu_init (NULL);
@@ -199,7 +199,7 @@ launcher_dialog_add_populate_model_idle (gpointer user_data)
/* TODO */
g_error_free (error);
}
-
+
/* shutdown menu library */
xfce_menu_shutdown ();
@@ -656,8 +656,9 @@ launcher_dialog_items_changed (XfconfChannel *channel,
void
-launcher_dialog_show (LauncherPlugin *plugin)
+launcher_dialog_show (XfceLauncherPlugin *plugin)
{
+ LauncherPluginDialog *dialog;
GtkBuilder *builder;
GObject *window, *object, *item;
guint i;
@@ -665,7 +666,7 @@ launcher_dialog_show (LauncherPlugin *plugin)
const gchar *button_names[] = { "item-add", "item-delete",
"item-move-up", "item-move-down",
"item-edit", "item-new" };
- LauncherPluginDialog *dialog;
+
panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
diff --git a/plugins/launcher/launcher-dialog.glade b/plugins/launcher/launcher-dialog.glade
index b1ffac5..071a9c4 100644
--- a/plugins/launcher/launcher-dialog.glade
+++ b/plugins/launcher/launcher-dialog.glade
@@ -3,7 +3,7 @@
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-requires libxfce4ui 0.0 -->
<!-- interface-naming-policy project-wide -->
- <object class="GtkListStore" id="arrow-position-store">
+ <object class="GtkListStore" id="arrow-position-model">
<columns>
<!-- column-name title -->
<column type="gchararray"/>
@@ -13,16 +13,16 @@
<col id="0" translatable="yes">Default</col>
</row>
<row>
- <col id="0" translatable="yes">Left</col>
+ <col id="0" translatable="yes">North</col>
</row>
<row>
- <col id="0" translatable="yes">Right</col>
+ <col id="0" translatable="yes">West</col>
</row>
<row>
- <col id="0" translatable="yes">Top</col>
+ <col id="0" translatable="yes">East</col>
</row>
<row>
- <col id="0" translatable="yes">Bottom</col>
+ <col id="0" translatable="yes">South</col>
</row>
<row>
<col id="0" translatable="yes">Inside Button</col>
@@ -323,8 +323,7 @@
<child>
<object class="GtkComboBox" id="arrow-position">
<property name="visible">True</property>
- <property name="active">0</property>
- <property name="button_sensitivity">on</property>
+ <property name="model">arrow-position-model</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
diff --git a/plugins/launcher/launcher-dialog.h b/plugins/launcher/launcher-dialog.h
index 193571a..5be30e8 100644
--- a/plugins/launcher/launcher-dialog.h
+++ b/plugins/launcher/launcher-dialog.h
@@ -22,6 +22,6 @@
#include "launcher.h"
-void launcher_dialog_show (LauncherPlugin *plugin);
+void launcher_dialog_show (XfceLauncherPlugin *plugin);
#endif /* !__XFCE_LAUNCHER_DIALOG_H__ */
diff --git a/plugins/launcher/launcher.c b/plugins/launcher/launcher.c
index b836bba..5d2d300 100644
--- a/plugins/launcher/launcher.c
+++ b/plugins/launcher/launcher.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (C) 2008-2009 Nick Schermer <nick at xfce.org>
- *
+ *
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
@@ -34,7 +34,12 @@
#include "launcher.h"
#include "launcher-dialog.h"
+#define ARROW_BUTTON_SIZE (12)
+#define DEFAULT_MENU_ICON_SIZE (24)
+#define MENU_POPUP_DELAY (225)
+
+static void launcher_plugin_style_set (GtkWidget *widget, GtkStyle *previous_style);
static void launcher_plugin_construct (XfcePanelPlugin *panel_plugin);
static void launcher_plugin_free_data (XfcePanelPlugin *panel_plugin);
@@ -44,14 +49,30 @@ static void launcher_plugin_save (XfcePanelPlugin *panel_plugin);
static void launcher_plugin_configure_plugin (XfcePanelPlugin *panel_plugin);
static void launcher_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin, gint position);
-static void launcher_plugin_button_set_icon (LauncherPlugin *plugin);
+static void launcher_plugin_property_changed (XfconfChannel *channel, const gchar *property_name, const GValue *value, XfceLauncherPlugin *plugin);
+static void launcher_plugin_icon_theme_changed (GtkIconTheme *icon_theme, XfceLauncherPlugin *plugin);
+
+static void launcher_plugin_pack_widgets (XfceLauncherPlugin *plugin);
+
+static void launcher_plugin_menu_deactivate (GtkWidget *menu, XfceLauncherPlugin *plugin);
+static gboolean launcher_plugin_menu_item_released (GtkMenuItem *widget, GdkEventButton *event, XfceMenuItem *item);
+static void launcher_plugin_menu_construct (XfceLauncherPlugin *plugin);
+static void launcher_plugin_menu_popup_destroyed (gpointer user_data);
+static gboolean launcher_plugin_menu_popup (gpointer user_data);
+static void launcher_plugin_menu_destroy (XfceLauncherPlugin *plugin);
+
+static void launcher_plugin_button_set_icon (XfceLauncherPlugin *plugin);
static void launcher_plugin_button_state_changed (GtkWidget *button_a, GtkStateType state, GtkWidget *button_b);
-static gboolean launcher_plugin_button_press_event (GtkWidget *button, GdkEventButton *event, LauncherPlugin *plugin);
-static gboolean launcher_plugin_button_release_event (GtkWidget *button, GdkEventButton *event, LauncherPlugin *plugin);
-static gboolean launcher_plugin_button_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, LauncherPlugin *plugin);
-static void launcher_plugin_button_drag_data_received (GtkWidget *widget,GdkDragContext *context, gint x,gint y,GtkSelectionData *selection_data, guint info, guint drag_time, LauncherPlugin *plugin);
+static gboolean launcher_plugin_button_press_event (GtkWidget *button, GdkEventButton *event, XfceLauncherPlugin *plugin);
+static gboolean launcher_plugin_button_release_event (GtkWidget *button, GdkEventButton *event, XfceLauncherPlugin *plugin);
+static gboolean launcher_plugin_button_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, XfceLauncherPlugin *plugin);
+static void launcher_plugin_button_drag_data_received (GtkWidget *widget,GdkDragContext *context, gint x,gint y,GtkSelectionData *selection_data, guint info, guint drag_time, XfceLauncherPlugin *plugin);
+static gboolean launcher_plugin_button_expose_event (GtkWidget *widget, GdkEventExpose *event, XfceLauncherPlugin *launcher);
+
+static void launcher_plugin_arrow_visibility (XfceLauncherPlugin *plugin);
+static gboolean launcher_plugin_arrow_press_event (GtkWidget *button, GdkEventButton *event, XfceLauncherPlugin *plugin);
-static void launcher_plugin_items_load (LauncherPlugin *plugin);
+static void launcher_plugin_items_load (XfceLauncherPlugin *plugin);
static gboolean launcher_plugin_item_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, XfceMenuItem *item);
static gboolean launcher_plugin_item_exec_on_screen (XfceMenuItem *item, guint32 event_time, GdkScreen *screen, GSList *uri_list);
@@ -59,33 +80,41 @@ static void launcher_plugin_item_exec (XfceMenuItem *item, guint32 event_time, G
static void launcher_plugin_item_exec_from_clipboard (XfceMenuItem *item, guint32 event_time, GdkScreen *screen);
static void launcher_plugin_exec_append_quoted (GString *string, const gchar *unquoted);
static gboolean launcher_plugin_exec_parse (XfceMenuItem *item, GSList *uri_list, gint *argc, gchar ***argv, GError **error);
+static GSList *launcher_plugin_uri_list_extract (GtkSelectionData *data);
+static void launcher_plugin_uri_list_free (GSList *uri_list);
-struct _LauncherPluginClass
+struct _XfceLauncherPluginClass
{
XfcePanelPluginClass __parent__;
};
-struct _LauncherPlugin
+struct _XfceLauncherPlugin
{
XfcePanelPlugin __parent__;
- XfconfChannel *channel;
+ XfconfChannel *channel;
- GtkWidget *box;
- GtkWidget *button;
- GtkWidget *arrow;
- GtkWidget *image;
+ GtkWidget *box;
+ GtkWidget *button;
+ GtkWidget *arrow;
+ GtkWidget *image;
+ GtkWidget *menu;
- GSList *items;
+ GSList *items;
- guint disable_tooltips : 1;
+ guint menu_timeout_id;
+ gint menu_icon_size;
+
+ guint disable_tooltips : 1;
+ guint move_first : 1;
+ LauncherArrowType arrow_position;
};
-G_DEFINE_TYPE (LauncherPlugin, launcher_plugin, XFCE_TYPE_PANEL_PLUGIN);
+G_DEFINE_TYPE (XfceLauncherPlugin, launcher_plugin, XFCE_TYPE_PANEL_PLUGIN);
@@ -94,11 +123,20 @@ XFCE_PANEL_PLUGIN_REGISTER_OBJECT (XFCE_TYPE_LAUNCHER_PLUGIN);
+/* quark to attach the plugin to menu items */
+GQuark launcher_plugin_quark = 0;
+
+
+
static void
-launcher_plugin_class_init (LauncherPluginClass *klass)
+launcher_plugin_class_init (XfceLauncherPluginClass *klass)
{
+ GtkWidgetClass *gtkwidget_class;
XfcePanelPluginClass *plugin_class;
+ gtkwidget_class = GTK_WIDGET_CLASS (klass);
+ gtkwidget_class->style_set = launcher_plugin_style_set;
+
plugin_class = XFCE_PANEL_PLUGIN_CLASS (klass);
plugin_class->construct = launcher_plugin_construct;
plugin_class->free_data = launcher_plugin_free_data;
@@ -107,48 +145,107 @@ launcher_plugin_class_init (LauncherPluginClass *klass)
plugin_class->save = launcher_plugin_save;
plugin_class->configure_plugin = launcher_plugin_configure_plugin;
plugin_class->screen_position_changed = launcher_plugin_screen_position_changed;
+
+ gtk_widget_class_install_style_property (gtkwidget_class,
+ g_param_spec_int ("menu-icon-size",
+ NULL,
+ "Icon size (pixels) used in the menu",
+ 16, 128,
+ DEFAULT_MENU_ICON_SIZE,
+ EXO_PARAM_READABLE));
+
+ /* initialize the quark */
+ launcher_plugin_quark = g_quark_from_static_string ("xfce-launcher-plugin");
}
static void
-launcher_plugin_init (LauncherPlugin *plugin)
+launcher_plugin_init (XfceLauncherPlugin *plugin)
{
+ GtkIconTheme *icon_theme;
+
+ plugin->disable_tooltips = FALSE;
+ plugin->move_first = FALSE;
+ plugin->arrow_position = LAUNCHER_ARROW_DEFAULT;
+ plugin->menu = NULL;
+ plugin->menu_timeout_id = 0;
+ plugin->menu_icon_size = DEFAULT_MENU_ICON_SIZE;
+
/* initialize xfconf */
xfconf_init (NULL);
/* show the configure menu item */
xfce_panel_plugin_menu_show_configure (XFCE_PANEL_PLUGIN (plugin));
+
+ /* monitor the default icon theme for changes */
+ icon_theme = gtk_icon_theme_get_default ();
+ if (G_LIKELY (icon_theme != NULL))
+ g_signal_connect (G_OBJECT (icon_theme), "changed",
+ G_CALLBACK (launcher_plugin_icon_theme_changed), plugin);
+
+ /* create the panel widgets */
+ plugin->box = xfce_hvbox_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (plugin), plugin->box);
+ gtk_widget_show (plugin->box);
+
+ plugin->button = xfce_panel_create_button ();
+ gtk_box_pack_start (GTK_BOX (plugin->box), plugin->button, TRUE, TRUE, 0);
+ xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->button);
+ gtk_widget_set_has_tooltip (plugin->button, TRUE);
+ gtk_widget_show (plugin->button);
+ g_signal_connect (G_OBJECT (plugin->button), "button-press-event",
+ G_CALLBACK (launcher_plugin_button_press_event), plugin);
+ g_signal_connect (G_OBJECT (plugin->button), "button-release-event",
+ G_CALLBACK (launcher_plugin_button_release_event), plugin);
+ g_signal_connect (G_OBJECT (plugin->button), "query-tooltip",
+ G_CALLBACK (launcher_plugin_button_query_tooltip), plugin);
+ g_signal_connect (G_OBJECT (plugin->button), "drag-data-received",
+ G_CALLBACK (launcher_plugin_button_drag_data_received), plugin);
+ g_signal_connect_after (G_OBJECT (plugin->button), "expose-event",
+ G_CALLBACK (launcher_plugin_button_expose_event), plugin);
+
+ plugin->image = xfce_scaled_image_new ();
+ gtk_container_add (GTK_CONTAINER (plugin->button), plugin->image);
+ gtk_widget_show (plugin->image);
+
+ plugin->arrow = xfce_arrow_button_new (GTK_ARROW_UP);
+ gtk_box_pack_start (GTK_BOX (plugin->box), plugin->arrow, FALSE, FALSE, 0);
+ xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->arrow);
+ gtk_button_set_relief (GTK_BUTTON (plugin->arrow), GTK_RELIEF_NONE);
+ g_signal_connect (G_OBJECT (plugin->arrow), "button-press-event",
+ G_CALLBACK (launcher_plugin_arrow_press_event), plugin);
+
+ /* sync button states */
+ g_signal_connect (G_OBJECT (plugin->button), "state-changed",
+ G_CALLBACK (launcher_plugin_button_state_changed),
+ plugin->arrow);
+ g_signal_connect (G_OBJECT (plugin->arrow), "state-changed",
+ G_CALLBACK (launcher_plugin_button_state_changed),
+ plugin->button);
}
static void
-launcher_plugin_property_changed (XfconfChannel *channel,
- const gchar *property_name,
- const GValue *value,
- LauncherPlugin *plugin)
+launcher_plugin_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
{
- panel_return_if_fail (XFCONF_IS_CHANNEL (channel));
- panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
- panel_return_if_fail (plugin->channel == channel);
+ XfceLauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (widget);
+ gint menu_icon_size;
- if (exo_str_is_equal (property_name, "/disable-tooltips"))
- {
- plugin->disable_tooltips = g_value_get_boolean (value);
- }
- else if (exo_str_is_equal (property_name, "/items"))
- {
- /* free items */
- g_slist_foreach (plugin->items, (GFunc) g_object_unref, NULL);
- g_slist_free (plugin->items);
- plugin->items = NULL;
+ /* let gtk update the widget style */
+ (*GTK_WIDGET_CLASS (launcher_plugin_parent_class)->style_set) (widget, previous_style);
- /* load the new items */
- launcher_plugin_items_load (plugin);
+ /* read the style properties */
+ gtk_widget_style_get (widget,
+ "menu-icon-size", &menu_icon_size,
+ NULL);
- /* update the icon */
- launcher_plugin_button_set_icon (plugin);
+ if (plugin->menu_icon_size != menu_icon_size)
+ {
+ plugin->menu_icon_size = menu_icon_size;
+ launcher_plugin_menu_destroy (plugin);
}
}
@@ -157,65 +254,30 @@ launcher_plugin_property_changed (XfconfChannel *channel,
static void
launcher_plugin_construct (XfcePanelPlugin *panel_plugin)
{
- LauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
- GtkWidget *widget;
+ XfceLauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
const gchar * const *filenames;
guint i;
XfceMenuItem *item;
+ guint value;
/* open the xfconf channel */
plugin->channel = xfce_panel_plugin_xfconf_channel_new (panel_plugin);
g_signal_connect (G_OBJECT (plugin->channel), "property-changed",
G_CALLBACK (launcher_plugin_property_changed), plugin);
- /* create the dialog widgets */
- plugin->box = xfce_hvbox_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
- gtk_container_add (GTK_CONTAINER (plugin), plugin->box);
- gtk_widget_show (plugin->box);
-
- plugin->button = widget = xfce_panel_create_button ();
- gtk_box_pack_start (GTK_BOX (plugin->box), widget, TRUE, TRUE, 0);
- xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), widget);
- gtk_widget_set_has_tooltip (widget, TRUE);
- gtk_widget_show (widget);
- g_signal_connect (G_OBJECT (widget), "button-press-event",
- G_CALLBACK (launcher_plugin_button_press_event),
- plugin);
- g_signal_connect (G_OBJECT (widget), "button-release-event",
- G_CALLBACK (launcher_plugin_button_release_event),
- plugin);
- g_signal_connect (G_OBJECT (widget), "query-tooltip",
- G_CALLBACK (launcher_plugin_button_query_tooltip),
- plugin);
- g_signal_connect (G_OBJECT (widget), "drag-data-received",
- G_CALLBACK (launcher_plugin_button_drag_data_received),
- plugin);
-
- plugin->image = xfce_scaled_image_new ();
- gtk_container_add (GTK_CONTAINER (plugin->button), plugin->image);
- gtk_widget_show (plugin->image);
-
- plugin->arrow = xfce_arrow_button_new (GTK_ARROW_UP);
- gtk_box_pack_start (GTK_BOX (plugin->box), plugin->arrow, FALSE, FALSE, 0);
- xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->arrow);
- gtk_button_set_relief (GTK_BUTTON (plugin->arrow), GTK_RELIEF_NONE);
-
- /* sync button states */
- g_signal_connect (G_OBJECT (plugin->button), "state-changed",
- G_CALLBACK (launcher_plugin_button_state_changed),
- plugin->arrow);
- g_signal_connect (G_OBJECT (plugin->arrow), "state-changed",
- G_CALLBACK (launcher_plugin_button_state_changed),
- plugin->button);
-
/* load global settings */
- plugin->disable_tooltips = xfconf_channel_get_bool (plugin->channel,
- "/disable-tooltips",
- FALSE);
+ plugin->disable_tooltips =
+ xfconf_channel_get_bool (plugin->channel, "/disable-tooltips", FALSE);
+ plugin->move_first =
+ xfconf_channel_get_bool (plugin->channel, "/move-first", FALSE);
+ value = xfconf_channel_get_uint (plugin->channel, "/arrow-position",
+ LAUNCHER_ARROW_DEFAULT);
+ plugin->arrow_position = MIN (value, LAUNCHER_ARROW_MAX);
/* load the items */
launcher_plugin_items_load (plugin);
+ /* handle and empty plugin */
if (G_UNLIKELY (plugin->items == NULL))
{
/* get the plugin arguments list */
@@ -234,6 +296,12 @@ launcher_plugin_construct (XfcePanelPlugin *panel_plugin)
/* update the icon */
launcher_plugin_button_set_icon (plugin);
+
+ /* update the arrow visibility */
+ launcher_plugin_arrow_visibility (plugin);
+
+ /* repack the widgets */
+ launcher_plugin_pack_widgets (plugin);
}
@@ -241,11 +309,14 @@ launcher_plugin_construct (XfcePanelPlugin *panel_plugin)
static void
launcher_plugin_free_data (XfcePanelPlugin *panel_plugin)
{
- LauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
+ XfceLauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
/* release the xfconf channel */
g_object_unref (G_OBJECT (plugin->channel));
+ /* destroy the menu and timeout */
+ launcher_plugin_menu_destroy (plugin);
+
/* shutdown xfconf */
xfconf_shutdown ();
@@ -260,7 +331,16 @@ static void
launcher_plugin_orientation_changed (XfcePanelPlugin *panel_plugin,
GtkOrientation orientation)
{
+ /* update the widget order */
+ launcher_plugin_pack_widgets (XFCE_LAUNCHER_PLUGIN (panel_plugin));
+ /* update the arrow button */
+ launcher_plugin_screen_position_changed (panel_plugin,
+ xfce_panel_plugin_get_screen_position (panel_plugin));
+
+ /* update the plugin size */
+ launcher_plugin_size_changed (panel_plugin,
+ xfce_panel_plugin_get_size (panel_plugin));
}
@@ -269,7 +349,56 @@ static gboolean
launcher_plugin_size_changed (XfcePanelPlugin *panel_plugin,
gint size)
{
- gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), size, size);
+ XfceLauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
+ gint p_width, p_height;
+ gint a_width, a_height;
+ gboolean horizontal;
+ LauncherArrowType arrow_position;
+
+ /* initialize the plugin size */
+ p_width = p_height = size;
+ a_width = a_height = -1;
+
+ /* add the arrow size */
+ if (GTK_WIDGET_VISIBLE (plugin->arrow))
+ {
+ /* if the panel is horizontal */
+ horizontal = !!(xfce_panel_plugin_get_orientation (panel_plugin) ==
+ GTK_ORIENTATION_HORIZONTAL);
+
+ /* set tmp arrow position */
+ arrow_position = plugin->arrow_position;
+ if (arrow_position == LAUNCHER_ARROW_DEFAULT)
+ arrow_position = horizontal ? LAUNCHER_ARROW_WEST : LAUNCHER_ARROW_NORTH;
+
+ switch (plugin->arrow_position)
+ {
+ case LAUNCHER_ARROW_NORTH:
+ case LAUNCHER_ARROW_SOUTH:
+ a_height = ARROW_BUTTON_SIZE;
+
+ if (horizontal)
+ p_width -= ARROW_BUTTON_SIZE;
+ else
+ p_height += ARROW_BUTTON_SIZE;
+ break;
+
+ default:
+ a_width = ARROW_BUTTON_SIZE;
+
+ if (horizontal)
+ p_width += ARROW_BUTTON_SIZE;
+ else
+ p_height -= ARROW_BUTTON_SIZE;
+ break;
+ }
+
+ /* set the arrow size */
+ gtk_widget_set_size_request (plugin->arrow, a_width, a_height);
+ }
+
+ /* set the panel plugin size */
+ gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), p_width, p_height);
return TRUE;
}
@@ -279,15 +408,19 @@ launcher_plugin_size_changed (XfcePanelPlugin *panel_plugin,
static void
launcher_plugin_save (XfcePanelPlugin *panel_plugin)
{
- LauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
- gchar **filenames;
- guint i, length;
- GSList *li;
- XfceMenuItem *item;
+ XfceLauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
+ gchar **filenames;
+ guint i, length;
+ GSList *li;
+ XfceMenuItem *item;
/* save the global settings */
xfconf_channel_set_bool (plugin->channel, "/disable-tooltips",
plugin->disable_tooltips);
+ xfconf_channel_set_bool (plugin->channel, "/move-first",
+ plugin->move_first);
+ xfconf_channel_set_uint (plugin->channel, "/arrow-position",
+ plugin->arrow_position);
length = g_slist_length (plugin->items);
if (G_LIKELY (length > 0))
@@ -322,13 +455,319 @@ static void
launcher_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin,
gint position)
{
+ XfceLauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (panel_plugin);
+
+ /* set the new arrow direction */
+ xfce_arrow_button_set_arrow_type (XFCE_ARROW_BUTTON (plugin->arrow),
+ xfce_panel_plugin_arrow_type (panel_plugin));
+ /* destroy the menu */
+ launcher_plugin_menu_destroy (plugin);
}
static void
-launcher_plugin_button_set_icon (LauncherPlugin *plugin)
+launcher_plugin_property_changed (XfconfChannel *channel,
+ const gchar *property_name,
+ const GValue *value,
+ XfceLauncherPlugin *plugin)
+{
+ panel_return_if_fail (XFCONF_IS_CHANNEL (channel));
+ panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+ panel_return_if_fail (plugin->channel == channel);
+
+ /* destroy the menu, all the setting changes need this */
+ launcher_plugin_menu_destroy (plugin);
+
+ if (exo_str_is_equal (property_name, "/disable-tooltips"))
+ {
+ plugin->disable_tooltips = g_value_get_boolean (value);
+ }
+ else if (exo_str_is_equal (property_name, "/move-first"))
+ {
+ plugin->move_first = g_value_get_boolean (value);
+ }
+ else if (exo_str_is_equal (property_name, "/arrow-position"))
+ {
+ plugin->arrow_position = MIN (g_value_get_uint (value),
+ LAUNCHER_ARROW_MAX);
+
+ goto update_arrow;
+
+ }
+ else if (exo_str_is_equal (property_name, "/items"))
+ {
+ /* free items */
+ g_slist_foreach (plugin->items, (GFunc) g_object_unref, NULL);
+ g_slist_free (plugin->items);
+ plugin->items = NULL;
+
+ /* load the new items */
+ launcher_plugin_items_load (plugin);
+
+ /* update the icon */
+ launcher_plugin_button_set_icon (plugin);
+
+ update_arrow:
+
+ /* update the arrow button visibility */
+ launcher_plugin_arrow_visibility (plugin);
+
+ /* repack the widgets */
+ launcher_plugin_pack_widgets (plugin);
+
+ /* update the plugin size */
+ launcher_plugin_size_changed (XFCE_PANEL_PLUGIN (plugin),
+ xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin)));
+ }
+}
+
+
+
+static void
+launcher_plugin_icon_theme_changed (GtkIconTheme *icon_theme,
+ XfceLauncherPlugin *plugin)
+{
+ panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+ panel_return_if_fail (GTK_IS_ICON_THEME (icon_theme));
+
+ /* update the button icon */
+ launcher_plugin_button_set_icon (plugin);
+
+ /* destroy the menu */
+ launcher_plugin_menu_destroy (plugin);
+}
+
+
+
+static void
+launcher_plugin_pack_widgets (XfceLauncherPlugin *plugin)
+{
+ LauncherArrowType pos = plugin->arrow_position;
+ gboolean rtl;
+
+ panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+
+ /* leave when the arrow button is not visible */
+ if (!GTK_WIDGET_VISIBLE (plugin->arrow)
+ || pos == LAUNCHER_ARROW_INTERNAL)
+ return;
+
+ if (pos == LAUNCHER_ARROW_DEFAULT)
+ {
+ /* get the plugin direction */
+ rtl = !!(gtk_widget_get_direction (GTK_WIDGET (plugin)) == GTK_TEXT_DIR_RTL);
+
+ if (xfce_panel_plugin_get_orientation (XFCE_PANEL_PLUGIN (plugin)) ==
+ GTK_ORIENTATION_HORIZONTAL)
+ pos = rtl ? LAUNCHER_ARROW_WEST : LAUNCHER_ARROW_EAST;
+ else
+ pos = rtl ? LAUNCHER_ARROW_NORTH : LAUNCHER_ARROW_SOUTH;
+ }
+
+ /* set the position of the arrow button in the box */
+ gtk_box_reorder_child (GTK_BOX (plugin->box), plugin->arrow,
+ (pos == LAUNCHER_ARROW_WEST || pos == LAUNCHER_ARROW_NORTH) ? 0 : -1);
+
+ /* set the orientation of the hvbox */
+ xfce_hvbox_set_orientation (XFCE_HVBOX (plugin->box),
+ !!(pos == LAUNCHER_ARROW_WEST || pos == LAUNCHER_ARROW_EAST) ?
+ GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
+}
+
+
+
+static void
+launcher_plugin_menu_deactivate (GtkWidget *menu,
+ XfceLauncherPlugin *plugin)
+{
+ panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+ panel_return_if_fail (plugin->menu == menu);
+
+ /* deactivate the arrow button */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->arrow), FALSE);
+}
+
+
+
+static gboolean
+launcher_plugin_menu_item_released (GtkMenuItem *widget,
+ GdkEventButton *event,
+ XfceMenuItem *item)
+{
+ XfceLauncherPlugin *plugin;
+ GdkScreen *screen;
+
+ panel_return_val_if_fail (GTK_IS_MENU_ITEM (widget), FALSE);
+ panel_return_val_if_fail (XFCE_IS_MENU_ITEM (item), FALSE);
+
+ /* get the widget screen */
+ screen = gtk_widget_get_screen (GTK_WIDGET (widget));
+
+ /* launch the command */
+ if (G_UNLIKELY (event->button == 2))
+ launcher_plugin_item_exec_from_clipboard (item, event->time, screen);
+ else
+ launcher_plugin_item_exec (item, event->time, screen, NULL);
+
+ /* get the plugin */
+ plugin = g_object_get_qdata (G_OBJECT (widget), launcher_plugin_quark);
+ panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
+
+ /* move the item to the first position if enabled */
+ if (G_UNLIKELY (plugin->move_first))
+ {
+ /* prepend the item in the list */
+ plugin->items = g_slist_remove (plugin->items, item);
+ plugin->items = g_slist_prepend (plugin->items, item);
+
+ /* destroy the menu and update the icon */
+ launcher_plugin_menu_destroy (plugin);
+ launcher_plugin_button_set_icon (plugin);
+ }
+
+ return FALSE;
+}
+
+
+
+static void
+launcher_plugin_menu_construct (XfceLauncherPlugin *plugin)
+{
+ GtkArrowType arrow_type;
+ guint n;
+ XfceMenuItem *item;
+ GtkWidget *mi, *image;
+ const gchar *name, *icon_name;
+ GSList *li;
+ GdkPixbuf *pixbuf;
+
+ panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+ panel_return_if_fail (plugin->menu == NULL);
+
+ /* create a new menu */
+ plugin->menu = gtk_menu_new ();
+ gtk_menu_attach_to_widget (GTK_MENU (plugin->menu), GTK_WIDGET (plugin), NULL);
+ g_signal_connect (G_OBJECT (plugin->menu), "deactivate",
+ G_CALLBACK (launcher_plugin_menu_deactivate), plugin);
+
+ /* get the arrow type of the plugin */
+ arrow_type = xfce_arrow_button_get_arrow_type (XFCE_ARROW_BUTTON (plugin->arrow));
+
+ /* walk through the menu entries */
+ for (li = plugin->items, n = 0; li != NULL; li = li->next, n++)
+ {
+ /* skip the first entry when the arrow is visible */
+ if (n == 0 && plugin->arrow_position != LAUNCHER_ARROW_INTERNAL)
+ continue;
+
+ /* get the item data */
+ item = XFCE_MENU_ITEM (li->data);
+
+ /* create the menu item */
+ name = xfce_menu_item_get_name (item);
+ mi = gtk_image_menu_item_new_with_label (IS_STRING (name) ? name :
+ _("Unnamed Item"));
+ g_object_set_qdata (G_OBJECT (mi), launcher_plugin_quark, plugin);
+ gtk_widget_set_has_tooltip (mi, TRUE);
+ gtk_widget_show (mi);
+ g_signal_connect (G_OBJECT (mi), "button-release-event",
+ G_CALLBACK (launcher_plugin_menu_item_released), item);
+
+ /* only connect the tooltip signal if tips are enabled */
+ if (plugin->disable_tooltips == FALSE)
+ g_signal_connect (G_OBJECT (mi), "query-tooltip",
+ G_CALLBACK (launcher_plugin_item_query_tooltip), item);
+
+ /* depending on the menu position we prepend or append */
+ if (G_UNLIKELY (arrow_type == GTK_ARROW_DOWN))
+ gtk_menu_shell_append (GTK_MENU_SHELL (plugin->menu), mi);
+ else
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (plugin->menu), mi);
+
+ /* set the icon if one is set */
+ icon_name = xfce_menu_item_get_icon_name (item);
+ if (IS_STRING (icon_name))
+ {
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+ icon_name, plugin->menu_icon_size,
+ 0, NULL);
+ if (G_LIKELY (pixbuf != NULL))
+ {
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
+ gtk_widget_show (image);
+
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+ }
+ }
+}
+
+
+
+static void
+launcher_plugin_menu_popup_destroyed (gpointer user_data)
+{
+ XFCE_LAUNCHER_PLUGIN (user_data)->menu_timeout_id = 0;
+}
+
+
+
+static gboolean
+launcher_plugin_menu_popup (gpointer user_data)
+{
+ XfceLauncherPlugin *plugin = XFCE_LAUNCHER_PLUGIN (user_data);
+
+ panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
+
+ GDK_THREADS_ENTER ();
+
+ /* construct the menu if needed */
+ if (plugin->menu == NULL)
+ launcher_plugin_menu_construct (plugin);
+
+ /* toggle the arrow button */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->arrow), TRUE);
+
+ /* popup the menu */
+ gtk_menu_popup (GTK_MENU (plugin->menu), NULL, NULL,
+ xfce_panel_plugin_position_menu,
+ XFCE_PANEL_PLUGIN (plugin), 1,
+ gtk_get_current_event_time ());
+
+ GDK_THREADS_LEAVE ();
+
+ return FALSE;
+}
+
+
+
+static void
+launcher_plugin_menu_destroy (XfceLauncherPlugin *plugin)
+{
+ panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+
+ /* stop pending timeout */
+ if (plugin->menu_timeout_id != 0)
+ g_source_remove (plugin->menu_timeout_id);
+
+ if (plugin->menu != NULL)
+ {
+ /* destroy the menu */
+ gtk_widget_destroy (plugin->menu);
+ plugin->menu = NULL;
+
+ /* deactivate the toggle button */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->arrow), FALSE);
+ }
+}
+
+
+
+static void
+launcher_plugin_button_set_icon (XfceLauncherPlugin *plugin)
{
XfceMenuItem *item;
const gchar *icon_name;
@@ -374,37 +813,72 @@ launcher_plugin_button_state_changed (GtkWidget *button_a,
static gboolean
-launcher_plugin_button_press_event (GtkWidget *button,
- GdkEventButton *event,
- LauncherPlugin *plugin)
+launcher_plugin_button_press_event (GtkWidget *button,
+ GdkEventButton *event,
+ XfceLauncherPlugin *plugin)
{
+ guint modifiers;
+
panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
/* do nothing on anything else then a single click */
if (event->type != GDK_BUTTON_PRESS)
return FALSE;
+ /* get the default accelerator modifier mask */
+ modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
+
+ /* leave when button 1 is not pressed or shift is pressed */
+ if (event->button != 1 || modifiers == GDK_CONTROL_MASK)
+ return FALSE;
+
+ if (plugin->arrow_position == LAUNCHER_ARROW_INTERNAL
+ && LIST_HAS_TWO_OR_MORE_ENTRIES (plugin->items))
+ {
+ /* directly popup the menu */
+ launcher_plugin_menu_popup (plugin);
+ }
+ else if (plugin->menu_timeout_id == 0
+ && LIST_HAS_TWO_OR_MORE_ENTRIES (plugin->items))
+ {
+ /* start the popup timeout */
+ plugin->menu_timeout_id =
+ g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
+ MENU_POPUP_DELAY,
+ launcher_plugin_menu_popup, plugin,
+ launcher_plugin_menu_popup_destroyed);
+ }
+
return FALSE;
}
static gboolean
-launcher_plugin_button_release_event (GtkWidget *button,
- GdkEventButton *event,
- LauncherPlugin *plugin)
+launcher_plugin_button_release_event (GtkWidget *button,
+ GdkEventButton *event,
+ XfceLauncherPlugin *plugin)
{
XfceMenuItem *item;
GdkScreen *screen;
panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
- if (G_UNLIKELY (plugin->items == NULL))
+ /* remove a delayed popup timeout */
+ if (plugin->menu_timeout_id != 0)
+ g_source_remove (plugin->menu_timeout_id);
+
+ /* leave when there are no menu items or there is an internal arrow */
+ if (plugin->items == NULL || GTK_BUTTON (button)->in_button == FALSE
+ || (plugin->arrow_position == LAUNCHER_ARROW_INTERNAL
+ && LIST_HAS_TWO_OR_MORE_ENTRIES (plugin->items)))
return FALSE;
+ /* get the menu item and the screen */
item = XFCE_MENU_ITEM (plugin->items->data);
screen = gtk_widget_get_screen (button);
+ /* launcher the entry */
if (event->button == 1)
launcher_plugin_item_exec (item, event->time, screen, NULL);
else if (event->button == 2)
@@ -418,12 +892,12 @@ launcher_plugin_button_release_event (GtkWidget *button,
static gboolean
-launcher_plugin_button_query_tooltip (GtkWidget *widget,
- gint x,
- gint y,
- gboolean keyboard_mode,
- GtkTooltip *tooltip,
- LauncherPlugin *plugin)
+launcher_plugin_button_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip,
+ XfceLauncherPlugin *plugin)
{
panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
@@ -441,24 +915,141 @@ launcher_plugin_button_query_tooltip (GtkWidget *widget,
static void
-launcher_plugin_button_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint drag_time,
- LauncherPlugin *plugin)
+launcher_plugin_button_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint drag_time,
+ XfceLauncherPlugin *plugin)
{
+ GSList *uri_list;
+
panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+ /* leave when there are not items or the arrow is internal */
+ if (plugin->arrow_position == LAUNCHER_ARROW_INTERNAL
+ || plugin->items == NULL)
+ return;
+
+ /* get the list of uris from the selection data */
+ uri_list = launcher_plugin_uri_list_extract (selection_data);
+ if (G_LIKELY (uri_list != NULL))
+ {
+ /* execute */
+ launcher_plugin_item_exec (XFCE_MENU_ITEM (plugin->items->data),
+ gtk_get_current_event_time (),
+ gtk_widget_get_screen (widget),
+ uri_list);
+
+ /* cleanup */
+ launcher_plugin_uri_list_free (uri_list);
+ }
+
gtk_drag_finish (context, TRUE, FALSE, drag_time);
}
+static gboolean
+launcher_plugin_button_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ XfceLauncherPlugin *plugin)
+{
+ GtkArrowType arrow_type;
+ gint size, x, y, thickness, offset;
+
+ panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
+
+ /* leave when the arrow is not shown inside the button or there are
+ * no menu items */
+ if (plugin->arrow_position != LAUNCHER_ARROW_INTERNAL
+ || !LIST_HAS_TWO_OR_MORE_ENTRIES (plugin->items))
+ return FALSE;
+
+ /* get the arrow type */
+ arrow_type = xfce_arrow_button_get_arrow_type (XFCE_ARROW_BUTTON (plugin->arrow));
+
+ /* style thickness */
+ thickness = MAX (widget->style->xthickness, widget->style->ythickness);
+
+ /* size of the arrow and the start coordinates */
+ size = widget->allocation.width / 3;
+ x = widget->allocation.x + thickness;
+ y = widget->allocation.y + thickness;
+ offset = size + 2 * thickness;
+
+ /* calculate the position based on the arrow type */
+ switch (arrow_type)
+ {
+ case GTK_ARROW_UP:
+ /* north east */
+ x += widget->allocation.width - offset;
+ break;
+
+ case GTK_ARROW_DOWN:
+ /* south west */
+ y += widget->allocation.height - offset;
+ break;
+
+ case GTK_ARROW_RIGHT:
+ /* south east */
+ x += widget->allocation.width - offset;
+ y += widget->allocation.height - offset;
+ break;
+
+ default:
+ /* north west */
+ break;
+ }
+
+ /* paint the arrow */
+ gtk_paint_arrow (widget->style, widget->window,
+ GTK_WIDGET_STATE (widget), GTK_SHADOW_IN,
+ &(event->area), widget, "launcher_button",
+ arrow_type, TRUE, x, y, size, size);
+
+ return FALSE;
+}
+
+
+
+static void
+launcher_plugin_arrow_visibility (XfceLauncherPlugin *plugin)
+{
+ panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+
+ if (plugin->arrow_position != LAUNCHER_ARROW_INTERNAL
+ && LIST_HAS_TWO_OR_MORE_ENTRIES (plugin->items))
+ gtk_widget_show (plugin->arrow);
+ else
+ gtk_widget_hide (plugin->arrow);
+}
+
+
+
+static gboolean
+launcher_plugin_arrow_press_event (GtkWidget *button,
+ GdkEventButton *event,
+ XfceLauncherPlugin *plugin)
+{
+ panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
+
+ /* only popup when button 1 is pressed */
+ if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
+ {
+ launcher_plugin_menu_popup (plugin);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
static void
-launcher_plugin_items_load (LauncherPlugin *plugin)
+launcher_plugin_items_load (XfceLauncherPlugin *plugin)
{
gchar **filenames;
guint i;
@@ -541,6 +1132,7 @@ launcher_plugin_item_exec_on_screen (XfceMenuItem *item,
gboolean succeed = FALSE;
panel_return_val_if_fail (XFCE_IS_MENU_ITEM (item), FALSE);
+ panel_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
/* parse the execute command */
if (launcher_plugin_exec_parse (item, uri_list, NULL, &argv, &error))
@@ -560,8 +1152,11 @@ launcher_plugin_item_exec_on_screen (XfceMenuItem *item,
if (G_UNLIKELY (succeed == FALSE))
{
- /* TODO make this some nice error dialog */
- g_message ("Failed to launch.... (%s)", error->message);
+ /* show an error dialog */
+ xfce_dialog_show_error (screen, error, _("Failed to execute command \"%s\"."),
+ xfce_menu_item_get_command (item));
+
+ /* cleanup */
g_error_free (error);
}
@@ -581,6 +1176,7 @@ launcher_plugin_item_exec (XfceMenuItem *item,
const gchar *command;
panel_return_if_fail (XFCE_IS_MENU_ITEM (item));
+ panel_return_if_fail (GDK_IS_SCREEN (screen));
/* leave when there is nothing to execute */
command = xfce_menu_item_get_command (item);
@@ -597,15 +1193,14 @@ launcher_plugin_item_exec (XfceMenuItem *item,
for (li = uri_list; li != NULL && proceed; li = li->next)
{
fake.data = li->data;
- proceed = launcher_plugin_item_exec_on_screen (item,
- event_time,
+ proceed = launcher_plugin_item_exec_on_screen (item, event_time,
screen, &fake);
}
}
else
{
- launcher_plugin_item_exec_on_screen (item, event_time, screen,
- uri_list);
+ launcher_plugin_item_exec_on_screen (item, event_time,
+ screen, uri_list);
}
}
@@ -613,12 +1208,51 @@ launcher_plugin_item_exec (XfceMenuItem *item,
static void
launcher_plugin_item_exec_from_clipboard (XfceMenuItem *item,
- guint32 event_time,
- GdkScreen *screen)
+ guint32 event_time,
+ GdkScreen *screen)
{
+ GtkClipboard *clipboard;
+ gchar *text = NULL;
+ GSList *uri_list;
+ GtkSelectionData data;
+
panel_return_if_fail (XFCE_IS_MENU_ITEM (item));
+ panel_return_if_fail (GDK_IS_SCREEN (screen));
+
+ /* get the primary clipboard text */
+ clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+ if (G_LIKELY (clipboard))
+ text = gtk_clipboard_wait_for_text (clipboard);
+
+ /* try the secondary keayboard if the text is empty */
+ if (IS_STRING (text))
+ {
+ /* get the secondary clipboard text */
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ if (G_LIKELY (clipboard))
+ text = gtk_clipboard_wait_for_text (clipboard);
+ }
- /* TODO */
+ if (IS_STRING (text))
+ {
+ /* create fake selection data */
+ data.data = (guchar *) text;
+ data.length = strlen (text);
+ data.target = GDK_NONE;
+
+ /* extract the uris from the selection data */
+ uri_list = launcher_plugin_uri_list_extract (&data);
+
+ /* launch with the uri list */
+ launcher_plugin_item_exec (item, event_time,
+ screen, uri_list);
+
+ /* cleanup */
+ launcher_plugin_uri_list_free (uri_list);
+ }
+
+ /* cleanup */
+ g_free (text);
}
@@ -740,8 +1374,96 @@ launcher_plugin_exec_parse (XfceMenuItem *item,
+static GSList *
+launcher_plugin_uri_list_extract (GtkSelectionData *data)
+{
+ GSList *list = NULL;
+ gchar **array;
+ guint i;
+ gchar *uri;
+ gint j;
+
+ /* leave if there is no data */
+ if (data->length <= 0)
+ return NULL;
+
+ /* extract the files */
+ if (data->target == gdk_atom_intern_static_string ("text/uri-list"))
+ {
+ /* extract the list of uris */
+ array = g_uri_list_extract_uris ((gchar *) data->data);
+ if (G_UNLIKELY (array == NULL))
+ return NULL;
+
+ /* create the list of uris */
+ for (i = 0; array[i] != NULL; i++)
+ {
+ if (IS_STRING (array[i]))
+ list = g_slist_prepend (list, array[i]);
+ else
+ g_free (array[i]);
+ }
+
+ /* cleanup */
+ g_free (array);
+ }
+ else
+ {
+ /* split the data on new lines */
+ array = g_strsplit_set ((const gchar *) data->data, "\n\r", -1);
+ if (G_UNLIKELY (array == NULL))
+ return NULL;
+
+ /* create the list of uris */
+ for (i = 0; array[i] != NULL; i++)
+ {
+ /* skip empty strings */
+ if (!IS_STRING (array[i]))
+ continue;
+
+ uri = NULL;
+
+ if (g_path_is_absolute (array[i]))
+ {
+ /* convert the filename to an uri */
+ uri = g_filename_to_uri (array[i], NULL, NULL);
+ }
+ else if (data->length > 6)
+ {
+ /* check if this looks like an other uri, if it does, use it */
+ for (j = 3; uri == NULL && j <= 5; j++)
+ if (g_str_has_prefix (array[i] + j, "://"))
+ uri = g_strdup (array[i]);
+ }
+
+ /* append the uri if we extracted one */
+ if (G_LIKELY (uri != NULL))
+ list = g_slist_prepend (list, uri);
+ }
+
+ /* cleanup */
+ g_strfreev (array);
+ }
+
+ return g_slist_reverse (list);
+}
+
+
+
+static void
+launcher_plugin_uri_list_free (GSList *uri_list)
+{
+ if (uri_list != NULL)
+ {
+ g_slist_foreach (uri_list, (GFunc) g_free, NULL);
+ g_slist_free (uri_list);
+ }
+}
+
+
+
XfconfChannel *
-launcher_plugin_get_channel (LauncherPlugin *plugin)
+launcher_plugin_get_channel (XfceLauncherPlugin *plugin)
{
panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), NULL);
return plugin->channel;
@@ -750,7 +1472,7 @@ launcher_plugin_get_channel (LauncherPlugin *plugin)
GSList *
-launcher_plugin_get_items (LauncherPlugin *plugin)
+launcher_plugin_get_items (XfceLauncherPlugin *plugin)
{
panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), NULL);
return plugin->items;
diff --git a/plugins/launcher/launcher.h b/plugins/launcher/launcher.h
index 67b1964..4b6eae9 100644
--- a/plugins/launcher/launcher.h
+++ b/plugins/launcher/launcher.h
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (C) 2008-2009 Nick Schermer <nick at xfce.org>
- *
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
@@ -27,22 +27,34 @@
G_BEGIN_DECLS
-typedef struct _LauncherPluginClass LauncherPluginClass;
-typedef struct _LauncherPlugin LauncherPlugin;
-typedef struct _LauncherEntry LauncherEntry;
+typedef struct _XfceLauncherPluginClass XfceLauncherPluginClass;
+typedef struct _XfceLauncherPlugin XfceLauncherPlugin;
+typedef enum _LauncherArrowType LauncherArrowType;
#define XFCE_TYPE_LAUNCHER_PLUGIN (launcher_plugin_get_type ())
-#define XFCE_LAUNCHER_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_LAUNCHER_PLUGIN, LauncherPlugin))
-#define XFCE_LAUNCHER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_LAUNCHER_PLUGIN, LauncherPluginClass))
+#define XFCE_LAUNCHER_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_LAUNCHER_PLUGIN, XfceLauncherPlugin))
+#define XFCE_LAUNCHER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_LAUNCHER_PLUGIN, XfceLauncherPluginClass))
#define XFCE_IS_LAUNCHER_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_LAUNCHER_PLUGIN))
#define XFCE_IS_LAUNCHER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_LAUNCHER_PLUGIN))
-#define XFCE_LAUNCHER_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_LAUNCHER_PLUGIN, LauncherPluginClass))
+#define XFCE_LAUNCHER_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_LAUNCHER_PLUGIN, XfceLauncherPluginClass))
+
+enum _LauncherArrowType
+{
+ LAUNCHER_ARROW_DEFAULT = 0,
+ LAUNCHER_ARROW_NORTH,
+ LAUNCHER_ARROW_WEST,
+ LAUNCHER_ARROW_EAST,
+ LAUNCHER_ARROW_SOUTH,
+ LAUNCHER_ARROW_INTERNAL,
+
+ LAUNCHER_ARROW_MAX = LAUNCHER_ARROW_INTERNAL
+};
GType launcher_plugin_get_type (void) G_GNUC_CONST;
-XfconfChannel *launcher_plugin_get_channel (LauncherPlugin *plugin);
+XfconfChannel *launcher_plugin_get_channel (XfceLauncherPlugin *plugin);
-GSList *launcher_plugin_get_items (LauncherPlugin *plugin);
+GSList *launcher_plugin_get_items (XfceLauncherPlugin *plugin);
G_END_DECLS
More information about the Xfce4-commits
mailing list