summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--flake.lock6
-rw-r--r--flake.nix5
-rwxr-xr-xscripts/line_count.sh2
-rw-r--r--taro/attic/sway_background_covered.diff9
-rw-r--r--taro/meson.build2
-rwxr-xr-xtaro/scripts/kill_wallpaper.sh11
-rwxr-xr-xtaro/scripts/make_prefix.sh25
-rwxr-xr-xtaro/scripts/run_wallpaper.sh20
-rw-r--r--taro/src/config.h69
-rw-r--r--taro/src/daemon.c483
-rw-r--r--taro/src/dirs.h10
-rw-r--r--taro/src/ui.c42
13 files changed, 218 insertions, 470 deletions
diff --git a/.gitignore b/.gitignore
index eba891f..83a6033 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,7 +13,6 @@ subprojects/libakiyo/
subprojects/libalabaster
subprojects/libalabaster/
subprojects/libev.wrap
-subprojects/liblfds.wrap
subprojects/lz4/
subprojects/s3tc-dxt-decompression/
subprojects/stb/
@@ -25,10 +24,11 @@ taro/subprojects/jansson.wrap
taro/subprojects/jansson/
taro/subprojects/libakiyo
taro/subprojects/libakiyo/
+taro/subprojects/libalabaster
+taro/subprojects/libalabaster/
taro/subprojects/libcurl.wrap
taro/subprojects/libcurl/
taro/subprojects/libev.wrap
-taro/subprojects/liblfds.wrap
taro/subprojects/notcurses/
taro/subprojects/stela
taro/subprojects/stela/
diff --git a/flake.lock b/flake.lock
index 1b26b9a..72f8d50 100644
--- a/flake.lock
+++ b/flake.lock
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1727802920,
- "narHash": "sha256-HP89HZOT0ReIbI7IJZJQoJgxvB2Tn28V6XS3MNKnfLs=",
+ "lastModified": 1728241625,
+ "narHash": "sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "27e30d177e57d912d614c88c622dcfdb2e6e6515",
+ "rev": "c31898adf5a8ed202ce5bea9f347b1c6871f32d1",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 4c32ef8..3555310 100644
--- a/flake.nix
+++ b/flake.nix
@@ -15,9 +15,6 @@
name = "mauri";
version = "0.13";
src = self;
- mesonFlags = [
- "-Dwrap_mode=default"
- ];
nativeBuildInputs = [
git
gcc
@@ -42,9 +39,9 @@
wlr-protocols
egl-wayland
jansson
+ # notcurses build
ncurses
libunistring
- doctest
ffmpeg-headless
];
meta = with lib; {
diff --git a/scripts/line_count.sh b/scripts/line_count.sh
index 2ecb7f5..1598b1a 100755
--- a/scripts/line_count.sh
+++ b/scripts/line_count.sh
@@ -1,2 +1,2 @@
#! /usr/bin/env sh
-find ./src -type f | xargs wc -l
+find ./src ./taro/src -type f | xargs wc -l
diff --git a/taro/attic/sway_background_covered.diff b/taro/attic/sway_background_covered.diff
index fe375e2..0dc9401 100644
--- a/taro/attic/sway_background_covered.diff
+++ b/taro/attic/sway_background_covered.diff
@@ -209,7 +209,7 @@ index 44b941ca..9004c3cb 100644
return output;
}
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
-index f8709a4c..3727116d 100644
+index f8709a4c..36ea5fc0 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -88,8 +88,12 @@ struct sway_workspace *workspace_create(struct sway_output *output,
@@ -233,7 +233,7 @@ index f8709a4c..3727116d 100644
list_free(workspace->current.floating);
list_free(workspace->current.tiling);
free(workspace);
-@@ -616,6 +621,78 @@ bool workspace_is_empty(struct sway_workspace *ws) {
+@@ -616,6 +621,77 @@ bool workspace_is_empty(struct sway_workspace *ws) {
return true;
}
@@ -265,7 +265,6 @@ index f8709a4c..3727116d 100644
+static void add_con_and_or_children_to_list(list_t *result, list_t *list)
+{
+ struct sway_container *con;
-+ const char *app_id;
+ for (int i = 0; i < list->length; ++i) {
+ con = list->items[i];
+ if (con->current.children) {
@@ -273,7 +272,8 @@ index f8709a4c..3727116d 100644
+ if (con->current.layout != L_NONE) return;
+ }
+ if (!con->view || !con->view->wlr_xdg_toplevel) continue; // Hack.
-+ if ((app_id = view_get_app_id(con->view)) && strcmp(app_id, TERMINAL_APP_ID) != 0) {
++ const char *app_id = view_get_app_id(con->view);
++ if (app_id == NULL || strcmp(app_id, TERMINAL_APP_ID) != 0) {
+ list_add(result, con);
+ }
+ }
@@ -308,7 +308,6 @@ index f8709a4c..3727116d 100644
+ }
+}
+
-+
static int find_output(const void *id1, const void *id2) {
return strcmp(id1, id2);
}
diff --git a/taro/meson.build b/taro/meson.build
index 87edfe7..0291648 100644
--- a/taro/meson.build
+++ b/taro/meson.build
@@ -12,8 +12,8 @@ if not notcurses.found() or not notcurses_core.found()
notcurses_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : 'Release' })
notcurses_opts.add_cmake_defines({ 'USE_CXX': false })
notcurses_opts.add_cmake_defines({ 'USE_PANDOC': false })
- notcurses_opts.add_cmake_defines({ 'BUILD_EXECUTABLES': false })
notcurses_opts.add_cmake_defines({ 'USE_POC': false })
+ notcurses_opts.add_cmake_defines({ 'BUILD_EXECUTABLES': false })
notcurses_proj = cmake.subproject('notcurses', options: notcurses_opts)
notcurses = notcurses_proj.dependency('notcurses')
notcurses_core = notcurses_proj.dependency('notcurses-core')
diff --git a/taro/scripts/kill_wallpaper.sh b/taro/scripts/kill_wallpaper.sh
deleted file mode 100755
index 04f01f8..0000000
--- a/taro/scripts/kill_wallpaper.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /usr/bin/env sh
-
-USE_MAURI=$1
-
-if [ "$USE_MAURI" = "true" ]; then
- pkill mauri
-else
- export WINEPREFIX=$2
- wineserver -k
- wineserver -w
-fi
diff --git a/taro/scripts/make_prefix.sh b/taro/scripts/make_prefix.sh
deleted file mode 100755
index 9facae2..0000000
--- a/taro/scripts/make_prefix.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/env sh
-
-export WINEPREFIX=$1
-
-CONFIG_DIR=$2
-
-install_dxvk() {
- mkdir -p $CONFIG_DIR/tmp && cd $CONFIG_DIR/tmp
- VER=$(curl https://raw.githubusercontent.com/doitsujin/dxvk/master/RELEASE)
- curl -OL https://github.com/doitsujin/dxvk/releases/download/v$VER/dxvk-$VER.tar.gz
- tar xf dxvk-$VER.tar.gz
- cd dxvk-$VER
- curl -OL https://gist.githubusercontent.com/doitsujin/1652e0e3382f0e0ff611e70142684d01/raw/4b80903eb4a8c1033750175de4ebe64685725a3e/setup_dxvk.sh
- chmod +x ./setup_dxvk.sh
- ./setup_dxvk.sh . install
- rm -r $CONFIG_DIR/tmp
-}
-
-if [ ! -d $WINEPREFIX ]; then
- wineboot --init
- winecfg -v win10
- wineserver -w
- install_dxvk
- wineserver -w
-fi
diff --git a/taro/scripts/run_wallpaper.sh b/taro/scripts/run_wallpaper.sh
index 5ce8bc6..a274889 100755
--- a/taro/scripts/run_wallpaper.sh
+++ b/taro/scripts/run_wallpaper.sh
@@ -1,20 +1,6 @@
#! /usr/bin/env sh
-
-USE_MAURI=$1
-
-export mesa_glthread=true
-
-if [ "$USE_MAURI" = "true" ]; then
- if [ "$5" = "true" ]; then
- exec mauri -p $6/scene.pkg -w $7 -h $8 -m $3
- else
- exec mauri -d $6 -w $7 -h $8 -m $3
- fi
+if [ "$1" = "true" ]; then
+ exec mauri -p $2/scene.pkg -m $3 -w $4 -h $5
else
- export WINEPREFIX=$2
- wineserver -k
- wineserver -w
- export WINEMONITOR=$3
- exec $4 ../../wallpaper_engine/wallpaper64.exe -control openWallpaper -file $6/project.json \
- -playInWindow "wallpaper" -width $7 -height $8 > $9 2>&1
+ exec mauri -d $2 -m $3 -w $4 -h $5
fi
diff --git a/taro/src/config.h b/taro/src/config.h
new file mode 100644
index 0000000..ddf3430
--- /dev/null
+++ b/taro/src/config.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <al/str.h>
+
+#include "file_ext.h"
+
+#define CONFIG_PATH "/.config/taro"
+
+struct config {
+ str config_dir;
+ str wallpaper_dir;
+};
+
+AL_UNUSED_FUNCTION_PUSH
+
+static void close_config(struct config *conf)
+{
+ al_str_free(&conf->config_dir);
+ al_str_free(&conf->wallpaper_dir);
+}
+
+static bool open_config(struct config *conf)
+{
+ conf->config_dir = al_str_zero();
+ conf->wallpaper_dir = al_str_zero();
+
+ char *envhome = getenv("HOME");
+ if (!envhome) return false;
+ al_str_from(&conf->config_dir, envhome);
+ al_str_cat(&conf->config_dir, al_str_c(CONFIG_PATH));
+ if (!aki_dir_exists(&conf->config_dir)) {
+ if (!aki_dir_create(&conf->config_dir)) {
+ close_config(conf);
+ return false;
+ }
+ }
+
+ str config_path;
+ al_str_clone(&config_path, &conf->config_dir);
+ al_str_cat(&config_path, al_str_c("/config.json"));
+ json_t *root = aki_file_open_as_json(&config_path);
+ al_str_free(&config_path);
+ if (!root) {
+ close_config(conf);
+ return false;
+ }
+
+ json_t *wallpaper_dir = json_object_get(root, "wallpaper_directory");
+ if (!wallpaper_dir) {
+ json_decref(root);
+ close_config(conf);
+ return false;
+ }
+
+ const char *dir_str = json_string_value(wallpaper_dir);
+ if (dir_str[0] == '~') {
+ al_str_from(&conf->wallpaper_dir, envhome);
+ dir_str++;
+ al_str_cat(&conf->wallpaper_dir, al_str_cr(dir_str));
+ } else {
+ al_str_from(&conf->wallpaper_dir, dir_str);
+ }
+
+ json_decref(root);
+
+ return true;
+}
+
+AL_UNUSED_FUNCTION_POP
diff --git a/taro/src/daemon.c b/taro/src/daemon.c
index ec68df0..45eb599 100644
--- a/taro/src/daemon.c
+++ b/taro/src/daemon.c
@@ -10,23 +10,18 @@
#include <stl/window.h>
#include <jansson.h>
-#include "dirs.h"
#include "file_ext.h"
-
-#define USE_QUEUE 0
-#define USE_MAURI "true"
+#include "config.h"
struct monitor {
struct stl_monitor *os;
struct aki_fs_event fs_event;
bool self_event_skip;
str config_dir;
- str prefix_dir;
- str wine_log_path;
str selection_path;
- //str pid_path;
pid_t pid;
bool paused;
+ bool covered;
struct daemon *dmon;
};
@@ -34,13 +29,9 @@ struct monitor {
#define IPC_MESSAGE_BUF_SIZE 64
struct daemon {
- struct stl_window *context;
+ struct aki_event_loop loop;
struct aki_poll context_poll;
array(struct monitor *) monitors;
- array(struct monitor *) queued_monitors;
- bool queue_running;
- struct aki_event_loop loop;
- struct aki_fs_event fs_event;
struct aki_socket ipc_socket;
bool connected;
struct aki_poll ipc_poll;
@@ -55,114 +46,25 @@ struct daemon {
ssize_t size;
ssize_t alloc;
} ipc;
- str wp_config_dir;
+ struct config conf;
};
-// If s is malformed, this will be false.
-#define JSON_STR_TO_BOOL(s) (al_str_eq(s, al_str_c("true")) ? true : false
-
-static json_t *parse_and_set_globals(json_t *root, str *gsub)
-{
- const char *key;
- json_t *value;
- json_t *general = NULL;
- json_t *user = NULL;
-
- json_object_foreach(root, key, value) {
- general = json_object_get(value, "general");
- if (general) {
- user = value;
- break;
- }
- }
-
- if (!general) {
- json_decref(root);
- return NULL;
- }
-
- // When wallpaper engine runs, it corrects this value. We use (abuse) that to
- // run the queue and set wallpapers in order.
- json_object_set_new(user, "version", json_integer(0));
-
- json_t *gprops = json_object();
-
- s32 count = 0;
- str tok = al_str_zero();
- while (al_str_get_line(gsub, ',', &tok)) {
- switch (count++) {
- case 0:
- json_object_set_new(gprops, "cameraparallax", json_boolean(JSON_STR_TO_BOOL(&tok))));
- break;
- case 1: {
- s64 n = al_str_to_long(&tok, 10);
- if (n < 0 || n > 200) n = 100;
- json_object_set_new(gprops, "rate", json_integer(n));
- break;
- }
- default:
- al_log_warn("tarod", "excess value \"%.*s\" in selection file at index %i", AL_STR_PRINTF(&tok), count);
- break;
- }
- }
-
- json_object_set_new(general, "defaultproperties", gprops);
-
- return root;
-}
-
-static json_t *parse_and_set_locals(json_t *root, str *lsub)
-{
- json_t *general = json_object_get(root, "general");
- if (!general) {
- json_decref(root);
- return NULL;
- }
-
- json_t *properties = json_object_get(general, "properties");
- if (!properties) {
- // Probably don't want to completely fail here.
- json_decref(root);
- return NULL;
- }
-
- void *iter = json_object_iter(properties);
- json_t *iter_obj = json_object_iter_value(iter);
-
- str tok = al_str_zero();
- while (al_str_get_line(lsub, ',', &tok)) {
- json_t *value = json_object_get(iter_obj, "value");
- switch (json_typeof(value)) {
- case JSON_TRUE:
- case JSON_FALSE:
- json_object_set_new(iter_obj, "value", json_boolean(JSON_STR_TO_BOOL(&tok))));
- break;
- default:
- break;
- }
- iter = json_object_iter_next(properties, iter);
- if (!iter) {
- break;
- }
- iter_obj = json_object_iter_value(iter);
- }
-
- return root;
-}
-
-static s32 parse_and_set_props(struct monitor *monitor, str *selection_str, str *selection_id, bool *is_package)
+static s32 parse_and_set_props(str *selection, str *wallpaper_path, bool *is_package)
{
- s32 index = al_str_find(selection_str, '|');
- s32 rindex = al_str_rfind(selection_str, '|');
- if (index < 2 || rindex == -1 || index == rindex) {
+ s32 index = al_str_find(selection, '|');
+ s32 rindex = al_str_rfind(selection, '|');
+ if (index == -1 || rindex == -1 || index == rindex) {
return -1;
}
- str *id = al_str_substr(selection_str, 0, index - 2);
- str *type = al_str_substr(selection_str, index - 2, index);
+ // index < 2 or id->len == 0 is expected behavior
+ // when a monitor has no wallpaper set.
+ if (index < 2) return 1;
+ str *id = al_str_substr(selection, 0, index - 2);
+ str *type = al_str_substr(selection, index - 2, index);
if (id->len == 0) return 1;
- al_str_cat(selection_id, id);
+ al_str_cat(wallpaper_path, id);
if (al_str_eq(type, al_str_c("_p"))) {
*is_package = true;
@@ -172,272 +74,100 @@ static s32 parse_and_set_props(struct monitor *monitor, str *selection_str, str
return -1;
}
- json_t *root = aki_file_open_as_json(&monitor->dmon->wp_config_dir);
- if (!root) return -1;
-
- str *gsub = al_str_substr(selection_str, index + 1, rindex);
- if (gsub->len > 0) {
- root = parse_and_set_globals(root, gsub);
- if (!root || !aki_file_dump_and_decref_json(&monitor->dmon->wp_config_dir, root)) {
- al_log_warn("tarod", "failed to parse and/or set global properties for %s", monitor->os->name);
- }
- }
-
- str project_path;
- al_str_clone(&project_path, selection_id);
- al_str_cat(&project_path, al_str_c("/project.json"));
-
- root = aki_file_open_as_json(&project_path);
- if (!root) {
- al_str_free(&project_path);
- return -1;
- }
-
- // If local props are empty, don't try to set them.
- if ((u32)rindex < selection_str->len - 1) {
- str *lsub = al_str_substr(selection_str, rindex + 1, selection_str->len - 1);
- if (lsub->len > 0) {
- root = parse_and_set_locals(root, lsub);
- if (!root || !aki_file_dump_and_decref_json(&project_path, root)) {
- al_log_warn("tarod", "failed to parse and/or set local properties for %s", monitor->os->name);
- }
- }
- }
-
- al_str_free(&project_path);
-
return 0;
}
static bool send_signal_to_pid(pid_t pid, s32 signal)
{
if (kill(pid, signal) != 0) {
- al_log_error("tarod", "kill(%i) failed (%s)", pid, aki_strerror(errno));
+ al_log_error("tarod", "kill(%d) failed (%s)", pid, aki_strerror(errno));
return false;
}
return true;
}
-// We assume that if exec fails, the entire operation of this daemon will no longer work properly.
static pid_t exec_or_exit(char *args[])
{
pid_t pid = fork();
if (pid == -1) {
- al_log_error("tarod", "FATAL: failed to fork process, exiting...");
+ al_log_error("tarod", "fatal: failed to fork process, exiting...");
exit(EXIT_FAILURE);
} else if (pid == 0) {
if (execv(args[0], args) == -1) {
- al_log_error("tarod", "FATAL: failed to run %s, exiting...", args[0]);
- pid_t ppid = getppid();
+ al_log_error("tarod", "fatal: failed to run '%s', exiting...", args[0]);
// This should return the pid of init if the parent process has already exited.
- if (ppid != 1) {
- send_signal_to_pid(ppid, SIGINT);
- }
+ pid_t ppid = getppid();
+ if (ppid != 1) send_signal_to_pid(ppid, SIGINT);
}
}
return pid;
}
-/*
-static void wait_for_exit(pid_t pid)
+static void maybe_kill_wallpaper(struct monitor *monitor)
{
- s32 status = 0;
- do {
- waitpid(pid, &status, 0);
- } while (!WIFEXITED(status));
-}
-*/
-
-#if USE_QUEUE
-static void lock_fs_event_callback(uv_fs_event_t *handle, const char *filename, s32 events, s32 status);
-static void close_callback(uv_handle_t *handle);
+ if (monitor->pid == -1) return;
-static inline void manually_push_queue(struct daemon *dmon)
-{
- if (uv_is_active((uv_handle_t *)&dmon->queue_evnt)) {
- uv_fs_event_stop(&dmon->queue_evnt);
+ if (monitor->paused) {
+ if (!send_signal_to_pid(monitor->pid, SIGCONT)) {
+ send_signal_to_pid(monitor->pid, SIGKILL);
+ }
+ monitor->paused = false;
}
- uv_close((uv_handle_t *)&dmon->queue_evnt, close_callback);
-}
-#endif
-static void maybe_kill_wallpaper(struct monitor *monitor)
-{
- if (monitor->pid != -1) {
- send_signal_to_pid(monitor->pid, SIGTERM);
- monitor->pid = -1;
- }
- /*
- char *c_str = al_str_to_c_str(&monitor->prefix_dir);
- pid_t pid = exec_or_exit((char *[]){ "./kill_wallpaper.sh", USE_MAURI, c_str, NULL });
- al_free(c_str);
- wait_for_exit(pid);
- */
+ send_signal_to_pid(monitor->pid, SIGTERM);
+ monitor->pid = -1;
}
-static bool run_wallpaper(struct monitor *monitor)
+static bool run_wallpaper(struct daemon *dmon, struct monitor *monitor)
{
-#if USE_QUEUE
- struct daemon *dmon = monitor->dmon;
- dmon->queue_running = true;
- uv_fs_event_init(uv_default_loop(), &dmon->queue_evnt);
-#endif
-
maybe_kill_wallpaper(monitor);
- monitor->paused = false;
-
- str selection_str;
+ str selection;
monitor->self_event_skip = true;
- if (!aki_file_open_and_read_wholly(&monitor->selection_path, &selection_str, true)) {
-#if USE_QUEUE
- manually_push_queue(dmon);
-#endif
+ if (!aki_file_open_and_read_wholly(&monitor->selection_path, &selection, true)) {
monitor->self_event_skip = false;
return false;
}
- if (!selection_str.len) {
+ if (selection.len == 0) {
al_log_error("tarod", "config for %s is empty", monitor->os->name);
- al_str_free(&selection_str);
-#if USE_QUEUE
- manually_push_queue(dmon);
-#endif
+ al_str_free(&selection);
return false;
}
- str selection;
- al_str_from(&selection, WALLPAPER_DIR);
- al_str_cat(&selection, al_str_c("/"));
-
+ str wallpaper_path;
+ al_str_clone(&wallpaper_path, &dmon->conf.wallpaper_dir);
+ al_str_cat(&wallpaper_path, al_str_c("/"));
bool is_package;
- s32 ret = parse_and_set_props(monitor, &selection_str, &selection, &is_package);
- al_str_free(&selection_str);
+ s32 ret = parse_and_set_props(&selection, &wallpaper_path, &is_package);
+ al_str_free(&selection);
if (ret != 0) {
if (ret == -1) {
al_log_error("tarod", "failed to set properties for wallpaper on %s", monitor->os->name);
- al_str_free(&selection);
}
-#if USE_QUEUE
- manually_push_queue(dmon);
-#endif
+ al_str_free(&wallpaper_path);
return false;
}
-#if USE_QUEUE
- c_str = al_str_to_c_str(&dmon->wp_config_dir);
- uv_fs_event_start(&dmon->queue_evnt, lock_fs_event_callback, c_str, 0);
- al_free(c_str);
-#endif
+ al_log_info("tarod", "setting wallpaper %.*s on %s", AL_STR_PRINTF(&wallpaper_path), monitor->os->name);
- char width[16], height[16];
- al_sprintf(width, "%i", monitor->os->width / monitor->os->scale);
- al_sprintf(height, "%i", monitor->os->height / monitor->os->scale);
+ char width[8], height[8];
+ al_sprintf(width, "%d", monitor->os->width / monitor->os->scale);
+ al_sprintf(height, "%d", monitor->os->height / monitor->os->scale);
- al_log_info("tarod", "setting wallpaper %.*s on %s", AL_STR_PRINTF(&selection), monitor->os->name);
-
- char *c_str0 = al_str_to_c_str(&monitor->prefix_dir);
- char *c_str1 = al_str_to_c_str(&selection);
- char *c_str2 = al_str_to_c_str(&monitor->wine_log_path);
- char *args[] = {
- "./run_wallpaper.sh", USE_MAURI, c_str0, monitor->os->name, WINE64_PATH,
- AL_BOOLSTR(is_package), c_str1, width, height, c_str2, NULL
- };
- monitor->pid = exec_or_exit(args);
+ char *c_str0 = al_str_to_c_str(&wallpaper_path);
+ al_str_free(&wallpaper_path);
+ monitor->pid = exec_or_exit((char *[]){ "./run_wallpaper.sh",
+ AL_BOOLSTR(is_package), c_str0, monitor->os->name, width, height, NULL });
al_free(c_str0);
- al_free(c_str1);
- al_free(c_str2);
- /*
- char pid_str[16];
- al_sprintf(pid_str, "%i", monitor->pid);
- // The daemon is the only writer or reader of this file.
- if (!aki_file_open_and_replace(&monitor->pid_path, al_str_c(pid_str), false)) {
- // If we can't track the pid of the child process don't let it keep running.
- kill(monitor->pid, SIGKILL);
- monitor->pid = -1;
-#if USE_QUEUE
- manually_push_queue(dmon);
-#endif
- return false;
+ if (monitor->covered && send_signal_to_pid(monitor->pid, SIGSTOP)) {
+ monitor->paused = true;
}
- */
-
- al_str_free(&selection);
return true;
}
-#if USE_QUEUE
-void close_callback(uv_handle_t *handle)
-{
- struct daemon *dmon = (struct dmon *)handle->data;
- bool ran_wallpaper = false;
- while (dmon->queued_monitors.size > 0) {
- struct monitor *monitor;
- al_array_pop_at(dmon->queued_monitors, 0, monitor);
- if (run_wallpaper(monitor)) {
- ran_wallpaper = true;
- break;
- }
- }
- if (!ran_wallpaper) {
- dmon->queue_running = false;
- }
-}
-
-void lock_fs_event_callback(uv_fs_event_t *handle, const char *filename, s32 events, s32 status)
-{
- (void)filename;
- (void)status;
- if (events & UV_CHANGE) {
- // uv_fs_event_stop doesn't work like I would expect, not sure if it's a
- // bug or not but using uv_close to run the queue works here.
- uv_fs_event_stop(handle);
- uv_close((uv_handle_t *)handle, close_callback);
- }
-}
-#endif
-
-static void maybe_create_config_directory(struct monitor *monitor)
-{
- bool config_dir_exists = aki_dir_exists(&monitor->config_dir);
- if (!config_dir_exists) {
- if (!aki_dir_create(&monitor->config_dir)) {
- return;
- }
- }
-
- if (!aki_dir_exists(&monitor->prefix_dir)) {
- char *c_str = al_str_to_c_str(&monitor->prefix_dir);
- //pid_t pid = exec_or_exit((char *[]){ "make_prefix.sh", c_str, CONFIG_DIR, NULL });
- al_free(c_str);
- //wait_for_exit(pid);
- }
-
- if (config_dir_exists) {
- return;
- }
-
- aki_file_create(&monitor->selection_path);
- aki_file_open_and_replace(&monitor->selection_path, al_str_c("||"), false);
-
- //aki_file_create(&monitor->pid_path);
-}
-
-static void enqueue_monitor(struct daemon *dmon, struct monitor *monitor)
-{
- if (!dmon->queue_running) {
- run_wallpaper(monitor);
- } else {
- struct monitor *queued_monitor;
- al_array_foreach(dmon->queued_monitors, i, queued_monitor) {
- if (queued_monitor == monitor) return;
- }
- al_array_push(dmon->queued_monitors, monitor);
- }
-}
-
static void selection_fs_event_callback(void *userdata, struct inotify_event *event)
{
struct monitor *monitor = (struct monitor *)userdata;
@@ -447,7 +177,7 @@ static void selection_fs_event_callback(void *userdata, struct inotify_event *ev
return;
}
struct daemon *dmon = monitor->dmon;
- enqueue_monitor(dmon, monitor);
+ run_wallpaper(dmon, monitor);
}
static void output_discovered_callback(void *userdata, struct stl_monitor *os_monitor)
@@ -457,41 +187,43 @@ static void output_discovered_callback(void *userdata, struct stl_monitor *os_mo
struct monitor *monitor;
al_array_foreach(dmon->monitors, i, monitor) {
if (strcmp(monitor->os->name, os_monitor->name) == 0) {
- enqueue_monitor(dmon, monitor);
+ if (monitor->pid == -1) {
+ run_wallpaper(dmon, monitor);
+ }
return;
}
}
- monitor = al_alloc_object(struct monitor);
- al_array_push(dmon->monitors, monitor);
-
- monitor->os = os_monitor;
- monitor->dmon = dmon;
+ str config_dir;
+ al_str_clone(&config_dir, &dmon->conf.config_dir);
+ al_str_cat(&config_dir, al_str_c("/"));
+ al_str_cat(&config_dir, al_str_cr(os_monitor->name));
- al_str_from(&monitor->config_dir, CONFIG_DIR);
- if (al_str_atr(&monitor->config_dir, -1) != '/') {
- al_str_cat(&monitor->config_dir, al_str_c("/"));
+ if (!aki_dir_exists(&config_dir)) {
+ if (!aki_dir_create(&config_dir)) return;
}
- al_str_cat(&monitor->config_dir, al_str_cr(monitor->os->name));
- al_str_clone(&monitor->prefix_dir, &monitor->config_dir);
- al_str_cat(&monitor->prefix_dir, al_str_c("/prefix"));
+ monitor = al_alloc_object(struct monitor);
+ monitor->os = os_monitor;
+ monitor->dmon = dmon;
+ al_array_push(dmon->monitors, monitor);
- al_str_clone(&monitor->wine_log_path, &monitor->config_dir);
- al_str_cat(&monitor->wine_log_path, al_str_c("/wine.log"));
+ al_str_clone(&monitor->config_dir, &config_dir);
+ al_str_free(&config_dir);
al_str_clone(&monitor->selection_path, &monitor->config_dir);
al_str_cat(&monitor->selection_path, al_str_c("/selection"));
- //al_str_clone(&monitor->pid_path, &monitor->config_dir);
- //al_str_cat(&monitor->pid_path, al_str_c("/pid"));
+ if (!aki_file_exists(&monitor->selection_path)) {
+ aki_file_create(&monitor->selection_path);
+ aki_file_open_and_replace(&monitor->selection_path, al_str_c("||"), false);
+ }
monitor->pid = -1;
monitor->paused = false;
+ monitor->covered = false;
- maybe_create_config_directory(monitor);
-
- enqueue_monitor(dmon, monitor);
+ run_wallpaper(dmon, monitor);
monitor->self_event_skip = false;
aki_fs_event_init(&monitor->fs_event, &monitor->selection_path, AKI_CLOSE_WRITE,
@@ -502,17 +234,13 @@ static void output_discovered_callback(void *userdata, struct stl_monitor *os_mo
static void close_monitor(struct monitor *monitor)
{
al_str_free(&monitor->config_dir);
- al_str_free(&monitor->prefix_dir);
- al_str_free(&monitor->wine_log_path);
al_str_free(&monitor->selection_path);
- //al_str_free(&monitor->pid_path);
aki_fs_event_stop(&monitor->fs_event);
aki_fs_event_free(&monitor->fs_event);
}
-static void ipc_handle_subscribe_success(struct daemon *dmon, json_t *root)
+static void ipc_handle_subscribe_success(json_t *root)
{
- (void)dmon;
if (json_boolean_value(root)) {
al_log_info("tarod", "successfully subscribed to sway background covered events");
} else {
@@ -522,8 +250,9 @@ static void ipc_handle_subscribe_success(struct daemon *dmon, json_t *root)
static void ipc_handle_response(struct daemon *dmon, u8 *buf, u32 size)
{
- json_error_t error;
al_log_debug("tarod", "IN: %.*s", size, (char *)buf);
+
+ json_error_t error;
json_t *root = json_loadb((char *)buf, size, 0, &error);
if (!root) {
al_log_error("tarod", "failed to parse sway-ipc json payload (%s)", error.text);
@@ -532,7 +261,7 @@ static void ipc_handle_response(struct daemon *dmon, u8 *buf, u32 size)
json_t *success = json_object_get(root, "success");
if (success) {
- ipc_handle_subscribe_success(dmon, success);
+ ipc_handle_subscribe_success(success);
goto done;
}
@@ -541,19 +270,15 @@ static void ipc_handle_response(struct daemon *dmon, u8 *buf, u32 size)
bool covered = json_boolean_value(json_object_get(root, "covered"));
struct monitor *monitor;
al_array_foreach(dmon->monitors, i, monitor) {
- if (strcmp(monitor->os->name, json_string_value(output)) == 0) {
- if (monitor->pid == -1) goto done;
- if (!monitor->paused && covered) {
- if (kill(monitor->pid, SIGSTOP) == 0) {
- monitor->paused = true;
- }
- } else if (monitor->paused && !covered) {
- if (kill(monitor->pid, SIGCONT) == 0) {
- monitor->paused = false;
- }
- }
- break;
+ if (strcmp(monitor->os->name, json_string_value(output)) != 0) continue;
+ monitor->covered = covered;
+ if (monitor->pid == -1) goto done;
+ if (covered && !monitor->paused && send_signal_to_pid(monitor->pid, SIGSTOP)) {
+ monitor->paused = true;
+ } else if (!covered && monitor->paused && send_signal_to_pid(monitor->pid, SIGCONT)) {
+ monitor->paused = false;
}
+ break;
}
}
@@ -612,15 +337,13 @@ static void ipc_poll_callback(void *userdata, s32 revents)
}
}
-/*
static void context_poll_callback(void *userdata, s32 revents)
{
- struct daemon *dmon = (struct daemon *)userdata;
+ (void)userdata;
al_assert(revents & AKI_POLL_READ);
- dmon->context->process_events(dmon->context);
- dmon->context->prepare_read(dmon->context);
+ stl_global_process_events();
}
-*/
+
// https://stackoverflow.com/a/59071370
static void handle_sigchld(s32 sig)
@@ -641,22 +364,19 @@ s32 main(void)
signal(SIGCHLD, handle_sigchld);
+ s32 ret = EXIT_FAILURE;
+
+ if (!open_config(&dmon.conf)) goto out;
+
aki_event_loop_init(&dmon.loop);
al_array_init(dmon.monitors);
- al_array_init(dmon.queued_monitors);
- dmon.queue_running = false;
-
- al_str_from(&dmon.wp_config_dir, WALLPAPER_ENGINE_DIR);
- al_str_cat(&dmon.wp_config_dir, al_str_c("/config.json"));
stl_set_output_discovered_callback(output_discovered_callback, &dmon);
if (!stl_global_init()) return EXIT_FAILURE;
- //dmon.context = stl_window_create();
- //aki_poll_init(&dmon.context_poll, context_poll_callback, &dmon);
- //aki_poll_set(&dmon.context_poll, dmon.context->get_poll_fd(dmon.context), AKI_POLL_READ);
- //dmon.context->prepare_read(dmon.context);
- //aki_poll_start(&dmon.context_poll, &dmon.loop);
+ aki_poll_init(&dmon.context_poll, context_poll_callback, &dmon);
+ aki_poll_set(&dmon.context_poll, stl_global_get_poll_fd(), AKI_POLL_READ);
+ aki_poll_start(&dmon.context_poll, &dmon.loop);
str monitors;
al_str_from(&monitors, "");
@@ -667,9 +387,11 @@ s32 main(void)
}
str monitors_path;
- al_str_from(&monitors_path, CONFIG_DIR);
+ al_str_clone(&monitors_path, &dmon.conf.config_dir);
al_str_cat(&monitors_path, al_str_c("/monitors"));
- if (!aki_file_exists(&monitors_path)) aki_file_create(&monitors_path);
+ if (!aki_file_exists(&monitors_path)) {
+ aki_file_create(&monitors_path);
+ }
aki_file_open_and_replace(&monitors_path, &monitors, false);
dmon.ipc.buf = NULL;
@@ -709,15 +431,16 @@ s32 main(void)
close_monitor(monitor);
}
al_array_free(dmon.monitors);
- al_array_free(dmon.queued_monitors);
- al_str_free(&dmon.wp_config_dir);
al_free(dmon.ipc.buf);
- dmon.context->free(&dmon.context);
-
aki_event_loop_destroy(&dmon.loop);
+ close_config(&dmon.conf);
+
+ ret = EXIT_SUCCESS;
+
+out:
aki_common_close();
- return EXIT_SUCCESS;
+ return ret;
}
diff --git a/taro/src/dirs.h b/taro/src/dirs.h
deleted file mode 100644
index e508983..0000000
--- a/taro/src/dirs.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-#define WINE64_PATH "/opt/wine-wayland/bin/wine64"
-
-#define HOME "/home/andrew"
-#define CONFIG_DIR HOME"/.config/taro"
-//#define WALLPAPER_DIR HOME"/c/mauri/workshop_wallpapers_11-8-21"
-#define WALLPAPER_DIR HOME"/c/mauri/workshop_wallpapers"
-//#define WALLPAPER_DIR "/mnt/hdd/SteamLibrary/steamapps/workshop/content/431960"
-#define WALLPAPER_ENGINE_DIR HOME"/c/wpe-wine/wallpaper_engine"
diff --git a/taro/src/ui.c b/taro/src/ui.c
index e8307f5..b2c700e 100644
--- a/taro/src/ui.c
+++ b/taro/src/ui.c
@@ -6,8 +6,8 @@
#include <al/log.h>
#include "db.h"
-#include "dirs.h"
#include "file_ext.h"
+#include "config.h"
#define PIXEL_BLIT 1
@@ -122,6 +122,7 @@ struct ui {
struct info n;
struct image_pool pool;
struct db db;
+ struct config conf;
};
// ---------
@@ -154,7 +155,7 @@ static void select_monitor(struct ui *u)
if (u->m.set_monitor == -1) return;
u->m.set_monitor = u->m.selected_monitor;
al_str_free(&u->m.selection_path);
- al_str_from(&u->m.selection_path, CONFIG_DIR);
+ al_str_clone(&u->m.selection_path, &u->conf.config_dir);
al_str_cat(&u->m.selection_path, al_str_c("/"));
char *monitor = al_array_at(u->m.monitors, u->m.set_monitor);
al_str_cat(&u->m.selection_path, al_str_cr(monitor));
@@ -303,15 +304,20 @@ static s32 monitor_cmp(void *va, void *vb)
static bool init_monitors(struct ui *u, struct monitors *m)
{
al_array_init(m->monitors);
+ str monitors_path;
+ al_str_clone(&monitors_path, &u->conf.config_dir);
+ al_str_cat(&monitors_path, al_str_c("/monitors"));
str monitors;
- if (!aki_file_open_and_read_wholly(al_str_c(CONFIG_DIR"/monitors"), &monitors, false)) {
+ bool ret = aki_file_open_and_read_wholly(&monitors_path, &monitors, false);
+ al_str_free(&monitors_path);
+ if (!ret) {
al_log_error("taro", "failed to open monitor list, is the daemon configured?");
return false;
}
str monitor_dir;
str monitor = al_str_zero();
while (al_str_get_line(&monitors, '\n', &monitor)) {
- al_str_from(&monitor_dir, CONFIG_DIR);
+ al_str_clone(&monitor_dir, &u->conf.config_dir);
al_str_cat(&monitor_dir, al_str_c("/"));
al_str_cat(&monitor_dir, &monitor);
if (aki_dir_exists(&monitor_dir)) {
@@ -394,7 +400,7 @@ static void draw_monitors(struct ui *u, struct monitors *m);
static void draw_grid_tiles(struct ui *u, struct grid *g, bool update_text);
static void draw_info(struct ui *u, struct info *n, bool update_text);
-static int resize_cb(struct ncplane *p)
+static s32 resize_cb(struct ncplane *p)
{
struct ui *u = ncplane_userptr(p);
if (!u) return 0;
@@ -1142,13 +1148,21 @@ static struct ui u = { 0 };
s32 main(void)
{
- aki_common_init();
+ if (!aki_common_init()) return EXIT_FAILURE;
- if (!db_load_entries(&u.db, al_str_c(WALLPAPER_DIR))) {
- return EXIT_FAILURE;
+ s32 ret = EXIT_FAILURE;
+
+ if (!open_config(&u.conf)) goto out;
+
+ if (!db_load_entries(&u.db, &u.conf.wallpaper_dir)) {
+ close_config(&u.conf);
+ goto out;
}
- if (!init_ui(&u)) return EXIT_FAILURE;
+ if (!init_ui(&u)) {
+ close_config(&u.conf);
+ goto out;
+ }
notcurses_stddim_yx(u.nc, &u.term_rows, &u.term_cols);
@@ -1157,8 +1171,9 @@ s32 main(void)
if (!layout_ui(&u)) {
notcurses_stop(u.nc);
+ close_config(&u.conf);
al_log_error("taro", "failed to layout ui, your terminal window is probably too small");
- return EXIT_FAILURE;
+ goto out;
}
u.layed_out = true;
draw_monitors(&u, &u.m);
@@ -1177,7 +1192,12 @@ s32 main(void)
notcurses_stop(u.nc);
+ close_config(&u.conf);
+
+ ret = EXIT_SUCCESS;
+
+out:
aki_common_close();
- return EXIT_SUCCESS;
+ return ret;
}