[PATCH Weston 1/1] desktop-shell: implement autolaunch
Derek Foreman
derekf at osg.samsung.com
Wed Oct 22 08:57:16 PDT 2014
I'd prefer to see the refactor and the new feature in separate patches,
but this is pretty trivial.
I also have a slight preference for exit(EXIT_FAILURE), which is already
used somewhere else in that file - though there's also precedent for
exit(1), so you make the call. :)
I'd not seen printf's %m until today - do we want to depend on a gnuism?
I've seen at least some activity towards a freebsd port - I don't
believe %m is supported there?
That said, it runs nicely here and does what it says on the tin...
Reviewed-by: Derek Foreman <derekf at osg.samsung.com>
On 22/10/14 08:53 AM, Pekka Paalanen wrote:
> 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
>
More information about the wayland-devel
mailing list