[PATCH Weston 1/1] desktop-shell: implement autolaunch
Pekka Paalanen
pekka.paalanen at collabora.co.uk
Wed Oct 22 06:53:55 PDT 2014
Process a new section 'autolaunch' from weston.ini, launching all
programs given there on desktop start-up.
[Frederic Plourde: cut redundancy between do_autolaunch and panel_add_launcher]
---
clients/desktop-shell.c | 97 ++++++++++++++++++++++++++++++++++++++++++-------
man/weston.ini.man | 17 +++++++++
weston.ini.in | 3 ++
3 files changed, 103 insertions(+), 14 deletions(-)
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 961a9b2..a964094 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -597,72 +597,82 @@ load_icon_or_fallback(const char *icon)
cairo_move_to(cr, 4, 16);
cairo_line_to(cr, 16, 4);
cairo_stroke(cr);
cairo_destroy(cr);
return surface;
}
static void
-panel_add_launcher(struct panel *panel, const char *icon, const char *path)
+parse_launcher_path(char *path, struct wl_array *envp_array, struct wl_array *argv_array)
{
- struct panel_launcher *launcher;
char *start, *p, *eq, **ps;
int i, j, k;
- launcher = xzalloc(sizeof *launcher);
- launcher->icon = load_icon_or_fallback(icon);
- launcher->path = xstrdup(path);
+ struct wl_array *envp = envp_array;
+ struct wl_array *argv = argv_array;
- wl_array_init(&launcher->envp);
- wl_array_init(&launcher->argv);
+ wl_array_init(envp);
+ wl_array_init(argv);
for (i = 0; environ[i]; i++) {
- ps = wl_array_add(&launcher->envp, sizeof *ps);
+ ps = wl_array_add(envp, sizeof *ps);
*ps = environ[i];
}
j = 0;
- start = launcher->path;
+ start = path;
while (*start) {
for (p = start, eq = NULL; *p && !isspace(*p); p++)
if (*p == '=')
eq = p;
if (eq && j == 0) {
- ps = launcher->envp.data;
+ ps = 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 = wl_array_add(envp, sizeof *ps);
*ps = start;
i++;
}
} else {
- ps = wl_array_add(&launcher->argv, sizeof *ps);
+ ps = wl_array_add(argv, sizeof *ps);
*ps = start;
j++;
}
while (*p && isspace(*p))
*p++ = '\0';
start = p;
}
- ps = wl_array_add(&launcher->envp, sizeof *ps);
+ ps = wl_array_add(envp, sizeof *ps);
*ps = NULL;
- ps = wl_array_add(&launcher->argv, sizeof *ps);
+ ps = wl_array_add(argv, sizeof *ps);
*ps = NULL;
+}
+
+static void
+panel_add_launcher(struct panel *panel, const char *icon, const char *path)
+{
+ struct panel_launcher *launcher;
+
+ launcher = xzalloc(sizeof *launcher);
+ launcher->icon = load_icon_or_fallback(icon);
+ launcher->path = xstrdup(path);
+
+ parse_launcher_path(launcher->path, &launcher->envp, &launcher->argv);
launcher->panel = panel;
wl_list_insert(panel->launcher_list.prev, &launcher->link);
launcher->widget = widget_add_widget(panel->widget, launcher);
widget_set_enter_handler(launcher->widget,
panel_launcher_enter_handler);
widget_set_leave_handler(launcher->widget,
panel_launcher_leave_handler);
widget_set_button_handler(launcher->widget,
@@ -1316,20 +1326,77 @@ panel_add_launchers(struct panel *panel, struct desktop *desktop)
}
if (count == 0) {
/* add default launcher */
panel_add_launcher(panel,
DATADIR "/weston/terminal.png",
BINDIR "/weston-terminal");
}
}
+static void
+do_autolaunch(const char *path_arg)
+{
+ struct wl_array envp;
+ struct wl_array argv;
+ pid_t pid;
+ char **argvpp;
+ char *path;
+
+ path = xstrdup(path_arg);
+
+ parse_launcher_path(path, &envp, &argv);
+
+ /* panel_launcher_activate */
+
+ pid = fork();
+ if (pid < 0) {
+ fprintf(stderr, "fork failed: %m\n");
+ goto out;
+ }
+
+ if (pid)
+ goto out;
+
+ argvpp = argv.data;
+ if (execve(argvpp[0], argvpp, envp.data) < 0) {
+ fprintf(stderr, "execl '%s' failed: %m\n", argvpp[0]);
+ exit(1);
+ }
+
+out:
+ wl_array_release(&argv);
+ wl_array_release(&envp);
+ free(path);
+}
+
+static void
+process_autolaunch(struct desktop *desktop)
+{
+ struct weston_config_section *s;
+ char *path;
+ const char *name;
+
+ s = NULL;
+ while (weston_config_next_section(desktop->config, &s, &name)) {
+ if (strcmp(name, "autolaunch") != 0)
+ continue;
+
+ weston_config_section_get_string(s, "path", &path, NULL);
+ if (!path)
+ continue;
+
+ do_autolaunch(path);
+ free(path);
+ }
+}
+
int main(int argc, char *argv[])
{
struct desktop desktop = { 0 };
struct output *output;
struct weston_config_section *s;
desktop.unlock_task.run = unlock_dialog_finish;
wl_list_init(&desktop.outputs);
desktop.config = weston_config_parse("weston.ini");
@@ -1349,20 +1416,22 @@ int main(int argc, char *argv[])
/* Create panel and background for outputs processed before the shell
* global interface was processed */
wl_list_for_each(output, &desktop.outputs, link)
if (!output->panel)
output_init(output, &desktop);
grab_surface_create(&desktop);
signal(SIGCHLD, sigchild_handler);
+ process_autolaunch(&desktop);
+
display_run(desktop.display);
/* Cleanup */
grab_surface_destroy(&desktop);
desktop_destroy_outputs(&desktop);
if (desktop.unlock_dialog)
unlock_dialog_destroy(desktop.unlock_dialog);
desktop_shell_destroy(desktop.shell);
display_destroy(desktop.display);
diff --git a/man/weston.ini.man b/man/weston.ini.man
index c05a221..365141c 100644
--- a/man/weston.ini.man
+++ b/man/weston.ini.man
@@ -66,20 +66,21 @@ Comment lines are ignored:
.RE
.PP
The section headers are:
.PP
.RS 4
.nf
.BR "core " "The core modules"
.BR "libinput " "Input device configuration"
.BR "shell " "Desktop customization"
.BR "launcher " "Add launcher to the panel"
+.BR "autolaunch " "Launch program automatically on startup"
.BR "screensaver " "Screensaver selection"
.BR "output " "Output configuration"
.BR "input-method " "Onscreen keyboard input"
.BR "keyboard " "Keyboard layouts"
.BR "terminal " "Terminal application options"
.BR "xwayland " "XWayland options"
.BR "screen-share " "Screen sharing options"
.fi
.RE
.PP
@@ -272,20 +273,36 @@ sets the path to the program that is run by clicking on this launcher (string).
It is possible to pass arguments and environment variables to the program. For
example:
.nf
.in +4n
path=GDK_BACKEND=wayland gnome-terminal --full-screen
.in
.fi
.PP
.RE
+.SH "AUTOLAUNCH SECTION"
+There can be multiple autolaunch sections for starting multiple programs.
+.TP 7
+.BI "path=" program
+sets the path (string) to the program that is run automatically when the
+desktop is starting.
+It is possible to pass arguments and environment variables to the program. For
+example:
+.nf
+.in +4n
+
+path=GDK_BACKEND=wayland gnome-terminal --full-screen
+.in
+.fi
+.PP
+.RE
.SH "SCREENSAVER SECTION"
The
.B screensaver
section is used to select and schedule a screensaver.
The
.B screensaver
section is optional, as are all of the entries that may be specified in
it.
.TP 7
.BI "path=" /usr/libexec/weston-screensaver
diff --git a/weston.ini.in b/weston.ini.in
index 4fca0bb..b0cb31f 100644
--- a/weston.ini.in
+++ b/weston.ini.in
@@ -30,20 +30,23 @@ icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png
path=@bindir@/weston-terminal
[launcher]
icon=/usr/share/icons/hicolor/24x24/apps/google-chrome.png
path=/usr/bin/google-chrome
[launcher]
icon=/usr/share/icons/gnome/24x24/apps/arts.png
path=@abs_top_builddir@/weston-flower
+#[autolaunch]
+#path=@bindir@/weston-terminal
+
[screensaver]
# Comment path to disable screensaver
path=@libexecdir@/weston-screensaver
duration=600
[input-method]
path=@libexecdir@/weston-keyboard
#[output]
#name=LVDS1
--
1.9.1
More information about the wayland-devel
mailing list