[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