Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
xdg-autostart-service: handle gnome autostart phase better on other d…
…esktops

Autostart files which contain the line gnome-autostart-phase are currently
completely skipped by systemd. This is because these are handled internally by
gnome startup through other means.

The problem is a number of desktop files that need to run on KDE too have this
flag set. Ideally they should just create systemd user units, but we're not at
this point universally yet.

This patch changes the logic so if the flag is set, we set NotShowIn-gnome,
which in turn would just not load decided at runtime.

As an optimisation if we would get conflicting OnlyShowIn lines we still
skip the file completely.

Example:
  $ rg 'Exec|Autostart-Phase' /etc/xdg/autostart/gnome-keyring-pkcs11.desktop
  Exec=/usr/bin/gnome-keyring-daemon --start --components=pkcs11
  X-GNOME-Autostart-Phase=PreDisplayServer

  $ cat '/tmp/xxx/app-gnome\x2dkeyring\x2dpkcs11@autostart.service'
  # Automatically generated by systemd-xdg-autostart-generator
  [Unit]
  SourcePath=/etc/xdg/autostart/gnome-keyring-pkcs11.desktop
  ...
  [Service]
  ...
  ExecCondition=/usr/lib/systemd/systemd-xdg-autostart-condition "Unity:MATE" "GNOME"

Co-authored-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
  • Loading branch information
2 people authored and YHNdnzj committed Apr 28, 2023
1 parent b640e27 commit c63dde8
Showing 1 changed file with 41 additions and 10 deletions.
51 changes: 41 additions & 10 deletions src/xdg-autostart-generator/xdg-autostart-service.c
Expand Up @@ -518,6 +518,7 @@ int xdg_autostart_service_generate_unit(

_cleanup_free_ char *path_escaped = NULL, *exec_start = NULL, *unit = NULL;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_strv_free_ char **only_show_in = NULL, **not_show_in = NULL;
int r;

assert(service);
Expand All @@ -544,6 +545,18 @@ int xdg_autostart_service_generate_unit(
return 0;
}

if (service->only_show_in) {
only_show_in = strv_copy(service->only_show_in);
if (!only_show_in)
return log_oom();
}

if (service->not_show_in) {
not_show_in = strv_copy(service->not_show_in);
if (!not_show_in)
return log_oom();
}

/* The TryExec key cannot be checked properly from the systemd unit, it is trivial to check using
* find_executable though. */
if (service->try_exec) {
Expand All @@ -563,9 +576,27 @@ int xdg_autostart_service_generate_unit(
}

if (service->gnome_autostart_phase) {
/* There is no explicit value for the "Application" phase. */
log_debug("%s: not generating unit, startup phases are not supported.", service->path);
return 0;
/* There is no explicit value for the "Application" phase.
*
* On GNOME secondary startup mechanism handles desktop files with startup phases set.
* We want to mark these as "NotShowIn=GNOME"
*
* If that means no-one will load them, we can get skip it entirely.
*/
if (strv_contains(only_show_in, "GNOME")) {
strv_remove(only_show_in, "GNOME");

if (strv_isempty(only_show_in)) {
log_debug("%s: GNOME startup phases are handled separately. Skipping.",
service->path);
return 0;
}
}
log_debug("%s: GNOME startup phases are handled seprately, marking as NotShowIn=GNOME.",
service->path);

if (strv_extend(&not_show_in, "GNOME") < 0)
return log_oom();
}

path_escaped = specifier_escape(service->path);
Expand Down Expand Up @@ -623,16 +654,16 @@ int xdg_autostart_service_generate_unit(
}

/* Generate an ExecCondition to check $XDG_CURRENT_DESKTOP */
if (!strv_isempty(service->only_show_in) || !strv_isempty(service->not_show_in)) {
_cleanup_free_ char *only_show_in = NULL, *not_show_in = NULL, *e_only_show_in = NULL, *e_not_show_in = NULL;
if (!strv_isempty(only_show_in) || !strv_isempty(not_show_in)) {
_cleanup_free_ char *only_show_in_string = NULL, *not_show_in_string = NULL, *e_only_show_in = NULL, *e_not_show_in = NULL;

only_show_in = strv_join(service->only_show_in, ":");
not_show_in = strv_join(service->not_show_in, ":");
if (!only_show_in || !not_show_in)
only_show_in_string = strv_join(only_show_in, ":");
not_show_in_string = strv_join(not_show_in, ":");
if (!only_show_in_string || !not_show_in_string)
return log_oom();

e_only_show_in = cescape(only_show_in);
e_not_show_in = cescape(not_show_in);
e_only_show_in = cescape(only_show_in_string);
e_not_show_in = cescape(not_show_in_string);
if (!e_only_show_in || !e_not_show_in)
return log_oom();

Expand Down

0 comments on commit c63dde8

Please sign in to comment.