[Xfce4-commits] <xfce4-panel:devel> * Move in object code, not working yet.

Nick Schermer nick at xfce.org
Tue Aug 11 20:24:35 CEST 2009


Updating branch refs/heads/devel
         to 7dd6a311b440570842ea8dae03bccfb558833cc9 (commit)
       from ed48562fb52f8135cf953c7a19647844fda8c4d0 (commit)

commit 7dd6a311b440570842ea8dae03bccfb558833cc9
Author: Nick Schermer <nick at xfce.org>
Date:   Wed Oct 8 23:09:41 2008 +0200

    * Move in object code, not working yet.

 plugins/launcher/launcher-dialog.c | 1594 -------------------------------
 plugins/launcher/launcher-dialog.h |   28 -
 plugins/launcher/launcher-exec.c   |  639 -------------
 plugins/launcher/launcher-exec.h   |   29 -
 plugins/launcher/launcher.c        | 1810 ++++++++++++++++--------------------
 plugins/launcher/launcher.h        |  176 ++--
 6 files changed, 858 insertions(+), 3418 deletions(-)

diff --git a/plugins/launcher/launcher-dialog.c b/plugins/launcher/launcher-dialog.c
deleted file mode 100644
index b46b906..0000000
--- a/plugins/launcher/launcher-dialog.c
+++ /dev/null
@@ -1,1594 +0,0 @@
-/*  $Id: launcher-dialog.c 26139 2007-10-17 09:21:10Z nick $
- *
- *  Copyright (c) 2005-2007 Jasper Huijsmans <jasper at xfce.org>
- *  Copyright (c) 2006-2007 Nick Schermer <nick at xfce.org>
- *  Copyright (c) 2005-2006 Benedikt Meurer <benny 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) any later version.
- *
- *  This program 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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include <libxfce4ui/libxfce4ui.h>
-#include <libxfce4panel/libxfce4panel.h>
-
-#include "launcher.h"
-#include "launcher-dialog.h"
-
-
-enum
-{
-    COLUMN_ICON = 0,
-    COLUMN_NAME
-};
-
-typedef struct _LauncherDialog LauncherDialog;
-
-struct _LauncherDialog
-{
-    LauncherPlugin *launcher;
-
-    /* stored setting */
-    guint           stored_move_first : 1;
-
-    /* arrow position */
-    GtkWidget      *arrow_position;
-
-    /* entries list */
-    GtkWidget      *treeview;
-    GtkListStore   *store;
-
-    /* tree buttons */
-    GtkWidget      *up;
-    GtkWidget      *down;
-    GtkWidget      *add;
-    GtkWidget      *remove;
-
-    /* lock */
-    guint           updating : 1;
-
-    /* active entry */
-    LauncherEntry  *entry;
-
-    /* entry widgets */
-    GtkWidget      *entry_name;
-    GtkWidget      *entry_comment;
-    GtkWidget      *entry_icon;
-    GtkWidget      *entry_exec;
-    GtkWidget      *entry_path;
-    GtkWidget      *entry_terminal;
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    GtkWidget      *entry_startup;
-#endif
-};
-
-
-
-/**
- * Prototypes
- **/
-static void        launcher_dialog_g_list_swap               (GList                 *li_a,
-                                                              GList                 *li_b);
-static void        launcher_dialog_tree_drag_data_received   (GtkWidget             *widget,
-                                                              GdkDragContext        *context,
-                                                              gint                   x,
-                                                              gint                   y,
-                                                              GtkSelectionData      *selection_data,
-                                                              guint                  info,
-                                                              guint                  time,
-                                                              LauncherDialog        *ld);
-static void        launcher_dialog_frame_drag_data_received  (GtkWidget             *widget,
-                                                              GdkDragContext        *context,
-                                                              gint                   x,
-                                                              gint                   y,
-                                                              GtkSelectionData      *selection_data,
-                                                              guint                  info,
-                                                              guint                  time,
-                                                              LauncherDialog        *ld);
-static void        launcher_dialog_save_entry                (GtkWidget             *entry,
-                                                               LauncherDialog        *ld);
-static void        launcher_dialog_save_button               (GtkWidget             *button,
-                                                              LauncherDialog        *ld);
-static void        launcher_dialog_update_entries            (LauncherDialog        *ld);
-static void        launcher_dialog_update_icon               (LauncherDialog        *ld);
-static void        launcher_dialog_folder_chooser            (LauncherDialog        *ld);
-static void        launcher_dialog_command_chooser           (LauncherDialog        *ld);
-static void        launcher_dialog_icon_chooser              (LauncherDialog        *ld);
-static void        launcher_dialog_tree_update_row           (LauncherDialog        *ld,
-                                                              gint                   column);
-static void        launcher_dialog_tree_selection_changed    (LauncherDialog        *ld,
-                                                              GtkTreeSelection      *selection);
-static void        launcher_dialog_tree_button_clicked       (GtkWidget             *button,
-                                                              LauncherDialog        *ld);
-static GtkWidget  *launcher_dialog_add_properties            (LauncherDialog        *ld) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-static GtkWidget  *launcher_dialog_add_tree                  (LauncherDialog        *ld) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-static GtkWidget  *launcher_dialog_add_tree_buttons          (LauncherDialog        *ld) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-static void        launcher_dialog_response                  (GtkWidget             *dialog,
-                                                              gint                   response,
-                                                              LauncherDialog        *ld);
-
-
-
-/**
- * .Desktop entry
- **/
-static void
-launcher_dialog_g_list_swap (GList *li_a,
-                             GList *li_b)
-{
-    gpointer data;
-
-    /* swap the data pointers */
-    data = li_a->data;
-    li_a->data = li_b->data;
-    li_b->data = data;
-}
-
-
-gboolean
-launcher_dialog_read_desktop_file (const gchar   *path,
-                                   LauncherEntry *entry)
-{
-    XfceRc      *rc = NULL;
-    const gchar *value = NULL;
-    const gchar *p;
-
-    /* we only support .desktop files */
-    if (G_UNLIKELY (g_str_has_suffix (path, ".desktop") == FALSE ||
-                    g_path_is_absolute (path) == FALSE))
-        return FALSE;
-
-    /* open de .desktop file */
-    rc = xfce_rc_simple_open (path, TRUE);
-    if (G_UNLIKELY (rc == NULL))
-        return FALSE;
-
-    /* set the desktop entry group */
-    xfce_rc_set_group (rc, "Desktop Entry");
-
-    /* name */
-    value = xfce_rc_read_entry (rc, "Name", NULL);
-    if (G_LIKELY (value != NULL))
-    {
-        g_free (entry->name);
-        entry->name = g_strdup (value);
-    }
-
-    /* comment */
-    value = xfce_rc_read_entry (rc, "Comment", NULL);
-    if (G_LIKELY (value != NULL))
-    {
-        g_free (entry->comment);
-        entry->comment = g_strdup (value);
-    }
-
-    /* icon */
-    value = xfce_rc_read_entry_untranslated (rc, "Icon", NULL);
-    if (G_LIKELY (value != NULL))
-    {
-        g_free (entry->icon);
-
-        /* get rid of extensions in non-absolute names */
-        if (G_UNLIKELY (g_path_is_absolute (value) == FALSE) &&
-            ((p = g_strrstr (value, ".")) && strlen (p) < 6))
-            entry->icon = g_strndup (value, p-value);
-        else
-            entry->icon = g_strdup (value);
-    }
-
-    /* exec */
-    value = xfce_rc_read_entry_untranslated (rc, "Exec", NULL);
-    if (G_LIKELY (value != NULL))
-    {
-        g_free (entry->exec);
-
-        /* expand variables and store */
-        entry->exec = value ? xfce_expand_variables (value, NULL) : NULL;
-    }
-
-    /* working directory */
-    value = xfce_rc_read_entry_untranslated (rc, "Path", NULL);
-    if (G_UNLIKELY (value != NULL))
-    {
-        g_free (entry->path);
-
-        /* expand variables and store */
-        entry->path = value ? xfce_expand_variables (value, NULL) : NULL;
-    }
-
-    /* terminal */
-    entry->terminal = xfce_rc_read_bool_entry (rc, "Terminal", FALSE);
-
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    /* startup notification */
-    entry->startup = xfce_rc_read_bool_entry (rc, "StartupNotify", FALSE);
-#endif
-
-    /* release rc file */
-    xfce_rc_close (rc);
-
-    return TRUE;
-}
-
-
-
-static void
-launcher_dialog_tree_drag_data_received (GtkWidget        *widget,
-                                         GdkDragContext   *context,
-                                         gint              x,
-                                         gint              y,
-                                         GtkSelectionData *selection_data,
-                                         guint             info,
-                                         guint             time,
-                                         LauncherDialog   *ld)
-{
-    GtkTreePath             *path = NULL;
-    GtkTreeViewDropPosition  position;
-    GtkTreeModel            *model;
-    GtkTreeIter              iter_a;
-    GtkTreeIter              iter_b;
-    GSList                  *filenames = NULL;
-    GSList                  *li;
-    const gchar             *file;
-    gboolean                 insert_before = FALSE;
-    gboolean                 update_icon = FALSE;
-    gint                     i = 0;
-    LauncherEntry           *entry;
-    GdkPixbuf               *pixbuf;
-
-    /* get drop position in the tree */
-    if (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (ld->treeview),
-                                           x, y, &path, &position) == FALSE)
-    {
-        /* probably droped in empty tree space, drop after last item */
-        path = gtk_tree_path_new_from_indices (g_list_length (ld->launcher->entries) -1 , -1);
-        position = GTK_TREE_VIEW_DROP_AFTER;
-    }
-
-    if (G_LIKELY (path != NULL))
-    {
-        /* get the iter we're going to drop after */
-        model = gtk_tree_view_get_model (GTK_TREE_VIEW (ld->treeview));
-        gtk_tree_model_get_iter (model,  &iter_a, path);
-
-        /* array position or current item */
-        i = gtk_tree_path_get_indices (path)[0];
-
-        /* insert position, array correction and the path we select afterwards */
-        switch (position)
-        {
-            case GTK_TREE_VIEW_DROP_BEFORE:
-            case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
-                insert_before = TRUE;
-                break;
-
-            case GTK_TREE_VIEW_DROP_AFTER:
-            case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
-                gtk_tree_path_next (path);
-                ++i;
-                insert_before = FALSE;
-                break;
-         }
-
-        /* we need to update the button icon afterwards */
-        if (i == 0)
-            update_icon = TRUE;
-
-        /* create list from selection data */
-        filenames = launcher_utility_filenames_from_selection_data (selection_data);
-    }
-
-    if (G_LIKELY (filenames != NULL))
-    {
-        for (li = filenames; li != NULL; li = li->next)
-        {
-            file = li->data;
-
-            /* create new entry */
-            entry = launcher_entry_new ();
-
-            /* try to parse desktop file */
-            if (G_LIKELY (launcher_dialog_read_desktop_file (file, entry) == TRUE))
-            {
-                /* insert new row in store */
-                if (insert_before)
-                    gtk_list_store_insert_before (ld->store, &iter_b, &iter_a);
-                else
-                    gtk_list_store_insert_after (ld->store, &iter_b, &iter_a);
-
-                /* try to load the pixbuf */
-                pixbuf = launcher_utility_load_pixbuf (gtk_widget_get_screen (ld->treeview), entry->icon, LAUNCHER_TREE_ICON_SIZE);
-
-                /* set tree data */
-                gtk_list_store_set (ld->store, &iter_b,
-                                    COLUMN_ICON, pixbuf,
-                                    COLUMN_NAME, entry->name,
-                                    -1);
-
-                /* release pixbuf */
-                if (G_LIKELY (pixbuf != NULL))
-                    g_object_unref (G_OBJECT (pixbuf));
-
-                /* insert in list */
-                ld->launcher->entries = g_list_insert (ld->launcher->entries, entry, i);
-
-                /* copy iter, so we add after last item */
-                iter_a = iter_b;
-
-                /* raise position counter */
-                ++i;
-
-                /* 1st item is inserted before existing item, after
-                 * that we insert after the 1st item */
-                insert_before = FALSE;
-            }
-            else
-            {
-                /* desktop file pasring failed, free new entry */
-                launcher_entry_free (entry, NULL);
-            }
-        }
-
-        /* select the new item (also updates treeview buttons) */
-        gtk_tree_view_set_cursor (GTK_TREE_VIEW (ld->treeview), path, NULL, FALSE);
-
-        /* update the panel */
-        launcher_plugin_rebuild (ld->launcher, update_icon);
-
-        /* cleanup */
-        launcher_free_filenames (filenames);
-    }
-
-    /* free path */
-    if (G_LIKELY (path != NULL))
-        gtk_tree_path_free (path);
-
-    /* finish drag */
-    gtk_drag_finish (context, TRUE, FALSE, time);
-}
-
-
-
-static void
-launcher_dialog_frame_drag_data_received (GtkWidget        *widget,
-                                          GdkDragContext   *context,
-                                          gint              x,
-                                          gint              y,
-                                          GtkSelectionData *selection_data,
-                                          guint             info,
-                                          guint             time,
-                                          LauncherDialog   *ld)
-{
-    GSList   *filenames, *li;
-    gchar    *file;
-    gboolean  update_icon = FALSE;
-
-    /* create list from all the uri list */
-    filenames = launcher_utility_filenames_from_selection_data (selection_data);
-
-    if (G_LIKELY (filenames != NULL))
-    {
-        for (li = filenames; li != NULL; li = li->next)
-        {
-            file = (gchar *) li->data;
-
-            /* try to update the current entry settings */
-            if (G_LIKELY (launcher_dialog_read_desktop_file (file, ld->entry) == TRUE))
-            {
-                /* update the widgets */
-                launcher_dialog_update_entries (ld);
-
-                /* update the tree */
-                launcher_dialog_tree_update_row (ld, COLUMN_NAME);
-                launcher_dialog_tree_update_row (ld, COLUMN_ICON);
-
-                /* also update the panel button icon */
-                if (g_list_index (ld->launcher->entries, ld->entry) == 0)
-                    update_icon = TRUE;
-
-                /* update the panel */
-                launcher_plugin_rebuild (ld->launcher, update_icon);
-
-                /* stop trying */
-                break;
-            }
-        }
-
-        /* cleanup */
-        launcher_free_filenames (filenames);
-    }
-
-    /* finish drag */
-    gtk_drag_finish (context, TRUE, FALSE, time);
-}
-
-
-
-/**
- * Properties update and save functions
- **/
-static void
-launcher_dialog_save_entry (GtkWidget      *entry,
-                            LauncherDialog *ld)
-{
-    const gchar *text;
-
-    /* quit if locked or no active entry set */
-    if (G_UNLIKELY (ld->updating == TRUE || ld->entry == NULL))
-        return;
-
-    /* get entry text */
-    text = gtk_entry_get_text (GTK_ENTRY (entry));
-
-    /* set text to null, if there is no valid text */
-    if (G_UNLIKELY (text == NULL || *text == '\0'))
-        text = NULL;
-
-    /* save new value */
-    if (entry == ld->entry_name)
-    {
-        g_free (ld->entry->name);
-        ld->entry->name = g_strdup (text);
-
-        /* update tree, when triggered by widget */
-        launcher_dialog_tree_update_row (ld, COLUMN_NAME);
-    }
-    else if (entry == ld->entry_comment)
-    {
-        g_free (ld->entry->comment);
-        ld->entry->comment = g_strdup (text);
-    }
-    else if (entry == ld->entry_exec)
-    {
-        g_free (ld->entry->exec);
-        ld->entry->exec = text ? xfce_expand_variables (text, NULL) : NULL;
-    }
-    else if (entry == ld->entry_path)
-    {
-        g_free (ld->entry->path);
-        ld->entry->path = text ? xfce_expand_variables (text, NULL) : NULL;
-    }
-
-    /* update panel */
-    launcher_plugin_rebuild (ld->launcher, FALSE);
-}
-
-
-
-static void
-launcher_dialog_save_button (GtkWidget      *button,
-                             LauncherDialog *ld)
-{
-    gboolean active;
-
-    /* quit if locked or no active entry set */
-    if (G_UNLIKELY (ld->updating == TRUE || ld->entry == NULL))
-        return;
-
-    /* get toggle button state */
-    active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
-
-    /* update entry or global setting */
-    if (button == ld->entry_terminal)
-    {
-        ld->entry->terminal = active;
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-        gtk_widget_set_sensitive (ld->entry_startup, !active);
-#endif
-    }
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    else if (button == ld->entry_startup)
-        ld->entry->startup = active;
-#endif
-}
-
-
-
-static void
-launcher_dialog_update_entries (LauncherDialog *ld)
-{
-    /* quit if locked or no active entry set */
-    if (G_UNLIKELY (ld->updating == TRUE || ld->entry == NULL))
-        return;
-
-    /* lock the save functions */
-    ld->updating = TRUE;
-
-    /* set new entry values */
-    gtk_entry_set_text (GTK_ENTRY (ld->entry_name),
-                        (ld->entry->name != NULL) ? ld->entry->name : "");
-
-    gtk_entry_set_text (GTK_ENTRY (ld->entry_comment),
-                        (ld->entry->comment != NULL) ? ld->entry->comment : "");
-
-    gtk_entry_set_text (GTK_ENTRY (ld->entry_exec),
-                        (ld->entry->exec != NULL) ? ld->entry->exec : "");
-
-    gtk_entry_set_text (GTK_ENTRY (ld->entry_path),
-                        (ld->entry->path != NULL) ? ld->entry->path : "");
-
-    /* set toggle buttons */
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ld->entry_terminal),
-                                  ld->entry->terminal);
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ld->entry_startup),
-                                  ld->entry->startup);
-
-    gtk_widget_set_sensitive (ld->entry_startup, !ld->entry->terminal);
-#endif
-
-    /* update icon button */
-    launcher_dialog_update_icon (ld);
-
-    /* unlock */
-    ld->updating = FALSE;
-}
-
-
-
-static void
-launcher_dialog_update_icon (LauncherDialog *ld)
-{
-    GdkPixbuf *icon = NULL;
-    GtkWidget *child;
-
-    /* drop the previous button child */
-    if (GTK_BIN (ld->entry_icon)->child != NULL)
-        gtk_widget_destroy (GTK_BIN (ld->entry_icon)->child);
-
-    if (G_LIKELY (ld->entry->icon))
-        icon = launcher_utility_load_pixbuf (gtk_widget_get_screen (ld->entry_icon), ld->entry->icon, LAUNCHER_CHOOSER_ICON_SIZE);
-
-    /* create icon button */
-    if (G_LIKELY (icon != NULL))
-    {
-        /* create image from pixbuf */
-        child = gtk_image_new_from_pixbuf (icon);
-
-        /* release icon */
-        g_object_unref (G_OBJECT (icon));
-
-        gtk_widget_set_size_request (child, LAUNCHER_CHOOSER_ICON_SIZE, LAUNCHER_CHOOSER_ICON_SIZE);
-    }
-    else
-    {
-        child = gtk_label_new (_("No icon"));
-
-        gtk_widget_set_size_request (child, -1, LAUNCHER_CHOOSER_ICON_SIZE);
-    }
-
-    gtk_container_add (GTK_CONTAINER (ld->entry_icon), child);
-    gtk_widget_show (child);
-}
-
-
-
-/**
- * Icon and command search dialogs
- **/
-static void
-launcher_dialog_folder_chooser (LauncherDialog *ld)
-{
-    GtkWidget *chooser;
-    gchar     *path;
-
-    chooser = gtk_file_chooser_dialog_new (_("Select a Directory"),
-                                           NULL,
-                                           GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                           GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-                                           NULL);
-
-    /* only here */
-    gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
-
-    /* use the bindir as default folder */
-    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), BINDIR);
-
-    /* select folder from field */
-    if (G_LIKELY (ld->entry->path != NULL))
-    {
-        if (G_LIKELY (g_path_is_absolute (ld->entry->path)))
-            gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (chooser), ld->entry->path);
-    }
-
-    /* run the chooser dialog */
-    if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
-    {
-        path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
-
-        /* set the new entry text */
-        gtk_entry_set_text (GTK_ENTRY (ld->entry_path), path);
-
-        /* cleanup */
-        g_free (path);
-    }
-
-    /* destroy dialog */
-    gtk_widget_destroy (chooser);
-}
-
-static void
-launcher_dialog_command_chooser (LauncherDialog *ld)
-{
-    GtkFileFilter *filter;
-    GtkWidget     *chooser;
-    gchar         *filename;
-    gchar         *s;
-
-    chooser = gtk_file_chooser_dialog_new (_("Select an Application"),
-                                           NULL,
-                                           GTK_FILE_CHOOSER_ACTION_OPEN,
-                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                           GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-                                           NULL);
-    gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
-
-    /* add file chooser filters */
-    filter = gtk_file_filter_new ();
-    gtk_file_filter_set_name (filter, _("All Files"));
-    gtk_file_filter_add_pattern (filter, "*");
-    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
-
-    filter = gtk_file_filter_new ();
-    gtk_file_filter_set_name (filter, _("Executable Files"));
-    gtk_file_filter_add_mime_type (filter, "application/x-csh");
-    gtk_file_filter_add_mime_type (filter, "application/x-executable");
-    gtk_file_filter_add_mime_type (filter, "application/x-perl");
-    gtk_file_filter_add_mime_type (filter, "application/x-python");
-    gtk_file_filter_add_mime_type (filter, "application/x-ruby");
-    gtk_file_filter_add_mime_type (filter, "application/x-shellscript");
-    gtk_file_filter_add_pattern (filter, "*.pl");
-    gtk_file_filter_add_pattern (filter, "*.py");
-    gtk_file_filter_add_pattern (filter, "*.rb");
-    gtk_file_filter_add_pattern (filter, "*.sh");
-    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
-    gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
-
-    filter = gtk_file_filter_new ();
-    gtk_file_filter_set_name (filter, _("Perl Scripts"));
-    gtk_file_filter_add_mime_type (filter, "application/x-perl");
-    gtk_file_filter_add_pattern (filter, "*.pl");
-    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
-
-    filter = gtk_file_filter_new ();
-    gtk_file_filter_set_name (filter, _("Python Scripts"));
-    gtk_file_filter_add_mime_type (filter, "application/x-python");
-    gtk_file_filter_add_pattern (filter, "*.py");
-    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
-
-    filter = gtk_file_filter_new ();
-    gtk_file_filter_set_name (filter, _("Ruby Scripts"));
-    gtk_file_filter_add_mime_type (filter, "application/x-ruby");
-    gtk_file_filter_add_pattern (filter, "*.rb");
-    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
-
-    filter = gtk_file_filter_new ();
-    gtk_file_filter_set_name (filter, _("Shell Scripts"));
-    gtk_file_filter_add_mime_type (filter, "application/x-csh");
-    gtk_file_filter_add_mime_type (filter, "application/x-shellscript");
-    gtk_file_filter_add_pattern (filter, "*.sh");
-    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
-
-    /* use the bindir as default folder */
-    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), BINDIR);
-
-    /* get the current command */
-    filename = gtk_editable_get_chars (GTK_EDITABLE (ld->entry_exec), 0, -1);
-    if (G_LIKELY (filename != NULL))
-    {
-        /* use only the first argument */
-        s = strchr (filename, ' ');
-        if (G_UNLIKELY (s != NULL))
-            *s = '\0';
-
-        /* check if we have a file name */
-        if (G_LIKELY (*filename != '\0'))
-        {
-            /* check if the filename is not an absolute path */
-            if (G_LIKELY (!g_path_is_absolute (filename)))
-            {
-                /* try to lookup the filename in $PATH */
-                s = g_find_program_in_path (filename);
-                if (G_LIKELY (s != NULL))
-                {
-                    /* use the absolute path instead */
-                    g_free (filename);
-                    filename = s;
-                }
-            }
-
-            /* check if we have an absolute path now */
-            if (G_LIKELY (g_path_is_absolute (filename)))
-                gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (chooser), filename);
-        }
-
-        /* release the filename */
-        g_free (filename);
-    }
-
-    /* run the chooser dialog */
-    if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
-    {
-        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
-
-        /* set the new entry text */
-        gtk_entry_set_text (GTK_ENTRY (ld->entry_exec), filename);
-
-        /* cleanup */
-        g_free (filename);
-    }
-
-    /* destroy dialog */
-    gtk_widget_destroy (chooser);
-}
-
-
-
-static void
-launcher_dialog_icon_chooser (LauncherDialog *ld)
-{
-    const gchar *name;
-    GtkWidget   *chooser;
-    gchar       *title;
-    gboolean     update_icon = FALSE;
-
-    /* determine the name of the entry being edited */
-    name = gtk_entry_get_text (GTK_ENTRY (ld->entry_name));
-    if (G_UNLIKELY (name == NULL || *name == '\0'))
-        name = _("Unknown");
-
-    /* allocate the chooser dialog */
-    title = g_strdup_printf (_("Select an Icon for \"%s\""), name);
-    chooser = exo_icon_chooser_dialog_new (title, NULL,
-                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                           GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                                           NULL);
-    gtk_dialog_set_alternative_button_order (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1);
-    gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
-    g_free (title);
-
-    /* set the current icon, if there is any */
-    if (G_LIKELY (ld->entry->icon))
-        exo_icon_chooser_dialog_set_icon (EXO_ICON_CHOOSER_DIALOG (chooser), ld->entry->icon);
-
-    /* run the icon chooser dialog */
-    if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
-    {
-        /* free the old icon name */
-        if (G_LIKELY (ld->entry->icon))
-            g_free (ld->entry->icon);
-
-        /* set new icon */
-        ld->entry->icon = exo_icon_chooser_dialog_get_icon (EXO_ICON_CHOOSER_DIALOG (chooser));
-
-        /* update the icon button */
-        launcher_dialog_update_icon (ld);
-
-        /* update the icon column in the tree */
-        launcher_dialog_tree_update_row (ld, COLUMN_ICON);
-
-        /* check if we need to update the icon button image */
-        if (g_list_index (ld->launcher->entries, ld->entry) == 0)
-            update_icon = TRUE;
-
-        /* update the panel widgets */
-        launcher_plugin_rebuild (ld->launcher, update_icon);
-    }
-
-    /* destroy the chooser */
-    gtk_widget_destroy (chooser);
-}
-
-
-
-/**
- * Tree functions
- **/
-static void
-launcher_dialog_tree_update_row (LauncherDialog *ld,
-                                 gint            column)
-{
-    GtkTreeSelection *selection;
-    GtkTreeIter       iter;
-    GdkPixbuf        *icon = NULL;
-    const gchar      *name;
-
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ld->treeview));
-
-    if (G_LIKELY (gtk_tree_selection_get_selected (selection, NULL, &iter)))
-    {
-        switch (column)
-        {
-            case COLUMN_ICON:
-                /* load entry icon */
-                icon = launcher_utility_load_pixbuf (gtk_widget_get_screen (ld->treeview), ld->entry->icon, LAUNCHER_TREE_ICON_SIZE);
-
-                /* set new icon */
-                gtk_list_store_set (ld->store, &iter,
-                                    COLUMN_ICON, icon,
-                                    -1);
-
-                /* release icon */
-                if (G_LIKELY (icon != NULL))
-                    g_object_unref (G_OBJECT (icon));
-
-                break;
-
-            case COLUMN_NAME:
-                /* build name */
-                name = ld->entry->name ? ld->entry->name : _("Unnamed");
-
-                /* set new name */
-                gtk_list_store_set (ld->store, &iter,
-                                    COLUMN_NAME, name,
-                                    -1);
-
-                break;
-        }
-    }
-}
-
-
-
-static void
-launcher_dialog_tree_selection_changed (LauncherDialog   *ld,
-                                        GtkTreeSelection *selection)
-{
-    GtkTreeModel *model;
-    GtkTreePath  *path;
-    GtkTreeIter   iter;
-    gboolean      selected;
-    gint          position = 0;
-    gint          items;
-
-    if (G_UNLIKELY (ld->updating == TRUE))
-        return;
-
-    g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
-
-    /* check if we have currently selected an item */
-    selected = gtk_tree_selection_get_selected (selection, &model, &iter);
-
-    if (G_LIKELY (selected))
-    {
-        /* determine the path for the selected iter */
-        path = gtk_tree_model_get_path (model, &iter);
-
-        /* get position */
-        position = gtk_tree_path_get_indices (path)[0];
-
-        /* set new active entry */
-        ld->entry = (LauncherEntry *) g_list_nth (ld->launcher->entries, position)->data;
-
-        /* update fields */
-        launcher_dialog_update_entries (ld);
-
-        /* scroll new item to center of window */
-        gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (ld->treeview), path, NULL,
-                                      TRUE, 0.5, 0.0);
-
-        /* release path */
-        gtk_tree_path_free (path);
-    }
-
-    /* items in the list */
-    items = gtk_tree_model_iter_n_children (model, NULL);
-
-    /* change sensitivity of buttons */
-    gtk_widget_set_sensitive (ld->up, selected && (position > 0));
-    gtk_widget_set_sensitive (ld->down, selected && (position < items - 1));
-    gtk_widget_set_sensitive (ld->remove, selected && (items > 1));
-}
-
-
-
-static void
-launcher_dialog_tree_button_clicked (GtkWidget      *button,
-                                     LauncherDialog *ld)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel     *model;
-    GtkTreePath      *path;
-    GtkTreeIter       iter_a;
-    GtkTreeIter       iter_b;
-    gint              position, list_length;
-    GList            *li;
-    GdkPixbuf        *icon = NULL;
-    LauncherEntry    *entry;
-    gboolean          update_icon = FALSE;
-
-    /* get the selected items in the treeview */
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ld->treeview));
-
-    /* get selected iter, quit if no iter found */
-    if (G_UNLIKELY (gtk_tree_selection_get_selected (selection, &model, &iter_a) == FALSE))
-        return;
-
-    /* run the requested button action */
-    if (button == ld->up)
-    {
-        /* get path */
-        path = gtk_tree_model_get_path (model, &iter_a);
-
-        /* position of the item in the list */
-        position = gtk_tree_path_get_indices (path)[0];
-
-        /* check if we need to update the icon button image */
-        if (position == 1)
-            update_icon = TRUE;
-
-        /* get previous path */
-        if (G_LIKELY (gtk_tree_path_prev (path)))
-        {
-            /* get iter for previous item */
-            gtk_tree_model_get_iter (model, &iter_b, path);
-
-            /* swap the entries */
-            gtk_list_store_swap (ld->store, &iter_a, &iter_b);
-
-            /* swap items in the list */
-            li = g_list_nth (ld->launcher->entries, position);
-            launcher_dialog_g_list_swap (li, li->prev);
-        }
-
-        /* release the path */
-        gtk_tree_path_free (path);
-
-        /* update tree view */
-        launcher_dialog_tree_selection_changed (ld, selection);
-    }
-    else if (button == ld->down)
-    {
-        /* get path of selected item */
-        path = gtk_tree_model_get_path (model, &iter_a);
-
-        /* get position of item we're going to move */
-        position = gtk_tree_path_get_indices (path)[0];
-
-        /* check if we need to update the icon button image*/
-        if (position == 0)
-            update_icon = TRUE;
-
-        /* get next item in the list */
-        gtk_tree_path_next (path);
-
-        /* get next iter */
-        if (G_LIKELY (gtk_tree_model_get_iter (model, &iter_b, path)))
-        {
-            /* swap the entries */
-            gtk_list_store_swap (ld->store, &iter_a, &iter_b);
-
-            /* swap items in the list */
-            li = g_list_nth (ld->launcher->entries, position);
-            launcher_dialog_g_list_swap (li, li->next);
-        }
-
-        /* release the path */
-        gtk_tree_path_free (path);
-
-        /* update tree view */
-        launcher_dialog_tree_selection_changed (ld, selection);
-    }
-    else if (button == ld->add)
-    {
-        /* create new entry */
-        entry = launcher_entry_new ();
-
-        /* load new launcher icon */
-        icon = launcher_utility_load_pixbuf (gtk_widget_get_screen (ld->treeview), entry->icon, LAUNCHER_TREE_ICON_SIZE);
-
-        /* append new entry */
-        gtk_list_store_insert_after (ld->store, &iter_b, &iter_a);
-        gtk_list_store_set (ld->store, &iter_b,
-                            COLUMN_ICON, icon,
-                            COLUMN_NAME, entry->name,
-                            -1);
-
-        /* release the pixbuf */
-        if (G_LIKELY (icon != NULL))
-            g_object_unref (G_OBJECT (icon));
-
-        /* get path of new item */
-        path = gtk_tree_model_get_path (model, &iter_b);
-
-        /* position in the list */
-        position = gtk_tree_path_get_indices (path)[0];
-
-        /* insert in list */
-        ld->launcher->entries = g_list_insert (ld->launcher->entries,
-                                               entry, position);
-
-        /* select the new item (also updates treeview buttons) */
-        gtk_tree_view_set_cursor (GTK_TREE_VIEW (ld->treeview), path, NULL, FALSE);
-
-        /* cleanup */
-        gtk_tree_path_free (path);
-
-        /* allow to set the arrow position */
-        gtk_widget_set_sensitive (ld->arrow_position, TRUE);
-
-    }
-    else if (button == ld->remove)
-    {
-        /* path from row to remove */
-        path = gtk_tree_model_get_path (model, &iter_a);
-
-        /* get position of the item to remove */
-        position = gtk_tree_path_get_indices (path)[0];
-
-        /* check if we need to update the icon button image*/
-        if (position == 0)
-            update_icon = TRUE;
-
-        /* lock */
-        ld->updating = TRUE;
-
-        /* remove active entry */
-        launcher_entry_free (ld->entry, ld->launcher);
-        ld->entry = NULL;
-
-        /* remove row from store */
-        gtk_list_store_remove (ld->store, &iter_a);
-
-        /* unlock */
-        ld->updating = FALSE;
-
-        /* list length */
-        list_length = g_list_length (ld->launcher->entries);
-
-        /* select previous item, if last item was removed */
-        if (position >= list_length)
-            gtk_tree_path_prev (path);
-
-        /* select the new item (also updates treeview buttons) */
-        gtk_tree_view_set_cursor (GTK_TREE_VIEW (ld->treeview), path, NULL, FALSE);
-
-        /* cleanup */
-        gtk_tree_path_free (path);
-
-        /* allow to set the arrow position */
-        gtk_widget_set_sensitive (ld->arrow_position, list_length > 1);
-
-        /* don't allow menu arrows */
-        if (list_length == 1 && ld->launcher->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON)
-            gtk_combo_box_set_active (GTK_COMBO_BOX (ld->arrow_position), LAUNCHER_ARROW_DEFAULT);
-    }
-
-    /* update panel */
-    launcher_plugin_rebuild (ld->launcher, update_icon);
-}
-
-
-
-static void
-launcher_dialog_arrow_position_changed (GtkComboBox    *combo,
-                                        LauncherDialog *ld)
-{
-    ld->launcher->arrow_position = gtk_combo_box_get_active (combo);
-
-    launcher_plugin_rebuild (ld->launcher, TRUE);
-}
-
-
-
-/**
- * Launcher dialog widgets
- **/
-static GtkWidget *
-launcher_dialog_add_properties (LauncherDialog *ld)
-{
-    GtkWidget    *frame, *vbox, *hbox;
-    GtkWidget    *label, *button, *image;
-    GtkSizeGroup *sg;
-
-    frame = gtk_frame_new (NULL);
-
-    vbox = gtk_vbox_new (FALSE, BORDER);
-    gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER);
-    gtk_container_add (GTK_CONTAINER (frame), vbox);
-
-    sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-
-    /* entry name field */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_label_new_with_mnemonic (_("_Name"));
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-
-    gtk_size_group_add_widget (sg, label);
-
-    ld->entry_name = gtk_entry_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), ld->entry_name, TRUE, TRUE, 0);
-
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), ld->entry_name);
-
-    g_signal_connect (G_OBJECT (ld->entry_name), "changed",
-                      G_CALLBACK (launcher_dialog_save_entry), ld);
-
-    /* entry comment field */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_label_new_with_mnemonic (_("_Description"));
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-
-    gtk_size_group_add_widget (sg, label);
-
-    ld->entry_comment = gtk_entry_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), ld->entry_comment, TRUE, TRUE, 0);
-    gtk_widget_set_size_request (ld->entry_comment, 300, -1);
-
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), ld->entry_comment);
-
-    g_signal_connect (G_OBJECT (ld->entry_comment), "changed",
-                      G_CALLBACK (launcher_dialog_save_entry), ld);
-
-    /* entry icon chooser button */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_label_new_with_mnemonic (_("_Icon"));
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-
-    gtk_size_group_add_widget (sg, label);
-
-    ld->entry_icon = gtk_button_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), ld->entry_icon, FALSE, FALSE, 0);
-
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), ld->entry_icon);
-
-    g_signal_connect_swapped (G_OBJECT (ld->entry_icon), "clicked",
-                              G_CALLBACK (launcher_dialog_icon_chooser), ld);
-
-    /* entry command field and button */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_label_new_with_mnemonic (_("Co_mmand"));
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-
-    gtk_size_group_add_widget (sg, label);
-
-    ld->entry_exec = gtk_entry_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), ld->entry_exec, TRUE, TRUE, 0);
-
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), ld->entry_exec);
-
-    g_signal_connect (G_OBJECT (ld->entry_exec), "changed",
-                      G_CALLBACK (launcher_dialog_save_entry), ld);
-
-    button = gtk_button_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-
-    g_signal_connect_swapped (G_OBJECT (button), "clicked",
-                              G_CALLBACK (launcher_dialog_command_chooser), ld);
-
-    image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
-    gtk_container_add (GTK_CONTAINER (button), image);
-
-    /* working directory field */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_label_new_with_mnemonic (_("_Working Directory"));
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-
-    gtk_size_group_add_widget (sg, label);
-
-    ld->entry_path = gtk_entry_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), ld->entry_path, TRUE, TRUE, 0);
-
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), ld->entry_path);
-
-    g_signal_connect (G_OBJECT (ld->entry_path), "changed",
-                      G_CALLBACK (launcher_dialog_save_entry), ld);
-
-    button = gtk_button_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-
-    g_signal_connect_swapped (G_OBJECT (button), "clicked",
-                              G_CALLBACK (launcher_dialog_folder_chooser), ld);
-
-    image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
-    gtk_container_add (GTK_CONTAINER (button), image);
-
-    /* entry terminal toggle button with spacer */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_alignment_new (0, 0, 0, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
-    gtk_size_group_add_widget (sg, label);
-
-    ld->entry_terminal = gtk_check_button_new_with_mnemonic (_("Run in _terminal"));
-    gtk_box_pack_start (GTK_BOX (hbox), ld->entry_terminal, TRUE, TRUE, 0);
-
-    g_signal_connect (G_OBJECT (ld->entry_terminal), "toggled",
-                      G_CALLBACK (launcher_dialog_save_button), ld);
-
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    /* startup notification */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_alignment_new (0, 0, 0, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
-    gtk_size_group_add_widget (sg, label);
-
-    ld->entry_startup = gtk_check_button_new_with_mnemonic (_("Use _startup notification"));
-    gtk_box_pack_start (GTK_BOX (hbox), ld->entry_startup, TRUE, TRUE, 0);
-
-    g_signal_connect (G_OBJECT (ld->entry_startup), "toggled",
-                      G_CALLBACK (launcher_dialog_save_button), ld);
-#endif
-
-    /* release size group */
-    g_object_unref (G_OBJECT (sg));
-
-    /* setup dnd in frame */
-    gtk_drag_dest_set (frame, GTK_DEST_DEFAULT_ALL,
-                       drop_targets, G_N_ELEMENTS (drop_targets),
-                       GDK_ACTION_COPY);
-
-    g_signal_connect (frame, "drag-data-received",
-                        G_CALLBACK (launcher_dialog_frame_drag_data_received), ld);
-
-    return frame;
-}
-
-
-
-
-static GtkWidget *
-launcher_dialog_add_tree (LauncherDialog *ld)
-{
-    GtkWidget         *scroll;
-    GtkTreeViewColumn *column;
-    GtkTreeSelection  *selection;
-    GtkCellRenderer   *renderer;
-    GtkTreeIter        iter;
-    GList             *li;
-    LauncherEntry     *entry;
-    GdkPixbuf         *icon;
-    const gchar       *name;
-
-    /* scrolled window */
-    scroll = gtk_scrolled_window_new (NULL, NULL);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
-                                    GTK_POLICY_NEVER,
-                                    GTK_POLICY_AUTOMATIC);
-    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
-                                         GTK_SHADOW_IN);
-
-    /* create new list store */
-    ld->store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
-
-    /* create tree view */
-    ld->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ld->store));
-    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (ld->treeview), FALSE);
-    gtk_tree_view_set_search_column (GTK_TREE_VIEW (ld->treeview), COLUMN_NAME);
-    gtk_tree_view_set_enable_search (GTK_TREE_VIEW (ld->treeview), TRUE);
-    gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (ld->treeview), TRUE);
-    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (ld->treeview), TRUE);
-    gtk_container_add (GTK_CONTAINER (scroll), ld->treeview);
-
-    /* create columns and cell renders */
-    column = gtk_tree_view_column_new ();
-    gtk_tree_view_column_set_expand (column, TRUE);
-    gtk_tree_view_column_set_resizable (column, FALSE);
-    gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (ld->treeview), column);
-
-    renderer = gtk_cell_renderer_pixbuf_new();
-    gtk_cell_renderer_set_fixed_size (renderer, LAUNCHER_TREE_ICON_SIZE, LAUNCHER_TREE_ICON_SIZE);
-    gtk_tree_view_column_pack_start (column, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", COLUMN_ICON, NULL);
-
-    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);
-    g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-
-    /* set selection change signal */
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ld->treeview));
-    gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-    g_signal_connect_swapped (G_OBJECT (selection), "changed",
-                              G_CALLBACK (launcher_dialog_tree_selection_changed), ld);
-
-    /* append current items */
-    for (li = ld->launcher->entries; li != NULL; li = li->next)
-    {
-        entry = li->data;
-
-        if (G_LIKELY (entry))
-        {
-            /* load icon */
-            icon = launcher_utility_load_pixbuf (gtk_widget_get_screen (ld->treeview), entry->icon, LAUNCHER_TREE_ICON_SIZE);
-
-            /* build name */
-            name = entry->name ? entry->name : _("Unnamed");
-
-            /* create new row and add the data */
-            gtk_list_store_append (ld->store, &iter);
-            gtk_list_store_set (ld->store, &iter,
-                                COLUMN_ICON, icon,
-                                COLUMN_NAME, name, -1);
-
-            /* release the pixbuf */
-            if (G_LIKELY (icon))
-                g_object_unref (G_OBJECT (icon));
-        }
-    }
-
-    /* dnd support */
-    gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (ld->treeview),
-                                          drop_targets, G_N_ELEMENTS (drop_targets),
-                                          GDK_ACTION_COPY);
-
-    g_signal_connect (G_OBJECT (ld->treeview), "drag-data-received",
-                      G_CALLBACK (launcher_dialog_tree_drag_data_received), ld);
-
-    return scroll;
-}
-
-
-
-static GtkWidget *
-launcher_dialog_add_tree_buttons (LauncherDialog *ld)
-{
-    GtkWidget *hbox, *button, *align, *image;
-
-    hbox = gtk_hbox_new (FALSE, BORDER);
-
-    /* up button */
-    ld->up = button = gtk_button_new ();
-    gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
-    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-
-    image = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
-    gtk_container_add (GTK_CONTAINER (button), image);
-
-    g_signal_connect (G_OBJECT (button), "clicked",
-                      G_CALLBACK (launcher_dialog_tree_button_clicked), ld);
-
-    gtk_widget_set_sensitive (button, FALSE);
-
-    /* down button */
-    ld->down = button = gtk_button_new ();
-    gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
-    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-
-    image = gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_BUTTON);
-    gtk_container_add (GTK_CONTAINER (button), image);
-
-    g_signal_connect (G_OBJECT (button), "clicked",
-                      G_CALLBACK (launcher_dialog_tree_button_clicked), ld);
-
-    gtk_widget_set_sensitive (button, FALSE);
-
-    /* free space between buttons */
-    align = gtk_alignment_new (0, 0, 0, 0);
-    gtk_widget_set_size_request (align, 1, 1);
-    gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, 0);
-
-    /* add button */
-    ld->add = button = gtk_button_new ();
-    gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
-    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-
-    image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
-    gtk_container_add (GTK_CONTAINER (button), image);
-
-    g_signal_connect (G_OBJECT (button), "clicked",
-                      G_CALLBACK (launcher_dialog_tree_button_clicked), ld);
-
-    /* remove button */
-    ld->remove = button = gtk_button_new ();
-    gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
-    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-
-    image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON);
-    gtk_container_add (GTK_CONTAINER (button), image);
-
-    g_signal_connect (G_OBJECT (button), "clicked",
-                      G_CALLBACK (launcher_dialog_tree_button_clicked), ld);
-
-    gtk_widget_set_sensitive (button, FALSE);
-
-    return hbox;
-}
-
-
-
-/**
- * Dialog functions
- **/
-static void
-launcher_dialog_response (GtkWidget      *dialog,
-                          gint            response,
-                          LauncherDialog *ld)
-{
-    LauncherPlugin *launcher = ld->launcher;
-
-    /* hide the dialog */
-    gtk_widget_hide (dialog);
-
-    /* lock for further updates */
-    ld->updating = TRUE;
-    ld->entry = NULL;
-
-    /* cleanup the store */
-    gtk_list_store_clear (ld->store);
-    g_object_unref (G_OBJECT (ld->store));
-
-    /* the launcher dialog dataS */
-    g_object_set_data (G_OBJECT (launcher->panel_plugin), I_("launcher-dialog"), NULL);
-
-    /* destroy the dialog */
-    gtk_widget_destroy (dialog);
-
-    /* unlock plugin menu */
-    xfce_panel_plugin_unblock_menu (launcher->panel_plugin);
-
-    /* restore move first */
-    launcher->move_first = ld->stored_move_first;
-
-    /* allow saving again */
-    launcher->plugin_can_save = TRUE;
-
-    if (response == GTK_RESPONSE_OK)
-    {
-        /* write new settings */
-        launcher_plugin_save (launcher);
-    }
-    else /* revert changes */
-    {
-        /* remove all the entries */
-        g_list_foreach (launcher->entries, (GFunc) launcher_entry_free, launcher);
-
-        /* read the last saved settings */
-        launcher_plugin_read (launcher);
-
-        /* add new item if there are no entries yet */
-        if (G_UNLIKELY (g_list_length (launcher->entries) == 0))
-            launcher->entries = g_list_append (launcher->entries, launcher_entry_new ());
-    }
-
-    /* free the panel structure */
-    g_slice_free (LauncherDialog, ld);
-}
-
-
-
-void
-launcher_dialog_show (LauncherPlugin  *launcher)
-{
-    LauncherDialog *ld;
-    GtkWidget      *dialog;
-    GtkWidget      *dialog_vbox;
-    GtkWidget      *paned, *vbox, *hbox;
-    GtkWidget      *widget, *label, *combo;
-    GtkTreePath    *path;
-
-    /* create new structure */
-    ld = g_slice_new0 (LauncherDialog);
-
-    /* init */
-    ld->launcher = launcher;
-    ld->entry = g_list_first (launcher->entries)->data;
-
-    /* prevent saving to be able to use the cancel button */
-    launcher->plugin_can_save = FALSE;
-
-    /* lock right-click plugin menu */
-    xfce_panel_plugin_block_menu (launcher->panel_plugin);
-
-    /* disable the auto sort of the list, while working in properties */
-    ld->stored_move_first = launcher->move_first;
-    launcher->move_first = FALSE;
-
-    /* create new dialog */
-    dialog = xfce_titled_dialog_new_with_buttons (_("Program Launcher"),
-                                                  NULL,
-                                                  GTK_DIALOG_NO_SEPARATOR,
-                                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                                  GTK_STOCK_OK, GTK_RESPONSE_OK,
-                                                  NULL);
-    gtk_window_set_screen (GTK_WINDOW (dialog), gtk_widget_get_screen (GTK_WIDGET (launcher->panel_plugin)));
-    gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
-    gtk_window_set_icon_name (GTK_WINDOW (dialog), "xfce4-settings");
-    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-
-    /* connect dialog to plugin, so we can destroy it when plugin is closed */
-    g_object_set_data (G_OBJECT (ld->launcher->panel_plugin), "dialog", dialog);
-
-    dialog_vbox = GTK_DIALOG (dialog)->vbox;
-
-    /* added the horizontal panes */
-    paned = gtk_hpaned_new ();
-    gtk_box_pack_start (GTK_BOX (dialog_vbox), paned, TRUE, TRUE, 0);
-    gtk_container_set_border_width (GTK_CONTAINER (paned), BORDER - 2);
-
-    vbox = gtk_vbox_new (FALSE, BORDER);
-    gtk_paned_pack1 (GTK_PANED (paned), vbox, FALSE, FALSE);
-
-    /* arrow button position */
-    hbox = gtk_hbox_new (FALSE, BORDER);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    label = gtk_label_new_with_mnemonic (_("A_rrow:"));
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
-    ld->arrow_position = combo = gtk_combo_box_new_text ();
-    gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
-    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Default"));
-    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Left"));
-    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Right"));
-    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Top"));
-    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Bottom"));
-    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Inside Button"));
-    gtk_widget_set_sensitive (combo, g_list_length (launcher->entries) > 1);
-    gtk_combo_box_set_active (GTK_COMBO_BOX (combo), launcher->arrow_position);
-    g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (launcher_dialog_arrow_position_changed), ld);
-    gtk_widget_show (combo);
-
-    /* add the entries list */
-    widget = launcher_dialog_add_tree (ld);
-    gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
-
-    /* add the tree navigation buttons */
-    widget = launcher_dialog_add_tree_buttons (ld);
-    gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
-
-    /* add the entry widgets */
-    widget = launcher_dialog_add_properties (ld);
-    gtk_paned_pack2 (GTK_PANED (paned), widget, TRUE, FALSE);
-
-    /* show all widgets inside dialog */
-    gtk_widget_show_all (dialog_vbox);
-
-    /* focus the title entry */
-    gtk_widget_grab_focus (ld->entry_name);
-
-    /* select first item in the tree (this also updates the fields) */
-    path = gtk_tree_path_new_first ();
-    gtk_tree_view_set_cursor (GTK_TREE_VIEW (ld->treeview), path, NULL, FALSE);
-    gtk_tree_path_free (path);
-
-    /* connect response signal */
-    g_signal_connect (G_OBJECT (dialog), "response",
-                      G_CALLBACK (launcher_dialog_response), ld);
-
-    /* show the dialog */
-    gtk_widget_show (dialog);
-}
diff --git a/plugins/launcher/launcher-dialog.h b/plugins/launcher/launcher-dialog.h
deleted file mode 100644
index a188af6..0000000
--- a/plugins/launcher/launcher-dialog.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*  $Id: launcher-dialog.h 26065 2007-09-10 12:04:49Z nick $
- *
- *  Copyright © 2005-2007 Jasper Huijsmans <jasper at xfce.org>
- *  Copyright (c) 2006-2007 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) any later version.
- *
- *  This program 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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __XFCE_PANEL_LAUNCHER_DIALOG_H__
-#define __XFCE_PANEL_LAUNCHER_DIALOG_H__
-
-gboolean launcher_dialog_read_desktop_file (const gchar *path, LauncherEntry *entry);
-
-void launcher_dialog_show (LauncherPlugin *launcher);
-
-#endif /* !__XFCE_PANEL_LAUNCHER_DIALOG_H__ */
diff --git a/plugins/launcher/launcher-exec.c b/plugins/launcher/launcher-exec.c
deleted file mode 100644
index 6fa8b96..0000000
--- a/plugins/launcher/launcher-exec.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/*  $Id: launcher-exec.c 26149 2007-10-20 09:22:49Z nick $
- *
- *  Copyright (c) 2006-2007 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 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 program 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 this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#ifndef WAIT_ANY
-#define WAIT_ANY (-1)
-#endif
-
-#include "launcher.h"
-#include "launcher-exec.h"
-
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-#ifdef GDK_WINDOWING_X11
-#include <X11/Xatom.h>
-#include <gdk/gdkx.h>
-#endif
-#include <libsn/sn.h>
-#endif
-
-
-
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-typedef struct
-{
-  SnLauncherContext *sn_launcher;
-  guint              timeout_id;
-  guint              watch_id;
-  GPid               pid;
-} LauncherStartupData;
-#endif
-
-
-
-/* Prototypes */
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-static gint             launcher_exec_get_active_workspace_number (GdkScreen             *screen);
-static gboolean         launcher_exec_startup_timeout             (gpointer               data);
-static void             launcher_exec_startup_timeout_destroy     (gpointer               data);
-static void             launcher_exec_startup_watch               (GPid                   pid,
-                                                                   gint                   status,
-                                                                   gpointer               data);
-#endif
-static void             launcher_exec_string_append_quoted        (GString               *string,
-                                                                   const gchar           *unquoted);
-static gchar          **launcher_exec_parse_argv                  (LauncherEntry         *entry,
-                                                                   GSList                *list,
-                                                                   GError               **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;;
-static gboolean         launcher_exec_on_screen                   (GdkScreen              *screen,
-                                                                   LauncherEntry          *entry,
-                                                                   GSList                 *list);
-
-
-
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-static gint
-launcher_exec_get_active_workspace_number (GdkScreen *screen)
-{
-    GdkWindow *root;
-    gulong     bytes_after_ret = 0;
-    gulong     nitems_ret = 0;
-    guint     *prop_ret = NULL;
-    Atom       _NET_CURRENT_DESKTOP;
-    Atom       _WIN_WORKSPACE;
-    Atom       type_ret = None;
-    gint       format_ret;
-    gint       ws_num = 0;
-
-    gdk_error_trap_push ();
-
-    root = gdk_screen_get_root_window (screen);
-
-    /* determine the X atom values */
-    _NET_CURRENT_DESKTOP = XInternAtom (GDK_WINDOW_XDISPLAY (root), "_NET_CURRENT_DESKTOP", False);
-    _WIN_WORKSPACE = XInternAtom (GDK_WINDOW_XDISPLAY (root), "_WIN_WORKSPACE", False);
-
-    if (XGetWindowProperty (GDK_WINDOW_XDISPLAY (root), GDK_WINDOW_XWINDOW (root),
-                            _NET_CURRENT_DESKTOP, 0, 32, False, XA_CARDINAL,
-                            &type_ret, &format_ret, &nitems_ret, &bytes_after_ret,
-                            (gpointer) &prop_ret) != Success)
-    {
-        if (XGetWindowProperty (GDK_WINDOW_XDISPLAY (root), GDK_WINDOW_XWINDOW (root),
-                                _WIN_WORKSPACE, 0, 32, False, XA_CARDINAL,
-                                &type_ret, &format_ret, &nitems_ret, &bytes_after_ret,
-                                (gpointer) &prop_ret) != Success)
-        {
-            if (G_UNLIKELY (prop_ret != NULL))
-            {
-                XFree (prop_ret);
-                prop_ret = NULL;
-            }
-        }
-    }
-
-    if (G_LIKELY (prop_ret != NULL))
-    {
-        if (G_LIKELY (type_ret != None && format_ret != 0))
-            ws_num = *prop_ret;
-        XFree (prop_ret);
-    }
-
-    gdk_error_trap_pop ();
-
-    return ws_num;
-}
-
-
-
-static gboolean
-launcher_exec_startup_timeout (gpointer data)
-{
-    LauncherStartupData *startup_data = data;
-    GTimeVal             now;
-    gdouble              elapsed;
-    glong                tv_sec;
-    glong                tv_usec;
-
-    /* determine the amount of elapsed time */
-    g_get_current_time (&now);
-    sn_launcher_context_get_last_active_time (startup_data->sn_launcher, &tv_sec, &tv_usec);
-    elapsed = (((gdouble) now.tv_sec - tv_sec) * G_USEC_PER_SEC + (now.tv_usec - tv_usec)) / 1000.0;
-
-    /* check if the timeout was reached */
-    if (elapsed >= LAUNCHER_STARTUP_TIMEOUT)
-    {
-        /* abort the startup notification */
-        sn_launcher_context_complete (startup_data->sn_launcher);
-        sn_launcher_context_unref (startup_data->sn_launcher);
-        startup_data->sn_launcher = NULL;
-    }
-
-    /* keep the startup timeout if not elapsed */
-    return (elapsed < LAUNCHER_STARTUP_TIMEOUT);
-}
-
-
-
-static void
-launcher_exec_startup_timeout_destroy (gpointer data)
-{
-    LauncherStartupData *startup_data = data;
-
-    g_return_if_fail (startup_data->sn_launcher == NULL);
-
-    /* cancel the watch (if any) */
-    if (startup_data->watch_id != 0)
-        g_source_remove (startup_data->watch_id);
-
-    /* close the PID */
-    g_spawn_close_pid (startup_data->pid);
-
-    /* release the startup data */
-    g_slice_free (LauncherStartupData, startup_data);
-}
-
-
-
-static void
-launcher_exec_startup_watch (GPid     pid,
-                             gint     status,
-                             gpointer data)
-{
-    LauncherStartupData *startup_data = data;
-    gint                 ret, serrno;
-
-    g_return_if_fail (startup_data->sn_launcher != NULL);
-    g_return_if_fail (startup_data->watch_id != 0);
-    g_return_if_fail (startup_data->pid == pid);
-
-    /* abort the startup notification (application exited) */
-    sn_launcher_context_complete (startup_data->sn_launcher);
-    sn_launcher_context_unref (startup_data->sn_launcher);
-    startup_data->sn_launcher = NULL;
-
-    /* avoid zombie processes */
-    serrno = errno;
-    while (1)
-      {
-        /* get the child process state without hanging */
-        ret = waitpid (WAIT_ANY, NULL, WNOHANG);
-
-        /* exit if there is nothing to wait for */
-        if (ret == 0 || ret < 0)
-          break;
-      }
-    errno = serrno;
-
-    /* cancel the startup notification timeout */
-    /* this will also activate the timeout_destroy function */
-    g_source_remove (startup_data->timeout_id);
-}
-#endif
-
-
-
-static void
-launcher_exec_string_append_quoted (GString     *string,
-                                    const gchar *unquoted)
-{
-    gchar *quoted;
-
-    quoted = g_shell_quote (unquoted);
-    g_string_append (string, quoted);
-    g_free (quoted);
-}
-
-
-
-static gchar **
-launcher_exec_parse_argv (LauncherEntry   *entry,
-                          GSList          *list,
-                          GError         **error)
-{
-    GString      *command_line = g_string_new (NULL);
-    const gchar  *p;
-    gchar        *t;
-    GSList       *li;
-    gchar       **argv = NULL;
-
-    /* build the full command */
-    for (p = entry->exec; *p != '\0'; ++p)
-    {
-        if (p[0] == '%' && p[1] != '\0')
-        {
-            switch (*++p)
-            {
-                case 'u':
-                case 'f':
-                    /* a single filename or url */
-                    if (list != NULL)
-                        launcher_exec_string_append_quoted (command_line, (gchar *) list->data);
-                    break;
-
-                case 'U':
-                case 'F':
-                    /* a list of filenames or urls */
-                    for (li = list; li != NULL; li = li->next)
-                    {
-                        if (G_LIKELY (li != list))
-                            g_string_append_c (command_line, ' ');
-
-                        launcher_exec_string_append_quoted (command_line, (gchar *) li->data);
-                    }
-                    break;
-
-                case 'd':
-                    /* directory containing the file that would be passed in a %f field */
-                    if (list != NULL)
-                    {
-                        t = g_path_get_dirname ((gchar *) list->data);
-                        if (t != NULL)
-                        {
-                            launcher_exec_string_append_quoted (command_line, t);
-                            g_free (t);
-                        }
-                    }
-                    break;
-
-                case 'D':
-                    /* list of directories containing the files that would be passed in to a %F field */
-                    for (li = list; li != NULL; li = li->next)
-                    {
-                        t = g_path_get_dirname (li->data);
-                        if (t != NULL)
-                        {
-                            if (G_LIKELY (li != list))
-                                g_string_append_c (command_line, ' ');
-
-                            launcher_exec_string_append_quoted (command_line, t);
-                            g_free (t);
-                        }
-                    }
-                    break;
-
-                case 'n':
-                    /* a single filename (without path). */
-                    if (list != NULL)
-                    {
-                        t = g_path_get_basename ((gchar *) list->data);
-                        if (t != NULL)
-                        {
-                            launcher_exec_string_append_quoted (command_line, t);
-                            g_free (t);
-                        }
-                    }
-                    break;
-
-                case 'N':
-                    /* a list of filenames (without paths) */
-                    for (li = list; li != NULL; li = li->next)
-                    {
-                        t = g_path_get_basename (li->data);
-                        if (t != NULL)
-                        {
-                            if (G_LIKELY (li != list))
-                                g_string_append_c (command_line, ' ');
-
-                            launcher_exec_string_append_quoted (command_line, t);
-                            g_free (t);
-                        }
-                    }
-                    break;
-
-                case 'i':
-                    /* the icon key of the desktop entry */
-                    if (G_LIKELY (entry->icon != NULL))
-                    {
-                        g_string_append (command_line, "--icon ");
-                        launcher_exec_string_append_quoted (command_line, entry->icon);
-                    }
-                    break;
-
-                case 'c':
-                    /* the translated name of the application */
-                    if (G_LIKELY (entry->name != NULL))
-                        launcher_exec_string_append_quoted (command_line, entry->name);
-                    break;
-
-                case '%':
-                    /* percentage character */
-                    g_string_append_c (command_line, '%');
-                    break;
-            }
-        }
-        else
-        {
-            g_string_append_c (command_line, *p);
-        }
-    }
-
-    DBG ("Execute: %s", command_line->str);
-
-    /* create the argv */
-    if (G_LIKELY (command_line->str != NULL))
-    {
-        if (entry->terminal == FALSE)
-        {
-            /* use glib to parge the argv */
-            g_shell_parse_argv (command_line->str, NULL, &argv, error);
-        }
-        else
-        {
-            /* we parse our own argv here so exo-open will handle all attributes without problems */
-            argv = g_new (gchar *, 5);
-            argv[0] = g_strdup ("exo-open");
-            argv[1] = g_strdup ("--launch");
-            argv[2] = g_strdup ("TerminalEmulator");
-            argv[3] = g_strdup (command_line->str);
-            argv[4] = NULL;
-        }
-    }
-
-    /* cleanup */
-    g_string_free (command_line, TRUE);
-
-    return argv;
-}
-
-
-static gboolean
-launcher_exec_on_screen (GdkScreen     *screen,
-                         LauncherEntry *entry,
-                         GSList        *list)
-{
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    SnLauncherContext    *sn_launcher = NULL;
-    SnDisplay            *sn_display = NULL;
-    LauncherStartupData  *startup_data;
-    gint                  sn_workspace;
-    extern gchar        **environ;
-    gint                  n, m;
-#endif
-    gboolean              succeed = FALSE;
-    GError               *error = NULL;
-    gchar               **argv;
-    gchar               **envp = NULL;
-    GtkWidget            *dialog;
-    GSpawnFlags           flags = G_SPAWN_SEARCH_PATH;
-    GPid                  pid;
-
-    /* parse the full command */
-    if ((argv = launcher_exec_parse_argv (entry, list, &error)) == NULL)
-        goto error;
-
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    /* setup startup notification, only when not running in terminal */
-    if (entry->startup && !entry->terminal)
-    {
-        sn_display = sn_display_new (GDK_SCREEN_XDISPLAY (screen),
-                                     (SnDisplayErrorTrapPush) gdk_error_trap_push,
-                                     (SnDisplayErrorTrapPop) gdk_error_trap_pop);
-
-        if (G_LIKELY (sn_display != NULL))
-        {
-            /* create new startup context */
-            sn_launcher = sn_launcher_context_new (sn_display, GDK_SCREEN_XNUMBER (screen));
-
-            if (G_LIKELY (sn_launcher != NULL && !sn_launcher_context_get_initiated (sn_launcher)))
-            {
-                /* setup the startup notification context */
-                sn_workspace = launcher_exec_get_active_workspace_number (screen);
-                sn_launcher_context_set_binary_name (sn_launcher, argv[0]);
-                sn_launcher_context_set_workspace (sn_launcher, sn_workspace);
-
-                /* set name */
-                if (entry->name || entry->comment)
-                  sn_launcher_context_set_name (sn_launcher, entry->name ? entry->name : entry->comment);
-
-                /* set icon */
-                if (entry->icon)
-                  sn_launcher_context_set_icon_name (sn_launcher, entry->icon);
-
-                sn_launcher_context_initiate (sn_launcher, g_get_prgname (), argv[0], CurrentTime);
-
-                /* count environ items */
-                for (n = 0; environ[n] != NULL; ++n)
-                    ;
-
-                /* alloc new envp string */
-                envp = g_new (gchar *, n + 2);
-
-                /* copy the environ vars into the envp */
-                for (n = m = 0; environ[n] != NULL; ++n)
-                    if (G_LIKELY (strncmp (environ[n], "DESKTOP_STARTUP_ID", 18) != 0))
-                        envp[m++] = g_strdup (environ[n]);
-
-                /* append the startup notification id */
-                envp[m++] = g_strconcat ("DESKTOP_STARTUP_ID=", sn_launcher_context_get_startup_id (sn_launcher), NULL);
-                envp[m] = NULL;
-
-                /* we want to watch the child process */
-                flags |= G_SPAWN_DO_NOT_REAP_CHILD;
-            }
-        }
-    }
-#endif
-
-    /* spawn the application */
-    succeed = gdk_spawn_on_screen (screen,
-                                   entry->path,
-                                   argv,
-                                   envp,
-                                   flags,
-                                   NULL, NULL,
-                                   &pid,
-                                   &error);
-
-    /* cleanup the argv */
-    g_strfreev (argv);
-
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    /* handle the sn launcher context */
-    if (sn_launcher != NULL)
-    {
-        if (G_UNLIKELY (!succeed))
-        {
-            /* abort the sn sequence */
-            sn_launcher_context_complete (sn_launcher);
-            sn_launcher_context_unref (sn_launcher);
-        }
-        else
-        {
-            /* schedule a startup notification timeout */
-            startup_data = g_slice_new (LauncherStartupData);
-            startup_data->sn_launcher = sn_launcher;
-            startup_data->timeout_id = g_timeout_add_full (G_PRIORITY_LOW, LAUNCHER_STARTUP_TIMEOUT,
-                                                           launcher_exec_startup_timeout,
-                                                           startup_data, launcher_exec_startup_timeout_destroy);
-            startup_data->watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, launcher_exec_startup_watch,
-                                                             startup_data, NULL);
-            startup_data->pid = pid;
-        }
-    }
-
-    /* release the sn display */
-    if (sn_display != NULL)
-        sn_display_unref (sn_display);
-
-    if (envp != NULL)
-        g_strfreev (envp);
-#endif
-
-error:
-    if (G_UNLIKELY (error != NULL))
-    {
-        /* create new warning dialog */
-        dialog = gtk_message_dialog_new (NULL,
-                                         GTK_DIALOG_MODAL,
-                                         GTK_MESSAGE_ERROR,
-                                         GTK_BUTTONS_CLOSE,
-                                         _("Failed to launch \"%s\""),
-                                         entry->name);
-
-        /* show g's error message, if there is any */
-        if (G_LIKELY (error->message))
-            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                      "%s.", error->message);
-
-        /* popup the dialog */
-        gtk_dialog_run (GTK_DIALOG (dialog));
-
-        /* cleanup */
-        gtk_widget_destroy (dialog);
-        g_error_free (error);
-    }
-
-    return succeed;
-}
-
-
-
-void
-launcher_execute (GdkScreen     *screen,
-                  LauncherEntry *entry,
-                  GSList        *file_list)
-{
-    GSList   *li;
-    GSList    fake;
-    gboolean  proceed = TRUE;
-
-    /* be secure */
-    if (G_UNLIKELY (screen == NULL))
-        screen = gdk_screen_get_default ();
-
-    /* maybe no command have been filed yet */
-    if (G_UNLIKELY (entry->exec == NULL || *entry->exec == '\0'))
-        return;
-
-    /* check if the launcher supports (and needs) multiple instances */
-    if (file_list != NULL &&
-        strstr (entry->exec, "%F") == NULL &&
-        strstr (entry->exec, "%U") == NULL)
-    {
-        /* fake an empty list */
-        fake.next = NULL;
-
-        /* run new instance for each file in the list */
-        for (li = file_list; li != NULL && proceed; li = li->next)
-        {
-            /* point to data */
-            fake.data = li->data;
-
-            /* spawn */
-            proceed = launcher_exec_on_screen (screen, entry, &fake);
-        }
-    }
-    else
-    {
-        /* spawn */
-        launcher_exec_on_screen (screen, entry, file_list);
-    }
-}
-
-
-
-void
-launcher_execute_from_clipboard (GdkScreen     *screen,
-                                 LauncherEntry *entry)
-{
-    GtkClipboard     *clipboard;
-    gchar            *text = NULL;
-    GSList           *filenames;
-    GtkSelectionData  selection_data;
-
-    /* get the clipboard */
-    clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
-
-    /* get clipboard text */
-    if (G_LIKELY (clipboard))
-        text = gtk_clipboard_wait_for_text (clipboard);
-
-    /* try other clipboard if this one was empty */
-    if (text == NULL)
-    {
-        /* get the clipboard */
-        clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
-        /* get clipboard text */
-        if (G_LIKELY (clipboard))
-            text = gtk_clipboard_wait_for_text (clipboard);
-    }
-
-    if (G_LIKELY (text))
-    {
-        /* create some fake selection data */
-        selection_data.data = (guchar *) text;
-        selection_data.length = strlen (text);
-
-        /* parse the filelist, this way we can handle 'copied' file from thunar */
-        filenames = launcher_utility_filenames_from_selection_data (&selection_data);
-
-        if (G_LIKELY (filenames))
-        {
-            /* run the command with argument from clipboard */
-            launcher_execute (screen, entry, filenames);
-
-            /* cleanup */
-            launcher_free_filenames (filenames);
-        }
-
-        /* cleanup */
-        g_free (text);
-    }
-}
diff --git a/plugins/launcher/launcher-exec.h b/plugins/launcher/launcher-exec.h
deleted file mode 100644
index 38fa00b..0000000
--- a/plugins/launcher/launcher-exec.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*  $Id: launcher-exec.h 26065 2007-09-10 12:04:49Z nick $
- *
- *  Copyright (c) 2006-2007 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) any later version.
- *
- *  This program 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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __XFCE_PANEL_EXEC_H__
-#define __XFCE_PANEL_EXEC_H__
-
-void launcher_execute                (GdkScreen     *screen,
-                                      LauncherEntry *entry,
-                                      GSList        *file_list);
-void launcher_execute_from_clipboard (GdkScreen     *screen,
-                                      LauncherEntry *entry);
-
-#endif /* !__XFCE_PANEL_EXEC_H__ */
diff --git a/plugins/launcher/launcher.c b/plugins/launcher/launcher.c
index 8469716..8b47041 100644
--- a/plugins/launcher/launcher.c
+++ b/plugins/launcher/launcher.c
@@ -1,1302 +1,1046 @@
-/*  $Id: launcher.c 26118 2007-09-30 18:14:31Z jasper $
+/* $Id$ */
+/*
+ * 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)
+ * any later version.
  *
- *  Copyright (c) 2005-2007 Jasper Huijsmans <jasper at xfce.org>
- *  Copyright (c) 2006-2007 Nick Schermer <nick at xfce.org>
+ * 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 General Public License for
+ * more details.
  *
- *  This program 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 program 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 this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
 
 #include <libxfce4util/libxfce4util.h>
 #include <libxfce4panel/libxfce4panel.h>
 
-#include "launcher.h"
-#include "launcher-exec.h"
-#include "launcher-dialog.h"
-
-/* prototypes */
-static gboolean        launcher_utility_icon_theme_changed          (GSignalInvocationHint *ihint,
-                                                                     guint                  n_param_values,
-                                                                     const GValue          *param_values,
-                                                                     LauncherPlugin        *launcher);
-static gboolean        launcher_icon_button_expose_event            (GtkWidget             *widget,
-                                                                     GdkEventExpose        *event,
-                                                                     LauncherPlugin        *launcher);
-static void            launcher_icon_button_set_icon                (LauncherPlugin        *launcher);
-#if LAUNCHER_NEW_TOOLTIP_API
-static gboolean        launcher_icon_button_query_tooltip           (GtkWidget             *widget,
-                                                                     gint                   x,
-                                                                     gint                   y,
-                                                                     gboolean               keyboard_mode,
-                                                                     GtkTooltip            *tooltip,
-                                                                     LauncherPlugin        *launcher);
-#else
-static void            launcher_icon_button_set_tooltip             (LauncherPlugin        *launcher);
-#endif
-static gboolean        launcher_icon_button_pressed                 (GtkWidget             *button,
-                                                                     GdkEventButton        *event,
-                                                                     LauncherPlugin        *launcher);
-static gboolean        launcher_icon_button_released                (GtkWidget             *button,
-                                                                     GdkEventButton        *event,
-                                                                     LauncherPlugin        *launcher);
-static void            launcher_icon_button_drag_data_received      (GtkWidget             *widget,
-                                                                     GdkDragContext        *context,
-                                                                     gint                   x,
-                                                                     gint                   y,
-                                                                     GtkSelectionData      *selection_data,
-                                                                     guint                  info,
-                                                                     guint                  time,
-                                                                     LauncherPlugin        *launcher);
-static gboolean        launcher_arrow_button_pressed                (GtkWidget             *button,
-                                                                     GdkEventButton        *event,
-                                                                     LauncherPlugin        *launcher);
-static void            launcher_button_state_changed                (GtkWidget             *button_a,
-                                                                     GtkStateType           state,
-                                                                     GtkWidget             *button_b);
-static gboolean        launcher_menu_item_released                  (GtkWidget             *mi,
-                                                                     GdkEventButton        *event,
-                                                                     LauncherPlugin        *launcher);
-static void            launcher_menu_popup_destroyed                (gpointer               user_data);
-static gboolean        launcher_menu_popup                          (gpointer               user_data);
-static void            launcher_menu_deactivated                    (LauncherPlugin        *launcher);
-static void            launcher_menu_destroy                        (LauncherPlugin        *launcher);
-static void            launcher_menu_rebuild                        (LauncherPlugin        *launcher);
-static LauncherPlugin *launcher_plugin_new                          (XfcePanelPlugin       *plugin) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-static void            launcher_plugin_pack_buttons                 (LauncherPlugin        *launcher);
-static gchar          *launcher_plugin_read_entry                   (XfceRc                *rc,
-                                                                     const gchar           *name) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-static void            launcher_plugin_screen_position_changed      (LauncherPlugin        *launcher);
-static void            launcher_plugin_orientation_changed          (LauncherPlugin        *launcher);
-static gboolean        launcher_plugin_set_size                     (LauncherPlugin        *launcher,
-                                                                     guint                  size);
-static void            launcher_plugin_free                         (LauncherPlugin        *launcher);
-static void            launcher_plugin_construct                    (XfcePanelPlugin       *plugin);
-
-
-
-/* register the plugin */
-XFCE_PANEL_PLUGIN_REGISTER (launcher_plugin_construct);
-
-
-
-/**
- * Utility Functions
- **/
-static gboolean
-launcher_utility_icon_theme_changed (GSignalInvocationHint *ihint,
-                                     guint                  n_param_values,
-                                     const GValue          *param_values,
-                                     LauncherPlugin        *launcher)
-{
-    /* update the button icon */
-    launcher_icon_button_set_icon (launcher);
+#include "xfce-test-plugin.h"
 
-    /* destroy the menu */
-    launcher_menu_destroy (launcher);
 
-    /* keep hook alive */
-    return TRUE;
-}
 
+static void xfce_test_plugin_class_init (XfceTestPluginClass *klass);
+static void xfce_test_plugin_init (XfceTestPlugin *plugin);
+static void xfce_test_plugin_construct (XfcePanelPlugin *panel_plugin);
+static void xfce_test_plugin_free_data (XfcePanelPlugin *panel_plugin);
+static void xfce_test_plugin_orientation_changed (XfcePanelPlugin *panel_plugin, GtkOrientation orientation);
+static gboolean xfce_test_plugin_size_changed (XfcePanelPlugin *panel_plugin, gint size);
+static void xfce_test_plugin_save (XfcePanelPlugin *panel_plugin);
+static void xfce_test_plugin_configure_plugin (XfcePanelPlugin *panel_plugin);
+static void xfce_test_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin, gint position);
+static void xfce_test_plugin_icon_theme_changed (GtkIconTheme *icon_theme, XfceTestPlugin *plugin);
+static void xfce_test_plugin_update_icon (XfceTestPlugin *plugin);
+static void xfce_test_plugin_reorder_buttons (XfceTestPlugin *plugin);
+static inline gchar *xfce_test_plugin_read_entry (XfceRc *rc, const gchar *name);
+static gboolean xfce_test_plugin_read (XfceTestPlugin *plugin);
+static void xfce_test_plugin_button_state_changed (GtkWidget *button_a, GtkStateType state, GtkWidget *button_b);
+static gboolean xfce_test_plugin_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, XfceTestPluginEntry *entry);
+static gboolean xfce_test_plugin_icon_button_pressed (GtkWidget *button, GdkEventButton *event, XfceTestPlugin *plugin);
+static gboolean xfce_test_plugin_icon_button_released (GtkWidget *button, GdkEventButton *event, XfceTestPlugin *plugin);
+static void xfce_test_plugin_icon_button_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, XfceTestPlugin *plugin);
+static gboolean xfce_test_plugin_icon_button_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, XfceTestPlugin *plugin);
+static gboolean xfce_test_plugin_arrow_button_pressed (GtkWidget *button, GdkEventButton *event, XfceTestPlugin *plugin);
+static gboolean xfce_test_plugin_menu_popup (gpointer user_data);
+static void xfce_test_plugin_menu_popup_destroyed (gpointer user_data);
+static void xfce_test_plugin_menu_deactivate (GtkWidget *menu, XfceTestPlugin *plugin);
+static void xfce_test_plugin_menu_destroy (XfceTestPlugin *plugin);
+static void xfce_test_plugin_menu_build (XfceTestPlugin *plugin);
+static gboolean xfce_test_plugin_menu_item_released (GtkMenuItem *menu_item, GdkEventButton *event, XfceTestPluginEntry *entry);
+static XfceTestPluginEntry *xfce_test_plugin_entry_new_default (void);
+static void xfce_test_plugin_entry_free (XfceTestPluginEntry *entry);
 
 
-GSList *
-launcher_utility_filenames_from_selection_data (GtkSelectionData *selection_data)
-{
-    gchar  **uri_list;
-    GSList  *filenames = NULL;
-    gchar   *filename;
-    guint    i;
 
-    /* check whether the retrieval worked */
-    if (G_LIKELY (selection_data->length > 0))
-    {
-        /* split the received uri list */
-        uri_list = g_uri_list_extract_uris ((gchar *) selection_data->data);
+static GQuark xfce_test_plugin_quark = 0;
 
-        if (G_LIKELY (uri_list))
-        {
-            /* walk though the list */
-            for (i = 0; uri_list[i] != NULL; i++)
-            {
-                /* convert the uri to a filename */
-                filename = g_filename_from_uri (uri_list[i], NULL, NULL);
 
-                /* prepend the filename */
-                if (G_LIKELY (filename))
-                    filenames = g_slist_prepend (filenames, filename);
-            }
 
-            /* cleanup */
-            g_strfreev (uri_list);
+G_DEFINE_TYPE (XfceTestPlugin, xfce_test_plugin, XFCE_TYPE_PANEL_PLUGIN);
 
-            /* reverse the list */
-            filenames = g_slist_reverse (filenames);
-        }
-    }
 
-    return filenames;
-}
 
+/* register the panel plugin */
+XFCE_PANEL_PLUGIN_REGISTER_OBJECT (XFCE_TYPE_TEST_PLUGIN);
 
 
-GdkPixbuf *
-launcher_utility_load_pixbuf (GdkScreen   *screen,
-                              const gchar *name,
-                              guint        size)
-{
-    GdkPixbuf    *pixbuf = NULL;
-    GdkPixbuf    *scaled;
-    GtkIconTheme *theme;
 
-    if (G_LIKELY (name))
-    {
-        if (g_path_is_absolute (name))
-        {
-            /* load the icon from the file */
-            pixbuf = exo_gdk_pixbuf_new_from_file_at_max_size (name, size, size, TRUE, NULL);
-        }
-        else
-        {
-            /* determine the appropriate icon theme */
-            if (G_LIKELY (screen))
-                theme = gtk_icon_theme_get_for_screen (screen);
-            else
-                theme = gtk_icon_theme_get_default ();
+static void
+xfce_test_plugin_class_init (XfceTestPluginClass *klass)
+{
+  XfcePanelPluginClass *plugin_class;
+
+  plugin_class = XFCE_PANEL_PLUGIN_CLASS (klass);
+  plugin_class->construct = xfce_test_plugin_construct;
+  plugin_class->free_data = xfce_test_plugin_free_data;
+  plugin_class->orientation_changed = xfce_test_plugin_orientation_changed;
+  plugin_class->size_changed = xfce_test_plugin_size_changed;
+  plugin_class->save = xfce_test_plugin_save;
+  plugin_class->configure_plugin = xfce_test_plugin_configure_plugin;
+  plugin_class->screen_position_changed = xfce_test_plugin_screen_position_changed;
+
+  /* initialize the quark */
+  xfce_test_plugin_quark = g_quark_from_static_string ("xfce-test-plugin");
+}
 
-            /* try to load the named icon */
-            pixbuf = gtk_icon_theme_load_icon (theme, name, size, 0, NULL);
 
-            if (G_LIKELY (pixbuf))
-            {
-                /* scale down the icon if required */
-                scaled = exo_gdk_pixbuf_scale_down (pixbuf, TRUE, size, size);
-                g_object_unref (G_OBJECT (pixbuf));
-                pixbuf = scaled;
-            }
-        }
-    }
 
-    return pixbuf;
+static void
+xfce_test_plugin_init (XfceTestPlugin *plugin)
+{
+  GdkScreen *screen;
+  
+  /* initialize variables */
+  plugin->entries = NULL;
+  plugin->menu = NULL;
+  plugin->popup_timeout_id = 0;
+  plugin->move_clicked_to_button = FALSE;
+  plugin->disable_tooltips = FALSE;
+  plugin->menu_reversed_order = FALSE;
+  plugin->show_labels = FALSE; /* TODO */
+  plugin->arrow_position = ARROW_POS_DEFAULT;
+
+  /* show the configure menu item */
+  xfce_panel_plugin_menu_show_configure (XFCE_PANEL_PLUGIN (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->icon_button = xfce_panel_create_button ();
+  gtk_box_pack_start (GTK_BOX (plugin->box), plugin->icon_button, TRUE, TRUE, 0);
+  xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->icon_button);
+  gtk_widget_show (plugin->icon_button);
+
+  plugin->image = xfce_scaled_image_new ();
+  gtk_container_add (GTK_CONTAINER (plugin->icon_button), plugin->image);
+  gtk_widget_show (plugin->image);
+
+  plugin->arrow_button = xfce_arrow_button_new (GTK_ARROW_UP);
+  gtk_box_pack_start (GTK_BOX (plugin->box), plugin->arrow_button, FALSE, FALSE, 0);
+  xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->arrow_button);
+  GTK_WIDGET_UNSET_FLAGS (plugin->arrow_button, GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
+  gtk_button_set_relief (GTK_BUTTON (plugin->arrow_button), GTK_RELIEF_NONE);
+  gtk_button_set_focus_on_click (GTK_BUTTON (plugin->arrow_button), FALSE);
+
+  /* signals */
+  g_signal_connect (G_OBJECT (plugin->icon_button), "state-changed",
+                    G_CALLBACK (xfce_test_plugin_button_state_changed), plugin->arrow_button);
+  g_signal_connect (G_OBJECT (plugin->arrow_button), "state-changed",
+                    G_CALLBACK (xfce_test_plugin_button_state_changed), plugin->icon_button);
+
+  g_signal_connect (G_OBJECT (plugin->icon_button), "button-press-event",
+                    G_CALLBACK (xfce_test_plugin_icon_button_pressed), plugin);
+  g_signal_connect (G_OBJECT (plugin->icon_button), "button-release-event",
+                    G_CALLBACK (xfce_test_plugin_icon_button_released), plugin);
+                    
+  gtk_drag_dest_set (plugin->icon_button, 0, drop_targets, /* TODO check flags */
+                     G_N_ELEMENTS (drop_targets), GDK_ACTION_COPY);
+  g_signal_connect (G_OBJECT (plugin->icon_button), "drag-data-received",
+                    G_CALLBACK (xfce_test_plugin_icon_button_drag_data_received), plugin);
+
+  g_object_set (G_OBJECT (plugin->icon_button), "has-tooltip", TRUE, NULL);
+  g_signal_connect (G_OBJECT (plugin->icon_button), "query-tooltip",
+                    G_CALLBACK (xfce_test_plugin_icon_button_query_tooltip), plugin);
+                    
+  /* store the icon theme */
+  screen = gtk_widget_get_screen (GTK_WIDGET (plugin));
+  plugin->icon_theme = screen ? gtk_icon_theme_get_for_screen (screen) 
+                         : gtk_icon_theme_get_default ();
+  g_signal_connect (G_OBJECT (plugin->icon_theme), "changed", 
+                    G_CALLBACK (xfce_test_plugin_icon_theme_changed), plugin);
 }
 
 
 
-#if LAUNCHER_NEW_TOOLTIP_API
-static gboolean
-launcher_utility_query_tooltip (GtkWidget     *widget,
-                                gint           x,
-                                gint           y,
-                                gboolean       keyboard_mode,
-                                GtkTooltip    *tooltip,
-                                LauncherEntry *entry)
+static void
+xfce_test_plugin_construct (XfcePanelPlugin *panel_plugin)
 {
-    gchar     *string;
-    GdkPixbuf *pixbuf;
-
-    /* create tooltip text */
-    if (G_LIKELY (entry && entry->name))
+  XfceTestPlugin      *plugin = XFCE_TEST_PLUGIN (panel_plugin);
+  const gchar * const *filenames;
+  guint                i;
+  
+  /* read the plugin configuration */
+  if (xfce_test_plugin_read (plugin) == FALSE)
     {
-        if (entry->comment)
-            string = g_strdup_printf ("<b>%s</b>\n%s", entry->name, entry->comment);
-        else
-            string = g_strdup_printf ("%s", entry->name);
-
-        /* set the markup tooltip */
-        gtk_tooltip_set_markup (tooltip, string);
-
-        /* cleanup */
-        g_free (string);
-
-        if (G_LIKELY (entry->icon))
+      /* try to build a launcher from the passed arguments */
+      filenames = xfce_panel_plugin_get_arguments (panel_plugin);
+      if (filenames)
         {
-            /* try to load an pixbuf */
-            pixbuf = launcher_utility_load_pixbuf (gtk_widget_get_screen (widget), entry->icon,
-                                                   LAUNCHER_TOOLTIP_SIZE);
-
-            if (G_LIKELY (pixbuf))
+          /* try to add all the passed filenames */
+          for (i = 0; filenames[i] != NULL; i++)
             {
-                /* set the tooltip icon */
-                gtk_tooltip_set_icon (tooltip, pixbuf);
-
-                /* releases */
-                g_object_unref (G_OBJECT (pixbuf));
+                /* TODO */
+                g_message ("%s", filenames[i]);
             }
         }
-
-        /* show the tooltip */
-        return TRUE;
+      
+      /* create a new launcher if there are still no entries */
+      if (plugin->entries == NULL)
+        plugin->entries = g_list_prepend (plugin->entries, xfce_test_plugin_entry_new_default ());
     }
-
-    /* nothing to show */
-    return FALSE;
+    
+  /* set the arrow direction */
+  xfce_test_plugin_screen_position_changed (panel_plugin, 0 /* TODO */);
+  
+  /* set the buttons in the correct position */
+  launcher_plugin_pack_buttons (launcher);
+  
+  /* change the visiblity of the arrow button */
+  launcher_menu_destroy (launcher);
 }
-#endif
 
 
 
-/**
- * Icon Button Functions
- **/
-static gboolean
-launcher_icon_button_expose_event (GtkWidget      *widget,
-                                   GdkEventExpose *event,
-                                   LauncherPlugin *launcher)
+static void
+xfce_test_plugin_free_data (XfcePanelPlugin *panel_plugin)
 {
-    gint         x, y, w;
-    GtkArrowType arrow_type;
-
-    /* only paint the arrow when the arrow button is hidden */
-    if (launcher->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON)
-    {
-        /* calculate the width of the arrow */
-        w = widget->allocation.width / 3;
-
-        /* get the arrow type */
-        arrow_type = xfce_arrow_button_get_arrow_type (XFCE_ARROW_BUTTON (launcher->arrow_button));
-
-        /* start coordinates */
-        x = widget->allocation.x;
-        y = widget->allocation.y;
-
-        /* calculate the position based on the arrow type */
-        switch (arrow_type)
-        {
-            case GTK_ARROW_UP:
-                /* north east */
-                x += (widget->allocation.width - w);
-                break;
+  XfceTestPlugin *plugin = XFCE_TEST_PLUGIN (panel_plugin);
 
-            case GTK_ARROW_DOWN:
-                /* south west */
-                y += (widget->allocation.height - w);
-                break;
-
-            case GTK_ARROW_RIGHT:
-                /* south east */
-                x += (widget->allocation.width - w);
-                y += (widget->allocation.height - w);
-                break;
+  /* stop popup timeout */
+  if (G_UNLIKELY (plugin->popup_timeout_id))
+    g_source_remove (plugin->popup_timeout_id);
 
-            default:
-                /* north west */
-                break;
-        }
+  /* destroy the popup menu */
+  if (plugin->menu)
+    gtk_widget_destroy (plugin->menu);
 
-        /* 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, w, w);
-    }
-
-    return FALSE;
+  /* remove the entries */
+  g_list_foreach (plugin->entries, (GFunc) xfce_test_plugin_entry_free, NULL);
+  g_list_free (plugin->entries);
 }
 
 
 
 static void
-launcher_icon_button_set_icon (LauncherPlugin *launcher)
+xfce_test_plugin_orientation_changed (XfcePanelPlugin *panel_plugin,
+                                      GtkOrientation   orientation)
 {
-    LauncherEntry *entry;
-
-    /* get the first entry in the list */
-    entry = g_list_first (launcher->entries)->data;
-    
-    if (g_path_is_absolute (entry->icon))
-      xfce_scaled_image_set_from_file (XFCE_SCALED_IMAGE (launcher->image), entry->icon);
-    else
-      xfce_scaled_image_set_from_icon_name (XFCE_SCALED_IMAGE (launcher->image), entry->icon);
+  /* update the arrow direction */
+  xfce_test_plugin_screen_position_changed (panel_plugin, 0 /* TODO */);
+  
+  /* reorder the buttons */
+  xfce_test_plugin_reorder_buttons (XFCE_TEST_PLUGIN (panel_plugin));
+
+  /* update the plugin size */
+  xfce_test_plugin_size_changed (plugin, xfce_panel_plugin_get_size (panel_plugin));
 }
 
 
 
-#if LAUNCHER_NEW_TOOLTIP_API
 static gboolean
-launcher_icon_button_query_tooltip (GtkWidget      *widget,
-                                    gint            x,
-                                    gint            y,
-                                    gboolean        keyboard_mode,
-                                    GtkTooltip     *tooltip,
-                                    LauncherPlugin *launcher)
+xfce_test_plugin_size_changed (XfcePanelPlugin *panel_plugin,
+                               gint             size)
 {
-    /* don't show tooltips on a menu button */
-    if (launcher->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON)
-       return FALSE;
+  XfceTestPlugin *plugin = XFCE_TEST_PLUGIN (panel_plugin);
+  gint            width, height;
+  GtkOrientation  orientation;
+  
+  /* init size */
+  width = height = size;
+  
+  if (plugin->arrow_position != LAUNCHER_ARROW_INSIDE_BUTTON
+      && LIST_HAS_TWO_OR_MORE_ENTRIES (plugin->entries))
+    {
+      /* get the orientation of the panel */
+      orientation = xfce_panel_plugin_get_orientation (panel_plugin);
+      
+      switch (launcher->arrow_position)
+        {
+          case LAUNCHER_ARROW_DEFAULT:
+            if (orientation == GTK_ORIENTATION_HORIZONTAL)
+              width += LAUNCHER_ARROW_SIZE;
+            else
+              height += LAUNCHER_ARROW_SIZE;
+            break;
+            
+          case LAUNCHER_ARROW_LEFT:
+          case LAUNCHER_ARROW_RIGHT:
+            if (orientation == GTK_ORIENTATION_HORIZONTAL)
+              width += LAUNCHER_ARROW_SIZE;
+            else
+              height -= LAUNCHER_ARROW_SIZE;
+            break;
+
+          default:
+            if (orientation == GTK_ORIENTATION_HORIZONTAL)
+              width -= LAUNCHER_ARROW_SIZE;
+            else
+              height += LAUNCHER_ARROW_SIZE;
+            break;
+        }
+    }
+    
+  /* set the size */
+  gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), width, height);
 
-    return launcher_utility_query_tooltip (widget, x, y, keyboard_mode, tooltip,
-                                           g_list_first (launcher->entries)->data);
+  return TRUE;
 }
 
 
 
-#else
 static void
-launcher_icon_button_set_tooltip (LauncherPlugin *launcher)
+xfce_test_plugin_save (XfcePanelPlugin *panel_plugin)
 {
-    LauncherEntry *entry;
-    gchar         *string = NULL;
+  gchar                *file;
+  gchar               **groups;
+  gchar                 group[10];
+  XfceRc               *rc;
+  GList                *li;
+  guint                 i;
+  XfceTestPluginEntry  *entry;
+
+  /* get rc file name, create it if needed */
+  file = xfce_panel_plugin_save_location (panel_plugin, TRUE);
+  if (G_LIKELY (file))
+    {
+      /* open the config file, writable */
+      rc = xfce_rc_simple_open (file, FALSE);
+      g_free (file);
 
-    /* get first entry */
-    entry = g_list_first (launcher->entries)->data;
+      if (G_LIKELY (rc))
+        {
+          /* delete all the existing groups */
+          groups = xfce_rc_get_groups (rc);
+          if (G_LIKELY (groups))
+            {
+              for (i = 0; groups[i] != NULL; i++)
+                xfce_rc_delete_group (rc, groups[i], TRUE);
+              g_strfreev (groups);
+            }
 
-    /* create tooltip text */
-    if (G_LIKELY (entry->name && launcher->arrow_position != LAUNCHER_ARROW_INSIDE_BUTTON))
-    {
-        if (entry->comment)
-            string = g_strdup_printf ("%s\n%s", entry->name, entry->comment);
-        else
-            string = g_strdup_printf ("%s", entry->name);
-    }
+          /* save global launcher settings */
+          xfce_rc_set_group (rc, "Global");
+          xfce_rc_write_bool_entry (rc, "MoveFirst", plugin->move_clicked_to_button);
+          xfce_rc_write_bool_entry (rc, "DisableTooltips", plugin->disable_tooltips);
+          xfce_rc_write_bool_entry (rc, "ShowLabels", plugin->show_labels);
 
-    /* set the tooltip */
-    gtk_tooltips_set_tip (launcher->tips, launcher->icon_button, string, NULL);
+          /* save all the entries */
+          for (li = launcher->entries, i = 0; li != NULL; li = li->next, i++)
+            {
+              entry = li->data;
+
+              /* set group */
+              g_snprintf (group, sizeof (group), "Entry %d", i);
+              xfce_rc_set_group (rc, group);
+
+              /* write entry settings */
+              if (G_LIKELY (entry->name))
+                xfce_rc_write_entry (rc, "Name", entry->name);
+              if (G_LIKELY (entry->comment))
+                xfce_rc_write_entry (rc, "Comment", entry->comment);
+              if (G_LIKELY (entry->icon))
+                xfce_rc_write_entry (rc, "Icon", entry->icon);
+              if (G_LIKELY (entry->exec))
+                xfce_rc_write_entry (rc, "Exec", entry->exec);
+              if (G_LIKELY (entry->path))
+                xfce_rc_write_entry (rc, "Path", entry->path);
+
+              xfce_rc_write_bool_entry (rc, "Terminal", entry->terminal);
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+              xfce_rc_write_bool_entry (rc, "StartupNotify", entry->startup);
+#endif
+            }
 
-    /* cleanup */
-    g_free (string);
+          /* close the rc file */
+          xfce_rc_close (rc);
+        }
+    }
 }
-#endif
 
 
 
-static gboolean
-launcher_icon_button_pressed (GtkWidget      *button,
-                              GdkEventButton *event,
-                              LauncherPlugin *launcher)
+static void
+xfce_test_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
 {
-    guint modifiers;
-
-    /* get the default accelerator modifier mask */
-    modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
 
-    /* exit if another button then 1 is pressed or control is hold */
-    if (event->button != 1 || modifiers == GDK_CONTROL_MASK)
-        return FALSE;
-
-    /* popup the menu or start the popup timeout */
-    if (launcher->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON)
-    {
-        launcher_menu_popup (launcher);
-    }
-    else if (launcher->popup_timeout_id == 0 && g_list_length (launcher->entries) > 1)
-    {
-        launcher->popup_timeout_id =
-            g_timeout_add_full (G_PRIORITY_DEFAULT, LAUNCHER_POPUP_DELAY, launcher_menu_popup,
-                                launcher, launcher_menu_popup_destroyed);
-    }
-
-    return FALSE;
 }
 
 
 
-static gboolean
-launcher_icon_button_released (GtkWidget      *button,
-                               GdkEventButton *event,
-                               LauncherPlugin *launcher)
+static void
+xfce_test_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin,
+                                          gint             position)
 {
-    LauncherEntry *entry;
-    GdkScreen     *screen;
-
-    /* remove the timeout */
-    if (G_LIKELY (launcher->popup_timeout_id > 0))
-        g_source_remove (launcher->popup_timeout_id);
-
-    /* only accept click in the button and don't respond on multiple clicks */
-    if (GTK_BUTTON (button)->in_button && launcher->arrow_position != LAUNCHER_ARROW_INSIDE_BUTTON)
-    {
-        /* get the first launcher entry */
-        entry = g_list_first (launcher->entries)->data;
-
-        /* get the widget screen */
-        screen = gtk_widget_get_screen (button);
+  GtkArrowType    arrow_type;
+  XfceTestPlugin *plugin = XFCE_TEST_PLUGIN (panel_plugin);
 
-        /* execute the command on button 1 and 2 */
-        if (event->button == 1)
-            launcher_execute (screen, entry, NULL);
-        else if (event->button == 2)
-            launcher_execute_from_clipboard (screen, entry);
-    }
+  /* get the arrow type */
+  arrow_type = xfce_panel_plugin_arrow_type (panel_plugin);
 
-    return FALSE;
+  /* set the arrow direction */
+  xfce_arrow_button_set_arrow_type (XFCE_ARROW_BUTTON (plugin->arrow_button), arrow_type);
 }
 
 
 
 static void
-launcher_icon_button_drag_data_received (GtkWidget        *widget,
-                                         GdkDragContext   *context,
-                                         gint              x,
-                                         gint              y,
-                                         GtkSelectionData *selection_data,
-                                         guint             info,
-                                         guint             time,
-                                         LauncherPlugin   *launcher)
+xfce_test_plugin_icon_theme_changed (GtkIconTheme   *icon_theme, 
+                                     XfceTestPlugin *plugin)
 {
-    GSList        *filenames;
-    LauncherEntry *entry;
-
-    /* execute */
-    if (launcher->arrow_position != LAUNCHER_ARROW_INSIDE_BUTTON)
-    {
-        /* create filenames list from all the uris */
-        filenames = launcher_utility_filenames_from_selection_data (selection_data);
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
+  panel_return_if_fail (GTK_IS_ICON_THEME (icon_theme));
+  
+  /* set the new icon theme */
+  plugin->icon_theme = icon_theme;
+  
+  /* update the button icon */
+  xfce_test_plugin_update_icon (plugin);
+  
+  /* destroy the menu */
+  xfce_test_plugin_menu_destroy (plugin);
+}
 
-        if (G_LIKELY (filenames))
-        {
-            /* get entry */
-            entry = g_list_first (launcher->entries)->data;
 
-            /* execute the entry with the filenames */
-            launcher_execute (gtk_widget_get_screen (widget), entry, filenames);
 
-            /* cleanup */
-            launcher_free_filenames (filenames);
-        }
-    }
-
-    /* finish drag */
-    gtk_drag_finish (context, TRUE, FALSE, time);
+static void
+xfce_test_plugin_update_icon (XfceTestPlugin *plugin)
+{
+  XfceTestPluginEntry *entry;
+  
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
+  
+  /* get the first entry */
+  entry = plugin->entries->data;
+  
+  if (g_path_is_absolute (entry->icon))
+    xfce_scaled_image_set_from_file (XFCE_SCALED_IMAGE (plugin->image), entry->icon);
+  else
+    xfce_scaled_image_set_from_icon_name (XFCE_SCALED_IMAGE (plugin->image), entry->icon);
 }
 
 
 
-/**
- * Arrow Button Functions
- **/
-static gboolean
-launcher_arrow_button_pressed (GtkWidget      *button,
-                               GdkEventButton *event,
-                               LauncherPlugin *launcher)
+void
+xfce_test_plugin_rebuild (XfceTestPlugin *plugin,
+                          gboolean        update_icon)
 {
-    /* only popup on 1st button */
-    if (event->button == 1)
-        launcher_menu_popup (launcher);
-
-    return FALSE;
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
+  
+  /* destroy the popup menu */
+  xfce_test_plugin_menu_destroy (plugin);
+  
+  /* reorder the buttons */
+  xfce_test_plugin_reorder_buttons (plugin);
+  
+  /* update the size */
+  xfce_test_plugin_size_changed (XFCE_PANEL_PLUGIN (plugin),
+                                 xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin));
+
+  /* update the icon if needed */
+  if (update_icon)
+    xfce_test_plugin_update_icon (plugin);
 }
 
 
 
-/**
- * Global Button Functions
- **/
 static void
-launcher_button_state_changed (GtkWidget    *button_a,
-                               GtkStateType  state,
-                               GtkWidget    *button_b)
+xfce_test_plugin_reorder_buttons (XfceTestPlugin *plugin)
 {
-    if (GTK_WIDGET_STATE (button_b) != GTK_WIDGET_STATE (button_a)
-        && GTK_WIDGET_STATE (button_a) != GTK_STATE_INSENSITIVE)
+  GtkOrientation         orientation;
+  XfceTestPluginArrowPos arrow_position = plugin->arrow_position;
+  
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
+
+  if (arrow_position == ARROW_POS_DEFAULT)
     {
-        /* sync the button states */
-        gtk_widget_set_state (button_b, GTK_WIDGET_STATE (button_a));
+      /* get the plugin orientation */
+      orientation = xfce_panel_plugin_get_orientation (XFCE_PANEL_PLUGIN (plugin));
+      
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        arrow_position = ARROW_POS_RIGHT;
+      else
+        arrow_position = ARROW_POS_BOTTOM;
     }
+  else if (arrow_position == ARROW_POS_INSIDE_BUTTON)
+    {
+      /* nothing to pack */
+      return; 
+    }
+  
+  /* set the position of the arrow button in the box */
+  gtk_box_reorder_child (GTK_BOX (plugin->box), plugin->arrow_button,
+                         (arrow_position == LAUNCHER_ARROW_LEFT 
+                          || arrow_position == LAUNCHER_ARROW_TOP) ? 0 : -1);
+  
+  /* set the hxbox orientation */
+  if (arrow_position == LAUNCHER_ARROW_LEFT || arrow_position == LAUNCHER_ARROW_RIGHT)
+    orientation = GTK_ORIENTATION_HORIZONTAL;
+  else
+    orientation = GTK_ORIENTATION_VERTICAL;
+  
+  xfce_hvbox_set_orientation (XFCE_HVBOX (launcher->box), orientation);
 }
 
 
 
-/**
- * Menu Functions
- **/
-static gboolean
-launcher_menu_item_released (GtkWidget      *mi,
-                             GdkEventButton *event,
-                             LauncherPlugin *launcher)
+static inline gchar *
+xfce_test_plugin_read_entry (XfceRc      *rc,
+                             const gchar *name)
 {
-    GdkScreen     *screen;
-    gint           i;
-    LauncherEntry *entry;
+    const gchar *temp;
+    gchar       *value = NULL;
 
-    /* get the widget screen */
-    screen = gtk_widget_get_screen (mi);
+    temp = xfce_rc_read_entry (rc, name, NULL);
+    if (G_LIKELY (temp != NULL && *temp != '\0'))
+        value = g_strdup (temp);
 
-    /* get the item number */
-    i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (mi), I_("entry-number")));
+    return value;
+}
 
-    /* get the entry from the list */
-    entry = g_list_nth_data (launcher->entries, i);
 
-    if (G_LIKELY (entry))
-    {
-        if (event->button == 1)
-            launcher_execute (screen, entry, NULL);
-        else if (event->button == 2)
-            launcher_execute_from_clipboard (screen, entry);
 
-        /* move the item to the first position in the list */
-        if (G_UNLIKELY (launcher->move_first && i > 0))
-        {
-            /* remove from the list */
-            launcher->entries = g_list_remove (launcher->entries, entry);
+static gboolean
+xfce_test_plugin_read (XfceTestPlugin *plugin)
+{
+  gchar               *file;
+  XfceRc              *rc;
+  guint                i;
+  gchar                group[10];
+  XfceTestPluginEntry *entry;
 
-            /* insert in first position */
-            launcher->entries = g_list_prepend (launcher->entries, entry);
+  panel_return_val_if_fail (XFCE_IS_TEST_PLUGIN (plugin), FALSE);
 
-            /* destroy the menu */
-            launcher_menu_destroy (launcher);
+  /* get rc file name, create it if needed */
+  file = xfce_panel_plugin_lookup_rc_file (XFCE_PANEL_PLUGIN (plugin));
+  if (G_LIKELY (file))
+    {
+      /* open config file, read-only, and cleanup */
+      rc = xfce_rc_simple_open (file, TRUE);
+      g_free (file);
 
-            /* rebuild the icon button */
-            launcher_icon_button_set_icon (launcher);
-#if !LAUNCHER_NEW_TOOLTIP_API
-            launcher_icon_button_set_tooltip (launcher);
+      if (G_LIKELY (rc))
+        {
+          /* read the global settings */
+          xfce_rc_set_group (rc, "Global");
+          plugin->move_clicked_to_button = xfce_rc_read_bool_entry (rc, "MoveFirst", FALSE);
+          plugin->disable_tooltips = xfce_rc_read_bool_entry (rc, "DisableTooltips", FALSE);
+          plugin->show_labels = xfce_rc_read_bool_entry (rc, "ShowLabels", FALSE);
+
+          /* read all the entries */
+          for (i = 0; i < 100 /* arbitrary */; i++)
+            {
+              /* set group, leave if we reached the last entry */
+              g_snprintf (group, sizeof (group), "Entry %d", i);
+              if (xfce_rc_has_group (rc, group) == FALSE)
+                break;
+              xfce_rc_set_group (rc, group);
+
+              /* create entry */
+              entry = g_slice_new (XfceTestPluginEntry);
+              entry->name = launcher_plugin_read_entry (rc, "Name");
+              entry->comment = launcher_plugin_read_entry (rc, "Comment");
+              entry->icon = launcher_plugin_read_entry (rc, "Icon");
+              entry->exec = launcher_plugin_read_entry (rc, "Exec");
+              entry->path = launcher_plugin_read_entry (rc, "Path");
+              entry->terminal = xfce_rc_read_bool_entry (rc, "Terminal", FALSE);
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+              entry->startup = xfce_rc_read_bool_entry (rc, "StartupNotify", FALSE);
 #endif
-        }
-    }
-
-    return FALSE;
-}
 
+              /* prepend to the list */
+              plugin->entries = g_list_prepend (plugin->entries, entry);
+            }
 
+          /* close the rc file */
+          xfce_rc_close (rc);
 
-static void
-launcher_menu_popup_destroyed (gpointer user_data)
-{
-    LauncherPlugin *launcher = user_data;
+          /* reverse the order of the list */
+          plugin->entries = g_list_reverse (plugin->entries);
+        }
+    }
 
-    launcher->popup_timeout_id = 0;
+  return (plugin->entries != NULL);
 }
 
 
 
-static gboolean
-launcher_menu_popup (gpointer user_data)
+GSList *
+xfce_test_plugin_filenames_from_selection_data (GtkSelectionData *selection_data)
 {
-    LauncherPlugin *launcher = user_data;
-
-    GDK_THREADS_ENTER ();
+  gchar  **uri_list;
+  GSList  *filenames = NULL;
+  gchar   *file;
+  guint    i;
 
-    /* check if the menu exists, if not, rebuild it */
-    if (launcher->menu == NULL)
-        launcher_menu_rebuild (launcher);
-
-    /* toggle the arrow button */
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (launcher->arrow_button), TRUE);
-
-    /* popup menu */
-    gtk_menu_popup (GTK_MENU (launcher->menu), NULL, NULL,
-                    xfce_panel_plugin_position_menu,
-                    launcher->panel_plugin,
-                    1, gtk_get_current_event_time ());
-
-    GDK_THREADS_LEAVE ();
+  /* check whether the retrieval worked */
+  if (G_LIKELY (selection_data->length > 0))
+    {
+      /* split the received uri list */
+      uri_list = g_uri_list_extract_uris ((gchar *) selection_data->data);
+      if (G_LIKELY (uri_list))
+        {
+          /* walk though the list */
+          for (i = 0; uri_list[i] != NULL; i++)
+            {
+              /* convert the uri to a filename */
+              file = g_filename_from_uri (uri_list[i], NULL, NULL);
 
-    return FALSE;
-}
+              /* prepend the filename */
+              if (G_LIKELY (file))
+                filenames = g_slist_prepend (filenames, file);
+            }
 
+          /* cleanup */
+          g_strfreev (uri_list);
 
+          /* reverse the list */
+          filenames = g_slist_reverse (filenames);
+      }
+  }
 
-static void
-launcher_menu_deactivated (LauncherPlugin *launcher)
-{
-    /* deactivate arrow button */
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (launcher->arrow_button), FALSE);
+  return filenames;
 }
 
 
 
-static void
-launcher_menu_destroy (LauncherPlugin *launcher)
+GdkPixbuf *
+xfce_test_plugin_load_pixbuf (const gchar  *name,
+                              gint          size,
+                              GtkIconTheme *icon_theme)
 {
-    if (launcher->menu != NULL)
+  GdkPixbuf *pixbuf, *scaled;
+  
+  panel_return_val_if_fail (size > 0, NULL);
+  panel_return_val_if_fail (GTK_IS_ICON_THEME (theme), NULL);
+  
+  /* return null if there is no name */
+  if (G_UNLIKELY (name == NULL || *name == '\0'))
+    return NULL;
+  
+  /* load the icon from a file or the icon theme */
+  if (g_path_is_absolute (name))
     {
-        /* destroy the menu and null the variable */
-        gtk_widget_destroy (launcher->menu);
-        launcher->menu = NULL;
-
-        /* deactivate arrow button */
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (launcher->arrow_button), FALSE);
+      pixbuf = exo_gdk_pixbuf_new_from_file_at_max_size (name, size, size, TRUE, NULL);
     }
-
-    /* set the visibility of the arrow button */
-    if (launcher->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON ||
-        g_list_length (launcher->entries) < 2)
+  else
     {
-        gtk_widget_hide (launcher->arrow_button);
-    }
-    else
-    {
-        gtk_widget_show (launcher->arrow_button);
+      pixbuf = gtk_icon_theme_load_icon (icon_theme, name, size, 0, NULL);
+      if (G_LIKELY (pixbuf))
+        {
+          scaled = exo_gdk_pixbuf_scale_down (pixbuf, TRUE, size, size);
+          g_object_unref (G_OBJECT (pixbuf));
+          pixbuf = scaled;
+        }
     }
+
+  return pixbuf;
 }
 
 
 
-static void
-launcher_menu_rebuild (LauncherPlugin *launcher)
+static gboolean
+xfce_test_plugin_query_tooltip (GtkWidget           *widget,
+                                gint                 x,
+                                gint                 y,
+                                gboolean             keyboard_mode,
+                                GtkTooltip          *tooltip,
+                                XfceTestPluginEntry *entry)
 {
-    GdkScreen     *screen;
-    GList         *li;
-    guint          n = 0;
-    LauncherEntry *entry;
-    GtkWidget     *mi, *image;
-    GdkPixbuf     *pixbuf;
+  gchar        *string;
+  GdkPixbuf    *pixbuf;
+  GtkIconTheme *icon_theme;
 
-    /* destroy the old menu */
-    if (G_UNLIKELY (launcher->menu))
-        launcher_menu_destroy (launcher);
-
-    /* create new menu */
-    launcher->menu = gtk_menu_new ();
-
-    /* get the plugin screen */
-    screen = gtk_widget_get_screen (GTK_WIDGET (launcher->panel_plugin));
-
-    /* set the menu screen */
-    gtk_menu_set_screen (GTK_MENU (launcher->menu), screen);
-
-    /* walk through the entries */
-    for (li = launcher->entries; li != NULL; li = li->next, n++)
+  if (G_LIKELY (entry && entry->name))
     {
-        /* skip the first entry when the arrow is visible */
-        if (n == 0 && launcher->arrow_position != LAUNCHER_ARROW_INSIDE_BUTTON)
-            continue;
-
-        entry = li->data;
+      /* create tooltip label */
+      if (entry->comment)
+        string = g_strdup_printf ("<b>%s</b>\n%s", entry->name, entry->comment);
+      else
+        string = g_strdup_printf ("%s", entry->name);
 
-        /* create menu item */
-        mi = gtk_image_menu_item_new_with_label (entry->name ? entry->name : _("New Item"));
-        gtk_menu_shell_prepend (GTK_MENU_SHELL (launcher->menu), mi);
-        gtk_widget_show (mi);
+      /* set the markup tooltip and cleanup */
+      gtk_tooltip_set_markup (tooltip, string);
+      g_free (string);
 
-        /* try to set an image */
-        if (G_LIKELY (entry->icon))
+      if (G_LIKELY (entry->icon))
         {
-            /* load pixbuf */
-            pixbuf = launcher_utility_load_pixbuf (screen, entry->icon, LAUNCHER_MENU_SIZE);
+          /* get the icon theme */
+          screen = gtk_widget_get_screen (widget);
+          icon_theme = gtk_icon_theme_get_for_screen (screen);
 
-            if (G_LIKELY (pixbuf))
+          /* try to load a pixbuf */
+          pixbuf = xfce_test_plugin_load_pixbuf (entry->icon, TOOLTIP_ICON_SIZE, icon_theme);
+          if (G_LIKELY (pixbuf))
             {
-                /* set image */
-                image = gtk_image_new_from_pixbuf (pixbuf);
-                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
-                gtk_widget_show (image);
-
-                /* release reference */
-                g_object_unref (G_OBJECT (pixbuf));
+              /* set the tooltip icon and release it */
+              gtk_tooltip_set_icon (tooltip, pixbuf);
+              g_object_unref (G_OBJECT (pixbuf));
             }
         }
 
-        /* set entries list number */
-        g_object_set_data (G_OBJECT (mi), I_("entry-number"), GINT_TO_POINTER (n));
-
-        /* connect signals */
-        g_signal_connect (G_OBJECT (mi), "button-release-event", G_CALLBACK (launcher_menu_item_released), launcher);
-#if LAUNCHER_NEW_TOOLTIP_API
-        g_object_set (G_OBJECT (mi), "has-tooltip", TRUE, NULL);
-        g_signal_connect (G_OBJECT (mi), "query-tooltip", G_CALLBACK (launcher_utility_query_tooltip), entry);
-#endif
-
-        /* dnd support */
-        gtk_drag_dest_set (mi, GTK_DEST_DEFAULT_ALL, drop_targets, G_N_ELEMENTS (drop_targets), GDK_ACTION_COPY);
-
-#if !LAUNCHER_NEW_TOOLTIP_API
-        /* set tooltip */
-        if (entry->comment)
-            gtk_tooltips_set_tip (launcher->tips, mi, entry->comment, NULL);
-#endif
+      /* show the tooltip */
+      return TRUE;
     }
 
-    /* connect deactivate signal */
-    g_signal_connect_swapped (G_OBJECT (launcher->menu), "deactivate", G_CALLBACK (launcher_menu_deactivated), launcher);
-}
-
-
-
-/**
- * Entry Functions
- **/
-LauncherEntry *
-launcher_entry_new (void)
-{
-    LauncherEntry *entry;
-
-    /* allocate structure */
-    entry = g_slice_new0 (LauncherEntry);
-
-    /* set some default values */
-    entry->name    = g_strdup (_("New Item"));
-    entry->comment = NULL;
-    entry->icon    = g_strdup ("applications-other");
-
-    /* fill others */
-    entry->exec     = NULL;
-    entry->path     = NULL;
-    entry->terminal = FALSE;
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    entry->startup  = FALSE;
-#endif
-
-    return entry;
+  /* nothing to show */
+  return FALSE;
 }
 
 
 
-void
-launcher_entry_free (LauncherEntry  *entry,
-                     LauncherPlugin *launcher)
+static void
+xfce_test_plugin_button_state_changed (GtkWidget    *button_a,
+                                       GtkStateType  state,
+                                       GtkWidget    *button_b)
 {
-    /* remove from the list */
-    if (G_LIKELY (launcher))
-        launcher->entries = g_list_remove (launcher->entries, entry);
-
-    /* free variables */
-    g_free (entry->name);
-    g_free (entry->comment);
-    g_free (entry->path);
-    g_free (entry->icon);
-    g_free (entry->exec);
-
-    /* free structure */
-    g_slice_free (LauncherEntry, entry);
+  /* sync the button states */
+  if (GTK_WIDGET_STATE (button_b) != GTK_WIDGET_STATE (button_a)
+      && GTK_WIDGET_STATE (button_a) != GTK_STATE_INSENSITIVE)
+    gtk_widget_set_state (button_b, GTK_WIDGET_STATE (button_a));
 }
 
 
 
-/**
- * Panel Plugin Functions
- **/
-static LauncherPlugin*
-launcher_plugin_new (XfcePanelPlugin *plugin)
+static gboolean
+xfce_test_plugin_icon_button_pressed (GtkWidget      *button,
+                                      GdkEventButton *event,
+                                      XfceTestPlugin *plugin)
 {
-    LauncherPlugin *launcher;
-    gpointer        klass;
-
-    /* create launcher structure */
-    launcher = g_slice_new0 (LauncherPlugin);
-
-    /* init */
-    launcher->panel_plugin = plugin;
-    launcher->menu = NULL;
-    launcher->plugin_can_save = TRUE;
+  guint modifiers;
 
-#if !LAUNCHER_NEW_TOOLTIP_API
-    /* create tooltips */
-    launcher->tips = gtk_tooltips_new ();
-    exo_gtk_object_ref_sink (GTK_OBJECT (launcher->tips));
-#endif
-
-    /* create widgets */
-    launcher->box = xfce_hvbox_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
-    gtk_container_add (GTK_CONTAINER (plugin), launcher->box);
-    gtk_widget_show (launcher->box);
-
-    launcher->icon_button = xfce_panel_create_button ();
-    gtk_box_pack_start (GTK_BOX (launcher->box), launcher->icon_button, TRUE, TRUE, 0);
-    gtk_widget_show (launcher->icon_button);
-
-    launcher->image = xfce_scaled_image_new ();
-    gtk_container_add (GTK_CONTAINER (launcher->icon_button), launcher->image);
-    gtk_widget_show (launcher->image);
-
-    launcher->arrow_button = xfce_arrow_button_new (GTK_ARROW_UP);
-    GTK_WIDGET_UNSET_FLAGS (launcher->arrow_button, GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
-    gtk_box_pack_start (GTK_BOX (launcher->box), launcher->arrow_button, FALSE, FALSE, 0);
-    gtk_button_set_relief (GTK_BUTTON (launcher->arrow_button), GTK_RELIEF_NONE);
-    gtk_button_set_focus_on_click (GTK_BUTTON (launcher->arrow_button), FALSE);
-
-    /* hook for icon themes changes */
-    klass = g_type_class_ref (GTK_TYPE_ICON_THEME);
-    launcher->theme_timeout_id =
-        g_signal_add_emission_hook (g_signal_lookup ("changed", GTK_TYPE_ICON_THEME),
-                                    0, (GSignalEmissionHook) launcher_utility_icon_theme_changed,
-                                    launcher, NULL);
-    g_type_class_unref (klass);
-
-    /* icon button signals */
-    g_signal_connect (G_OBJECT (launcher->icon_button), "state-changed",
-                      G_CALLBACK (launcher_button_state_changed), launcher->arrow_button);
-    g_signal_connect (G_OBJECT (launcher->icon_button), "button-press-event",
-                      G_CALLBACK (launcher_icon_button_pressed), launcher);
-    g_signal_connect (G_OBJECT (launcher->icon_button), "button-release-event",
-                      G_CALLBACK (launcher_icon_button_released), launcher);
-    g_signal_connect (G_OBJECT (launcher->icon_button), "drag-data-received",
-                      G_CALLBACK (launcher_icon_button_drag_data_received), launcher);
-    g_signal_connect_after (G_OBJECT (launcher->image), "expose-event",
-                            G_CALLBACK (launcher_icon_button_expose_event), launcher);
-
-#if LAUNCHER_NEW_TOOLTIP_API
-    g_object_set (G_OBJECT (launcher->icon_button), "has-tooltip", TRUE, NULL);
-    g_signal_connect (G_OBJECT (launcher->icon_button), "query-tooltip",
-                      G_CALLBACK (launcher_icon_button_query_tooltip), launcher);
-#endif
-
-    /* arrow button signals */
-    g_signal_connect (G_OBJECT (launcher->arrow_button), "state-changed",
-                      G_CALLBACK (launcher_button_state_changed), launcher->icon_button);
-    g_signal_connect (G_OBJECT (launcher->arrow_button), "button-press-event",
-                      G_CALLBACK (launcher_arrow_button_pressed), launcher);
-
-    /* set drag destinations */
-    gtk_drag_dest_set (launcher->icon_button, GTK_DEST_DEFAULT_ALL,
-                       drop_targets, G_N_ELEMENTS (drop_targets),
-                       GDK_ACTION_COPY);
-    gtk_drag_dest_set (launcher->arrow_button, GTK_DEST_DEFAULT_ALL,
-                       drop_targets, G_N_ELEMENTS (drop_targets),
-                       GDK_ACTION_COPY);
-
-    /* read the user settings */
-    launcher_plugin_read (launcher);
-
-    /* create new launcher */
-    if (G_UNLIKELY (g_list_length (launcher->entries) == 0))
-      {
-        gchar **filenames;
-        guint i;
-        LauncherEntry *entry;
-
-        /* check for startup arguments */
-        if (xfce_panel_plugin_get_arguments (plugin, &filenames))
-          {
-            /* try to add the entries to the new launcher */
-            for (i = 0; filenames[i] != NULL; i++)
-              {
-                /* create new entry */
-                entry = launcher_entry_new ();
-
-                if (launcher_dialog_read_desktop_file (filenames[i], entry))
-                  launcher->entries = g_list_append (launcher->entries, entry);
-                else
-                  launcher_entry_free (entry, NULL);
-              }
-
-            /* cleanup */
-            g_strfreev (filenames);
-          }
-
-        /* add new entry if the list is still empty */
-        if (G_UNLIKELY (g_list_length (launcher->entries) == 0))
-          launcher->entries = g_list_prepend (launcher->entries, launcher_entry_new ());
-      }
+  panel_return_val_if_fail (XFCE_IS_TEST_PLUGIN (plugin), FALSE);
 
-    /* set the arrow direction */
-    launcher_plugin_screen_position_changed (launcher);
+  /* get the default accelerator modifier mask */
+  modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
 
-    /* set the buttons in the correct position */
-    launcher_plugin_pack_buttons (launcher);
-
-    /* change the visiblity of the arrow button */
-    launcher_menu_destroy (launcher);
+  /* leave when button 1 is not pressed, shift if hold */
+  if (event->button != 1 || modifiers == GDK_CONTROL_MASK)
+    return FALSE;
 
-#if !LAUNCHER_NEW_TOOLTIP_API
-    /* set the button tooltip */
-    launcher_icon_button_set_tooltip (launcher);
-#endif
+  /* popup the menu or start the popup timeout */
+  if (plugin->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON)
+    xfce_test_plugin_menu_popup (plugin);
+  else if (launcher->popup_timeout_id == 0
+           && LIST_HAS_TWO_OR_MORE_ENTRIES (launcher->entries))
+    plugin->popup_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, XFCE_TEST_PLUGIN_POPUP_DELAY,
+                                                   xfce_test_plugin_menu_popup, plugin,
+                                                   xfce_test_plugin_menu_popup_destroyed);
 
-    return launcher;
+  return FALSE;
 }
 
 
 
-void
-launcher_plugin_rebuild (LauncherPlugin *launcher,
-                         gboolean        update_icon)
+static gboolean
+xfce_test_plugin_icon_button_released (GtkWidget      *button,
+                                       GdkEventButton *event,
+                                       XfceTestPlugin *plugin)
 {
-    /* pack buttons again */
-    launcher_plugin_pack_buttons (launcher);
+  XfceTestPluginEntry *entry;
+  GdkScreen           *screen;
 
-    /* size */
-    launcher_plugin_set_size (launcher, xfce_panel_plugin_get_size (launcher->panel_plugin));
+  panel_return_val_if_fail (XFCE_IS_TEST_PLUGIN (plugin), FALSE);
 
-#if !LAUNCHER_NEW_TOOLTIP_API
-    /* update tooltip */
-    launcher_icon_button_set_tooltip (launcher);
-#endif
+  /* remove a delayout popup timeout */
+  if (G_LIKELY (plugin->popup_timeout_id != 0))
+    g_source_remove (plugin->popup_timeout_id);
 
-    if (update_icon)
-        launcher_icon_button_set_icon (launcher);
+  /* only accept click in the button and don't respond on multiple clicks */
+  if (GTK_BUTTON (button)->in_button
+      && launcher->arrow_position != LAUNCHER_ARROW_INSIDE_BUTTON)
+    {
+      /* get the first launcher entry */
+      entry = plugin->entries->data;
 
-    /* destroy menu */
-    launcher_menu_destroy (launcher);
+      /* get the widget screen */
+      screen = gtk_widget_get_screen (button);
+
+      /* execute the command on button 1 and 2 */
+      if (event->button == 1)
+        xfce_test_plugin_execute (screen, entry, NULL);
+      else if (event->button == 2)
+        xfce_test_plugin_execute_from_clipboard (screen, entry);
+    }
+
+  return FALSE;
 }
 
 
 
 static void
-launcher_plugin_pack_buttons (LauncherPlugin *launcher)
+xfce_test_plugin_icon_button_drag_data_received (GtkWidget        *widget,
+                                                 GdkDragContext   *context,
+                                                 gint              x,
+                                                 gint              y,
+                                                 GtkSelectionData *selection_data,
+                                                 guint             info,
+                                                 guint             time,
+                                                 XfceTestPlugin   *plugin)
 {
-    GtkOrientation orientation;
-    guint          position = launcher->arrow_position;
-    gint           box_position, width = -1, height = -1;
-
-    if (position == LAUNCHER_ARROW_DEFAULT)
-    {
-        /* get the current panel orientation */
-        orientation = xfce_panel_plugin_get_orientation (launcher->panel_plugin);
-
-        /* get the arrow position in the default layout */
-        if (orientation == GTK_ORIENTATION_HORIZONTAL)
-            position = LAUNCHER_ARROW_RIGHT;
-        else
-            position = LAUNCHER_ARROW_BOTTOM;
-    }
-    else if (position == LAUNCHER_ARROW_INSIDE_BUTTON)
+  GSList *filenames;
+  
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
+  
+  /* leave when arrow is inside the button */
+  if (plugin->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON)
+    return;
+  
+  /* get the filenames from the selection data */
+  filenames = xfce_test_plugin_filenames_from_selection_data (selection_data);
+  if (G_LIKELY (filenames))
     {
-        /* nothing to arrange */
-        return;
-    }
-
-    /* set the arrow button position in the box */
-    box_position = (position == LAUNCHER_ARROW_LEFT || position == LAUNCHER_ARROW_TOP) ? 0 : -1;
-    gtk_box_reorder_child (GTK_BOX (launcher->box), launcher->arrow_button, box_position);
-
-    /* set the arrow button size and box orientation */
-    if (position == LAUNCHER_ARROW_LEFT || position == LAUNCHER_ARROW_RIGHT)
-    {
-        orientation = GTK_ORIENTATION_HORIZONTAL;
-        width = LAUNCHER_ARROW_SIZE;
-    }
-    else
-    {
-        orientation = GTK_ORIENTATION_VERTICAL;
-        height = LAUNCHER_ARROW_SIZE;
+      /* execute */
+      launcher_execute (gtk_widget_get_screen (widget), plugin->entries->data, filenames);
+    
+      /* cleanup */
+      xfce_test_plugin_filenames_free (filenames);
     }
-
-    gtk_widget_set_size_request (launcher->arrow_button, width, height);
-    xfce_hvbox_set_orientation (XFCE_HVBOX (launcher->box), orientation);
-
-    /* set the visibility of the arrow button */
-    if (g_list_length (launcher->entries) > 1)
-        gtk_widget_show (launcher->arrow_button);
-    else
-        gtk_widget_hide (launcher->arrow_button);
+  
+  /* finish the drag */
+  gtk_drag_finish (context, TRUE, FALSE, time);
 }
 
 
 
-static gchar *
-launcher_plugin_read_entry (XfceRc      *rc,
-                            const gchar *name)
+static gboolean
+xfce_test_plugin_icon_button_query_tooltip (GtkWidget      *widget,
+                                            gint            x,
+                                            gint            y,
+                                            gboolean        keyboard_mode,
+                                            GtkTooltip     *tooltip,
+                                            XfceTestPlugin *plugin)
 {
-    const gchar *temp;
-    gchar       *value = NULL;
+  panel_return_val_if_fail (XFCE_IS_TEST_PLUGIN (plugin), FALSE);
 
-    temp = xfce_rc_read_entry (rc, name, NULL);
-    if (G_LIKELY (temp != NULL && *temp != '\0'))
-        value = g_strdup (temp);
+  /* don't show tooltips on a menu button or when tooltips are disabled */
+  if (plugin->disable_tooltips
+      || plugin->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON)
+    return FALSE;
 
-    return value;
+  /* run the tooltip query function */
+  return xfce_test_plugin_query_tooltip (widget, x, y, keyboard_mode, tooltip, plugin->entries->data);
 }
 
 
 
-void
-launcher_plugin_read (LauncherPlugin *launcher)
+static gboolean
+xfce_test_plugin_arrow_button_pressed (GtkWidget      *button,
+                                       GdkEventButton *event,
+                                       XfceTestPlugin *plugin)
 {
-    gchar         *file;
-    gchar          group[10];
-    XfceRc        *rc;
-    guint          i;
-    LauncherEntry *entry;
-
-    /* get rc file name, create it if needed */
-    file = xfce_panel_plugin_lookup_rc_file ( launcher->panel_plugin);
-    if (G_LIKELY (file))
-    {
-        /* open config file, read-only */
-        rc = xfce_rc_simple_open (file, TRUE);
+  panel_return_val_if_fail (XFCE_IS_TEST_PLUGIN (plugin), FALSE);
 
-        /* cleanup */
-        g_free (file);
+  /* only popup when button 1 is pressed */
+  if (event->button == 1)
+    xfce_test_plugin_menu_popup (plugin);
 
-        if (G_LIKELY (rc))
-        {
-            /* read global settings */
-            xfce_rc_set_group (rc, "Global");
+  return FALSE;
+}
 
-            launcher->move_first = xfce_rc_read_bool_entry (rc, "MoveFirst", FALSE);
-            launcher->arrow_position = xfce_rc_read_int_entry (rc, "ArrowPosition", 0);
 
-            for (i = 0; i < 100 /* arbitrary */; ++i)
-            {
-                /* create group name */
-                g_snprintf (group, sizeof (group), "Entry %d", i);
 
-                /* break if no more entries found */
-                if (xfce_rc_has_group (rc, group) == FALSE)
-                    break;
+static gboolean
+xfce_test_plugin_menu_popup (gpointer user_data)
+{
+  XfceTestPlugin *plugin = XFCE_TEST_PLUGIN (user_data);
 
-                /* set the group */
-                xfce_rc_set_group (rc, group);
+  /* build the menu */
+  if (G_UNLIKELY (plugin->menu == NULL))
+    xfce_test_plugin_menu_build (plugin);
 
-                /* create new entry structure */
-                entry = g_slice_new0 (LauncherEntry);
+  GDK_THREADS_ENTER ();
 
-                /* read all the entry settings */
-                entry->name = launcher_plugin_read_entry (rc, "Name");
-                entry->comment = launcher_plugin_read_entry (rc, "Comment");
-                entry->icon = launcher_plugin_read_entry (rc, "Icon");
-                entry->exec = launcher_plugin_read_entry (rc, "Exec");
-                entry->path = launcher_plugin_read_entry (rc, "Path");
+  /* toggle the arrow button */
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->arrow_button), TRUE);
 
-                entry->terminal = xfce_rc_read_bool_entry (rc, "Terminal", FALSE);
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-                entry->startup = xfce_rc_read_bool_entry (rc, "StartupNotify", FALSE);
-#endif
-                /* prepend the entry */
-                launcher->entries = g_list_prepend (launcher->entries, entry);
-            }
+  /* 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 ());
 
-            /* reverse the list */
-            launcher->entries = g_list_reverse (launcher->entries);
+  GDK_THREADS_LEAVE ();
 
-            /* close the rc file */
-            xfce_rc_close (rc);
-        }
-    }
+  return FALSE;
 }
 
 
 
-void
-launcher_plugin_save (LauncherPlugin *launcher)
+static void
+xfce_test_plugin_menu_popup_destroyed (gpointer user_data)
 {
-    gchar          *file;
-    gchar         **groups;
-    gchar           group[10];
-    XfceRc         *rc;
-    GList          *li;
-    guint           i;
-    LauncherEntry  *entry;
-
-    /* check if it's allowed to save */
-    if (G_UNLIKELY (launcher->plugin_can_save == FALSE))
-        return;
-
-    /* get rc file name, create it if needed */
-    file = xfce_panel_plugin_save_location ( launcher->panel_plugin, TRUE);
-    if (G_LIKELY (file))
-    {
-        /* open the config file, writable */
-        rc = xfce_rc_simple_open (file, FALSE);
-
-        /* cleanup */
-        g_free (file);
-
-        if (G_LIKELY (rc))
-        {
-            /* retreive all the groups in the config file */
-            groups = xfce_rc_get_groups (rc);
-            if (G_LIKELY (groups))
-            {
-                /* remove all the groups */
-                for (i = 0; groups[i] != NULL; i++)
-                    xfce_rc_delete_group (rc, groups[i], TRUE);
-
-                /* cleanup */
-                g_strfreev (groups);
-            }
-
-            /* save global launcher settings */
-            xfce_rc_set_group (rc, "Global");
-            xfce_rc_write_bool_entry (rc, "MoveFirst", launcher->move_first);
-            xfce_rc_write_int_entry (rc, "ArrowPosition", launcher->arrow_position);
-
-            /* save all the entries */
-            for (li = launcher->entries, i = 0; li != NULL; li = li->next, i++)
-            {
-                entry = li->data;
-
-                /* create group name */
-                g_snprintf (group, sizeof (group), "Entry %d", i);
-
-                /* set entry group */
-                xfce_rc_set_group (rc, group);
-
-                /* write entry settings */
-                if (G_LIKELY (entry->name))
-                    xfce_rc_write_entry (rc, "Name", entry->name);
-                if (G_LIKELY (entry->comment))
-                    xfce_rc_write_entry (rc, "Comment", entry->comment);
-                if (G_LIKELY (entry->icon))
-                    xfce_rc_write_entry (rc, "Icon", entry->icon);
-                if (G_LIKELY (entry->exec))
-                    xfce_rc_write_entry (rc, "Exec", entry->exec);
-                if (G_LIKELY (entry->path))
-                    xfce_rc_write_entry (rc, "Path", entry->path);
-                xfce_rc_write_bool_entry (rc, "Terminal", entry->terminal);
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-                xfce_rc_write_bool_entry (rc, "StartupNotify", entry->startup);
-#endif
-            }
-
-            /* close the rc file */
-            xfce_rc_close (rc);
-        }
-    }
+  XFCE_TEST_PLUGIN (user_data)->popup_timeout_id = 0;
 }
 
 
 
 static void
-launcher_plugin_screen_position_changed (LauncherPlugin *launcher)
+xfce_test_plugin_menu_deactivate (GtkWidget      *menu,
+                                  XfceTestPlugin *plugin)
 {
-    GtkArrowType arrow_type;
-
-    /* get the arrow type */
-    arrow_type = xfce_panel_plugin_arrow_type (launcher->panel_plugin);
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
+  panel_return_if_fail (plugin->menu == menu);
 
-    /* set the arrow direction */
-    xfce_arrow_button_set_arrow_type (XFCE_ARROW_BUTTON (launcher->arrow_button), arrow_type);
+  /* deactivate the arrow button */
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->arrow_button), FALSE);
 }
 
 
 
 static void
-launcher_plugin_orientation_changed (LauncherPlugin *launcher)
+xfce_test_plugin_menu_destroy (XfceTestPlugin *plugin)
 {
-    /* set the arrow direction */
-    launcher_plugin_screen_position_changed (launcher);
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
 
-    /* reorder the boxes again */
-    launcher_plugin_pack_buttons (launcher);
+  if (G_LIKELY (plugin->menu != NULL))
+    {
+      /* destroy the menu and null the variable */
+      gtk_widget_destroy (plugin->menu);
+      plugin->menu = NULL;
 
-    /* update size */
-    launcher_plugin_set_size (launcher, xfce_panel_plugin_get_size (launcher->panel_plugin));
+      /* deactivate arrow button */
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->arrow_button), FALSE);
+    }
+
+  /* set the visibility of the arrow button */
+  if (plugin->arrow_position == LAUNCHER_ARROW_INSIDE_BUTTON
+      || LIST_HAS_ONE_ENTRY (plugin->entries))
+    gtk_widget_hide (plugin->arrow_button);
+  else
+    gtk_widget_show (plugin->arrow_button);
 }
 
 
 
-static gboolean
-launcher_plugin_set_size (LauncherPlugin  *launcher,
-                          guint            size)
+static void
+xfce_test_plugin_menu_build (XfceTestPlugin *plugin)
 {
-    gint            width = size, height = size;
-    GtkOrientation  orientation;
-
-    if (g_list_length (launcher->entries) > 1)
+  GList               *li;
+  guint                n;
+  XfceTestPluginEntry *entry;
+  GtkWidget           *mi, *image;
+  GdkScreen           *screen;
+  GdkPixbuf           *pixbuf;
+
+  panel_return_if_fail (XFCE_IS_TEST_PLUGIN (plugin));
+  panel_return_if_fail (plugin->menu == NULL);
+
+  /* create a new menu */
+  plugin->menu = gtk_menu_new ();
+  screen = gtk_widget_get_screen (GTK_WIDGET (plugin));
+  gtk_menu_set_screen (GTK_MENU (launcher->menu), screen);
+  g_signal_connect (G_OBJECT (plugin->menu), "deactivate", G_CALLBACK (xfce_test_plugin_menu_deactivate), plugin);
+
+  /* walk through the entries */
+  for (li = plugin->entries, n = 0; li != NULL; li = li->next, n++)
     {
-        /* get the orientation of the panel */
-        orientation = xfce_panel_plugin_get_orientation (launcher->panel_plugin);
+      /* skip the first entry when the arrow is visible */
+      if (n == 0 && launcher->arrow_position != LAUNCHER_ARROW_INSIDE_BUTTON)
+        continue;
 
-        switch (launcher->arrow_position)
-        {
-            case LAUNCHER_ARROW_DEFAULT:
-                if (orientation == GTK_ORIENTATION_HORIZONTAL)
-                    width += LAUNCHER_ARROW_SIZE;
-                else
-                    height += LAUNCHER_ARROW_SIZE;
+      entry = li->data;
 
-                break;
+      /* create menu item */
+      mi = gtk_image_menu_item_new_with_label (entry->name ? entry->name : _("New Item"));
+      g_object_set_qdata (G_OBJECT (mi), xfce_test_plugin_quark, plugin);
+      g_object_set (G_OBJECT (mi), "has-tooltip", TRUE, NULL);
+      gtk_widget_show (mi);
 
-            case LAUNCHER_ARROW_LEFT:
-            case LAUNCHER_ARROW_RIGHT:
-                if (orientation == GTK_ORIENTATION_HORIZONTAL)
-                    width += LAUNCHER_ARROW_SIZE;
-                else
-                    height -= LAUNCHER_ARROW_SIZE;
+      /* depending on the menu position we append or prepend */
+      if (plugin->menu_reversed_order)
+        gtk_menu_shell_append (GTK_MENU_SHELL (plugin->menu), mi);
+      else
+        gtk_menu_shell_prepend (GTK_MENU_SHELL (plugin->menu), mi);
 
-                break;
+      /* connect signals */
+      g_signal_connect (G_OBJECT (mi), "button-release-event", G_CALLBACK (xfce_test_plugin_menu_item_released), entry);
 
-            case LAUNCHER_ARROW_TOP:
-            case LAUNCHER_ARROW_BOTTOM:
-                if (orientation == GTK_ORIENTATION_HORIZONTAL)
-                    width -= LAUNCHER_ARROW_SIZE;
-                else
-                    height += LAUNCHER_ARROW_SIZE;
+      if (plugin->disable_tooltips == FALSE)
+        g_signal_connect (G_OBJECT (mi), "query-tooltip", G_CALLBACK (xfce_test_plugin_query_tooltip), entry);
 
-                break;
+      /* try to set an image */
+      if (G_LIKELY (entry->icon))
+        {
+          /* load pixbuf */
+          pixbuf = xfce_test_plugin_load_pixbuf (entry->icon, MENU_ICON_SIZE, plugin->icon_theme);
+          if (G_LIKELY (pixbuf))
+            {
+              /* set image */
+              image = gtk_image_new_from_pixbuf (pixbuf);
+              gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
+              gtk_widget_show (image);
 
-            default:
-                /* nothing to do for a hidden arrow button */
-                break;
+              /* release reference */
+              g_object_unref (G_OBJECT (pixbuf));
+            }
         }
     }
-
-    /* set the plugin size */
-    gtk_widget_set_size_request (GTK_WIDGET (launcher->panel_plugin), width, height);
-
-    /* we handled the size */
-    return TRUE;
 }
 
 
 
-static void
-launcher_plugin_free (LauncherPlugin  *launcher)
+static gboolean
+xfce_test_plugin_menu_item_released (GtkMenuItem         *menu_item,
+                                     GdkEventButton      *event,
+                                     XfceTestPluginEntry *entry)
 {
-    GtkWidget *dialog;
+  XfceTestPlugin *plugin;
+  GdkScreen      *screen;
 
-    /* check if we still need to destroy the properties dialog */
-    dialog = g_object_get_data (G_OBJECT (launcher->panel_plugin), I_("launcher-dialog"));
-    if (G_UNLIKELY (dialog != NULL))
-        gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+  /* get the plugin */
+  plugin = g_object_get_qdata (G_OBJECT (menu_item), xfce_test_plugin_quark);
+  panel_return_val_if_fail (XFCE_IS_TEST_PLUGIN (plugin), FALSE);
 
-    /* stop timeout */
-    if (G_UNLIKELY (launcher->popup_timeout_id))
-        g_source_remove (launcher->popup_timeout_id);
+  /* get the current screen */
+  screen = gtk_widget_get_screen (GTK_WIDGET (plugin));
 
-    /* remove icon theme change */
-    g_signal_remove_emission_hook (g_signal_lookup ("changed", GTK_TYPE_ICON_THEME),
-                                   launcher->theme_timeout_id);
+  if (event->button != 2)
+    launcher_execute (screen, entry, NULL);
+  else
+    launcher_execute_from_clipboard (screen, entry);
 
-    /* destroy the popup menu */
-    if (launcher->menu)
-        gtk_widget_destroy (launcher->menu);
+  /* move the item to the first position if enabled */
+  if (G_UNLIKELY (plugin->move_clicked_to_button))
+    {
+      /* remove the item to the first place */
+      plugin->entries = g_list_remove (plugin->entries, entry);
+      plugin->entries = g_list_prepend (plugin->entries, entry);
 
-    /* remove the entries */
-    g_list_foreach (launcher->entries, (GFunc) launcher_entry_free, launcher);
-    g_list_free (launcher->entries);
+      /* destroy the menu and update the icon */
+      xfce_test_plugin_menu_destroy (plugin);
+      xfce_test_plugin_icon_button_set_icon (plugin);
+    }
+}
 
-#if !LAUNCHER_NEW_TOOLTIP_API
-    /* release the tooltips */
-    g_object_unref (G_OBJECT (launcher->tips));
-#endif
 
-    /* free launcher structure */
-    g_slice_free (LauncherPlugin, launcher);
+
+static XfceTestPluginEntry *
+xfce_test_plugin_entry_new_default (void)
+{
+  XfceTestPluginEntry *entry;
+  
+  /* allocate */
+  entry = g_slice_new0 (XfceTestPluginEntry);
+  entry->name = g_strdup (_("New Item"));
+  entry->icon = g_strdup ("applications-other");
+  
+  /* TODO remove after test */
+  if (entry->comment)
+    g_critical ("while crearing the default entry, vars were not null");
+  
+  return entry;
 }
 
 
 
 static void
-launcher_plugin_construct (XfcePanelPlugin *plugin)
+xfce_test_plugin_entry_free (XfceTestPluginEntry *entry)
 {
-    LauncherPlugin *launcher;
-
-    /* create the plugin */
-    launcher = launcher_plugin_new (plugin);
-
-    /* set the action widgets and show configure */
-    xfce_panel_plugin_add_action_widget (plugin, launcher->icon_button);
-    xfce_panel_plugin_add_action_widget (plugin, launcher->arrow_button);
-    xfce_panel_plugin_menu_show_configure (plugin);
-
-    /* connect signals */
-    g_signal_connect_swapped (G_OBJECT (plugin), "screen-position-changed",
-                              G_CALLBACK (launcher_plugin_screen_position_changed), launcher);
-    g_signal_connect_swapped (G_OBJECT (plugin), "orientation-changed",
-                              G_CALLBACK (launcher_plugin_orientation_changed), launcher);
-    g_signal_connect_swapped (G_OBJECT (plugin), "size-changed",
-                              G_CALLBACK (launcher_plugin_set_size), launcher);
-    g_signal_connect_swapped (G_OBJECT (plugin), "save",
-                              G_CALLBACK (launcher_plugin_save), launcher);
-    g_signal_connect_swapped (G_OBJECT (plugin), "free-data",
-                              G_CALLBACK (launcher_plugin_free), launcher);
-    g_signal_connect_swapped (G_OBJECT (plugin), "configure-plugin",
-                              G_CALLBACK (launcher_dialog_show), launcher);
-                              
-    /* init the icon */
-    launcher_icon_button_set_icon (launcher);
+  /* free data */
+  g_free (entry->name);
+  g_free (entry->comment);
+  g_free (entry->path);
+  g_free (entry->icon);
+  g_free (entry->exec);
+  
+  /* free structure */
+  g_slice_free (XfceTestPluginEntry, entry);
 }
diff --git a/plugins/launcher/launcher.h b/plugins/launcher/launcher.h
index ce70d6c..d1656e6 100644
--- a/plugins/launcher/launcher.h
+++ b/plugins/launcher/launcher.h
@@ -1,122 +1,108 @@
-/*  $Id: launcher.h 26065 2007-09-10 12:04:49Z nick $
+/* $Id$ */
+/*
+ * 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)
+ * any later version.
  *
- *  Copyright (c) 2005-2007 Jasper Huijsmans <jasper at xfce.org>
- *  Copyright (c) 2006-2007 Nick Schermer <nick at xfce.org>
+ * This program 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 General Public License for
+ * more details.
  *
- *  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) any later version.
- *
- *  This program 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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef __XFCE_PANEL_LAUNCHER_H__
-#define __XFCE_PANEL_LAUNCHER_H__
+#ifndef __XFCE_TEST_PLUGIN_H__
+#define __XFCE_TEST_PLUGIN_H__
 
 #include <gtk/gtk.h>
-#include <exo/exo.h>
 #include <libxfce4panel/libxfce4panel.h>
 
-#define BORDER                     (8)
-#define LAUNCHER_NEW_TOOLTIP_API   (GTK_CHECK_VERSION (2,11,6))
-#define LAUNCHER_ARROW_SIZE        (16)
-#define LAUNCHER_POPUP_DELAY       (225)
-#define LAUNCHER_TOOLTIP_SIZE      (32)
-#define LAUNCHER_MENU_SIZE	       (24)
-#define LAUNCHER_STARTUP_TIMEOUT   (30 * 1000)
-#define LAUNCHER_TREE_ICON_SIZE    (24)
-#define LAUNCHER_CHOOSER_ICON_SIZE (48)
+G_BEGIN_DECLS
 
-/* frequently used code */
-#define launcher_free_filenames(list) G_STMT_START{ \
-    g_slist_foreach (list, (GFunc) g_free, NULL); \
-    g_slist_free (list); \
-    }G_STMT_END
+typedef struct _XfceTestPluginClass    XfceTestPluginClass;
+typedef struct _XfceTestPlugin         XfceTestPlugin;
+typedef struct _XfceTestPluginEntry    XfceTestPluginEntry;
+typedef enum   _XfceTestPluginArrowPos XfceTestPluginArrowPos;
 
+#define XFCE_TYPE_TEST_PLUGIN            (xfce_test_plugin_get_type ())
+#define XFCE_TEST_PLUGIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_TEST_PLUGIN, XfceTestPlugin))
+#define XFCE_TEST_PLUGIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_TEST_PLUGIN, XfceTestPluginClass))
+#define XFCE_IS_TEST_PLUGIN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_TEST_PLUGIN))
+#define XFCE_IS_TEST_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_TEST_PLUGIN))
+#define XFCE_TEST_PLUGIN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_TEST_PLUGIN, XfceTestPluginClass))
 
-typedef struct _LauncherEntry  LauncherEntry;
-typedef struct _LauncherPlugin LauncherPlugin;
+#define LIST_HAS_ONE_ENTRY(list)         ((list) != NULL && (list)->next == NULL)
+#define LIST_HAS_TWO_OR_MORE_ENTRIES     ((list) != NULL && (list)->next != NULL)
 
-struct _LauncherEntry
+struct _XfceTestPluginClass
 {
-    gchar    *name;
-    gchar    *comment;
-    gchar    *exec;
-    gchar    *path;
-    gchar    *icon;
-
-    guint     terminal : 1;
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
-    guint     startup : 1;
-#endif
+  XfcePanelPluginClass __parent__;
 };
 
-struct _LauncherPlugin
+struct _XfceTestPlugin
 {
-    /* panel plugin */
-    XfcePanelPlugin *panel_plugin;
-
-    /* whether saving is allowed */
-    guint            plugin_can_save : 1;
-
-    /* list of launcher entries */
-    GList           *entries;
-
-    /* panel widgets */
-    GtkWidget       *box;
-    GtkWidget       *icon_button;
-    GtkWidget       *arrow_button;
-    GtkWidget       *image;
-    GtkWidget       *menu;
-#if !LAUNCHER_NEW_TOOLTIP_API
-    GtkTooltips     *tips;
-#endif
-
-    /* event source ids */
-    guint            popup_timeout_id;
-    guint            theme_timeout_id;
-
-    /* settings */
-    guint            move_first : 1;
-    guint            arrow_position;
+  XfcePanelPlugin __parent__;
+
+  /* settings */
+  guint                   move_clicked_to_button : 1;
+  guint                   disable_tooltips : 1;
+  guint                   show_labels : 1;
+  XfceTestPluginArrowPos  arrow_position;
+
+  /* list of entries in the launcher */
+  GList                  *entries;
+  
+  /* store the icon theme */
+  GtkIconTheme           *icon_theme;
+
+  /* plugin widgets */
+  GtkWidget              *box;
+  GtkWidget              *icon_button;
+  GtkWidget              *arrow_button;
+  GtkWidget              *image;
+  GtkWidget              *menu;
+
+  /* delayout menu popup */
+  guint                   popup_timeout_id;
+
+  /* whether the menu appends in revered order */
+  guint                   menu_reversed_order : 1;
 };
 
-enum
+struct _XfceTestPluginEntry
 {
-    LAUNCHER_ARROW_DEFAULT = 0,
-    LAUNCHER_ARROW_LEFT,
-    LAUNCHER_ARROW_RIGHT,
-    LAUNCHER_ARROW_TOP,
-    LAUNCHER_ARROW_BOTTOM,
-    LAUNCHER_ARROW_INSIDE_BUTTON
+  gchar *name;
+  gchar *comment;
+  gchar *exec;
+  gchar *icon;
+  gchar *path;
+
+  guint  terminal : 1;
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+  guint  startup_notify : 1;
+#endif
 };
 
-/* target types for dropping in the launcher plugin */
-static const GtkTargetEntry drop_targets[] =
+enum _XfceTestPluginArrowPos
 {
-    { "text/uri-list", 0, 0, },
+  ARROW_POS_DEFAULT,
+  ARROW_POS_LEFT,
+  ARROW_POS_RIGHT,
+  ARROW_POS_TOP,
+  ARROW_POS_BOTTOM,
+  ARROW_POS_INSIDE_BUTTON  
 };
 
+GType      xfce_test_plugin_get_type (void) G_GNUC_CONST;
+
+void       xfce_test_plugin_rebuild  (XfceTestPlugin *plugin, gboolean update_icon);
 
+GdkPixbuf *xfce_test_plugin_load_pixbuf (const gchar *name, gint size, GtkIconTheme *icon_theme);
 
-GSList        *launcher_utility_filenames_from_selection_data (GtkSelectionData *selection_data) G_GNUC_MALLOC;
-GdkPixbuf     *launcher_utility_load_pixbuf                   (GdkScreen        *screen,
-                                                               const gchar      *name,
-                                                               guint             size) G_GNUC_MALLOC;
-LauncherEntry *launcher_entry_new                             (void) G_GNUC_MALLOC;
-void           launcher_entry_free                            (LauncherEntry    *entry,
-                                                               LauncherPlugin   *launcher);
-void           launcher_plugin_rebuild                        (LauncherPlugin   *launcher,
-                                                               gboolean          update_icon);
-void           launcher_plugin_read                           (LauncherPlugin   *launcher);
-void           launcher_plugin_save                           (LauncherPlugin   *launcher);
+G_END_DECLS
 
-#endif /* !__XFCE_PANEL_LAUNCHER_H__ */
+#endif /* !__XFCE_TEST_PLUGIN_H__ */



More information about the Xfce4-commits mailing list