[PATCH Weston 1/1] desktop-shell: implement autolaunch

Karsten Otto karsten.otto at posteo.de
Wed Oct 22 23:04:57 PDT 2014


The %m from glibc would indeed be a portability problem. However, it is already lightly used within wayland (11 occurrences) and heavily in weston (125 occurrences). I suggest you keep them for now, then clean them all up in one patch later - assuming the wayland community and prospective users consider portability a worthwhile effort.

Cheers, Karsten

Am 22.10.2014 um 17:57 schrieb Derek Foreman <derekf at osg.samsung.com>:

> 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
>> 
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel



More information about the wayland-devel mailing list