Commit 149c06f9 authored by Simon Steinbeiß's avatar Simon Steinbeiß

tasklist: Add "Launch New Instance" item to menu (Fixes #158)

Works on at least Linux where `/proc/<pid>/exe` is a symlink to
the running executable. Could be adapted to other platforms by using
their version of that symlink.
If not supported, the "Launch New Instance" item is not added to
the menu.
parent 1bde38b4
Pipeline #1325 passed with stage
in 10 seconds
......@@ -2941,6 +2941,89 @@ xfce_tasklist_button_enter_notify_event (GtkWidget *button,
static void
xfce_tasklist_button_start_new_instance_clicked (GtkMenuItem *item,
XfceTasklistChild *child)
GError *error = NULL;
const gchar *path = g_object_get_data (G_OBJECT (item), "exe-path");
if (!g_spawn_command_line_async (path, &error))
GtkWidget *dialog =
gtk_message_dialog_new (NULL,
_("Unable to start new instance of '%s'"),
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", error->message);
gtk_window_set_title (GTK_WINDOW (dialog), _("Error"));
g_error_free (error);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
static gchar *
xfce_tasklist_button_get_child_path (XfceTasklistChild *child)
gchar *path = NULL;
WnckApplication *app = wnck_window_get_application (child->window);
int pid = wnck_application_get_pid (app);
if (pid > 0)
gchar *link = g_strdup_printf ("/proc/%d/exe", pid);
if (g_file_test (link, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_SYMLINK))
path = g_file_read_link (link, NULL);
g_free (link);
return path;
static void
xfce_tasklist_button_add_launch_new_instance_item (XfceTasklistChild *child,
GtkWidget *menu,
gboolean append)
gchar *path;
GtkWidget *sep;
GtkWidget *item;
/* add "Launch New Instance" item to menu if supported by the platform */
path = xfce_tasklist_button_get_child_path (child);
if (path == NULL)
sep = gtk_separator_menu_item_new ();
gtk_widget_show (sep);
item = gtk_menu_item_new_with_label (_("Launch New Instance..."));
g_object_set_data_full (G_OBJECT (item), "exe-path", path, g_free);
gtk_widget_show (item);
g_signal_connect (item,
G_CALLBACK (xfce_tasklist_button_start_new_instance_clicked),
if (append)
gtk_menu_shell_append (GTK_MENU_SHELL (menu), sep);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), sep);
gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
static void
xfce_tasklist_button_menu_destroy (GtkWidget *menu,
XfceTasklistChild *child)
......@@ -2983,6 +3066,7 @@ xfce_tasklist_button_button_press_event (GtkWidget *button,
if (event->button == 3 && !GTK_IS_MENU_ITEM (button))
menu = wnck_action_menu_new (child->window);
xfce_tasklist_button_add_launch_new_instance_item (child, menu, FALSE);
g_signal_connect (G_OBJECT (menu), "selection-done",
G_CALLBACK (xfce_tasklist_button_menu_destroy), child);
......@@ -3653,6 +3737,9 @@ xfce_tasklist_group_button_menu (XfceTasklistChild *group_child,
if (action_menu_entries)
gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi),
wnck_action_menu_new (child->window));
if (li->next == NULL)
xfce_tasklist_button_add_launch_new_instance_item (child, menu, TRUE);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment