Index: uspace/app/taskbar/tbsmenu.c
===================================================================
--- uspace/app/taskbar/tbsmenu.c	(revision ee3b28a97324351b0acfb1161a2ed94632eab95c)
+++ uspace/app/taskbar/tbsmenu.c	(revision d92b8e8f16d19c0ce7828d8dfbc2f178747ce076)
@@ -64,4 +64,5 @@
 static void tbsmenu_smenu_entry_cb(ui_menu_entry_t *, void *);
 static errno_t tbsmenu_entry_start(tbsmenu_entry_t *);
+static void tbsmenu_cmd_fini(tbsmenu_cmd_t *);
 
 /** Create taskbar start menu.
@@ -69,9 +70,10 @@
  * @param window Containing window
  * @param fixed Fixed layout to which start button will be added
+ * @param dspec Display specification (for passing to applications)
  * @param rtbsmenu Place to store pointer to new start menu
  * @return @c EOK on success or an error code
  */
 errno_t tbsmenu_create(ui_window_t *window, ui_fixed_t *fixed,
-    tbsmenu_t **rtbsmenu)
+    const char *dspec, tbsmenu_t **rtbsmenu)
 {
 	ui_resource_t *res = ui_window_get_res(window);
@@ -85,4 +87,10 @@
 	}
 
+	tbsmenu->display_spec = str_dup(dspec);
+	if (tbsmenu->display_spec == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
 	rc = ui_pbutton_create(res, "Start", &tbsmenu->sbutton);
 	if (rc != EOK)
@@ -111,4 +119,6 @@
 	return EOK;
 error:
+	if (tbsmenu != NULL && tbsmenu->display_spec != NULL)
+		free(tbsmenu->display_spec);
 	if (tbsmenu != NULL)
 		ui_pbutton_destroy(tbsmenu->sbutton);
@@ -476,15 +486,16 @@
 static errno_t tbsmenu_cmd_split(const char *str, tbsmenu_cmd_t *cmd)
 {
+	char *buf;
 	char *arg;
 	char *next;
 	size_t cnt;
 
-	cmd->buf = str_dup(str);
-	if (cmd->buf == NULL)
+	buf = str_dup(str);
+	if (buf == NULL)
 		return ENOMEM;
 
 	/* Count the entries */
 	cnt = 0;
-	arg = str_tok(cmd->buf, " ", &next);
+	arg = str_tok(buf, " ", &next);
 	while (arg != NULL) {
 		++cnt;
@@ -493,20 +504,26 @@
 
 	/* Need to copy again as buf was mangled */
-	free(cmd->buf);
-	cmd->buf = str_dup(str);
-	if (cmd->buf == NULL)
+	free(buf);
+	buf = str_dup(str);
+	if (buf == NULL)
 		return ENOMEM;
 
 	cmd->argv = calloc(cnt + 1, sizeof(char *));
 	if (cmd->argv == NULL) {
-		free(cmd->buf);
+		free(buf);
 		return ENOMEM;
 	}
 
-	/* Fill in pointers */
+	/* Copy individual arguments */
 	cnt = 0;
-	arg = str_tok(cmd->buf, " ", &next);
+	arg = str_tok(buf, " ", &next);
 	while (arg != NULL) {
-		cmd->argv[cnt++] = arg;
+		cmd->argv[cnt] = str_dup(arg);
+		if (cmd->argv[cnt] == NULL) {
+			tbsmenu_cmd_fini(cmd);
+			return ENOMEM;
+		}
+		++cnt;
+
 		arg = str_tok(next, " ", &next);
 	}
@@ -523,6 +540,45 @@
 static void tbsmenu_cmd_fini(tbsmenu_cmd_t *cmd)
 {
+	char **cp;
+
+	/* Free all pointers in NULL-terminated list */
+	cp = cmd->argv;
+	while (*cp != NULL) {
+		free(*cp);
+		++cp;
+	}
+
+	/* Free the array of pointers */
 	free(cmd->argv);
-	free(cmd->buf);
+}
+
+/** Free command structure.
+ *
+ * @param cmd Command
+ * @param entry Start menu entry
+ * @param dspec Display specification
+ * @return EOK on success or an error code
+ */
+static errno_t tbsmenu_cmd_subst(tbsmenu_cmd_t *cmd, tbsmenu_entry_t *entry,
+    const char *dspec)
+{
+	char **cp;
+
+	(void)entry;
+
+	/* Walk NULL-terminated list of arguments */
+	cp = cmd->argv;
+	while (*cp != NULL) {
+		if (str_cmp(*cp, "%d") == 0) {
+			/* Display specification */
+			free(*cp);
+			*cp = str_dup(dspec);
+			if (*cp == NULL)
+				return ENOMEM;
+		}
+		++cp;
+	}
+
+	return EOK;
 }
 
@@ -545,4 +601,7 @@
 	char **cp;
 	const char **targv = NULL;
+	char *dspec = NULL;
+	sysarg_t idev_id;
+	int rv;
 	errno_t rc;
 	ui_t *ui;
@@ -551,7 +610,22 @@
 	suspended = false;
 
+	idev_id = ui_menu_get_idev_id(entry->tbsmenu->smenu);
+
+	rv = asprintf(&dspec, "%s?idev=%zu",
+	    entry->tbsmenu->display_spec, (size_t)idev_id);
+	if (rv < 0)
+		return ENOMEM;
+
+	/* Split command string into individual arguments */
 	rc = tbsmenu_cmd_split(entry->cmd, &cmd);
-	if (rc != EOK)
+	if (rc != EOK) {
+		free(dspec);
 		return rc;
+	}
+
+	/* Substitute metacharacters in command */
+	rc = tbsmenu_cmd_subst(&cmd, entry, dspec);
+	if (rc != EOK)
+		goto error;
 
 	/* Free up and clean console for the child task. */
@@ -571,13 +645,15 @@
 		}
 
-		targv = calloc(cnt + 3, sizeof(char **));
+		targv = calloc(cnt + 5, sizeof(char **));
 		if (targv == NULL)
 			goto error;
 
 		targv[0] = "/app/terminal";
-		targv[1] = "-c";
+		targv[1] = "-d";
+		targv[2] = dspec;
+		targv[3] = "-c";
 
 		for (i = 0; i <= cnt; i++) {
-			targv[2 + i] = cmd.argv[i];
+			targv[4 + i] = cmd.argv[i];
 		}
 
@@ -607,4 +683,5 @@
 	return EOK;
 error:
+	free(dspec);
 	if (targv != NULL)
 		free(targv);
