## 6. Roadmap
- [x] Support xwayland
-- [x] Parse [rc.xml](docs/rc.xml)
-- [x] Parse [themerc](docs/themerc)
-- [x] Read xbm icons
+- [x] Parse ~/.config/labwc/{rc.xml,autostart,environment}
+- [x] Parse /usr/share/themes/<name>/openbox-3/themerc and associated xbm icons
- [x] Show maximize, iconify, close buttons
-- [x] Catch SIGHUP to reconfigure (re-load config and theme)
+- [x] Catch SIGHUP to re-load config file and theme
- [x] Support layer-shell protocol (partial)
- [ ] Support 'maximize'
- [ ] Show window title
-- [ ] Read ~/.config/labwc/autostart
-- [ ] Read ~/.config/labwc/environment (useful for XKB environment variables)
- [ ] Support foreign-toplevel protocol (e.g. to integrate with wlroots panels/bars)
- [ ] Support damage control to reduce CPU usage
- [ ] Implement client-menu
--- /dev/null
+#ifndef __LABWC_SESSION_H
+#define __LABWC_SESSION_H
+
+/**
+ * session_environment_init - set enrivonment variables
+ * Note: Same as `. ~/.config/labwc/environment` (or equivalent XDG config dir)
+ */
+session_environment_init(void);
+
+/**
+ * session_autostart_init - run autostart file as shell script
+ * Note: Same as `sh ~/.config/labwc/autostart` (or equivalent XDG config dir)
+ */
+session_autostart_init(void);
+
+#endif /* __LABWC_SESSION_H */
--- /dev/null
+#define _POSIX_C_SOURCE 200809L
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "common/dir.h"
+#include "common/log.h"
+#include "common/spawn.h"
+
+static bool
+isfile(const char *path)
+{
+ struct stat st;
+ return (!stat(path, &st));
+}
+
+static bool
+string_empty(const char *s)
+{
+ return !s || !*s;
+}
+
+static void
+rtrim(char **s)
+{
+ size_t len = strlen(*s);
+ if (!len) {
+ return;
+ }
+ char *end = *s + len - 1;
+ while (end >= *s && isspace(*end)) {
+ end--;
+ }
+ *(end + 1) = '\0';
+}
+
+static char *
+strstrip(char *s)
+{
+ rtrim(&s);
+ while (isspace(*s)) {
+ s++;
+ }
+ return s;
+}
+
+static void
+process_line(char *line)
+{
+ if (string_empty(line) || line[0] == '#') {
+ return;
+ }
+ char *key = NULL, *value = NULL;
+ char *p = strchr(line, '=');
+ if (!p) {
+ return;
+ }
+ *p = '\0';
+ key = strstrip(line);
+ value = strstrip(++p);
+ if (string_empty(key) || string_empty(value)) {
+ return;
+ }
+ info("setenv %s %s", key, value);
+ setenv(key, value, 1);
+}
+
+void
+read_environment_file(const char *filename)
+{
+ char *line = NULL;
+ size_t len = 0;
+ FILE *stream = fopen(filename, "r");
+ if (!stream) {
+ return;
+ }
+ while (getline(&line, &len, stream) != -1) {
+ char *p = strrchr(line, '\n');
+ if (p) {
+ *p = '\0';
+ }
+ process_line(line);
+ }
+ free(line);
+ fclose(stream);
+}
+
+static const char *
+config_dir_append(const char *append)
+{
+ const char *config = config_dir();
+ if (string_empty(config) || string_empty(append)) {
+ return NULL;
+ }
+ int len = strlen(config) + strlen(append) + 2;
+ char *buffer = calloc(len, 1);
+ strcat(buffer, config);
+ strcat(buffer, "/");
+ strcat(buffer, append);
+ return buffer;
+}
+
+void
+session_environment_init(void)
+{
+ const char *environment = config_dir_append("environment");
+ if (!environment)
+ return;
+ read_environment_file(environment);
+ free((void*)environment);
+}
+
+void
+session_autostart_init(void)
+{
+ const char *autostart = config_dir_append("autostart");
+ if (!autostart)
+ return;
+ if (!isfile(autostart)) {
+ warn("no autostart file");
+ return;
+ }
+ int len = strlen(autostart) + 4;
+ char *cmd = calloc(len, 1);
+ strcat(cmd, "sh ");
+ strcat(cmd, autostart);
+ spawn_async_no_shell(cmd);
+ free((void*)autostart);
+}
#include "common/spawn.h"
+#include "config/session.h"
#include "labwc.h"
#include "theme/theme.h"
#include "xbm/xbm.h"
}
wlr_log_init(WLR_ERROR, NULL);
+
+ session_environment_init();
rcxml_read(config_file);
if (!getenv("XDG_RUNTIME_DIR")) {
theme_read(rc.theme_name);
xbm_load(server.renderer);
+ session_autostart_init();
if (startup_cmd) {
spawn_async_no_shell(startup_cmd);
}