mirror of
https://github.com/labwc/labwc.git
synced 2026-02-23 01:40:18 -05:00
session: run shutdown script, clean up activation env before exit
This commit is contained in:
parent
4ddeb3cd42
commit
f90b7dca2a
6 changed files with 157 additions and 16 deletions
|
|
@ -8,7 +8,7 @@ labwc - configuration files
|
||||||
|
|
||||||
Labwc uses openbox-3.6 specification for configuration and theming, but does not
|
Labwc uses openbox-3.6 specification for configuration and theming, but does not
|
||||||
support all options. The following files form the basis of the labwc
|
support all options. The following files form the basis of the labwc
|
||||||
configuration: rc.xml, menu.xml, autostart and environment.
|
configuration: rc.xml, menu.xml, autostart, shutdown and environment.
|
||||||
|
|
||||||
No configuration files are needed to start and run labwc.
|
No configuration files are needed to start and run labwc.
|
||||||
|
|
||||||
|
|
@ -34,11 +34,8 @@ alternative.
|
||||||
The configuration directory location can be override with the -C command line
|
The configuration directory location can be override with the -C command line
|
||||||
option.
|
option.
|
||||||
|
|
||||||
All configuration and theme files except autostart are re-loaded on receiving
|
All configuration and theme files except autostart and shutdown are re-loaded on
|
||||||
signal SIGHUP.
|
receiving signal SIGHUP.
|
||||||
|
|
||||||
The *autostart* file is executed as a shell script. This is the place for
|
|
||||||
executing clients for handling background images, panels and similar.
|
|
||||||
|
|
||||||
The *environment* file is parsed as *variable=value* and sets environment
|
The *environment* file is parsed as *variable=value* and sets environment
|
||||||
variables accordingly. It is recommended to specify keyboard layout settings and
|
variables accordingly. It is recommended to specify keyboard layout settings and
|
||||||
|
|
@ -48,6 +45,20 @@ sourced prior to running openbox.
|
||||||
Note: Tilde (~) and environment variables in the value are expanded, but
|
Note: Tilde (~) and environment variables in the value are expanded, but
|
||||||
subshell syntax and apostrophes are ignored.
|
subshell syntax and apostrophes are ignored.
|
||||||
|
|
||||||
|
The *autostart* file is executed as a shell script after labwc has read its
|
||||||
|
configuration and set variables defined in the environment file. Additionally,
|
||||||
|
the environment variables WAYLAND_DISPLAY and (when labwc is built with Xwayland
|
||||||
|
support) DISPLAY will be defined. This is the place for executing clients for
|
||||||
|
handling background images, panels and other tasks that should run automatically
|
||||||
|
when labwc launches.
|
||||||
|
|
||||||
|
The *shutdown* file is executed as a shell script when labwc is preparing to
|
||||||
|
terminate itself. All environment variables, including WAYLAND_DISPLAY and
|
||||||
|
DISPLAY, will be available to the script. However, because the script runs
|
||||||
|
asynchronously with other termination tasks, the shutdown file should not assume
|
||||||
|
that the display will be usable. This file is useful to perform any custom
|
||||||
|
operations necessary to finalize a labwc session.
|
||||||
|
|
||||||
The *menu.xml* file defines the context/root-menus and is described in
|
The *menu.xml* file defines the context/root-menus and is described in
|
||||||
labwc-menu(5).
|
labwc-menu(5).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,4 +43,23 @@ void string_truncate_at_pattern(char *buf, const char *pattern);
|
||||||
*/
|
*/
|
||||||
char *strdup_printf(const char *fmt, ...);
|
char *strdup_printf(const char *fmt, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* str_join - format and join an array of strings with a separator
|
||||||
|
* @parts: NULL-terminated array of string parts to be joined
|
||||||
|
* @fmt: printf-style format string applied to each part
|
||||||
|
* @sep: separator inserted between parts when joining
|
||||||
|
*
|
||||||
|
* A new string is allocated to hold the joined result. The user must free the
|
||||||
|
* returned string. Returns NULL on error.
|
||||||
|
*
|
||||||
|
* Each part of the array is converted via the equivalent of sprintf(output,
|
||||||
|
* fmt, part), so fmt should include a single "%s" format specification. If fmt
|
||||||
|
* is NULL, a default "%s" will be used to copy each part verbatim.
|
||||||
|
*
|
||||||
|
* The separator is arbitrary. When the separator is NULL, a single space will
|
||||||
|
* be used.
|
||||||
|
*/
|
||||||
|
char *str_join(const char * const parts[],
|
||||||
|
const char *restrict fmt, const char *restrict sep);
|
||||||
|
|
||||||
#endif /* LABWC_STRING_HELPERS_H */
|
#endif /* LABWC_STRING_HELPERS_H */
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,10 @@ void session_environment_init(void);
|
||||||
*/
|
*/
|
||||||
void session_autostart_init(void);
|
void session_autostart_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* session_shutdown - run session shutdown file as shell script
|
||||||
|
* Note: Same as `sh ~/.config/labwc/shutdown` (or equivalent XDG config dir)
|
||||||
|
*/
|
||||||
|
void session_shutdown(void);
|
||||||
|
|
||||||
#endif /* LABWC_SESSION_H */
|
#endif /* LABWC_SESSION_H */
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -83,3 +84,73 @@ strdup_printf(const char *fmt, ...)
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
str_join(const char * const parts[],
|
||||||
|
const char *restrict fmt, const char *restrict sep)
|
||||||
|
{
|
||||||
|
assert(parts);
|
||||||
|
|
||||||
|
if (!fmt) {
|
||||||
|
fmt = "%s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sep) {
|
||||||
|
sep = " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = 0;
|
||||||
|
size_t n_parts = 0;
|
||||||
|
|
||||||
|
size_t sep_len = strlen(sep);
|
||||||
|
|
||||||
|
/* Count the length of each formatted string */
|
||||||
|
for (const char *const *s = parts; *s; ++s) {
|
||||||
|
int n = snprintf(NULL, 0, fmt, *s);
|
||||||
|
if (n < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size += (size_t)n;
|
||||||
|
++n_parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_parts < 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need (n_parts - 1) separators, plus one NULL terminator */
|
||||||
|
size += (n_parts - 1) * sep_len + 1;
|
||||||
|
|
||||||
|
/* Concatenate the strings and separators */
|
||||||
|
char *buf = xzalloc(size);
|
||||||
|
char *p = buf;
|
||||||
|
for (const char *const *s = parts; *s; ++s) {
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (p != buf) {
|
||||||
|
n = snprintf(p, size, "%s", sep);
|
||||||
|
if (n < 0 || (size_t)n >= size) {
|
||||||
|
p = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size -= (size_t)n;
|
||||||
|
p += (size_t)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = snprintf(p, size, fmt, *s);
|
||||||
|
if (n < 0 || (size_t)n >= size) {
|
||||||
|
p = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size -= (size_t)n;
|
||||||
|
p += (size_t)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -9,11 +10,19 @@
|
||||||
#include "common/buf.h"
|
#include "common/buf.h"
|
||||||
#include "common/dir.h"
|
#include "common/dir.h"
|
||||||
#include "common/file-helpers.h"
|
#include "common/file-helpers.h"
|
||||||
|
#include "common/mem.h"
|
||||||
#include "common/spawn.h"
|
#include "common/spawn.h"
|
||||||
#include "common/string-helpers.h"
|
#include "common/string-helpers.h"
|
||||||
#include "config/session.h"
|
#include "config/session.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
|
static const char *const env_vars[] = {
|
||||||
|
"DISPLAY",
|
||||||
|
"WAYLAND_DISPLAY",
|
||||||
|
"XDG_CURRENT_DESKTOP",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_line(char *line)
|
process_line(char *line)
|
||||||
{
|
{
|
||||||
|
|
@ -65,7 +74,7 @@ read_environment_file(const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_activation_env(const char *env_keys)
|
update_activation_env(bool initialize)
|
||||||
{
|
{
|
||||||
if (!getenv("DBUS_SESSION_BUS_ADDRESS")) {
|
if (!getenv("DBUS_SESSION_BUS_ADDRESS")) {
|
||||||
/* Prevent accidentally auto-launching a dbus session */
|
/* Prevent accidentally auto-launching a dbus session */
|
||||||
|
|
@ -75,13 +84,22 @@ update_activation_env(const char *env_keys)
|
||||||
}
|
}
|
||||||
wlr_log(WLR_INFO, "Updating dbus execution environment");
|
wlr_log(WLR_INFO, "Updating dbus execution environment");
|
||||||
|
|
||||||
char *cmd = strdup_printf("dbus-update-activation-environment %s", env_keys);
|
char *env_keys = str_join(env_vars, "%s", " ");
|
||||||
|
char *env_unset_keys = initialize ? NULL : str_join(env_vars, "%s=", " ");
|
||||||
|
|
||||||
|
char *cmd =
|
||||||
|
strdup_printf("dbus-update-activation-environment %s",
|
||||||
|
initialize ? env_keys : env_unset_keys);
|
||||||
spawn_async_no_shell(cmd);
|
spawn_async_no_shell(cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
|
||||||
cmd = strdup_printf("systemctl --user import-environment %s", env_keys);
|
cmd = strdup_printf("systemctl --user %s %s",
|
||||||
|
initialize ? "import-environment" : "unset-environment", env_keys);
|
||||||
spawn_async_no_shell(cmd);
|
spawn_async_no_shell(cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
|
||||||
|
free(env_keys);
|
||||||
|
free(env_unset_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -120,14 +138,11 @@ session_environment_init(void)
|
||||||
paths_destroy(&paths);
|
paths_destroy(&paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
session_autostart_init(void)
|
run_session_script(const char *script)
|
||||||
{
|
{
|
||||||
/* Update dbus and systemd user environment, each may fail gracefully */
|
|
||||||
update_activation_env("DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP");
|
|
||||||
|
|
||||||
struct wl_list paths;
|
struct wl_list paths;
|
||||||
paths_config_create(&paths, "autostart");
|
paths_config_create(&paths, script);
|
||||||
|
|
||||||
bool should_merge_config = rc.merge_config;
|
bool should_merge_config = rc.merge_config;
|
||||||
struct wl_list *(*iter)(struct wl_list *list);
|
struct wl_list *(*iter)(struct wl_list *list);
|
||||||
|
|
@ -138,7 +153,7 @@ session_autostart_init(void)
|
||||||
if (!file_exists(path->string)) {
|
if (!file_exists(path->string)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
wlr_log(WLR_INFO, "run autostart file %s", path->string);
|
wlr_log(WLR_INFO, "run session script %s", path->string);
|
||||||
char *cmd = strdup_printf("sh %s", path->string);
|
char *cmd = strdup_printf("sh %s", path->string);
|
||||||
spawn_async_no_shell(cmd);
|
spawn_async_no_shell(cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
|
@ -149,3 +164,20 @@ session_autostart_init(void)
|
||||||
}
|
}
|
||||||
paths_destroy(&paths);
|
paths_destroy(&paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
session_autostart_init(void)
|
||||||
|
{
|
||||||
|
/* Update dbus and systemd user environment, each may fail gracefully */
|
||||||
|
update_activation_env(/* initialize */ true);
|
||||||
|
run_session_script("autostart");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
session_shutdown(void)
|
||||||
|
{
|
||||||
|
run_session_script("shutdown");
|
||||||
|
|
||||||
|
/* Clear the dbus and systemd user environment, each may fail gracefully */
|
||||||
|
update_activation_env(/* initialize */ false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,8 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
wl_display_run(server.wl_display);
|
wl_display_run(server.wl_display);
|
||||||
|
|
||||||
|
session_shutdown();
|
||||||
|
|
||||||
server_finish(&server);
|
server_finish(&server);
|
||||||
|
|
||||||
menu_finish(&server);
|
menu_finish(&server);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue