desktop-shell: Break command lines into env vars, executable and arguments
We now support specifying environment variables and arguments in launchers by saying path=GDK_BACKEND=wayland gnome-terminal --full-screen for example. https://bugs.freedesktop.org/show_bug.cgi?id=47920
This commit is contained in:
+54
-3
@@ -34,6 +34,7 @@
|
|||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
@@ -90,8 +91,10 @@ struct panel_launcher {
|
|||||||
struct panel *panel;
|
struct panel *panel;
|
||||||
cairo_surface_t *icon;
|
cairo_surface_t *icon;
|
||||||
int focused, pressed;
|
int focused, pressed;
|
||||||
const char *path;
|
char *path;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
struct wl_array envp;
|
||||||
|
struct wl_array argv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct panel_clock {
|
struct panel_clock {
|
||||||
@@ -173,6 +176,7 @@ show_menu(struct panel *panel, struct input *input, uint32_t time)
|
|||||||
static void
|
static void
|
||||||
panel_launcher_activate(struct panel_launcher *widget)
|
panel_launcher_activate(struct panel_launcher *widget)
|
||||||
{
|
{
|
||||||
|
char **argv;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
@@ -184,8 +188,9 @@ panel_launcher_activate(struct panel_launcher *widget)
|
|||||||
if (pid)
|
if (pid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (execl(widget->path, widget->path, NULL) < 0) {
|
argv = widget->argv.data;
|
||||||
fprintf(stderr, "execl '%s' failed: %m\n", widget->path);
|
if (execve(argv[0], argv, widget->envp.data) < 0) {
|
||||||
|
fprintf(stderr, "execl '%s' failed: %m\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -469,11 +474,57 @@ static void
|
|||||||
panel_add_launcher(struct panel *panel, const char *icon, const char *path)
|
panel_add_launcher(struct panel *panel, const char *icon, const char *path)
|
||||||
{
|
{
|
||||||
struct panel_launcher *launcher;
|
struct panel_launcher *launcher;
|
||||||
|
char *start, *p, *eq, **ps;
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
launcher = malloc(sizeof *launcher);
|
launcher = malloc(sizeof *launcher);
|
||||||
memset(launcher, 0, sizeof *launcher);
|
memset(launcher, 0, sizeof *launcher);
|
||||||
launcher->icon = cairo_image_surface_create_from_png(icon);
|
launcher->icon = cairo_image_surface_create_from_png(icon);
|
||||||
launcher->path = strdup(path);
|
launcher->path = strdup(path);
|
||||||
|
|
||||||
|
wl_array_init(&launcher->envp);
|
||||||
|
wl_array_init(&launcher->argv);
|
||||||
|
for (i = 0; __environ[i]; i++) {
|
||||||
|
ps = wl_array_add(&launcher->envp, sizeof *ps);
|
||||||
|
*ps = __environ[i];
|
||||||
|
}
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
start = launcher->path;
|
||||||
|
while (*start) {
|
||||||
|
for (p = start, eq = NULL; *p && !isspace(*p); p++)
|
||||||
|
if (*p == '=')
|
||||||
|
eq = p;
|
||||||
|
|
||||||
|
if (eq && j == 0) {
|
||||||
|
ps = launcher->envp.data;
|
||||||
|
for (k = 0; k < i; k++)
|
||||||
|
if (strncmp(ps[k], start, eq - start) == 0) {
|
||||||
|
ps[k] = start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (k == i) {
|
||||||
|
ps = wl_array_add(&launcher->envp, sizeof *ps);
|
||||||
|
*ps = start;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ps = wl_array_add(&launcher->argv, sizeof *ps);
|
||||||
|
*ps = start;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*p && isspace(*p))
|
||||||
|
*p++ = '\0';
|
||||||
|
|
||||||
|
start = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
ps = wl_array_add(&launcher->envp, sizeof *ps);
|
||||||
|
*ps = NULL;
|
||||||
|
ps = wl_array_add(&launcher->argv, sizeof *ps);
|
||||||
|
*ps = NULL;
|
||||||
|
|
||||||
launcher->panel = panel;
|
launcher->panel = panel;
|
||||||
wl_list_insert(panel->launcher_list.prev, &launcher->link);
|
wl_list_insert(panel->launcher_list.prev, &launcher->link);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user