From 5db61745a4bf863f3852f4ee3e0f9e3d76a2d073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 14 Jul 2023 09:04:32 +0200 Subject: [PATCH 001/112] =?UTF-8?q?changelog:=20add=20new=20=E2=80=98unrel?= =?UTF-8?q?eased=E2=80=99=20section?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 416a617..c94058a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +* [Unreleased](#unreleased) * [1.10.0](#1-10-0) * [1.9.0](#1-9-0) * [1.8.0](#1-8-0) @@ -10,6 +11,16 @@ * [1.5.0](#1-5-0) +## Unreleased +### Added +### Changed +### Deprecated +### Removed +### Fixed +### Security +### Contributors + + ## 1.10.0 ### Added From e1fc3a0e29b608110f0965a19f35d85fb3df03e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 14 Jul 2023 12:52:19 +0200 Subject: [PATCH 002/112] =?UTF-8?q?tag:=20explicitly=20initialize=20?= =?UTF-8?q?=E2=80=98fmt=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following compiler warning/error: In file included from /usr/include/stdio.h:906, from ../tag.c:6: In function ‘snprintf’, inlined from ‘tags_expand_template’ at ../tag.c:708:13: /usr/include/bits/stdio2.h:54:10: error: ‘fmt’ may be used uninitialized [-Werror=maybe-uninitialized] 54 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | __glibc_objsize (__s), __fmt, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 | __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~ ../tag.c: In function ‘tags_expand_template’: ../tag.c:677:25: note: ‘fmt’ was declared here 677 | const char *fmt; | ^~~ cc1: all warnings being treated as errors Closes #311 --- tag.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tag.c b/tag.c index b098eb7..0f44d7e 100644 --- a/tag.c +++ b/tag.c @@ -674,7 +674,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) const long max = tag->max(tag); long value = kind == VALUE_MIN ? min : max; - const char *fmt; + const char *fmt = NULL; switch (format) { case FMT_DEFAULT: fmt = zero_pad ? "%0*ld" : "%*ld"; break; case FMT_HEX: fmt = zero_pad ? "%0*lx" : "%*lx"; break; @@ -704,6 +704,8 @@ tags_expand_template(const char *template, const struct tag_set *tags) } } + assert(fmt != NULL); + char str[24]; snprintf(str, sizeof(str), fmt, digits, value); sbuf_append(&formatted, str); From 42cef9373e27d10275a1e14fc5fbbbc7f15cffab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 14 Jul 2023 12:54:23 +0200 Subject: [PATCH 003/112] =?UTF-8?q?changelog:=20"=E2=80=98fmt=E2=80=99=20m?= =?UTF-8?q?ay=20be=20used=20uninitialized"=20compiler=20warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c94058a..73d0100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,12 @@ ### Deprecated ### Removed ### Fixed + +* Compiler error _‘fmt’ may be used uninitialized_ ([#311][311]). + +[311]: https://codeberg.org/dnkl/yambar/issues/311 + + ### Security ### Contributors From 78f7b60e1308d9f6c879b5cbae2dadba4fa88762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 24 Jul 2023 17:13:19 +0200 Subject: [PATCH 004/112] particle/map: non-greedy matching of quotes Flex regexps are greedy. This means '"foo" || "bar"' will return 'foo" || "bar', which is obviously wrong. Use "start conditions" to implement non-greedy matching. Closes #302 --- CHANGELOG.md | 3 +++ particles/map.l | 56 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73d0100..faa616a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,8 +19,11 @@ ### Fixed * Compiler error _‘fmt’ may be used uninitialized_ ([#311][311]). +* map: conditions failing to match when they contain multiple, quoted + tag values ([#302][302]). [311]: https://codeberg.org/dnkl/yambar/issues/311 +[302]: https://codeberg.org/dnkl/yambar/issues/302 ### Security diff --git a/particles/map.l b/particles/map.l index 7a5ebc8..d34f086 100644 --- a/particles/map.l +++ b/particles/map.l @@ -2,13 +2,67 @@ #include #include "map.h" #include "map.tab.h" +void yyerror(const char *s); %} %option warn nodefault nounput noinput noyywrap + char *quoted = NULL; + size_t quote_len = 0; + +%x QUOTE + %% + [[:alnum:]_-]+ yylval.str = strdup(yytext); return WORD; -\".*\" yylval.str = strndup(yytext + 1, strlen(yytext) - 2); return STRING; + +\" { + BEGIN(QUOTE); + quoted = calloc(1, sizeof(quoted[0])); +} + +[^\\\"]* { + /* printf("CAT: %s\n", yytext); */ + const size_t yy_length = strlen(yytext); + quoted = realloc(quoted, quote_len + yy_length + 1); + strcat(quoted, yytext); + quote_len += yy_length; +} + +\\\" { + /* printf("escaped quote\n"); */ + quoted = realloc(quoted, quote_len + 1 + 1); + strcat(quoted, "\""); + quote_len++; +} + +\\. { + /* printf("CAT: %s\n", yytext); */ + const size_t yy_length = strlen(yytext); + quoted = realloc(quoted, quote_len + yy_length + 1); + strcat(quoted, yytext); + quote_len += yy_length; +} + +\\ { + /* quoted string that ends with a backslash: "string\ */ + quoted = realloc(quoted, quote_len + 1 + 1); + strcat(quoted, "\\"); + quote_len++; +} + +\" { + /* printf("QUOTED=%s\n", quoted); */ + yylval.str = strdup(quoted); + + free(quoted); + quoted = NULL; + quote_len = 0; + + BEGIN(INITIAL); + return STRING; +} + == yylval.op = MAP_OP_EQ; return CMP_OP; != yylval.op = MAP_OP_NE; return CMP_OP; \<= yylval.op = MAP_OP_LE; return CMP_OP; From 9a111a52f5312fe2bd7d9dbd5326d52895a165ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 18 Aug 2023 16:49:18 +0200 Subject: [PATCH 005/112] ci: 'pipeline' -> 'steps' --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 058b08a..0b0cd6a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,4 +1,4 @@ -pipeline: +steps: codespell: when: branch: From 7fbc1f2c44482c56f1aacf00d74c20645db10a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 8 Oct 2023 11:12:08 +0200 Subject: [PATCH 006/112] bar/wayland: seal memfd --- bar/wayland.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bar/wayland.c b/bar/wayland.c index edbf0db..2b1148b 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -937,6 +937,17 @@ get_buffer(struct wayland_backend *backend) goto err; } +#if defined(MEMFD_CREATE) + /* Seal file - we no longer allow any kind of resizing */ + /* TODO: wayland mmaps(PROT_WRITE), for some unknown reason, hence we cannot use F_SEAL_FUTURE_WRITE */ + if (fcntl(pool_fd, F_ADD_SEALS, + F_SEAL_GROW | F_SEAL_SHRINK | /*F_SEAL_FUTURE_WRITE |*/ F_SEAL_SEAL) < 0) + { + LOG_ERRNO("failed to seal SHM backing memory file"); + /* This is not a fatal error */ + } +#endif + pool = wl_shm_create_pool(backend->shm, pool_fd, size); if (pool == NULL) { LOG_ERR("failed to create SHM pool"); From cbd3bebb040d3baa442e396ad2c8b02baad449b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 8 Oct 2023 11:12:15 +0200 Subject: [PATCH 007/112] bar/wayland: create memfd with MFD_NOEXEC_SEAL --- bar/wayland.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bar/wayland.c b/bar/wayland.c index 2b1148b..eb770da 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -28,6 +28,12 @@ #include "private.h" +#if defined(MFD_NOEXEC_SEAL) + #define YAMBAR_MFD_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL) +#else + #define YAMBAR_MFD_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING) +#endif + struct buffer { bool busy; size_t width; @@ -907,7 +913,7 @@ get_buffer(struct wayland_backend *backend) /* Backing memory for SHM */ #if defined(MEMFD_CREATE) - pool_fd = memfd_create("yambar-wayland-shm-buffer-pool", MFD_CLOEXEC); + pool_fd = memfd_create("yambar-wayland-shm-buffer-pool", YAMBAR_MFD_FLAGS); #elif defined(__FreeBSD__) // memfd_create on FreeBSD 13 is SHM_ANON without sealing support pool_fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600); From 89e74139f59ce789a3c3686da5eba3e6a26f1c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 13 Oct 2023 16:34:02 +0200 Subject: [PATCH 008/112] bar: wayland: shm: try with MFD_NOEXEC_SEAL first, then without MFD_NOEXEC_SEAL is only supported on kernels 6.3 and later. If we were compiled on linux >= 6.3, but run on linux < 6.3, we'd exit with an error, due to memfd_create() failing with EINVAL. This patch fixes the problem by first trying to call memfd_create() *with* MFD_NOEXEC_SEAL, and if that fails with EINVAL, we try again without it. --- bar/wayland.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/bar/wayland.c b/bar/wayland.c index eb770da..e95e032 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -28,10 +28,8 @@ #include "private.h" -#if defined(MFD_NOEXEC_SEAL) - #define YAMBAR_MFD_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL) -#else - #define YAMBAR_MFD_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING) +#if !defined(MFD_NOEXEC_SEAL) + #define MFD_NOEXEC_SEAL 0 #endif struct buffer { @@ -913,7 +911,19 @@ get_buffer(struct wayland_backend *backend) /* Backing memory for SHM */ #if defined(MEMFD_CREATE) - pool_fd = memfd_create("yambar-wayland-shm-buffer-pool", YAMBAR_MFD_FLAGS); + /* + * Older kernels reject MFD_NOEXEC_SEAL with EINVAL. Try first + * *with* it, and if that fails, try again *without* it. + */ + errno = 0; + pool_fd = memfd_create( + "yambar-wayland-shm-buffer-pool", + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL); + + if (pool_fd < 0 && errno == EINVAL) { + pool_fd = memfd_create( + "yambar-wayland-shm-buffer-pool", MFD_CLOEXEC | MFD_ALLOW_SEALING); + } #elif defined(__FreeBSD__) // memfd_create on FreeBSD 13 is SHM_ANON without sealing support pool_fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600); From 14550440dde33328d94e0bec0929fe758cdc924f Mon Sep 17 00:00:00 2001 From: oob <> Date: Sun, 27 Aug 2023 12:48:56 +0000 Subject: [PATCH 009/112] Minor documentation update --- README.md | 3 ++- doc/meson.build | 1 + doc/yambar-modules-network.5.scd | 2 +- doc/yambar-modules.5.scd | 12 ++++++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 759f667..ca90ae9 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Available modules: * mem * mpd * network +* pipewire * pulse * removables * river @@ -106,7 +107,7 @@ mkdir -p bld/release && cd bld/release Second, configure the build (if you intend to install it globally, you might also want `--prefix=/usr`): ```sh -meson --buildtype=release ../.. +meson setup --buildtype=release .. ``` Optionally, explicitly disable a backend (or enable, if you want a diff --git a/doc/meson.build b/doc/meson.build index 0b4e13a..e5728ab 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -36,6 +36,7 @@ if plugin_mpd_enabled endif if plugin_i3_enabled plugin_pages += ['yambar-modules-i3.5.scd'] + plugin_pages += ['yambar-modules-sway.5.scd'] endif if plugin_label_enabled plugin_pages += ['yambar-modules-label.5.scd'] diff --git a/doc/yambar-modules-network.5.scd b/doc/yambar-modules-network.5.scd index 8b8b507..2aefc89 100644 --- a/doc/yambar-modules-network.5.scd +++ b/doc/yambar-modules-network.5.scd @@ -73,7 +73,7 @@ address. : int : no : Periodically (in milliseconds) update the signal, rx+tx bitrate, and - ul+dl speed tags. Setting it to 0 disables updates. Cannot be less + ul+dl speed tags (default=0). Setting it to 0 disables updates. Cannot be less than 250ms. diff --git a/doc/yambar-modules.5.scd b/doc/yambar-modules.5.scd index e8c388c..765d06f 100644 --- a/doc/yambar-modules.5.scd +++ b/doc/yambar-modules.5.scd @@ -142,14 +142,26 @@ Available modules have their own pages: *yambar-modules-clock*(5) +*yambar-modules-cpu*(5) + +*yambar-modules-disk-io*(5) + +*yambar-modules-dwl*(5) + +*yambar-modules-foreign-toplevel*(5) + *yambar-modules-i3*(5) *yambar-modules-label*(5) +*yambar-modules-mem*(5) + *yambar-modules-mpd*(5) *yambar-modules-network*(5) +*yambar-modules-pipewire*(5) + *yambar-modules-pulse*(5) *yambar-modules-removables*(5) From 60671da2caef8a4b32f626021f5918aab6963160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 15 Dec 2023 22:36:51 -0600 Subject: [PATCH 010/112] lowercase DWL (dwl is the preferred form) --- doc/yambar-modules-dwl.5.scd | 2 +- meson.build | 2 +- meson_options.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/yambar-modules-dwl.5.scd b/doc/yambar-modules-dwl.5.scd index 289955a..1562e56 100644 --- a/doc/yambar-modules-dwl.5.scd +++ b/doc/yambar-modules-dwl.5.scd @@ -28,7 +28,7 @@ Running multiple instances at the same time may result in :< *Description* | id : int -: Dwl tag id. +: dwl tag id. | name : string : The name of the tag (defaults to _id_ if not set). diff --git a/meson.build b/meson.build index fcb647a..f0369cd 100644 --- a/meson.build +++ b/meson.build @@ -174,7 +174,7 @@ summary( 'Clock': plugin_clock_enabled, 'CPU monitoring': plugin_cpu_enabled, 'Disk I/O monitoring': plugin_disk_io_enabled, - 'DWL (dwm for Wayland)': plugin_dwl_enabled, + 'dwl (dwm for Wayland)': plugin_dwl_enabled, 'Foreign toplevel (window tracking for Wayland)': plugin_foreign_toplevel_enabled, 'Memory monitoring': plugin_mem_enabled, 'Music Player Daemon (MPD)': plugin_mpd_enabled, diff --git a/meson_options.txt b/meson_options.txt index 03c0ead..a9aac05 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -19,7 +19,7 @@ option('plugin-cpu', type: 'feature', value: 'auto', option('plugin-disk-io', type: 'feature', value: 'auto', description: 'Disk I/O support') option('plugin-dwl', type: 'feature', value: 'auto', - description: 'DWL (dwm for wayland) support') + description: 'dwl (dwm for wayland) support') option('plugin-foreign-toplevel', type: 'feature', value: 'auto', description: 'Foreign toplevel (window tracking for Wayland) support') option('plugin-mem', type: 'feature', value: 'auto', From 1283160e170737d9e71cfa69e8a709e2296d0e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A4in=C3=B6=20M=C3=A4kel=C3=A4?= Date: Fri, 29 Dec 2023 11:05:20 +0200 Subject: [PATCH 011/112] bar/wayland: Reset last_mapped_monitor on enter If the surface enters an output, there's no need for last_mapped_monitor, and it must be reset to fulfill the asserts in other parts of the code. This makes yambar no longer crash when it is hidden by an opaque window multiple times on a compositor using wlroots' scene tree. --- bar/wayland.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bar/wayland.c b/bar/wayland.c index e95e032..2b1e0a5 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -1339,6 +1339,9 @@ surface_enter(void *data, struct wl_surface *wl_surface, { struct wayland_backend *backend = data; + free(backend->last_mapped_monitor); + backend->last_mapped_monitor = NULL; + tll_foreach(backend->monitors, it) { struct monitor *mon = &it->item; From d5823bcc4c41af1a009559d3aaa1973cbe3184ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 3 Jan 2024 15:15:20 +0100 Subject: [PATCH 012/112] changelog: fixed: crash when hidden by an opaque window --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index faa616a..3c620f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ * Compiler error _‘fmt’ may be used uninitialized_ ([#311][311]). * map: conditions failing to match when they contain multiple, quoted tag values ([#302][302]). +* Crash when hidden by an opaque window. [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 From 176ed4a6f38c4bd878915ef65cc07b7d45dec8de Mon Sep 17 00:00:00 2001 From: kotyk Date: Tue, 25 Jul 2023 16:22:52 +0000 Subject: [PATCH 013/112] particles/string: rewrite truncation code, show three dots only for max>3 --- particles/string.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/particles/string.c b/particles/string.c index e11ec45..186d50e 100644 --- a/particles/string.c +++ b/particles/string.c @@ -180,20 +180,10 @@ instantiate(const struct particle *particle, const struct tag_set *tags) /* Truncate, if necessary */ if (p->max_len > 0 && chars > p->max_len) { - size_t end = p->max_len; - if (end >= 1) { - /* "allocate" room for three dots at the end */ - end -= 1; - } - - if (p->max_len > 1) { - wtext[end] = U'…'; - wtext[end + 1] = U'\0'; - chars = end + 1; - } else { - wtext[end] = U'\0'; - chars = 0; - } + chars = p->max_len; + if (p->max_len > 3) + wtext[p->max_len - 1] = U'…'; + wtext[p->max_len] = U'\0'; } e->kern_x = calloc(chars, sizeof(e->kern_x[0])); From e54e8635e0bd29e73e437d2cb966b92dd399e39f Mon Sep 17 00:00:00 2001 From: Sertonix Date: Tue, 2 Jan 2024 13:28:40 +0100 Subject: [PATCH 014/112] main: change default log level to warning --- CHANGELOG.md | 3 +++ completions/zsh/_yambar | 2 +- doc/yambar.1.scd | 2 +- main.c | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c620f2..8579644 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ ## Unreleased ### Added ### Changed + +* log-level: default to `warning` + ### Deprecated ### Removed ### Fixed diff --git a/completions/zsh/_yambar b/completions/zsh/_yambar index 65b3100..90b1117 100644 --- a/completions/zsh/_yambar +++ b/completions/zsh/_yambar @@ -8,6 +8,6 @@ _arguments \ '(-c --config)'{-c,--config}'[alternative configuration file]:filename:_files' \ '(-C --validate)'{-C,--validate}'[verify configuration then quit]' \ '(-p --print-pid)'{-p,--print-pid}'[print PID to this file or FD when up and running]:pidfile:_files' \ - '(-d --log-level)'{-d,--log-level}'[log level (info)]:loglevel:(info warning error none)' \ + '(-d --log-level)'{-d,--log-level}'[log level (warning)]:loglevel:(info warning error none)' \ '(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \ '(-s --log-no-syslog)'{-s,--log-no-syslog}'[disable syslog logging]' diff --git a/doc/yambar.1.scd b/doc/yambar.1.scd index a34f13c..549b980 100644 --- a/doc/yambar.1.scd +++ b/doc/yambar.1.scd @@ -29,7 +29,7 @@ yambar - modular status panel for X11 and Wayland *-d*,*--log-level*={*info*,*warning*,*error*,*none*} Log level, used both for log output on stderr as well as - syslog. Default: _info_. + syslog. Default: _warning_. *-l*,*--log-colorize*=[{*never*,*always*,*auto*}] Enables or disables colorization of log output on stderr. diff --git a/main.c b/main.c index 7aab81a..9604631 100644 --- a/main.c +++ b/main.c @@ -131,7 +131,7 @@ print_usage(const char *prog_name) " -c,--config=FILE alternative configuration file\n" " -C,--validate verify configuration then quit\n" " -p,--print-pid=FILE|FD print PID to file or FD\n" - " -d,--log-level={info|warning|error|none} log level (info)\n" + " -d,--log-level={info|warning|error|none} log level (warning)\n" " -l,--log-colorize=[never|always|auto] enable/disable colorization of log output on stderr\n" " -s,--log-no-syslog disable syslog logging\n" " -v,--version show the version number and quit\n"); @@ -197,7 +197,7 @@ main(int argc, char *const *argv) char *config_path = NULL; enum bar_backend backend = BAR_BACKEND_AUTO; - enum log_class log_level = LOG_CLASS_INFO; + enum log_class log_level = LOG_CLASS_WARNING; enum log_colorize log_colorize = LOG_COLORIZE_AUTO; bool log_syslog = true; From a943def94e5cc8194ab700fb1d13e37ea588dbbf Mon Sep 17 00:00:00 2001 From: Jordan Isaacs Date: Wed, 15 Nov 2023 01:37:51 -0800 Subject: [PATCH 015/112] battery scale and discharge smoothing --- doc/yambar-modules-battery.5.scd | 10 ++++ modules/battery.c | 98 +++++++++++++++++++++++++++----- 2 files changed, 95 insertions(+), 13 deletions(-) diff --git a/doc/yambar-modules-battery.5.scd b/doc/yambar-modules-battery.5.scd index ef7a6bd..99a7708 100644 --- a/doc/yambar-modules-battery.5.scd +++ b/doc/yambar-modules-battery.5.scd @@ -61,6 +61,16 @@ the state *unknown* under other conditions. (default=*60000*). Set to `0` to disable polling (*warning*: many batteries do not support asynchronous reporting). Cannot be less than 250ms. +| battery-scale +: int +: no +: How much to scale down the battery charge amount. Some batteries + report too high resulting in bad discharge estimates +| smoothing-secs +: int +: no +: How many seconds to perform smoothing over for battery discharge + estimates. # EXAMPLES diff --git a/modules/battery.c b/modules/battery.c index f838c8e..1ea0f58 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -12,9 +13,10 @@ #include #include +#include #define LOG_MODULE "battery" -#define LOG_ENABLE_DBG 1 +#define LOG_ENABLE_DBG 0 #include "../log.h" #include "../bar/bar.h" #include "../config.h" @@ -25,13 +27,22 @@ static const long min_poll_interval = 250; static const long default_poll_interval = 60 * 1000; +static const long one_sec_in_ns = 1000000000; enum state { STATE_FULL, STATE_NOTCHARGING, STATE_CHARGING, STATE_DISCHARGING, STATE_UNKNOWN }; +struct current_state { + long ema; + long current; + struct timespec time; +}; + struct private { struct particle *label; long poll_interval; + int battery_scale; + long smoothing_scale; char *battery; char *manufacturer; char *model; @@ -45,16 +56,53 @@ struct private { long energy; long power; long charge; - long current; + struct current_state ema_current; long time_to_empty; long time_to_full; }; +int64_t difftimespec_ns(const struct timespec after, const struct timespec before) +{ + return ((int64_t)after.tv_sec - (int64_t)before.tv_sec) * (int64_t)one_sec_in_ns + + ((int64_t)after.tv_nsec - (int64_t)before.tv_nsec); +} + +// Linear Exponential Moving Average (unevenly spaced time series) +// http://www.eckner.com/papers/Algorithms%20for%20Unevenly%20Spaced%20Time%20Series.pdf +// Adapted from: https://github.com/andreas50/utsAlgorithms/blob/master/ema.c +void +ema_linear(struct current_state *state, struct current_state curr, long tau) +{ + double w, w2, tmp; + + if (state->current == -1) { + *state = curr; + return; + } + + long time = difftimespec_ns(curr.time, state->time); + tmp = time / (double)tau; + w = exp(-tmp); + if (tmp > 1e-6) { + w2 = (1 - w) / tmp; + } else { + // Use taylor expansion for numerical stability + w2 = 1 - tmp/2 + tmp*tmp/6 - tmp*tmp*tmp/24; + } + + double ema = state->ema * w + curr.current * (1 - w2) + state->current * (w2 - w); + + state->ema = ema; + state->current = curr.current; + state->time = curr.time; + + LOG_DBG("ema current: %ld", (long)ema); +} + static void timespec_sub(const struct timespec *a, const struct timespec *b, struct timespec *res) { - const long one_sec_in_ns = 1000000000; res->tv_sec = a->tv_sec - b->tv_sec; res->tv_nsec = a->tv_nsec - b->tv_nsec; @@ -127,15 +175,15 @@ content(struct module *mod) hours = hours_as_float; minutes = (hours_as_float - (double)hours) * 60; - } else if (m->charge_full >= 0 && m->charge >= 0 && m->current >= 0) { + } else if (m->charge_full >= 0 && m->charge >= 0 && m->ema_current.current >= 0) { unsigned long charge = m->state == STATE_CHARGING ? m->charge_full - m->charge : m->charge; double hours_as_float; if (m->state == STATE_FULL || m->state == STATE_NOTCHARGING) hours_as_float = 0.0; - else if (m->current > 0) - hours_as_float = (double)charge / m->current; + else if (m->ema_current.current > 0) + hours_as_float = (double)charge / m->ema_current.current; else hours_as_float = 99.0; @@ -291,7 +339,7 @@ initialize(struct private *m) goto err; } - m->charge_full_design = readint_from_fd(fd); + m->charge_full_design = readint_from_fd(fd) / m->battery_scale; close(fd); } @@ -302,7 +350,7 @@ initialize(struct private *m) goto err; } - m->charge_full = readint_from_fd(fd); + m->charge_full = readint_from_fd(fd) / m->battery_scale; close(fd); } } else { @@ -366,6 +414,10 @@ update_status(struct module *mod) long time_to_empty = time_to_empty_fd >= 0 ? readint_from_fd(time_to_empty_fd) : -1; long time_to_full = time_to_full_fd >= 0 ? readint_from_fd(time_to_full_fd) : -1; + if (charge >= -1) { + charge /= m->battery_scale; + } + char buf[512]; const char *status = readline_from_fd(status_fd, sizeof(buf), buf); @@ -409,16 +461,23 @@ update_status(struct module *mod) } LOG_DBG("capacity: %ld, energy: %ld, power: %ld, charge=%ld, current=%ld, " - "time-to-empty: %ld, time-to-full: %ld", capacity, energy, power, - charge, current, time_to_empty, time_to_full); + "time-to-empty: %ld, time-to-full: %ld", capacity, + energy, power, charge, current, time_to_empty, time_to_full); mtx_lock(&mod->lock); + if (m->state != state) { + m->ema_current = (struct current_state){-1, 0, (struct timespec){0, 0}}; + } m->state = state; m->capacity = capacity; m->energy = energy; m->power = power; m->charge = charge; - m->current = current; + if (current != -1) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + ema_linear(&m->ema_current, (struct current_state){current, current, t}, m->smoothing_scale); + } m->time_to_empty = time_to_empty; m->time_to_full = time_to_full; mtx_unlock(&mod->lock); @@ -548,13 +607,16 @@ out: } static struct module * -battery_new(const char *battery, struct particle *label, long poll_interval_msecs) +battery_new(const char *battery, struct particle *label, long poll_interval_msecs, int battery_scale, long smoothing_secs) { struct private *m = calloc(1, sizeof(*m)); m->label = label; m->poll_interval = poll_interval_msecs; + m->battery_scale = battery_scale; + m->smoothing_scale = smoothing_secs * one_sec_in_ns; m->battery = strdup(battery); m->state = STATE_UNKNOWN; + m->ema_current = (struct current_state){ -1, 0, (struct timespec){0, 0} }; struct module *mod = module_common_new(); mod->private = m; @@ -571,13 +633,21 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *c = yml_get_value(node, "content"); const struct yml_node *name = yml_get_value(node, "name"); const struct yml_node *poll_interval = yml_get_value(node, "poll-interval"); + const struct yml_node *battery_scale = yml_get_value(node, "battery-scale"); + const struct yml_node *smoothing_secs = yml_get_value(node, "smoothing-secs"); return battery_new( yml_value_as_string(name), conf_to_particle(c, inherited), (poll_interval != NULL ? yml_value_as_int(poll_interval) - : default_poll_interval)); + : default_poll_interval), + (battery_scale != NULL + ? yml_value_as_int(battery_scale) + : 1), + (smoothing_secs != NULL + ? yml_value_as_int(smoothing_secs) + : 100)); } static bool @@ -603,6 +673,8 @@ verify_conf(keychain_t *chain, const struct yml_node *node) static const struct attr_info attrs[] = { {"name", true, &conf_verify_string}, {"poll-interval", false, &conf_verify_poll_interval}, + {"battery-scale", false, &conf_verify_unsigned}, + {"smoothing-secs", false, &conf_verify_unsigned}, MODULE_COMMON_ATTRS, }; From 4d46f258547917847e677ee0535469611df5bb94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 3 Jan 2024 15:28:32 +0100 Subject: [PATCH 016/112] doc: battery: document defaults for battery-scale and smoothing-secs --- doc/yambar-modules-battery.5.scd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/yambar-modules-battery.5.scd b/doc/yambar-modules-battery.5.scd index 99a7708..aab2106 100644 --- a/doc/yambar-modules-battery.5.scd +++ b/doc/yambar-modules-battery.5.scd @@ -65,12 +65,12 @@ the state *unknown* under other conditions. : int : no : How much to scale down the battery charge amount. Some batteries - report too high resulting in bad discharge estimates + report too high resulting in bad discharge estimates. Default=1. | smoothing-secs : int : no : How many seconds to perform smoothing over for battery discharge - estimates. + estimates. Default=100s. # EXAMPLES From 3a3a711b698bb855df62f0ac7ef259f8c2324169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 3 Jan 2024 15:29:06 +0100 Subject: [PATCH 017/112] changelog: battery: smoothing + scaling --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8579644..85a7469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,12 @@ ## Unreleased ### Added + +* battery: current smoothing, for improved discharge estimates. +* battery: scale option, for batteries that report 'charge' at a + different scale than 'current'. + + ### Changed * log-level: default to `warning` From 9365580539bee8cbeee43e212f055cd7313c1104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 3 Jan 2024 15:30:03 +0100 Subject: [PATCH 018/112] module: battery: style --- modules/battery.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/battery.c b/modules/battery.c index 1ea0f58..c947649 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -61,7 +61,8 @@ struct private { long time_to_full; }; -int64_t difftimespec_ns(const struct timespec after, const struct timespec before) +static int64_t +difftimespec_ns(const struct timespec after, const struct timespec before) { return ((int64_t)after.tv_sec - (int64_t)before.tv_sec) * (int64_t)one_sec_in_ns + ((int64_t)after.tv_nsec - (int64_t)before.tv_nsec); @@ -70,7 +71,7 @@ int64_t difftimespec_ns(const struct timespec after, const struct timespec befor // Linear Exponential Moving Average (unevenly spaced time series) // http://www.eckner.com/papers/Algorithms%20for%20Unevenly%20Spaced%20Time%20Series.pdf // Adapted from: https://github.com/andreas50/utsAlgorithms/blob/master/ema.c -void +static void ema_linear(struct current_state *state, struct current_state curr, long tau) { double w, w2, tmp; From cdee55afed6eee4e2618926d096d1322b58e2962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 3 Jan 2024 15:39:04 +0100 Subject: [PATCH 019/112] bar: wayland: update bar size + refresh in output_done() This ensures the bar's size (width) is updated when the screen resolution (and/or scale) is changed. Note that we already handled scale changes. This logic has been moved from output_scale() to output_done(). Closes #330 --- CHANGELOG.md | 3 +++ bar/wayland.c | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a7469..01bd423 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,9 +31,12 @@ * map: conditions failing to match when they contain multiple, quoted tag values ([#302][302]). * Crash when hidden by an opaque window. +* Bar not resizing itself when the screen resolution is changed + ([#330][330]). [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 +[330]: https://codeberg.org/dnkl/yambar/issues/330 ### Security diff --git a/bar/wayland.c b/bar/wayland.c index 2b1e0a5..22ca3e2 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -475,13 +475,24 @@ output_mode(void *data, struct wl_output *wl_output, uint32_t flags, { } +static bool update_size(struct wayland_backend *backend); +static void refresh(const struct bar *_bar); + static void output_done(void *data, struct wl_output *wl_output) { -} + struct monitor *mon = data; -static bool update_size(struct wayland_backend *backend); -static void refresh(const struct bar *_bar); + if (mon->backend->monitor == mon) { + int old_scale = mon->backend->scale; + int old_width = mon->backend->width; + + update_size(mon->backend); + + if (mon->backend->scale != old_scale || mon->backend->width != old_width) + refresh(mon->backend->bar); + } +} static void output_scale(void *data, struct wl_output *wl_output, int32_t factor) @@ -491,14 +502,6 @@ output_scale(void *data, struct wl_output *wl_output, int32_t factor) return; mon->scale = factor; - - if (mon->backend->monitor == mon) { - int old_scale = mon->backend->scale; - update_size(mon->backend); - - if (mon->backend->scale != old_scale) - refresh(mon->backend->bar); - } } #if defined(WL_OUTPUT_NAME_SINCE_VERSION) @@ -1058,9 +1061,6 @@ update_size(struct wayland_backend *backend) assert(backend->surface != NULL); - if (backend->scale == scale) - return true; - backend->scale = scale; int height = bar->height_with_border; From 26bf62a8996801b32dc4c541ef6fc02158d16e60 Mon Sep 17 00:00:00 2001 From: rdbo Date: Thu, 4 Jan 2024 08:21:05 +0000 Subject: [PATCH 020/112] fixed meson setup directory on readme Signed-off-by: rdbo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca90ae9..2887f53 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ mkdir -p bld/release && cd bld/release Second, configure the build (if you intend to install it globally, you might also want `--prefix=/usr`): ```sh -meson setup --buildtype=release .. +meson setup --buildtype=release ../.. ``` Optionally, explicitly disable a backend (or enable, if you want a From e1f78a16ab4649fe0f9d4000463e5fc271927443 Mon Sep 17 00:00:00 2001 From: Delgan Date: Wed, 3 Jan 2024 16:21:49 +0100 Subject: [PATCH 021/112] Add new "quality" tag to "network" module --- CHANGELOG.md | 1 + doc/yambar-modules-network.5.scd | 5 ++++- modules/network.c | 13 ++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01bd423..38f2c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * battery: current smoothing, for improved discharge estimates. * battery: scale option, for batteries that report 'charge' at a different scale than 'current'. +* network: new `quality` tag (Wi-Fi only). ### Changed diff --git a/doc/yambar-modules-network.5.scd b/doc/yambar-modules-network.5.scd index 2aefc89..44605e2 100644 --- a/doc/yambar-modules-network.5.scd +++ b/doc/yambar-modules-network.5.scd @@ -45,6 +45,9 @@ address. | signal : int : Signal strength, in dBm (Wi-Fi only) +| quality +: range +: Quality of the signal, in percent (Wi-Fi only) | rx-bitrate : int : RX bitrate, in bits/s @@ -72,7 +75,7 @@ address. | poll-interval : int : no -: Periodically (in milliseconds) update the signal, rx+tx bitrate, and +: Periodically (in milliseconds) update the signal, quality, rx+tx bitrate, and ul+dl speed tags (default=0). Setting it to 0 disables updates. Cannot be less than 250ms. diff --git a/modules/network.c b/modules/network.c index 0cc8cb6..3336c23 100644 --- a/modules/network.c +++ b/modules/network.c @@ -154,6 +154,16 @@ content(struct module *mod) inet_ntop(AF_INET6, &it->item.addr.ipv6, ipv6_str, sizeof(ipv6_str)); } + int quality = 0; + if (m->signal_strength_dbm != 0) { + if (m->signal_strength_dbm <= -100) + quality = 0; + else if (m->signal_strength_dbm >= -50) + quality = 100; + else + quality = 2 * (m->signal_strength_dbm + 100); + } + struct tag_set tags = { .tags = (struct tag *[]){ tag_new_string(mod, "name", m->iface), @@ -165,12 +175,13 @@ content(struct module *mod) tag_new_string(mod, "ipv6", ipv6_str), tag_new_string(mod, "ssid", m->ssid), tag_new_int(mod, "signal", m->signal_strength_dbm), + tag_new_int_range(mod, "quality", quality, 0, 100), tag_new_int(mod, "rx-bitrate", m->rx_bitrate), tag_new_int(mod, "tx-bitrate", m->tx_bitrate), tag_new_float(mod, "dl-speed", m->dl_speed), tag_new_float(mod, "ul-speed", m->ul_speed), }, - .count = 13, + .count = 14, }; mtx_unlock(&mod->lock); From bdc4fbe8e71491c16a7b22a9373bec1015b9b4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 4 Jan 2024 13:57:17 +0100 Subject: [PATCH 022/112] doc: pipewire: describe the 'content' config option --- doc/yambar-modules-pipewire.5.scd | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/yambar-modules-pipewire.5.scd b/doc/yambar-modules-pipewire.5.scd index 0f7a40b..be94489 100644 --- a/doc/yambar-modules-pipewire.5.scd +++ b/doc/yambar-modules-pipewire.5.scd @@ -39,8 +39,16 @@ pipewire - Monitors pipewire for volume, mute/unmute, device change # CONFIGURATION -No additional attributes supported, only the generic ones (see -*GENERIC CONFIGURATION* in *yambar-modules*(5)) +[[ *Name* +:[ *Type* +:[ *Req* +:< *Description* +| content +: particle +: yes +: Unlike other modules, _content_ is a template particle that will be + expanded twice (i.e. into a list of two elements). The first + element is the 'sink', and the second element the 'source'. # EXAMPLES From 8b1fa136867cb9af78e0767974f246cfb2977a9d Mon Sep 17 00:00:00 2001 From: steovd Date: Wed, 3 Jan 2024 17:25:46 +0100 Subject: [PATCH 023/112] main: allow reading alternative config from pipe --- CHANGELOG.md | 2 ++ main.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38f2c57..72f7eb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ ### Changed * log-level: default to `warning` +* Read alternative config from pipes (e.g. `--config /dev/stdin`) + ([#340][340]). ### Deprecated ### Removed diff --git a/main.c b/main.c index 9604631..3a8b9f7 100644 --- a/main.c +++ b/main.c @@ -223,8 +223,8 @@ main(int argc, char *const *argv) if (stat(optarg, &st) == -1) { fprintf(stderr, "%s: invalid configuration file: %s\n", optarg, strerror(errno)); return EXIT_FAILURE; - } else if (!S_ISREG(st.st_mode)) { - fprintf(stderr, "%s: invalid configuration file: not a regular file\n", + } else if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode)) { + fprintf(stderr, "%s: invalid configuration file: neither a regular file nor a pipe\n", optarg); return EXIT_FAILURE; } From cb2561a72cd14afa6d49a9cd2fb3c8984b251c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 4 Jan 2024 16:33:59 +0100 Subject: [PATCH 024/112] changelog: move 'reading config from pipe' from changed to added --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72f7eb7..ef54b1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,13 +18,15 @@ * battery: scale option, for batteries that report 'charge' at a different scale than 'current'. * network: new `quality` tag (Wi-Fi only). +* Read alternative config from pipes (e.g. `--config /dev/stdin`) + ([#340][340]). + +[340]: https://codeberg.org/dnkl/yambar/pulls/340 ### Changed * log-level: default to `warning` -* Read alternative config from pipes (e.g. `--config /dev/stdin`) - ([#340][340]). ### Deprecated ### Removed From bbbf2b601e2f0bf9676ff300861803711ce5c44c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 4 Jan 2024 16:35:05 +0100 Subject: [PATCH 025/112] main: S_ISFIFO() matches both pipes and FIFOs --- CHANGELOG.md | 4 ++-- main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef54b1d..4e18535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,8 +18,8 @@ * battery: scale option, for batteries that report 'charge' at a different scale than 'current'. * network: new `quality` tag (Wi-Fi only). -* Read alternative config from pipes (e.g. `--config /dev/stdin`) - ([#340][340]). +* Read alternative config from pipes and FIFOs (e.g. `--config + /dev/stdin`) ([#340][340]). [340]: https://codeberg.org/dnkl/yambar/pulls/340 diff --git a/main.c b/main.c index 3a8b9f7..5d9df44 100644 --- a/main.c +++ b/main.c @@ -224,7 +224,7 @@ main(int argc, char *const *argv) fprintf(stderr, "%s: invalid configuration file: %s\n", optarg, strerror(errno)); return EXIT_FAILURE; } else if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode)) { - fprintf(stderr, "%s: invalid configuration file: neither a regular file nor a pipe\n", + fprintf(stderr, "%s: invalid configuration file: neither a regular file nor a pipe or FIFO\n", optarg); return EXIT_FAILURE; } From 9d90848291e37f8c97c2c175059fa0806421d1c6 Mon Sep 17 00:00:00 2001 From: Yiyu Zhou Date: Sat, 13 Jan 2024 00:24:58 -0500 Subject: [PATCH 026/112] style: remove trailing spaces --- examples/configurations/river-tags.conf | 18 +++++++++--------- examples/scripts/dwl-tags.sh | 1 - examples/scripts/pacman.sh | 11 +++++------ 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/examples/configurations/river-tags.conf b/examples/configurations/river-tags.conf index 54289e6..28bc0b9 100644 --- a/examples/configurations/river-tags.conf +++ b/examples/configurations/river-tags.conf @@ -15,20 +15,20 @@ bar: anchors: - base: &river_base left-margin: 10 - right-margin: 13 + right-margin: 13 default: {string: {text: , font: *hack}} conditions: - id == 1: {string: {text: ﳐ, font: *hack}} - id == 2: {string: {text: , font: *hack}} - id == 3: {string: {text: , font: *hack}} - id == 4: {string: {text: , font: *hack}} - id == 5: {string: {text: , font: *hack}} - id == 10: {string: {text: "scratchpad", font: *hack}} - id == 11: {string: {text: "work", font: *hack}} + id == 1: {string: {text: ﳐ, font: *hack}} + id == 2: {string: {text: , font: *hack}} + id == 3: {string: {text: , font: *hack}} + id == 4: {string: {text: , font: *hack}} + id == 5: {string: {text: , font: *hack}} + id == 10: {string: {text: "scratchpad", font: *hack}} + id == 11: {string: {text: "work", font: *hack}} content: map: - on-click: + on-click: left: sh -c "riverctl set-focused-tags $((1 << ({id} - 1)))" right: sh -c "riverctl toggle-focused-tags $((1 << ({id} -1)))" middle: sh -c "riverctl toggle-view-tags $((1 << ({id} -1)))" diff --git a/examples/scripts/dwl-tags.sh b/examples/scripts/dwl-tags.sh index 7b70fff..b1dbe4c 100755 --- a/examples/scripts/dwl-tags.sh +++ b/examples/scripts/dwl-tags.sh @@ -136,4 +136,3 @@ done unset -v output title layout activetags selectedtags unset -v tags name - diff --git a/examples/scripts/pacman.sh b/examples/scripts/pacman.sh index a04b7a9..83e2a3f 100755 --- a/examples/scripts/pacman.sh +++ b/examples/scripts/pacman.sh @@ -15,13 +15,13 @@ # Exemples configuration: # - script: # path: /absolute/path/to/pacman.sh -# args: [] +# args: [] # content: { string: { text: "{pacman} + {aur} = {pkg}" } } # # To display a message when there is no update: # - script: # path: /absolute/path/to/pacman.sh -# args: [] +# args: [] # content: # map: # default: { string: { text: "{pacman} + {aur} = {pkg}" } } @@ -47,9 +47,9 @@ while true; do # Change interval # NUMBER[SUFFIXE] # Possible suffix: - # "s" seconds / "m" minutes / "h" hours / "d" days + # "s" seconds / "m" minutes / "h" hours / "d" days interval="1h" - + # Change your aur manager aur_helper="paru" @@ -62,7 +62,7 @@ while true; do else aur_num=$("${aur_helper}" -Qmu | wc -l) fi - + pkg_num=$(( pacman_num + aur_num )) printf -- '%s\n' "pacman|int|${pacman_num}" @@ -76,4 +76,3 @@ done unset -v interval aur_helper pacman_num aur_num pkg_num unset -f _err - From 195ac5d1cd0aad9b96f06347d9e7d374e91d099b Mon Sep 17 00:00:00 2001 From: Delgan Date: Sat, 27 Jan 2024 21:12:08 +0100 Subject: [PATCH 027/112] Fix incorrect empty/title state of i3 workspaces --- CHANGELOG.md | 2 ++ modules/i3.c | 41 ++++++++++++++++------------------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e18535..c75d270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,10 +38,12 @@ * Crash when hidden by an opaque window. * Bar not resizing itself when the screen resolution is changed ([#330][330]). +* i3/sway: incorrect empty/title state of workspaces ([#343][343]). [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 [330]: https://codeberg.org/dnkl/yambar/issues/330 +[343]: https://codeberg.org/dnkl/yambar/issues/343 ### Security diff --git a/modules/i3.c b/modules/i3.c index 65ee332..a5af4f8 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -569,12 +569,11 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m } const char *change_str = json_object_get_string(change); - bool is_new = strcmp(change_str, "new") == 0; bool is_focus = strcmp(change_str, "focus") == 0; bool is_close = strcmp(change_str, "close") == 0; bool is_title = strcmp(change_str, "title") == 0; - if (!is_new && !is_focus && !is_close && !is_title) + if (!is_focus && !is_close && !is_title) return true; mtx_lock(&mod->lock); @@ -591,27 +590,6 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m assert(focused == 1); assert(ws != NULL); - if (is_close) { - free(ws->window.title); - free(ws->window.application); - - ws->window.id = -1; - ws->window.title = ws->window.application = NULL; - ws->window.pid = -1; - - /* May not be true, but e.g. a subsequent “focus” event will - * reset it... */ - ws->empty = true; - - m->dirty = true; - mtx_unlock(&mod->lock); - return true; - - } - - /* Non-close event - thus workspace cannot be empty */ - ws->empty = false; - struct json_object *container, *id, *name; if (!json_object_object_get_ex(json, "container", &container) || !json_object_object_get_ex(container, "id", &id) || @@ -622,8 +600,21 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m return false; } - if (is_title && ws->window.id != json_object_get_int(id)) { - /* Ignore title changed event if it's not current window */ + if ((is_close || is_title) && ws->window.id != json_object_get_int(id)) { + /* Ignore close event and title changed event if it's not current window */ + mtx_unlock(&mod->lock); + return true; + } + + if (is_close) { + free(ws->window.title); + free(ws->window.application); + + ws->window.id = -1; + ws->window.title = ws->window.application = NULL; + ws->window.pid = -1; + + m->dirty = true; mtx_unlock(&mod->lock); return true; } From aeeef4f236f838becca52acea6d5797fdcf61e11 Mon Sep 17 00:00:00 2001 From: Delgan Date: Sun, 4 Feb 2024 16:11:35 +0100 Subject: [PATCH 028/112] Fix "mem" values updated while it should not Closes #352 --- CHANGELOG.md | 2 ++ modules/mem.c | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c75d270..dd2bfff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,11 +39,13 @@ * Bar not resizing itself when the screen resolution is changed ([#330][330]). * i3/sway: incorrect empty/title state of workspaces ([#343][343]). +* mem: state updated on each bar redraw ([#352][352]). [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 [330]: https://codeberg.org/dnkl/yambar/issues/330 [343]: https://codeberg.org/dnkl/yambar/issues/343 +[352]: https://codeberg.org/dnkl/yambar/issues/352 ### Security diff --git a/modules/mem.c b/modules/mem.c index 3a2eda7..6a196c6 100644 --- a/modules/mem.c +++ b/modules/mem.c @@ -24,6 +24,8 @@ struct private { struct particle *label; uint16_t interval; + uint64_t mem_free; + uint64_t mem_total; }; static void @@ -79,15 +81,12 @@ static struct exposable * content(struct module *mod) { const struct private *p = mod->private; - uint64_t mem_free = 0; - uint64_t mem_used = 0; - uint64_t mem_total = 0; - if (!get_mem_stats(&mem_free, &mem_total)) { - LOG_ERR("unable to retrieve the memory stats"); - } + mtx_lock(&mod->lock); - mem_used = mem_total - mem_free; + const uint64_t mem_free = p->mem_free; + const uint64_t mem_total = p->mem_total; + const uint64_t mem_used = mem_total - mem_free; double percent_used = ((double)mem_used * 100) / (mem_total + 1); double percent_free = ((double)mem_free * 100) / (mem_total + 1); @@ -102,6 +101,7 @@ content(struct module *mod) struct exposable *exposable = p->label->instantiate(p->label, &tags); tag_set_destroy(&tags); + mtx_unlock(&mod->lock); return exposable; } @@ -127,6 +127,13 @@ run(struct module *mod) if (fds[0].revents & POLLIN) break; + mtx_lock(&mod->lock); + p->mem_free = 0; + p->mem_total = 0; + if (!get_mem_stats(&p->mem_free, &p->mem_total)) { + LOG_ERR("unable to retrieve the memory stats"); + } + mtx_unlock(&mod->lock); bar->refresh(bar); } From f2d25c8341d4d24bc3444d1719c7dce051e2702f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 5 Feb 2024 12:52:40 +0100 Subject: [PATCH 029/112] script: fix buffer resize bug If the amount of data coming in is more than we can hold in our buffer, we resized the buffer by doubling its size. However, there were two(!) issues here: * If this was the first resize, the buffer size was set to 1024. This may not be enough (i.e. there may be more than 1024 bytes to process). * In all other cases, the buffer size was doubled. However, there is still no guarantee the buffer is large enough. Fix by looping until the buffer *is* large enough. --- CHANGELOG.md | 1 + modules/script.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd2bfff..f1d6b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ ([#330][330]). * i3/sway: incorrect empty/title state of workspaces ([#343][343]). * mem: state updated on each bar redraw ([#352][352]). +* script: buffer overflow when reading large amounts of data. [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 diff --git a/modules/script.c b/modules/script.c index 63928a6..0932cb2 100644 --- a/modules/script.c +++ b/modules/script.c @@ -298,7 +298,7 @@ data_received(struct module *mod, const char *data, size_t len) { struct private *m = mod->private; - if (len > m->recv_buf.sz - m->recv_buf.idx) { + while (len > m->recv_buf.sz - m->recv_buf.idx) { size_t new_sz = m->recv_buf.sz == 0 ? 1024 : m->recv_buf.sz * 2; char *new_buf = realloc(m->recv_buf.data, new_sz); From 89ae7bd74338206d8f14bb03082061275c76dd99 Mon Sep 17 00:00:00 2001 From: Haden Collins Date: Thu, 14 Mar 2024 16:14:53 -0500 Subject: [PATCH 030/112] Handle `reload` workspace events from sway correctly Closes #361 --- modules/i3.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/i3.c b/modules/i3.c index a5af4f8..d62db5e 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -418,10 +418,12 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void bool is_rename = strcmp(change_str, "rename") == 0; bool is_move = strcmp(change_str, "move") == 0; bool is_urgent = strcmp(change_str, "urgent") == 0; + bool is_reload = strcmp(change_str, "reload") == 0; struct json_object *current, *_current_id; - if (!json_object_object_get_ex(json, "current", ¤t) || - !json_object_object_get_ex(current, "id", &_current_id)) + if ((!json_object_object_get_ex(json, "current", ¤t) || + !json_object_object_get_ex(current, "id", &_current_id)) && + !is_reload) { LOG_ERR("workspace event without 'current' and/or 'id' properties"); return false; @@ -543,6 +545,12 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void w->urgent = json_object_get_boolean(urgent); } + else if (is_reload) { + /* Schedule full update to check if anything was changed + * during reload */ + i3_send_pkg(sock, I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL); + } + else { LOG_WARN("unimplemented workspace event '%s'", change_str); } From 7a5cf26fb502dc4b9d638062bf2eab67a3a48262 Mon Sep 17 00:00:00 2001 From: Haden Collins Date: Sat, 16 Mar 2024 10:00:24 -0500 Subject: [PATCH 031/112] Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d6b0b..7b66586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,12 +41,14 @@ * i3/sway: incorrect empty/title state of workspaces ([#343][343]). * mem: state updated on each bar redraw ([#352][352]). * script: buffer overflow when reading large amounts of data. +* i3/sway: module fails when reloading config file ([#361][361]). [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 [330]: https://codeberg.org/dnkl/yambar/issues/330 [343]: https://codeberg.org/dnkl/yambar/issues/343 [352]: https://codeberg.org/dnkl/yambar/issues/352 +[361]: https://codeberg.org/dnkl/yambar/issues/361 ### Security From 424f22ab84893c78f2865d70f6ba0604b39a1164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 18 Mar 2024 16:39:34 +0100 Subject: [PATCH 032/112] ci: rename .woodpecker.yml -> .woodpecker.yaml --- .woodpecker.yml => .woodpecker.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .woodpecker.yml => .woodpecker.yaml (100%) diff --git a/.woodpecker.yml b/.woodpecker.yaml similarity index 100% rename from .woodpecker.yml rename to .woodpecker.yaml From 4066326614a7fca98cf09f6dd2768e9949954c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 18 Mar 2024 16:40:25 +0100 Subject: [PATCH 033/112] ci: sync with woodpecker 2.x changes --- .woodpecker.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.woodpecker.yaml b/.woodpecker.yaml index 0b0cd6a..3ebe51d 100644 --- a/.woodpecker.yaml +++ b/.woodpecker.yaml @@ -1,5 +1,5 @@ steps: - codespell: + - name: codespell when: branch: - master @@ -11,7 +11,7 @@ steps: - pip install codespell - codespell README.md CHANGELOG.md *.c *.h doc/*.scd - subprojects: + - name: subprojects when: branch: - master @@ -24,12 +24,12 @@ steps: - git clone https://codeberg.org/dnkl/fcft.git - cd .. - x64: + - name: x64 when: branch: - master - releases/* - group: build + depends_on: [subprojects] image: alpine:latest commands: - apk update @@ -83,12 +83,12 @@ steps: - ./yambar --version - cd ../.. - x86: + - name: x86 when: branch: - master - releases/* - group: build + depends_on: [subprojects] image: i386/alpine:latest commands: - apk add musl-dev eudev-libs eudev-dev linux-headers meson ninja gcc scdoc From c19a31d9253f1975b9111490e28a4533b17ba420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 18 Mar 2024 16:45:41 +0100 Subject: [PATCH 034/112] ci: install and run codespell in/from a venv --- .woodpecker.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.woodpecker.yaml b/.woodpecker.yaml index 3ebe51d..ca65b29 100644 --- a/.woodpecker.yaml +++ b/.woodpecker.yaml @@ -8,8 +8,11 @@ steps: commands: - apk add python3 - apk add py3-pip + - python3 -m venv codespell-venv + - source codespell-venv/bin/activate - pip install codespell - codespell README.md CHANGELOG.md *.c *.h doc/*.scd + - deactivate - name: subprojects when: From 4e07b63cefdaa8b623ce7920e317ed8717d7c089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 18 Mar 2024 16:42:45 +0100 Subject: [PATCH 035/112] plugin: workaround gcc bug that triggers a compilation error GCC thinks str2type() returns NULL when it doesn't. Closes #350 --- CHANGELOG.md | 2 ++ plugin.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b66586..e31c0c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ * mem: state updated on each bar redraw ([#352][352]). * script: buffer overflow when reading large amounts of data. * i3/sway: module fails when reloading config file ([#361][361]). +* Worked around bug in gcc causing a compilation error ([#350][350]). [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 @@ -49,6 +50,7 @@ [343]: https://codeberg.org/dnkl/yambar/issues/343 [352]: https://codeberg.org/dnkl/yambar/issues/352 [361]: https://codeberg.org/dnkl/yambar/issues/361 +[350]: https://codeberg.org/dnkl/yambar/issues/350 ### Security diff --git a/plugin.c b/plugin.c index ed7f63c..20dfbbf 100644 --- a/plugin.c +++ b/plugin.c @@ -126,7 +126,8 @@ type2str(enum plugin_type type) case PLUGIN_DECORATION: return "decoration"; } - return NULL; + assert(false && "invalid type"); + return ""; } static void __attribute__((constructor)) From c44c66c83f1234fa3842856eba9b17714a597706 Mon Sep 17 00:00:00 2001 From: Sertonix Date: Wed, 7 Feb 2024 14:33:52 +0100 Subject: [PATCH 036/112] network: use dynlist instead of fixed name Closes #271 Closes #265 Closes #71 --- CHANGELOG.md | 4 + doc/yambar-modules-network.5.scd | 29 +- examples/configurations/laptop.conf | 41 +- modules/network.c | 851 +++++++++++++++------------- 4 files changed, 504 insertions(+), 421 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e31c0c8..44f1dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,10 @@ ### Changed * log-level: default to `warning` +* network: use dynlist instead of fixed name ([#355][355]) + +[355]: https://codeberg.org/dnkl/yambar/pulls/355 + ### Deprecated ### Removed diff --git a/doc/yambar-modules-network.5.scd b/doc/yambar-modules-network.5.scd index 44605e2..cdc5530 100644 --- a/doc/yambar-modules-network.5.scd +++ b/doc/yambar-modules-network.5.scd @@ -6,11 +6,12 @@ network - This module monitors network connection state # DESCRIPTION This module monitors network connection state; disconnected/connected -state and MAC/IP addresses. +state and MAC/IP addresses. It instantiates the provided _content_ +particle for each network interface. Note: while the module internally tracks all assigned IPv4/IPv6 addresses, it currently exposes only a single IPv4 and a single IPv6 -address. +address per network interface. # TAGS @@ -68,10 +69,18 @@ address. :[ *Type* :[ *Req* :< *Description* -| name -: string -: yes -: Name of network interface to monitor +| left-spacing +: int +: no +: Space, in pixels, in the left side of each rendered volume +| right-spacing +: int +: no +: Space, in pixels, on the right side of each rendered volume +| spacing +: int +: no +: Short-hand for setting both _left-spacing_ and _right-spacing_ | poll-interval : int : no @@ -86,9 +95,13 @@ address. bar: left: - network: - name: wlp3s0 content: - string: {text: "{name}: {state} ({ipv4})"} + map: + default: + string: {text: "{name}: {state} ({ipv4})"} + conditions: + ipv4 == "": + string: {text: "{name}: {state}"} ``` # SEE ALSO diff --git a/examples/configurations/laptop.conf b/examples/configurations/laptop.conf index 87f3d1c..cee2639 100644 --- a/examples/configurations/laptop.conf +++ b/examples/configurations/laptop.conf @@ -169,34 +169,39 @@ bar: - string: {text: , font: *awesome} - string: {text: "{layout}"} - network: - name: enp1s0 content: map: + default: {empty: {}} conditions: - ~carrier: {empty: {}} - carrier: - map: - default: {string: {text: , font: *awesome, foreground: ffffff66}} - conditions: - state == up && ipv4 != "": {string: {text: , font: *awesome}} + name == enp1s0: + conditions: + ~carrier: {empty: {}} + carrier: + map: + default: {string: {text: , font: *awesome, foreground: ffffff66}} + conditions: + state == up && ipv4 != "": {string: {text: , font: *awesome}} - network: - name: wlp2s0 poll-interval: 1000 content: map: - default: {string: {text: , font: *awesome, foreground: ffffff66}} + default: {empty: {}} conditions: - state == down: {string: {text: , font: *awesome, foreground: ff0000ff}} - state == up: + name == wlp2s0: map: - default: - - string: {text: , font: *awesome} - - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s"} - + default: {string: {text: , font: *awesome, foreground: ffffff66}} conditions: - ipv4 == "": - - string: {text: , font: *awesome, foreground: ffffff66} - - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s", foreground: ffffff66} + state == down: {string: {text: , font: *awesome, foreground: ff0000ff}} + state == up: + map: + default: + - string: {text: , font: *awesome} + - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s"} + + conditions: + ipv4 == "": + - string: {text: , font: *awesome, foreground: ffffff66} + - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s", foreground: ffffff66} - alsa: card: hw:PCH mixer: Master diff --git a/modules/network.c b/modules/network.c index 3336c23..24e811f 100644 --- a/modules/network.c +++ b/modules/network.c @@ -30,9 +30,10 @@ #include "../config.h" #include "../config-verify.h" #include "../module.h" +#include "../particles/dynlist.h" #include "../plugin.h" -#define UNUSED __attribute__((unused)) +#define max(x, y) ((x) > (y) ? (x) : (y)) static const long min_poll_interval = 250; @@ -49,25 +50,12 @@ struct af_addr { } addr; }; -struct private { - char *iface; - struct particle *label; - int poll_interval; +struct iface { + char *name; - int genl_sock; - int rt_sock; - int urandom_fd; + uint32_t get_stats_seq_nr; - struct { - uint16_t family_id; - uint32_t get_interface_seq_nr; - uint32_t get_station_seq_nr; - uint32_t get_scan_seq_nr; - } nl80211; - - bool get_addresses; - - int ifindex; + int index; uint8_t mac[6]; bool carrier; uint8_t state; /* IFLA_OPERSTATE */ @@ -88,6 +76,36 @@ struct private { uint64_t dl_bits; }; +struct private { + struct particle *label; + int poll_interval; + + int left_spacing; + int right_spacing; + + bool get_addresses; + + int genl_sock; + int rt_sock; + int urandom_fd; + + struct { + uint16_t family_id; + uint32_t get_interface_seq_nr; + uint32_t get_scan_seq_nr; + } nl80211; + + tll(struct iface) ifaces; +}; + +static void +free_iface(struct iface iface) +{ + tll_free(iface.addrs); + free(iface.ssid); + free(iface.name); +} + static void destroy(struct module *mod) { @@ -100,22 +118,17 @@ destroy(struct module *mod) if (m->urandom_fd >= 0) close(m->urandom_fd); - tll_free(m->addrs); - free(m->ssid); - free(m->iface); - free(m); + tll_foreach(m->ifaces, it) + free_iface(it->item); + free(m); module_default_destroy(mod); } static const char * description(const struct module *mod) { - static char desc[32]; - const struct private *m = mod->private; - - snprintf(desc, sizeof(desc), "net(%s)", m->iface); - return desc; + return "network"; } static struct exposable * @@ -125,70 +138,78 @@ content(struct module *mod) mtx_lock(&mod->lock); - const char *state = NULL; - switch (m->state) { - case IF_OPER_UNKNOWN: state = "unknown"; break; - case IF_OPER_NOTPRESENT: state = "not present"; break; - case IF_OPER_DOWN: state = "down"; break; - case IF_OPER_LOWERLAYERDOWN: state = "lower layers down"; break; - case IF_OPER_TESTING: state = "testing"; break; - case IF_OPER_DORMANT: state = "dormant"; break; - case IF_OPER_UP: state = "up"; break; - default: state = "unknown"; break; + struct exposable *exposables[max(tll_length(m->ifaces), 1)]; + size_t idx = 0; + + tll_foreach(m->ifaces, it) { + struct iface *iface = &it->item; + + const char *state = NULL; + switch (iface->state) { + case IF_OPER_UNKNOWN: state = "unknown"; break; + case IF_OPER_NOTPRESENT: state = "not present"; break; + case IF_OPER_DOWN: state = "down"; break; + case IF_OPER_LOWERLAYERDOWN: state = "lower layers down"; break; + case IF_OPER_TESTING: state = "testing"; break; + case IF_OPER_DORMANT: state = "dormant"; break; + case IF_OPER_UP: state = "up"; break; + default: state = "unknown"; break; + } + + char mac_str[6 * 2 + 5 + 1]; + char ipv4_str[INET_ADDRSTRLEN] = {0}; + char ipv6_str[INET6_ADDRSTRLEN] = {0}; + + snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", + iface->mac[0], iface->mac[1], iface->mac[2], iface->mac[3], iface->mac[4], iface->mac[5]); + + /* TODO: this exposes the *last* added address of each kind. Can + * we expose all in some way? */ + tll_foreach(iface->addrs, it) { + if (it->item.family == AF_INET) + inet_ntop(AF_INET, &it->item.addr.ipv4, ipv4_str, sizeof(ipv4_str)); + else if (it->item.family == AF_INET6) + if(!IN6_IS_ADDR_LINKLOCAL(&it->item.addr.ipv6)) + inet_ntop(AF_INET6, &it->item.addr.ipv6, ipv6_str, sizeof(ipv6_str)); + } + + int quality = 0; + if (iface->signal_strength_dbm != 0) { + if (iface->signal_strength_dbm <= -100) + quality = 0; + else if (iface->signal_strength_dbm >= -50) + quality = 100; + else + quality = 2 * (iface->signal_strength_dbm + 100); + } + + struct tag_set tags = { + .tags = (struct tag *[]){ + tag_new_string(mod, "name", iface->name), + tag_new_int(mod, "index", iface->index), + tag_new_bool(mod, "carrier", iface->carrier), + tag_new_string(mod, "state", state), + tag_new_string(mod, "mac", mac_str), + tag_new_string(mod, "ipv4", ipv4_str), + tag_new_string(mod, "ipv6", ipv6_str), + tag_new_string(mod, "ssid", iface->ssid), + tag_new_int(mod, "signal", iface->signal_strength_dbm), + tag_new_int_range(mod, "quality", quality, 0, 100), + tag_new_int(mod, "rx-bitrate", iface->rx_bitrate), + tag_new_int(mod, "tx-bitrate", iface->tx_bitrate), + tag_new_float(mod, "dl-speed", iface->dl_speed), + tag_new_float(mod, "ul-speed", iface->ul_speed), + }, + .count = 14, + }; + exposables[idx++] = m->label->instantiate(m->label, &tags); + tag_set_destroy(&tags); } - char mac_str[6 * 2 + 5 + 1]; - char ipv4_str[INET_ADDRSTRLEN] = {0}; - char ipv6_str[INET6_ADDRSTRLEN] = {0}; - - snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", - m->mac[0], m->mac[1], m->mac[2], m->mac[3], m->mac[4], m->mac[5]); - - /* TODO: this exposes the *last* added address of each kind. Can - * we expose all in some way? */ - tll_foreach(m->addrs, it) { - if (it->item.family == AF_INET) - inet_ntop(AF_INET, &it->item.addr.ipv4, ipv4_str, sizeof(ipv4_str)); - else if (it->item.family == AF_INET6) - if(!IN6_IS_ADDR_LINKLOCAL(&it->item.addr.ipv6)) - inet_ntop(AF_INET6, &it->item.addr.ipv6, ipv6_str, sizeof(ipv6_str)); - } - - int quality = 0; - if (m->signal_strength_dbm != 0) { - if (m->signal_strength_dbm <= -100) - quality = 0; - else if (m->signal_strength_dbm >= -50) - quality = 100; - else - quality = 2 * (m->signal_strength_dbm + 100); - } - - struct tag_set tags = { - .tags = (struct tag *[]){ - tag_new_string(mod, "name", m->iface), - tag_new_int(mod, "index", m->ifindex), - tag_new_bool(mod, "carrier", m->carrier), - tag_new_string(mod, "state", state), - tag_new_string(mod, "mac", mac_str), - tag_new_string(mod, "ipv4", ipv4_str), - tag_new_string(mod, "ipv6", ipv6_str), - tag_new_string(mod, "ssid", m->ssid), - tag_new_int(mod, "signal", m->signal_strength_dbm), - tag_new_int_range(mod, "quality", quality, 0, 100), - tag_new_int(mod, "rx-bitrate", m->rx_bitrate), - tag_new_int(mod, "tx-bitrate", m->tx_bitrate), - tag_new_float(mod, "dl-speed", m->dl_speed), - tag_new_float(mod, "ul-speed", m->ul_speed), - }, - .count = 14, - }; - mtx_unlock(&mod->lock); - struct exposable *exposable = m->label->instantiate(m->label, &tags); - tag_set_destroy(&tags); - return exposable; + return dynlist_exposable_new( + exposables, idx, m->left_spacing, m->right_spacing); } /* Returns a value suitable for nl_pid/nlmsg_pid */ @@ -279,8 +300,8 @@ send_rt_request(struct private *m, int request) }; if (!send_nlmsg(m->rt_sock, &req, req.hdr.nlmsg_len)) { - LOG_ERRNO("%s: failed to send netlink RT request (%d)", - m->iface, request); + LOG_ERRNO("failed to send netlink RT request (%d)", + request); return false; } @@ -288,8 +309,22 @@ send_rt_request(struct private *m, int request) } static bool -send_rt_getstats_request(struct private *m) +send_rt_getstats_request(struct private *m, struct iface *iface) { + if (iface->get_stats_seq_nr > 0) { + LOG_DBG( + "%s: RT get-stats request already in progress", iface->name); + return true; + } + + LOG_DBG("%s: sending RT get-stats request", iface->name); + + uint32_t seq; + if (read(m->urandom_fd, &seq, sizeof(seq)) != sizeof(seq)) { + LOG_ERRNO("failed to read from /dev/urandom"); + return false; + } + struct { struct nlmsghdr hdr; struct if_stats_msg rt; @@ -298,12 +333,12 @@ send_rt_getstats_request(struct private *m) .nlmsg_len = NLMSG_LENGTH(sizeof(req.rt)), .nlmsg_type = RTM_GETSTATS, .nlmsg_flags = NLM_F_REQUEST, - .nlmsg_seq = 1, + .nlmsg_seq = seq, .nlmsg_pid = nl_pid_value(), }, .rt = { - .ifindex = m->ifindex, + .ifindex = iface->index, .filter_mask = IFLA_STATS_LINK_64, .family = AF_UNSPEC, }, @@ -311,9 +346,10 @@ send_rt_getstats_request(struct private *m) if (!send_nlmsg(m->rt_sock, &req, req.hdr.nlmsg_len)) { LOG_ERRNO("%s: failed to send netlink RT getstats request (%d)", - m->iface, RTM_GETSTATS); + iface->name, RTM_GETSTATS); return false; } + iface->get_stats_seq_nr = seq; return true; } @@ -361,8 +397,7 @@ send_ctrl_get_family_request(struct private *m) ""); if (!send_nlmsg(m->genl_sock, &req, req.hdr.nlmsg_len)) { - LOG_ERRNO("%s: failed to send netlink ctrl-get-family request", - m->iface); + LOG_ERRNO("failed to send netlink ctrl-get-family request"); return false; } @@ -370,11 +405,69 @@ send_ctrl_get_family_request(struct private *m) } static bool -send_nl80211_request(struct private *m, uint8_t cmd, uint16_t flags, uint32_t seq) +send_nl80211_request(struct private *m, uint8_t cmd, uint32_t seq) { - if (m->ifindex < 0) + if (m->nl80211.family_id == (uint16_t)-1) return false; + const struct { + struct nlmsghdr hdr; + struct { + struct genlmsghdr genl; + } msg __attribute__((aligned(NLMSG_ALIGNTO))); + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(req.msg)), + .nlmsg_type = m->nl80211.family_id, + .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, + .nlmsg_seq = seq, + .nlmsg_pid = nl_pid_value(), + }, + + .msg = { + .genl = { + .cmd = cmd, + .version = 1, + }, + }, + }; + + if (!send_nlmsg(m->genl_sock, &req, req.hdr.nlmsg_len)) { + LOG_ERRNO("failed to send netlink nl80211 get-inteface request"); + return false; + } + + return true; +} + +static bool +send_nl80211_get_interface(struct private *m) +{ + if (m->nl80211.get_interface_seq_nr > 0) { + LOG_DBG("nl80211 get-interface request already in progress"); + return true; + } + + uint32_t seq; + if (read(m->urandom_fd, &seq, sizeof(seq)) != sizeof(seq)) { + LOG_ERRNO("failed to read from /dev/urandom"); + return false; + } + + LOG_DBG("sending nl80211 get-interface request %d", seq); + + if (!send_nl80211_request(m, NL80211_CMD_GET_INTERFACE, seq)) + return false; + + m->nl80211.get_interface_seq_nr = seq; + return true; +} + +static bool +send_nl80211_get_station(struct private *m, struct iface *iface) +{ + LOG_DBG("sending nl80211 get-station request"); + if (m->nl80211.family_id == (uint16_t)-1) return false; @@ -391,14 +484,14 @@ send_nl80211_request(struct private *m, uint8_t cmd, uint16_t flags, uint32_t se .hdr = { .nlmsg_len = NLMSG_LENGTH(sizeof(req.msg)), .nlmsg_type = m->nl80211.family_id, - .nlmsg_flags = flags, - .nlmsg_seq = seq, + .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, + .nlmsg_seq = 1, .nlmsg_pid = nl_pid_value(), }, .msg = { .genl = { - .cmd = cmd, + .cmd = NL80211_CMD_GET_STATION, .version = 1, }, @@ -408,124 +501,40 @@ send_nl80211_request(struct private *m, uint8_t cmd, uint16_t flags, uint32_t se .nla_len = sizeof(req.msg.ifindex), }, - .index = m->ifindex, + .index = iface->index, }, }, }; if (!send_nlmsg(m->genl_sock, &req, req.hdr.nlmsg_len)) { - LOG_ERRNO("%s: failed to send netlink nl80211 get-inteface request", - m->iface); + LOG_ERRNO("failed to send netlink nl80211 get-inteface request"); return false; } return true; } -static bool -send_nl80211_get_interface(struct private *m) -{ - if (m->nl80211.get_interface_seq_nr > 0) { - LOG_DBG( - "%s: nl80211 get-interface request already in progress", m->iface); - return true; - } - - LOG_DBG("%s: sending nl80211 get-interface request", m->iface); - - uint32_t seq; - if (read(m->urandom_fd, &seq, sizeof(seq)) != sizeof(seq)) { - LOG_ERRNO("failed to read from /dev/urandom"); - return false; - } - - if (send_nl80211_request(m, NL80211_CMD_GET_INTERFACE, NLM_F_REQUEST, seq)) { - m->nl80211.get_interface_seq_nr = seq; - return true; - } else - return false; -} - -static bool -send_nl80211_get_station(struct private *m) -{ - if (m->nl80211.get_station_seq_nr > 0) { - LOG_DBG( - "%s: nl80211 get-station request already in progress", m->iface); - return true; - } - - LOG_DBG("%s: sending nl80211 get-station request", m->iface); - - uint32_t seq; - if (read(m->urandom_fd, &seq, sizeof(seq)) != sizeof(seq)) { - LOG_ERRNO("failed to read from /dev/urandom"); - return false; - } - - if (send_nl80211_request( - m, NL80211_CMD_GET_STATION, NLM_F_REQUEST | NLM_F_DUMP, seq)) - { - m->nl80211.get_station_seq_nr = seq; - return true; - } else - return false; -} - static bool send_nl80211_get_scan(struct private *m) { if (m->nl80211.get_scan_seq_nr > 0) { - LOG_ERR( - "%s: nl80211 get-scan request already in progress", m->iface); + LOG_ERR("nl80211 get-scan request already in progress"); return true; } - LOG_DBG("%s: sending nl80211 get-scan request", m->iface); - uint32_t seq; if (read(m->urandom_fd, &seq, sizeof(seq)) != sizeof(seq)) { LOG_ERRNO("failed to read from /dev/urandom"); return false; } - if (send_nl80211_request( - m, NL80211_CMD_GET_SCAN, NLM_F_REQUEST | NLM_F_DUMP, seq)) - { - m->nl80211.get_scan_seq_nr = seq; - return true; - } else + LOG_DBG("sending nl80211 get-scan request %d", seq); + + if (!send_nl80211_request(m, NL80211_CMD_GET_SCAN, seq)) return false; -} -static bool -find_my_ifindex(struct module *mod, const struct ifinfomsg *msg, size_t len) -{ - struct private *m = mod->private; - - for (const struct rtattr *attr = IFLA_RTA(msg); - RTA_OK(attr, len); - attr = RTA_NEXT(attr, len)) - { - switch (attr->rta_type) { - case IFLA_IFNAME: - if (strcmp((const char *)RTA_DATA(attr), m->iface) == 0) { - LOG_INFO("%s: ifindex=%d", m->iface, msg->ifi_index); - - mtx_lock(&mod->lock); - m->ifindex = msg->ifi_index; - mtx_unlock(&mod->lock); - - send_nl80211_get_interface(m); - send_nl80211_get_station(m); - return true; - } - - return false; - } - } - - return false; + m->nl80211.get_scan_seq_nr = seq; + return true; } static void @@ -536,54 +545,73 @@ handle_link(struct module *mod, uint16_t type, struct private *m = mod->private; - if (m->ifindex == -1) { - /* We don't know our own ifindex yet. Let's see if we can find - * it in the message */ - if (!find_my_ifindex(mod, msg, len)) { - /* Nope, message wasn't for us (IFLA_IFNAME mismatch) */ - return; + if (type == RTM_DELLINK) { + tll_foreach(m->ifaces, it) { + if (msg->ifi_index != it->item.index) + continue; + mtx_lock(&mod->lock); + tll_remove_and_free(m->ifaces, it, free_iface); + mtx_unlock(&mod->lock); + break; } - } - assert(m->ifindex >= 0); - - if (msg->ifi_index != m->ifindex) { - /* Not for us */ + mod->bar->refresh(mod->bar); return; } - bool update_bar = false; + struct iface *iface = NULL; + tll_foreach(m->ifaces, it) { + if (msg->ifi_index != it->item.index) + continue; + iface = &it->item; + break; + } + + if (iface == NULL) { + mtx_lock(&mod->lock); + tll_push_back(m->ifaces, + ((struct iface){ + .index = msg->ifi_index, + .state = IF_OPER_DOWN, + .addrs = tll_init(), + })); + mtx_unlock(&mod->lock); + iface = &tll_back(m->ifaces); + } for (const struct rtattr *attr = IFLA_RTA(msg); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) { switch (attr->rta_type) { + case IFLA_IFNAME: + mtx_lock(&mod->lock); + iface->name = strdup((const char *)RTA_DATA(attr)); + LOG_DBG("%s: index=%d", iface->name, iface->index); + mtx_unlock(&mod->lock); case IFLA_OPERSTATE: { uint8_t operstate = *(const uint8_t *)RTA_DATA(attr); - if (m->state == operstate) + if (iface->state == operstate) break; - LOG_DBG("%s: IFLA_OPERSTATE: %hhu -> %hhu", m->iface, m->state, operstate); + LOG_DBG("%s: IFLA_OPERSTATE: %hhu -> %hhu", iface->name, iface->state, operstate); mtx_lock(&mod->lock); - m->state = operstate; + iface->state = operstate; mtx_unlock(&mod->lock); - update_bar = true; break; } case IFLA_CARRIER: { uint8_t carrier = *(const uint8_t *)RTA_DATA(attr); - if (m->carrier == carrier) + if (iface->carrier == carrier) break; - LOG_DBG("%s: IFLA_CARRIER: %hhu -> %hhu", m->iface, m->carrier, carrier); + LOG_DBG("%s: IFLA_CARRIER: %hhu -> %hhu", iface->name, iface->carrier, carrier); mtx_lock(&mod->lock); - m->carrier = carrier; + iface->carrier = carrier; mtx_unlock(&mod->lock); - update_bar = true; break; } @@ -592,24 +620,28 @@ handle_link(struct module *mod, uint16_t type, break; const uint8_t *mac = RTA_DATA(attr); - if (memcmp(m->mac, mac, sizeof(m->mac)) == 0) + if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0) break; LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", - m->iface, + iface->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); mtx_lock(&mod->lock); - memcpy(m->mac, mac, sizeof(m->mac)); + memcpy(iface->mac, mac, sizeof(iface->mac)); mtx_unlock(&mod->lock); - update_bar = true; break; } } } - if (update_bar) - mod->bar->refresh(mod->bar); + assert(iface->name != NULL); + + /* Reset address initialization */ + m->get_addresses = true; + + send_nl80211_get_interface(m); + mod->bar->refresh(mod->bar); } static void @@ -620,14 +652,21 @@ handle_address(struct module *mod, uint16_t type, struct private *m = mod->private; - assert(m->ifindex >= 0); + bool update_bar = false; - if (msg->ifa_index != m->ifindex) { - /* Not for us */ - return; + struct iface *iface = NULL; + + tll_foreach(m->ifaces, it) { + if (msg->ifa_index != it->item.index) + continue; + iface = &it->item; + break; } - bool update_bar = false; + if (iface == NULL) { + LOG_ERR("failed to find network interface with index %d. Probaly a yambar bug", msg->ifa_index); + return; + } for (const struct rtattr *attr = IFA_RTA(msg); RTA_OK(attr, len); @@ -642,21 +681,21 @@ handle_address(struct module *mod, uint16_t type, char s[INET6_ADDRSTRLEN]; inet_ntop(msg->ifa_family, raw_addr, s, sizeof(s)); #endif - LOG_DBG("%s: IFA_ADDRESS (%s): %s", m->iface, + LOG_DBG("%s: IFA_ADDRESS (%s): %s", iface->name, type == RTM_NEWADDR ? "add" : "del", s); mtx_lock(&mod->lock); if (type == RTM_DELADDR) { /* Find address in our list and remove it */ - tll_foreach(m->addrs, it) { + tll_foreach(iface->addrs, it) { if (it->item.family != msg->ifa_family) continue; if (memcmp(&it->item.addr, raw_addr, addr_len) != 0) continue; - tll_remove(m->addrs, it); + tll_remove(iface->addrs, it); update_bar = true; break; } @@ -664,7 +703,7 @@ handle_address(struct module *mod, uint16_t type, /* Append address to our list */ struct af_addr a = {.family = msg->ifa_family}; memcpy(&a.addr, raw_addr, addr_len); - tll_push_back(m->addrs, a); + tll_push_back(iface->addrs, a); update_bar = true; } @@ -679,9 +718,10 @@ handle_address(struct module *mod, uint16_t type, } static bool -foreach_nlattr(struct module *mod, const struct genlmsghdr *genl, size_t len, - bool (*cb)(struct module *mod, uint16_t type, bool nested, - const void *payload, size_t len)) +foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len, + bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, + const void *payload, size_t len, void *ctx), + void *ctx) { const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN; const uint8_t *end = (const uint8_t *)genl + len; @@ -694,7 +734,7 @@ foreach_nlattr(struct module *mod, const struct genlmsghdr *genl, size_t len, bool nested = (attr->nla_type & NLA_F_NESTED) != 0;; const void *payload = raw + NLA_HDRLEN; - if (!cb(mod, type, nested, payload, attr->nla_len - NLA_HDRLEN)) + if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) return false; } @@ -702,8 +742,8 @@ foreach_nlattr(struct module *mod, const struct genlmsghdr *genl, size_t len, } static bool -foreach_nlattr_nested(struct module *mod, const void *parent_payload, size_t len, - bool (*cb)(struct module *mod, uint16_t type, +foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len, + bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, void *ctx), void *ctx) @@ -719,7 +759,7 @@ foreach_nlattr_nested(struct module *mod, const void *parent_payload, size_t len bool nested = (attr->nla_type & NLA_F_NESTED) != 0; const void *payload = raw + NLA_HDRLEN; - if (!cb(mod, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) + if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) return false; } @@ -732,10 +772,9 @@ struct mcast_group { }; static bool -parse_mcast_group(struct module *mod, uint16_t type, bool nested, +parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, void *_ctx) { - struct private *m = mod->private; struct mcast_group *ctx = _ctx; switch (type) { @@ -750,8 +789,8 @@ parse_mcast_group(struct module *mod, uint16_t type, bool nested, } default: - LOG_WARN("%s: unrecognized GENL MCAST GRP attribute: " - "type=%hu, nested=%d, len=%zu", m->iface, type, nested, len); + LOG_WARN("unrecognized GENL MCAST GRP attribute: " + "type=%hu, nested=%d, len=%zu", type, nested, len); break; } @@ -759,13 +798,13 @@ parse_mcast_group(struct module *mod, uint16_t type, bool nested, } static bool -parse_mcast_groups(struct module *mod, uint16_t type, bool nested, +parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, void *_ctx) { struct private *m = mod->private; struct mcast_group group = {0}; - foreach_nlattr_nested(mod, payload, len, &parse_mcast_group, &group); + foreach_nlattr_nested(mod, NULL, payload, len, &parse_mcast_group, &group); LOG_DBG("MCAST: %s -> %u", group.name, group.id); @@ -787,8 +826,8 @@ parse_mcast_groups(struct module *mod, uint16_t type, bool nested, } static bool -handle_genl_ctrl(struct module *mod, uint16_t type, bool nested, - const void *payload, size_t len) +handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool nested, + const void *payload, size_t len, void *_ctx) { struct private *m = mod->private; @@ -796,7 +835,6 @@ handle_genl_ctrl(struct module *mod, uint16_t type, bool nested, case CTRL_ATTR_FAMILY_ID: { m->nl80211.family_id = *(const uint16_t *)payload; send_nl80211_get_interface(m); - send_nl80211_get_station(m); break; } @@ -805,12 +843,38 @@ handle_genl_ctrl(struct module *mod, uint16_t type, bool nested, break; case CTRL_ATTR_MCAST_GROUPS: - foreach_nlattr_nested(mod, payload, len, &parse_mcast_groups, NULL); + foreach_nlattr_nested(mod, NULL, payload, len, &parse_mcast_groups, NULL); break; default: - LOG_DBG("%s: unrecognized GENL CTRL attribute: " - "type=%hu, nested=%d, len=%zu", m->iface, type, nested, len); + LOG_DBG("unrecognized GENL CTRL attribute: " + "type=%hu, nested=%d, len=%zu", type, nested, len); + break; + } + + return true; +} + + +static bool +find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool nested, + const void *payload, size_t len, void *ctx) +{ + struct private *m = mod->private; + struct iface **iface = ctx; + + switch (type) { + case NL80211_ATTR_IFINDEX: + if (*iface != NULL) + if (*(uint32_t *)payload == (*iface)->index) + return false; + tll_foreach(m->ifaces, it) { + if (*(uint32_t *)payload != it->item.index) + continue; + *iface = &it->item; + return false; + } + LOG_ERR("could not find interface with index %d", *(uint32_t *)payload); break; } @@ -818,46 +882,23 @@ handle_genl_ctrl(struct module *mod, uint16_t type, bool nested, } static bool -check_for_nl80211_ifindex(struct module *mod, uint16_t type, bool nested, - const void *payload, size_t len) +handle_nl80211_new_interface(struct module *mod, struct iface *iface, uint16_t type, bool nested, + const void *payload, size_t len, void *_ctx) { - struct private *m = mod->private; - switch (type) { case NL80211_ATTR_IFINDEX: - return *(uint32_t *)payload == m->ifindex; - } - - return true; -} - -static bool -nl80211_is_for_us(struct module *mod, const struct genlmsghdr *genl, - size_t msg_size) -{ - return foreach_nlattr(mod, genl, msg_size, &check_for_nl80211_ifindex); -} - -static bool -handle_nl80211_new_interface(struct module *mod, uint16_t type, bool nested, - const void *payload, size_t len) -{ - struct private *m = mod->private; - - switch (type) { - case NL80211_ATTR_IFINDEX: - assert(*(uint32_t *)payload == m->ifindex); + assert(*(uint32_t *)payload == iface->index); break; case NL80211_ATTR_SSID: { const char *ssid = payload; - if (m->ssid == NULL || strncmp(m->ssid, ssid, len) != 0) - LOG_INFO("%s: SSID: %.*s", m->iface, (int)len, ssid); + if (iface->ssid == NULL || strncmp(iface->ssid, ssid, len) != 0) + LOG_INFO("%s: SSID: %.*s", iface->name, (int)len, ssid); mtx_lock(&mod->lock); - free(m->ssid); - m->ssid = strndup(ssid, len); + free(iface->ssid); + iface->ssid = strndup(ssid, len); mtx_unlock(&mod->lock); mod->bar->refresh(mod->bar); @@ -866,7 +907,7 @@ handle_nl80211_new_interface(struct module *mod, uint16_t type, bool nested, default: LOG_DBG("%s: unrecognized nl80211 attribute: " - "type=%hu, nested=%d, len=%zu", m->iface, type, nested, len); + "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); break; } @@ -878,10 +919,9 @@ struct rate_info_ctx { }; static bool -handle_nl80211_rate_info(struct module *mod, uint16_t type, bool nested, +handle_nl80211_rate_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, void *_ctx) { - struct private *m UNUSED = mod->private; struct rate_info_ctx *ctx = _ctx; switch (type) { @@ -902,7 +942,7 @@ handle_nl80211_rate_info(struct module *mod, uint16_t type, bool nested, default: LOG_DBG("%s: unrecognized nl80211 rate info attribute: " - "type=%hu, nested=%d, len=%zu", m->iface, type, nested, len); + "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); break; } @@ -914,10 +954,9 @@ struct station_info_ctx { }; static bool -handle_nl80211_station_info(struct module *mod, uint16_t type, bool nested, +handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, void *_ctx) { - struct private *m = mod->private; struct station_info_ctx *ctx = _ctx; switch (type) { @@ -925,23 +964,22 @@ handle_nl80211_station_info(struct module *mod, uint16_t type, bool nested, LOG_DBG("signal strength (last): %hhd dBm", *(uint8_t *)payload); break; - case NL80211_STA_INFO_SIGNAL_AVG: { + case NL80211_STA_INFO_SIGNAL_AVG: LOG_DBG("signal strength (average): %hhd dBm", *(uint8_t *)payload); mtx_lock(&mod->lock); - m->signal_strength_dbm = *(int8_t *)payload; + iface->signal_strength_dbm = *(int8_t *)payload; mtx_unlock(&mod->lock); ctx->update_bar = true; break; - } case NL80211_STA_INFO_TX_BITRATE: { struct rate_info_ctx rctx = {0}; foreach_nlattr_nested( - mod, payload, len, &handle_nl80211_rate_info, &rctx); + mod, iface, payload, len, &handle_nl80211_rate_info, &rctx); LOG_DBG("TX bitrate: %.1f Mbit/s", rctx.bitrate / 1000. / 1000.); mtx_lock(&mod->lock); - m->tx_bitrate = rctx.bitrate; + iface->tx_bitrate = rctx.bitrate; mtx_unlock(&mod->lock); ctx->update_bar = true; break; @@ -950,11 +988,11 @@ handle_nl80211_station_info(struct module *mod, uint16_t type, bool nested, case NL80211_STA_INFO_RX_BITRATE: { struct rate_info_ctx rctx = {0}; foreach_nlattr_nested( - mod, payload, len, &handle_nl80211_rate_info, &rctx); + mod, iface, payload, len, &handle_nl80211_rate_info, &rctx); LOG_DBG("RX bitrate: %.1f Mbit/s", rctx.bitrate / 1000. / 1000.); mtx_lock(&mod->lock); - m->rx_bitrate = rctx.bitrate; + iface->rx_bitrate = rctx.bitrate; mtx_unlock(&mod->lock); ctx->update_bar = true; break; @@ -962,7 +1000,7 @@ handle_nl80211_station_info(struct module *mod, uint16_t type, bool nested, default: LOG_DBG("%s: unrecognized nl80211 station info attribute: " - "type=%hu, nested=%d, len=%zu", m->iface, type, nested, len); + "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); break; } @@ -970,16 +1008,17 @@ handle_nl80211_station_info(struct module *mod, uint16_t type, bool nested, } static bool -handle_nl80211_new_station(struct module *mod, uint16_t type, bool nested, - const void *payload, size_t len) +handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t type, bool nested, + const void *payload, size_t len, void *_ctx) { - struct private *m UNUSED = mod->private; - switch (type) { + case NL80211_ATTR_IFINDEX: + break; + case NL80211_ATTR_STA_INFO: { struct station_info_ctx ctx = {0}; foreach_nlattr_nested( - mod, payload, len, &handle_nl80211_station_info, &ctx); + mod, iface, payload, len, &handle_nl80211_station_info, &ctx); if (ctx.update_bar) mod->bar->refresh(mod->bar); @@ -988,7 +1027,7 @@ handle_nl80211_new_station(struct module *mod, uint16_t type, bool nested, default: LOG_DBG("%s: unrecognized nl80211 attribute: " - "type=%hu, nested=%d, len=%zu", m->iface, type, nested, len); + "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); break; } @@ -996,9 +1035,8 @@ handle_nl80211_new_station(struct module *mod, uint16_t type, bool nested, } static bool -handle_ies(struct module *mod, const void *_ies, size_t len) +handle_ies(struct module *mod, struct iface *iface, const void *_ies, size_t len) { - struct private *m = mod->private; const uint8_t *ies = _ies; while (len >= 2 && len - 2 >= ies[1]) { @@ -1007,12 +1045,12 @@ handle_ies(struct module *mod, const void *_ies, size_t len) const char *ssid = (const char *)&ies[2]; const size_t ssid_len = ies[1]; - if (m->ssid == NULL || strncmp(m->ssid, ssid, ssid_len) != 0) - LOG_INFO("%s: SSID: %.*s", m->iface, (int)ssid_len, ssid); + if (iface->ssid == NULL || strncmp(iface->ssid, ssid, ssid_len) != 0) + LOG_INFO("%s: SSID: %.*s", iface->name, (int)ssid_len, ssid); mtx_lock(&mod->lock); - free(m->ssid); - m->ssid = strndup(ssid, ssid_len); + free(iface->ssid); + iface->ssid = strndup(ssid, ssid_len); mtx_unlock(&mod->lock); mod->bar->refresh(mod->bar); @@ -1034,10 +1072,9 @@ struct scan_results_context { }; static bool -handle_nl80211_bss(struct module *mod, uint16_t type, bool nested, +handle_nl80211_bss(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, void *_ctx) { - struct private *m UNUSED = mod->private; struct scan_results_context *ctx = _ctx; switch (type) { @@ -1049,7 +1086,7 @@ handle_nl80211_bss(struct module *mod, uint16_t type, bool nested, if (ctx->ies != NULL) { /* Deferred handling of BSS_INFORMATION_ELEMENTS */ - return handle_ies(mod, ctx->ies, ctx->ies_size); + return handle_ies(mod, iface, ctx->ies, ctx->ies_size); } } break; @@ -1057,7 +1094,7 @@ handle_nl80211_bss(struct module *mod, uint16_t type, bool nested, case NL80211_BSS_INFORMATION_ELEMENTS: if (ctx->associated) - return handle_ies(mod, payload, len); + return handle_ies(mod, iface, payload, len); else { /* * We’re either not associated, or, we haven’t seen the @@ -1076,16 +1113,14 @@ handle_nl80211_bss(struct module *mod, uint16_t type, bool nested, } static bool -handle_nl80211_scan_results(struct module *mod, uint16_t type, bool nested, - const void *payload, size_t len) +handle_nl80211_scan_results(struct module *mod, struct iface *iface, uint16_t type, bool nested, + const void *payload, size_t len, void *_ctx) { - struct private *m UNUSED = mod->private; - struct scan_results_context ctx = {0}; switch (type) { case NL80211_ATTR_BSS: - foreach_nlattr_nested(mod, payload, len, &handle_nl80211_bss, &ctx); + foreach_nlattr_nested(mod, iface, payload, len, &handle_nl80211_bss, &ctx); break; } @@ -1131,21 +1166,38 @@ netlink_receive_messages(int sock, void **reply, size_t *len) } static void -handle_stats(struct module *mod, struct rt_stats_msg *msg) +handle_stats(struct module *mod, uint32_t seq, struct rt_stats_msg *msg) { struct private *m = mod->private; + + struct iface *iface = NULL; + + tll_foreach(m->ifaces, it) { + if (seq != it->item.get_stats_seq_nr) + continue; + iface = &it->item; + /* Current request is now considered complete */ + iface->get_stats_seq_nr = 0; + break; + } + + if (iface == NULL) { + LOG_ERR("Couldn't find iface"); + return; + } + uint64_t ul_bits = msg->stats.tx_bytes * 8; uint64_t dl_bits = msg->stats.rx_bytes * 8; const double poll_interval_secs = (double)m->poll_interval / 1000.; - if (m->ul_bits != 0) - m->ul_speed = (double)(ul_bits - m->ul_bits) / poll_interval_secs; - if (m->dl_bits != 0) - m->dl_speed = (double)(dl_bits - m->dl_bits) / poll_interval_secs; + if (iface->ul_bits != 0) + iface->ul_speed = (double)(ul_bits - iface->ul_bits) / poll_interval_secs; + if (iface->dl_bits != 0) + iface->dl_speed = (double)(dl_bits - iface->dl_bits) / poll_interval_secs; - m->ul_bits = ul_bits; - m->dl_bits = dl_bits; + iface->ul_bits = ul_bits; + iface->dl_bits = dl_bits; } static bool @@ -1155,15 +1207,12 @@ parse_rt_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) /* Process response */ for (; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) { + switch (hdr->nlmsg_type) { case NLMSG_DONE: - if (m->ifindex == -1) { - LOG_ERR("%s: failed to find interface", m->iface); - return false; - } /* Request initial list of IPv4/6 addresses */ - if (m->get_addresses && m->ifindex != -1) { + if (m->get_addresses) { m->get_addresses = false; send_rt_request(m, RTM_GETADDR); } @@ -1188,20 +1237,20 @@ parse_rt_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) } case RTM_NEWSTATS: { struct rt_stats_msg *msg = NLMSG_DATA(hdr); - handle_stats(mod, msg); + handle_stats(mod, hdr->nlmsg_seq, msg); break; } case NLMSG_ERROR:{ const struct nlmsgerr *err = NLMSG_DATA(hdr); - LOG_ERRNO_P(-err->error, "%s: netlink RT reply", m->iface); + LOG_ERRNO_P(-err->error, "netlink RT reply"); return false; } default: LOG_WARN( - "%s: unrecognized netlink message type: 0x%x", - m->iface, hdr->nlmsg_type); + "unrecognized netlink message type: 0x%x", + hdr->nlmsg_type); return false; } } @@ -1213,29 +1262,35 @@ static bool parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) { struct private *m = mod->private; + struct iface *iface = NULL; for (; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) { + if (hdr->nlmsg_type == GENL_ID_CTRL) { + assert(hdr->nlmsg_seq == 1); + const struct genlmsghdr *genl = NLMSG_DATA(hdr); + const size_t msg_size = NLMSG_PAYLOAD(hdr, 0); + foreach_nlattr(mod, NULL, genl, msg_size, &handle_genl_ctrl, NULL); + continue; + } + if (hdr->nlmsg_seq == m->nl80211.get_interface_seq_nr) { /* Current request is now considered complete */ m->nl80211.get_interface_seq_nr = 0; + + /* Can’t issue both get-station and get-scan at the + * same time. So, always run a get-scan when a + * get-station is complete */ + send_nl80211_get_scan(m); } if (hdr->nlmsg_type == NLMSG_DONE) { - if (hdr->nlmsg_seq == m->nl80211.get_station_seq_nr) { - /* Current request is now considered complete */ - m->nl80211.get_station_seq_nr = 0; - } - - else if (hdr->nlmsg_seq == m->nl80211.get_scan_seq_nr) { + if (hdr->nlmsg_seq == m->nl80211.get_scan_seq_nr) { /* Current request is now considered complete */ m->nl80211.get_scan_seq_nr = 0; - } - } - else if (hdr->nlmsg_type == GENL_ID_CTRL) { - const struct genlmsghdr *genl = NLMSG_DATA(hdr); - const size_t msg_size = NLMSG_PAYLOAD(hdr, 0); - foreach_nlattr(mod, genl, msg_size, &handle_genl_ctrl); + tll_foreach(m->ifaces, it) + send_nl80211_get_station(m, &it->item); + } } else if (hdr->nlmsg_type == m->nl80211.family_id) { @@ -1244,11 +1299,12 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) switch (genl->cmd) { case NL80211_CMD_NEW_INTERFACE: - if (nl80211_is_for_us(mod, genl, msg_size)) { - LOG_DBG("%s: got interface information", m->iface); - foreach_nlattr( - mod, genl, msg_size, &handle_nl80211_new_interface); - } + if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) + continue; + + LOG_DBG("%s: got interface information", iface->name); + foreach_nlattr( + mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL); break; case NL80211_CMD_CONNECT: @@ -1262,49 +1318,43 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) * * Thus, we need to explicitly request an update. */ - if (nl80211_is_for_us(mod, genl, msg_size)) { - LOG_DBG("%s: connected, requesting interface information", - m->iface); - send_nl80211_get_interface(m); - send_nl80211_get_station(m); - } + LOG_DBG("connected, requesting interface information"); + send_nl80211_get_interface(m); break; case NL80211_CMD_DISCONNECT: - if (nl80211_is_for_us(mod, genl, msg_size)) { - LOG_DBG("%s: disconnected, resetting SSID etc", m->iface); + if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) + continue; - mtx_lock(&mod->lock); - free(m->ssid); - m->ssid = NULL; - m->signal_strength_dbm = 0; - m->rx_bitrate = m->tx_bitrate = 0; - mtx_unlock(&mod->lock); - } + LOG_DBG("%s: disconnected, resetting SSID etc", iface->name); + + mtx_lock(&mod->lock); + free(iface->ssid); + iface->ssid = NULL; + iface->signal_strength_dbm = 0; + iface->rx_bitrate = iface->tx_bitrate = 0; + mtx_unlock(&mod->lock); break; case NL80211_CMD_NEW_STATION: - if (nl80211_is_for_us(mod, genl, msg_size)) { - LOG_DBG("%s: got station information", m->iface); - foreach_nlattr(mod, genl, msg_size, &handle_nl80211_new_station); - } + if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) + continue; + + LOG_DBG("%s: got station information", iface->name); + foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_station, NULL); LOG_DBG("%s: signal: %d dBm, RX=%u Mbit/s, TX=%u Mbit/s", - m->iface, m->signal_strength_dbm, - m->rx_bitrate / 1000 / 1000, - m->tx_bitrate / 1000 / 1000); - - /* Can’t issue both get-station and get-scan at the - * same time. So, always run a get-scan when a - * get-station is complete */ - send_nl80211_get_scan(m); + iface->name, iface->signal_strength_dbm, + iface->rx_bitrate / 1000 / 1000, + iface->tx_bitrate / 1000 / 1000); break; case NL80211_CMD_NEW_SCAN_RESULTS: - if (nl80211_is_for_us(mod, genl, msg_size)) { - LOG_DBG("%s: got scan results", m->iface); - foreach_nlattr(mod, genl, msg_size, &handle_nl80211_scan_results); - } + if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) + continue; + + LOG_DBG("%s: got scan results", iface->name); + foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_scan_results, NULL); break; default: @@ -1321,15 +1371,16 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) ; /* iface is not an nl80211 device */ else if (nl_errno == ENOENT) ; /* iface down? */ - else - LOG_ERRNO_P(nl_errno, "%s: nl80211 reply (seq-nr: %u)", - m->iface, hdr->nlmsg_seq); + else { + LOG_ERRNO_P(nl_errno, "nl80211 reply (seq-nr: %u)", + hdr->nlmsg_seq); + } } else { LOG_WARN( - "%s: unrecognized netlink message type: 0x%x", - m->iface, hdr->nlmsg_type); + "unrecognized netlink message type: 0x%x", + hdr->nlmsg_type); return false; } } @@ -1347,7 +1398,7 @@ run(struct module *mod) if (m->poll_interval > 0) { timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timer_fd < 0) { - LOG_ERRNO("%s: failed to create poll timer FD", m->iface); + LOG_ERRNO("failed to create poll timer FD"); goto out; } @@ -1360,7 +1411,7 @@ run(struct module *mod) }; if (timerfd_settime(timer_fd, 0, &poll_time, NULL) < 0) { - LOG_ERRNO("%s: failed to arm poll timer", m->iface); + LOG_ERRNO("failed to arm poll timer"); goto out; } } @@ -1394,12 +1445,12 @@ run(struct module *mod) if ((fds[1].revents & POLLHUP) || (fds[2].revents & POLLHUP)) { - LOG_ERR("%s: disconnected from netlink socket", m->iface); + LOG_ERR("disconnected from netlink socket"); break; } if (fds[3].revents & POLLHUP) { - LOG_ERR("%s: disconnected from timer FD", m->iface); + LOG_ERR("disconnected from timer FD"); break; } @@ -1442,8 +1493,10 @@ run(struct module *mod) break; } - send_nl80211_get_station(m); - send_rt_getstats_request(m); + tll_foreach(m->ifaces, it) { + send_nl80211_get_station(m, &it->item); + send_rt_getstats_request(m, &it->item); + }; } } @@ -1461,7 +1514,7 @@ run(struct module *mod) } static struct module * -network_new(const char *iface, struct particle *label, int poll_interval) +network_new(struct particle *label, int poll_interval, int left_spacing, int right_spacing) { int urandom_fd = open("/dev/urandom", O_RDONLY); if (urandom_fd < 0) { @@ -1470,17 +1523,16 @@ network_new(const char *iface, struct particle *label, int poll_interval) } struct private *priv = calloc(1, sizeof(*priv)); - priv->iface = strdup(iface); priv->label = label; priv->poll_interval = poll_interval; + priv->left_spacing = left_spacing; + priv->right_spacing = right_spacing; priv->genl_sock = -1; priv->rt_sock = -1; priv->urandom_fd = urandom_fd; + priv->get_addresses = false; priv->nl80211.family_id = -1; - priv->get_addresses = true; - priv->ifindex = -1; - priv->state = IF_OPER_DOWN; struct module *mod = module_common_new(); mod->private = priv; @@ -1494,13 +1546,20 @@ network_new(const char *iface, struct particle *label, int poll_interval) static struct module * from_conf(const struct yml_node *node, struct conf_inherit inherited) { - const struct yml_node *name = yml_get_value(node, "name"); const struct yml_node *content = yml_get_value(node, "content"); const struct yml_node *poll = yml_get_value(node, "poll-interval"); + const struct yml_node *spacing = yml_get_value(node, "spacing"); + const struct yml_node *left_spacing = yml_get_value(node, "left-spacing"); + const struct yml_node *right_spacing = yml_get_value(node, "right-spacing"); + + int left = spacing != NULL ? yml_value_as_int(spacing) : + left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; + int right = spacing != NULL ? yml_value_as_int(spacing) : + right_spacing != NULL ? yml_value_as_int(right_spacing) : 0; return network_new( - yml_value_as_string(name), conf_to_particle(content, inherited), - poll != NULL ? yml_value_as_int(poll) : 0); + conf_to_particle(content, inherited), + poll != NULL ? yml_value_as_int(poll) : 0, left, right); } static bool @@ -1523,7 +1582,9 @@ static bool verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { - {"name", true, &conf_verify_string}, + {"spacing", false, &conf_verify_unsigned}, + {"left-spacing", false, &conf_verify_unsigned}, + {"right-spacing", false, &conf_verify_unsigned}, {"poll-interval", false, &conf_verify_poll_interval}, MODULE_COMMON_ATTRS, }; From 53dec73ed2c6be7411551db5533860c928e557f4 Mon Sep 17 00:00:00 2001 From: Delgan Date: Sun, 31 Mar 2024 18:53:57 +0000 Subject: [PATCH 037/112] Fix miscalculation of list width in presence of empty particles --- CHANGELOG.md | 2 ++ particles/dynlist.c | 7 ++++--- particles/list.c | 7 ++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44f1dad..b181fca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ * script: buffer overflow when reading large amounts of data. * i3/sway: module fails when reloading config file ([#361][361]). * Worked around bug in gcc causing a compilation error ([#350][350]). +* Miscalculation of list width in presence of empty particles ([#369][369]). [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 @@ -55,6 +56,7 @@ [352]: https://codeberg.org/dnkl/yambar/issues/352 [361]: https://codeberg.org/dnkl/yambar/issues/361 [350]: https://codeberg.org/dnkl/yambar/issues/350 +[369]: https://codeberg.org/dnkl/yambar/issues/369 ### Security diff --git a/particles/dynlist.c b/particles/dynlist.c index 5b64dbe..85cad7b 100644 --- a/particles/dynlist.c +++ b/particles/dynlist.c @@ -71,7 +71,8 @@ dynlist_expose(const struct exposable *exposable, pixman_image_t *pix, int x, in for (size_t i = 0; i < e->count; i++) { const struct exposable *ee = e->exposables[i]; ee->expose(ee, pix, x + left_spacing, y, height); - x += left_spacing + e->widths[i] + right_spacing; + if (e->widths[i] > 0) + x += left_spacing + e->widths[i] + right_spacing; } } @@ -95,8 +96,8 @@ on_mouse(struct exposable *exposable, struct bar *bar, } return; } - - px += e->left_spacing + e->exposables[i]->width + e->right_spacing; + if (e->exposables[i]->width > 0) + px += e->left_spacing + e->exposables[i]->width + e->right_spacing; } LOG_DBG("on_mouse missed all sub-particles"); diff --git a/particles/list.c b/particles/list.c index a2c37c6..2887d3c 100644 --- a/particles/list.c +++ b/particles/list.c @@ -80,7 +80,8 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int for (size_t i = 0; i < e->count; i++) { const struct exposable *ee = e->exposables[i]; ee->expose(ee, pix, x + left_spacing, y, height); - x += left_spacing + e->widths[i] + right_spacing; + if (e->widths[i] > 0) + x += left_spacing + e->widths[i] + right_spacing; } } @@ -109,8 +110,8 @@ on_mouse(struct exposable *exposable, struct bar *bar, } return; } - - px += e->left_spacing + e->exposables[i]->width + e->right_spacing; + if (e->exposables[i]->width > 0) + px += e->left_spacing + e->exposables[i]->width + e->right_spacing; } /* We're between sub-particles (or in the left/right margin) */ From 58c397d15416faa50c76edef08f334ede293f17a Mon Sep 17 00:00:00 2001 From: Delgan Date: Mon, 1 Apr 2024 08:39:17 +0000 Subject: [PATCH 038/112] Fix CI failing due to outdated test config file --- test/full-conf-good.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/full-conf-good.yml b/test/full-conf-good.yml index d89d494..a6f6e99 100644 --- a/test/full-conf-good.yml +++ b/test/full-conf-good.yml @@ -39,8 +39,13 @@ bar: host: 127.0.0.1 content: {string: {text: "{state}"}} - network: - name: ldsjfdf - content: {string: {text: "{name}"}} + content: + map: + default: + string: {text: "{name}: {state} ({ipv4})"} + conditions: + ipv4 == "": + string: {text: "{name}: {state}"} - removables: content: {string: {text: "{label}"}} # - xkb: From da19c091222c0af48795db14550093786fa28b64 Mon Sep 17 00:00:00 2001 From: Delgan Date: Mon, 1 Apr 2024 08:53:50 +0000 Subject: [PATCH 039/112] Add missing "dynlist" dependency to network module --- modules/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/meson.build b/modules/meson.build index f8d1e80..e2ed56e 100644 --- a/modules/meson.build +++ b/modules/meson.build @@ -98,7 +98,7 @@ if plugin_label_enabled endif if plugin_network_enabled - mod_data += {'network': [[], []]} + mod_data += {'network': [[], [dynlist]]} endif if plugin_pipewire_enabled From 28a18ad91e67e67d634f82d431c6b2ceab905640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 5 Apr 2024 16:11:37 +0200 Subject: [PATCH 040/112] log: fix syslog not respecting the configured log level --- CHANGELOG.md | 1 + log.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b181fca..2d01729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ * i3/sway: module fails when reloading config file ([#361][361]). * Worked around bug in gcc causing a compilation error ([#350][350]). * Miscalculation of list width in presence of empty particles ([#369][369]). +* Log-level not respected by syslog. [311]: https://codeberg.org/dnkl/yambar/issues/311 [302]: https://codeberg.org/dnkl/yambar/issues/302 diff --git a/log.c b/log.c index 5864853..2d454a8 100644 --- a/log.c +++ b/log.c @@ -15,7 +15,7 @@ #define UNUSED __attribute__((unused)) static bool colorize = false; -static bool do_syslog = true; +static bool do_syslog = false; static enum log_class log_level = LOG_CLASS_NONE; static const struct { @@ -102,6 +102,9 @@ _sys_log(enum log_class log_class, const char *module, if (!do_syslog) return; + if (log_class > log_level) + return; + /* Map our log level to syslog's level */ int level = log_level_map[log_class].syslog_equivalent; From d841aeeecd41077a9ff51ea184dc926f7181d90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 6 Apr 2024 15:39:19 +0200 Subject: [PATCH 041/112] config: layer: add 'overlay' and 'background' The layer option (Wayland only) now accepts 'overlay' and 'background'. Closes #372 --- CHANGELOG.md | 3 +++ bar/bar.h | 2 +- bar/wayland.c | 23 ++++++++++++++++++++--- config-verify.c | 4 +++- config.c | 6 +++++- doc/yambar.5.scd | 3 ++- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d01729..09f8c93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,8 +20,11 @@ * network: new `quality` tag (Wi-Fi only). * Read alternative config from pipes and FIFOs (e.g. `--config /dev/stdin`) ([#340][340]). +* Added `overlay` and `background` as possible `layer` values + ([#372][372]). [340]: https://codeberg.org/dnkl/yambar/pulls/340 +[372]: https://codeberg.org/dnkl/yambar/issues/372 ### Changed diff --git a/bar/bar.h b/bar/bar.h index 717b690..ce91247 100644 --- a/bar/bar.h +++ b/bar/bar.h @@ -18,7 +18,7 @@ struct bar { }; enum bar_location { BAR_TOP, BAR_BOTTOM }; -enum bar_layer { BAR_LAYER_TOP, BAR_LAYER_BOTTOM }; +enum bar_layer { BAR_LAYER_OVERLAY, BAR_LAYER_TOP, BAR_LAYER_BOTTOM, BAR_LAYER_BACKGROUND }; enum bar_backend { BAR_BACKEND_AUTO, BAR_BACKEND_XCB, BAR_BACKEND_WAYLAND }; struct bar_config { diff --git a/bar/wayland.c b/bar/wayland.c index 22ca3e2..7b6575b 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -814,9 +814,26 @@ create_surface(struct wayland_backend *backend) wl_surface_add_listener(backend->surface, &surface_listener, backend); - enum zwlr_layer_shell_v1_layer layer = bar->layer == BAR_LAYER_BOTTOM - ? ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM - : ZWLR_LAYER_SHELL_V1_LAYER_TOP; + + enum zwlr_layer_shell_v1_layer layer; + + switch (bar->layer) { + case BAR_LAYER_BACKGROUND: + layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; + break; + + case BAR_LAYER_BOTTOM: + layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; + break; + + case BAR_LAYER_TOP: + layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP; + break; + + case BAR_LAYER_OVERLAY: + layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; + break; + } backend->layer_surface = zwlr_layer_shell_v1_get_layer_surface( backend->layer_shell, backend->surface, diff --git a/config-verify.c b/config-verify.c index 9b4fad7..d4211f1 100644 --- a/config-verify.c +++ b/config-verify.c @@ -453,7 +453,9 @@ verify_bar_location(keychain_t *chain, const struct yml_node *node) static bool verify_bar_layer(keychain_t *chain, const struct yml_node *node) { - return conf_verify_enum(chain, node, (const char *[]){"top", "bottom"}, 2); + return conf_verify_enum( + chain, node, + (const char *[]){"overlay", "top", "bottom", "background"}, 4); } bool diff --git a/config.c b/config.c index 2ad305f..a0eba59 100644 --- a/config.c +++ b/config.c @@ -340,10 +340,14 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) const struct yml_node *layer = yml_get_value(bar, "layer"); if (layer != NULL) { const char *tmp = yml_value_as_string(layer); - if (strcmp(tmp, "top") == 0) + if (strcmp(tmp, "overlay") == 0) + conf.layer = BAR_LAYER_OVERLAY; + else if (strcmp(tmp, "top") == 0) conf.layer = BAR_LAYER_TOP; else if (strcmp(tmp, "bottom") == 0) conf.layer = BAR_LAYER_BOTTOM; + else if (strcmp(tmp, "background") == 0) + conf.layer = BAR_LAYER_BACKGROUND; else assert(false); } diff --git a/doc/yambar.5.scd b/doc/yambar.5.scd index 3cc9557..1b06939 100644 --- a/doc/yambar.5.scd +++ b/doc/yambar.5.scd @@ -49,7 +49,8 @@ types that are frequently used: | layer : string : no -: Layer to put bar on. One of _top_ or _bottom_. Wayland only +: Layer to put bar on. One of _overlay_, _top_, _bottom_ or + _background_. Wayland only. Default: _bottom_. | left-spacing : int : no From b85ba99980312114b591d5ae837afe20db5e4480 Mon Sep 17 00:00:00 2001 From: Delgan Date: Sun, 7 Apr 2024 10:05:10 +0200 Subject: [PATCH 042/112] Apply "clang-format" preferences globally --- .clang-format | 7 + bar/backend.h | 6 +- bar/bar.c | 77 +++----- bar/private.h | 3 +- bar/wayland.c | 366 +++++++++++++++---------------------- bar/xcb.c | 208 ++++++++------------- char32.c | 15 +- char32.h | 2 +- config-verify.c | 115 ++++-------- config-verify.h | 7 +- config.c | 113 ++++-------- config.h | 7 +- decoration.h | 9 +- decorations/background.c | 11 +- decorations/border.c | 32 ++-- decorations/overline.c | 9 +- decorations/stack.c | 17 +- decorations/underline.c | 10 +- log.c | 42 ++--- log.h | 71 +++---- main.c | 53 +++--- module.c | 2 +- module.h | 12 +- modules/alsa.c | 223 +++++++++------------- modules/backlight.c | 23 ++- modules/battery.c | 105 +++++------ modules/clock.c | 50 ++--- modules/cpu.c | 68 +++---- modules/disk-io.c | 56 +++--- modules/dwl.c | 16 +- modules/foreign-toplevel.c | 149 +++++++-------- modules/i3-common.c | 57 +++--- modules/i3-common.h | 6 +- modules/i3.c | 214 +++++++++------------- modules/label.c | 8 +- modules/mem.c | 7 +- modules/mpd.c | 126 ++++++------- modules/network.c | 317 +++++++++++++++----------------- modules/pipewire.c | 8 +- modules/pulse.c | 87 +++------ modules/removables.c | 224 +++++++++++------------ modules/river.c | 174 +++++++----------- modules/script.c | 86 +++------ modules/sway-xkb.c | 49 ++--- modules/xkb.c | 145 +++++---------- modules/xwindow.c | 80 ++++---- particle.c | 63 +++---- particle.h | 47 ++--- particles/dynlist.c | 16 +- particles/dynlist.h | 4 +- particles/empty.c | 5 +- particles/list.c | 43 ++--- particles/map.c | 180 +++++++++--------- particles/map.h | 2 +- particles/progress-bar.c | 59 +++--- particles/ramp.c | 56 +++--- particles/string.c | 48 ++--- plugin.c | 132 +++++++------ plugin.h | 8 +- tag.c | 118 ++++++------ tag.h | 17 +- xcb.c | 82 ++++----- yml.c | 186 ++++++++----------- yml.h | 8 +- 64 files changed, 1868 insertions(+), 2678 deletions(-) diff --git a/.clang-format b/.clang-format index 528a36b..2436e90 100644 --- a/.clang-format +++ b/.clang-format @@ -3,6 +3,7 @@ BasedOnStyle: GNU IndentWidth: 4 --- Language: Cpp +Standard: Auto PointerAlignment: Right ColumnLimit: 120 BreakBeforeBraces: Custom @@ -15,3 +16,9 @@ BraceWrapping: SpaceBeforeParens: ControlStatements Cpp11BracedListStyle: true + +WhitespaceSensitiveMacros: + - REGISTER_CORE_PARTICLE + - REGISTER_CORE_DECORATION + - REGISTER_CORE_PLUGIN + - REGISTER_CORE_MODULE diff --git a/bar/backend.h b/bar/backend.h index 47fae95..b7a9fcb 100644 --- a/bar/backend.h +++ b/bar/backend.h @@ -7,10 +7,8 @@ struct backend { bool (*setup)(struct bar *bar); void (*cleanup)(struct bar *bar); - void (*loop)(struct bar *bar, - void (*expose)(const struct bar *bar), - void (*on_mouse)(struct bar *bar, enum mouse_event event, - enum mouse_button btn, int x, int y)); + void (*loop)(struct bar *bar, void (*expose)(const struct bar *bar), + void (*on_mouse)(struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y)); void (*commit)(const struct bar *bar); void (*refresh)(const struct bar *bar); void (*set_cursor)(struct bar *bar, const char *cursor); diff --git a/bar/bar.c b/bar/bar.c index 10e0785..3890bc0 100644 --- a/bar/bar.c +++ b/bar/bar.c @@ -1,15 +1,15 @@ #include "bar.h" #include "private.h" -#include -#include -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include +#include +#include #include @@ -18,11 +18,11 @@ #include "../log.h" #if defined(ENABLE_X11) - #include "xcb.h" +#include "xcb.h" #endif #if defined(ENABLE_WAYLAND) - #include "wayland.h" +#include "wayland.h" #endif #define max(x, y) ((x) > (y) ? (x) : (y)) @@ -75,9 +75,8 @@ expose(const struct bar *_bar) const struct private *bar = _bar->private; pixman_image_t *pix = bar->pix; - pixman_image_fill_rectangles( - PIXMAN_OP_SRC, pix, &bar->background, 1, - &(pixman_rectangle16_t){0, 0, bar->width, bar->height_with_border}); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, pix, &bar->background, 1, + &(pixman_rectangle16_t){0, 0, bar->width, bar->height_with_border}); pixman_image_fill_rectangles( PIXMAN_OP_OVER, pix, &bar->border.color, 4, @@ -86,20 +85,15 @@ expose(const struct bar *_bar) {0, 0, bar->border.left_width, bar->height_with_border}, /* Right */ - {bar->width - bar->border.right_width, - 0, bar->border.right_width, bar->height_with_border}, + {bar->width - bar->border.right_width, 0, bar->border.right_width, bar->height_with_border}, /* Top */ - {bar->border.left_width, - 0, - bar->width - bar->border.left_width - bar->border.right_width, + {bar->border.left_width, 0, bar->width - bar->border.left_width - bar->border.right_width, bar->border.top_width}, /* Bottom */ - {bar->border.left_width, - bar->height_with_border - bar->border.bottom_width, - bar->width - bar->border.left_width - bar->border.right_width, - bar->border.bottom_width}, + {bar->border.left_width, bar->height_with_border - bar->border.bottom_width, + bar->width - bar->border.left_width - bar->border.right_width, bar->border.bottom_width}, }); for (size_t i = 0; i < bar->left.count; i++) { @@ -136,12 +130,8 @@ expose(const struct bar *_bar) int x = bar->border.left_width + bar->left_margin - bar->left_spacing; pixman_region32_t clip; pixman_region32_init_rect( - &clip, - bar->border.left_width + bar->left_margin, - bar->border.top_width, - (bar->width - - bar->left_margin - bar->right_margin - - bar->border.left_width - bar->border.right_width), + &clip, bar->border.left_width + bar->left_margin, bar->border.top_width, + (bar->width - bar->left_margin - bar->right_margin - bar->border.left_width - bar->border.right_width), bar->height); pixman_image_set_clip_region32(pix, &clip); pixman_region32_fini(&clip); @@ -161,11 +151,7 @@ expose(const struct bar *_bar) x += bar->left_spacing + e->width + bar->right_spacing; } - x = bar->width - ( - right_width + - bar->left_spacing + - bar->right_margin + - bar->border.right_width); + x = bar->width - (right_width + bar->left_spacing + bar->right_margin + bar->border.right_width); for (size_t i = 0; i < bar->right.count; i++) { const struct exposable *e = bar->right.exps[i]; @@ -177,7 +163,6 @@ expose(const struct bar *_bar) bar->backend.iface->commit(_bar); } - static void refresh(const struct bar *bar) { @@ -200,15 +185,12 @@ output_name(const struct bar *bar) } static void -on_mouse(struct bar *_bar, enum mouse_event event, enum mouse_button btn, - int x, int y) +on_mouse(struct bar *_bar, enum mouse_event event, enum mouse_button btn, int x, int y) { struct private *bar = _bar->private; - if ((y < bar->border.top_width || - y >= (bar->height_with_border - bar->border.bottom_width)) || - (x < bar->border.left_width || x >= (bar->width - bar->border.right_width))) - { + if ((y < bar->border.top_width || y >= (bar->height_with_border - bar->border.bottom_width)) + || (x < bar->border.left_width || x >= (bar->width - bar->border.right_width))) { set_cursor(_bar, "left_ptr"); return; } @@ -250,10 +232,7 @@ on_mouse(struct bar *_bar, enum mouse_event event, enum mouse_button btn, mx += e->width + bar->right_spacing; } - mx = bar->width - (right_width + - bar->left_spacing + - bar->right_margin + - bar->border.right_width); + mx = bar->width - (right_width + bar->left_spacing + bar->right_margin + bar->border.right_width); for (size_t i = 0; i < bar->right.count; i++) { struct exposable *e = bar->right.exps[i]; @@ -294,8 +273,7 @@ run(struct bar *_bar) { struct private *bar = _bar->private; - bar->height_with_border = - bar->height + bar->border.top_width + bar->border.bottom_width; + bar->height_with_border = bar->height + bar->border.top_width + bar->border.bottom_width; if (!bar->backend.iface->setup(_bar)) { bar->backend.iface->cleanup(_bar); @@ -347,8 +325,7 @@ run(struct bar *_bar) thrd_join(thrd_left[i], &mod_ret); if (mod_ret != 0) { const struct module *m = bar->left.mods[i]; - LOG_ERR("module: LEFT #%zu (%s): non-zero exit value: %d", - i, m->description(m), mod_ret); + LOG_ERR("module: LEFT #%zu (%s): non-zero exit value: %d", i, m->description(m), mod_ret); } ret = ret == 0 && mod_ret != 0 ? mod_ret : ret; } @@ -356,8 +333,7 @@ run(struct bar *_bar) thrd_join(thrd_center[i], &mod_ret); if (mod_ret != 0) { const struct module *m = bar->center.mods[i]; - LOG_ERR("module: CENTER #%zu (%s): non-zero exit value: %d", - i, m->description(m), mod_ret); + LOG_ERR("module: CENTER #%zu (%s): non-zero exit value: %d", i, m->description(m), mod_ret); } ret = ret == 0 && mod_ret != 0 ? mod_ret : ret; } @@ -365,8 +341,7 @@ run(struct bar *_bar) thrd_join(thrd_right[i], &mod_ret); if (mod_ret != 0) { const struct module *m = bar->right.mods[i]; - LOG_ERR("module: RIGHT #%zu (%s): non-zero exit value: %d", - i, m->description(m), mod_ret); + LOG_ERR("module: RIGHT #%zu (%s): non-zero exit value: %d", i, m->description(m), mod_ret); } ret = ret == 0 && mod_ret != 0 ? mod_ret : ret; } diff --git a/bar/private.h b/bar/private.h index f216c99..d48b07f 100644 --- a/bar/private.h +++ b/bar/private.h @@ -3,7 +3,8 @@ #include "../bar/bar.h" #include "backend.h" -struct private { +struct private +{ /* From bar_config */ char *monitor; enum bar_layer layer; diff --git a/bar/wayland.c b/bar/wayland.c index 7b6575b..50dc62d 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -1,25 +1,25 @@ #include "wayland.h" +#include +#include +#include +#include #include #include #include -#include #include -#include -#include -#include -#include #include #include +#include #include #include #include #include -#include #include +#include #define LOG_MODULE "bar:wayland" #define LOG_ENABLE_DBG 0 @@ -29,7 +29,7 @@ #include "private.h" #if !defined(MFD_NOEXEC_SEAL) - #define MFD_NOEXEC_SEAL 0 +#define MFD_NOEXEC_SEAL 0 #endif struct buffer { @@ -116,16 +116,15 @@ struct wayland_backend { /* We're already waiting for a frame done callback */ bool render_scheduled; - tll(struct buffer) buffers; /* List of SHM buffers */ - struct buffer *next_buffer; /* Bar is rendering to this one */ - struct buffer *pending_buffer; /* Finished, but not yet rendered */ + tll(struct buffer) buffers; /* List of SHM buffers */ + struct buffer *next_buffer; /* Bar is rendering to this one */ + struct buffer *pending_buffer; /* Finished, but not yet rendered */ struct wl_callback *frame_callback; double aggregated_scroll; bool have_discrete; - void (*bar_on_mouse)(struct bar *bar, enum mouse_event event, - enum mouse_button btn, int x, int y); + void (*bar_on_mouse)(struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y); }; static void @@ -157,7 +156,7 @@ bar_backend_wayland_new(void) static void shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) { - //printf("SHM format: 0x%08x\n", format); + // printf("SHM format: 0x%08x\n", format); } static const struct wl_shm_listener shm_listener = { @@ -167,10 +166,7 @@ static const struct wl_shm_listener shm_listener = { static void update_cursor_surface(struct wayland_backend *backend, struct seat *seat) { - if (seat->pointer.serial == 0 || - seat->pointer.cursor == NULL || - seat->pointer.surface == NULL) - { + if (seat->pointer.serial == 0 || seat->pointer.cursor == NULL || seat->pointer.surface == NULL) { return; } @@ -179,17 +175,12 @@ update_cursor_surface(struct wayland_backend *backend, struct seat *seat) const int scale = seat->pointer.scale; wl_surface_set_buffer_scale(seat->pointer.surface, scale); - wl_surface_attach( - seat->pointer.surface, wl_cursor_image_get_buffer(image), 0, 0); + wl_surface_attach(seat->pointer.surface, wl_cursor_image_get_buffer(image), 0, 0); - wl_pointer_set_cursor( - seat->wl_pointer, seat->pointer.serial, - seat->pointer.surface, - image->hotspot_x / scale, image->hotspot_y / scale); + wl_pointer_set_cursor(seat->wl_pointer, seat->pointer.serial, seat->pointer.surface, image->hotspot_x / scale, + image->hotspot_y / scale); - - wl_surface_damage_buffer( - seat->pointer.surface, 0, 0, INT32_MAX, INT32_MAX); + wl_surface_damage_buffer(seat->pointer.surface, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(seat->pointer.surface); wl_display_flush(backend->display); @@ -219,11 +210,9 @@ reload_cursor_theme(struct seat *seat, int new_scale) } } - LOG_INFO("%s: cursor theme: %s, size: %u, scale: %d", - seat->name, cursor_theme, cursor_size, new_scale); + LOG_INFO("%s: cursor theme: %s, size: %u, scale: %d", seat->name, cursor_theme, cursor_size, new_scale); - struct wl_cursor_theme *theme = wl_cursor_theme_load( - cursor_theme, cursor_size * new_scale, seat->backend->shm); + struct wl_cursor_theme *theme = wl_cursor_theme_load(cursor_theme, cursor_size * new_scale, seat->backend->shm); if (theme == NULL) { LOG_ERR("%s: failed to load cursor theme", seat->name); @@ -235,8 +224,7 @@ reload_cursor_theme(struct seat *seat, int new_scale) } static void -wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, +wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { struct seat *seat = data; @@ -252,8 +240,7 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, } static void -wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) +wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) { struct seat *seat = data; struct wayland_backend *backend = seat->backend; @@ -265,8 +252,7 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, } static void -wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) +wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { struct seat *seat = data; struct wayland_backend *backend = seat->backend; @@ -275,14 +261,12 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, seat->pointer.y = wl_fixed_to_int(surface_y) * backend->scale; backend->active_seat = seat; - backend->bar_on_mouse( - backend->bar, ON_MOUSE_MOTION, MOUSE_BTN_NONE, - seat->pointer.x, seat->pointer.y); + backend->bar_on_mouse(backend->bar, ON_MOUSE_MOTION, MOUSE_BTN_NONE, seat->pointer.x, seat->pointer.y); } static void -wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, uint32_t time, uint32_t button, uint32_t state) +wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, + uint32_t state) { struct seat *seat = data; struct wayland_backend *backend = seat->backend; @@ -293,23 +277,31 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, enum mouse_button btn; switch (button) { - case BTN_LEFT: btn = MOUSE_BTN_LEFT; break; - case BTN_MIDDLE: btn = MOUSE_BTN_MIDDLE; break; - case BTN_RIGHT: btn = MOUSE_BTN_RIGHT; break; - case BTN_SIDE: btn = MOUSE_BTN_PREVIOUS; break; - case BTN_EXTRA: btn = MOUSE_BTN_NEXT; break; + case BTN_LEFT: + btn = MOUSE_BTN_LEFT; + break; + case BTN_MIDDLE: + btn = MOUSE_BTN_MIDDLE; + break; + case BTN_RIGHT: + btn = MOUSE_BTN_RIGHT; + break; + case BTN_SIDE: + btn = MOUSE_BTN_PREVIOUS; + break; + case BTN_EXTRA: + btn = MOUSE_BTN_NEXT; + break; default: return; } - backend->bar_on_mouse( - backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); + backend->bar_on_mouse(backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); } } static void -wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) +wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) return; @@ -325,24 +317,18 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, const double amount = wl_fixed_to_double(value); - if ((backend->aggregated_scroll > 0 && amount < 0) || - (backend->aggregated_scroll < 0 && amount > 0)) - { + if ((backend->aggregated_scroll > 0 && amount < 0) || (backend->aggregated_scroll < 0 && amount > 0)) { backend->aggregated_scroll = amount; } else backend->aggregated_scroll += amount; - enum mouse_button btn = backend->aggregated_scroll > 0 - ? MOUSE_BTN_WHEEL_DOWN - : MOUSE_BTN_WHEEL_UP; + enum mouse_button btn = backend->aggregated_scroll > 0 ? MOUSE_BTN_WHEEL_DOWN : MOUSE_BTN_WHEEL_UP; const double step = bar->trackpad_sensitivity; const double adjust = backend->aggregated_scroll > 0 ? -step : step; while (fabs(backend->aggregated_scroll) >= step) { - backend->bar_on_mouse( - backend->bar, ON_MOUSE_CLICK, btn, - seat->pointer.x, seat->pointer.y); + backend->bar_on_mouse(backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); backend->aggregated_scroll += adjust; } } @@ -356,14 +342,12 @@ wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) } static void -wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, - uint32_t axis_source) +wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source) { } static void -wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis) +wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) { if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) return; @@ -374,8 +358,7 @@ wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, } static void -wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, - uint32_t axis, int32_t discrete) +wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) { if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) return; @@ -384,16 +367,12 @@ wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, struct wayland_backend *backend = seat->backend; backend->have_discrete = true; - enum mouse_button btn = discrete > 0 - ? MOUSE_BTN_WHEEL_DOWN - : MOUSE_BTN_WHEEL_UP; + enum mouse_button btn = discrete > 0 ? MOUSE_BTN_WHEEL_DOWN : MOUSE_BTN_WHEEL_UP; int count = abs(discrete); for (int32_t i = 0; i < count; i++) { - backend->bar_on_mouse( - backend->bar, ON_MOUSE_CLICK, btn, - seat->pointer.x, seat->pointer.y); + backend->bar_on_mouse(backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); } } @@ -410,16 +389,14 @@ static const struct wl_pointer_listener pointer_listener = { }; static void -seat_handle_capabilities(void *data, struct wl_seat *wl_seat, - enum wl_seat_capability caps) +seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { struct seat *seat = data; if (caps & WL_SEAT_CAPABILITY_POINTER) { if (seat->wl_pointer == NULL) { assert(seat->pointer.surface == NULL); - seat->pointer.surface = wl_compositor_create_surface( - seat->backend->compositor); + seat->pointer.surface = wl_compositor_create_surface(seat->backend->compositor); if (seat->pointer.surface == NULL) { LOG_ERR("%s: failed to create pointer surface", seat->name); @@ -459,10 +436,8 @@ static const struct wl_seat_listener seat_listener = { }; static void -output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, - int32_t physical_width, int32_t physical_height, - int32_t subpixel, const char *make, const char *model, - int32_t transform) +output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t physical_width, + int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t transform) { struct monitor *mon = data; mon->width_mm = physical_width; @@ -470,8 +445,7 @@ output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, } static void -output_mode(void *data, struct wl_output *wl_output, uint32_t flags, - int32_t width, int32_t height, int32_t refresh) +output_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { } @@ -516,8 +490,7 @@ output_name(void *data, struct wl_output *wl_output, const char *name) #if defined(WL_OUTPUT_DESCRIPTION_SINCE_VERSION) static void -output_description(void *data, struct wl_output *wl_output, - const char *description) +output_description(void *data, struct wl_output *wl_output, const char *description) { } #endif @@ -536,9 +509,7 @@ static const struct wl_output_listener output_listener = { }; static void -xdg_output_handle_logical_position(void *data, - struct zxdg_output_v1 *xdg_output, - int32_t x, int32_t y) +xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) { struct monitor *mon = data; mon->x = x; @@ -546,8 +517,7 @@ xdg_output_handle_logical_position(void *data, } static void -xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, - int32_t width, int32_t height) +xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) { struct monitor *mon = data; mon->width_px = width; @@ -562,9 +532,8 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) { const struct monitor *mon = data; - LOG_INFO("monitor: %s: %dx%d+%d+%d (%dx%dmm)", - mon->name, mon->width_px, mon->height_px, - mon->x, mon->y, mon->width_mm, mon->height_mm); + LOG_INFO("monitor: %s: %dx%d+%d+%d (%dx%dmm)", mon->name, mon->width_px, mon->height_px, mon->x, mon->y, + mon->width_mm, mon->height_mm); struct wayland_backend *backend = mon->backend; struct private *bar = backend->bar->private; @@ -576,15 +545,11 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) return; } - const bool output_is_our_configured_monitor = ( - bar->monitor != NULL && - mon->name != NULL && - strcmp(bar->monitor, mon->name) == 0); + const bool output_is_our_configured_monitor + = (bar->monitor != NULL && mon->name != NULL && strcmp(bar->monitor, mon->name) == 0); - const bool output_is_last_mapped = ( - backend->last_mapped_monitor != NULL && - mon->name != NULL && - strcmp(backend->last_mapped_monitor, mon->name) == 0); + const bool output_is_last_mapped = (backend->last_mapped_monitor != NULL && mon->name != NULL + && strcmp(backend->last_mapped_monitor, mon->name) == 0); if (output_is_our_configured_monitor) LOG_DBG("%s: using this monitor (user configured)", mon->name); @@ -606,8 +571,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) } static void -xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, - const char *name) +xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name) { struct monitor *mon = data; free(mon->name); @@ -615,8 +579,7 @@ xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, } static void -xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, - const char *description) +xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, const char *description) { } @@ -634,14 +597,12 @@ verify_iface_version(const char *iface, uint32_t version, uint32_t wanted) if (version >= wanted) return true; - LOG_ERR("%s: need interface version %u, but compositor only implements %u", - iface, wanted, version); + LOG_ERR("%s: need interface version %u, but compositor only implements %u", iface, wanted, version); return false; } static void -handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) +handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { LOG_DBG("global: 0x%08x, interface=%s, version=%u", name, interface, version); struct wayland_backend *backend = data; @@ -651,8 +612,7 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - backend->compositor = wl_registry_bind( - registry, name, &wl_compositor_interface, required); + backend->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, required); } else if (strcmp(interface, wl_shm_interface.name) == 0) { @@ -660,8 +620,7 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - backend->shm = wl_registry_bind( - registry, name, &wl_shm_interface, required); + backend->shm = wl_registry_bind(registry, name, &wl_shm_interface, required); wl_shm_add_listener(backend->shm, &shm_listener, backend); } @@ -670,13 +629,9 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - struct wl_output *output = wl_registry_bind( - registry, name, &wl_output_interface, required); + struct wl_output *output = wl_registry_bind(registry, name, &wl_output_interface, required); - tll_push_back(backend->monitors, ((struct monitor){ - .backend = backend, - .wl_name = name, - .output = output})); + tll_push_back(backend->monitors, ((struct monitor){.backend = backend, .wl_name = name, .output = output})); struct monitor *mon = &tll_back(backend->monitors); wl_output_add_listener(output, &output_listener, mon); @@ -689,8 +644,7 @@ handle_global(void *data, struct wl_registry *registry, assert(backend->xdg_output_manager != NULL); if (backend->xdg_output_manager != NULL) { - mon->xdg = zxdg_output_manager_v1_get_xdg_output( - backend->xdg_output_manager, mon->output); + mon->xdg = zxdg_output_manager_v1_get_xdg_output(backend->xdg_output_manager, mon->output); zxdg_output_v1_add_listener(mon->xdg, &xdg_output_listener, mon); } @@ -701,8 +655,7 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - backend->layer_shell = wl_registry_bind( - registry, name, &zwlr_layer_shell_v1_interface, required); + backend->layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, required); } else if (strcmp(interface, wl_seat_interface.name) == 0) { @@ -710,12 +663,10 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - struct wl_seat *seat = wl_registry_bind( - registry, name, &wl_seat_interface, required); + struct wl_seat *seat = wl_registry_bind(registry, name, &wl_seat_interface, required); assert(seat != NULL); - tll_push_back( - backend->seats, ((struct seat){.backend = backend, .seat = seat, .id = name})); + tll_push_back(backend->seats, ((struct seat){.backend = backend, .seat = seat, .id = name})); wl_seat_add_listener(seat, &seat_listener, &tll_back(backend->seats)); } @@ -725,8 +676,7 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - backend->xdg_output_manager = wl_registry_bind( - registry, name, &zxdg_output_manager_v1_interface, required); + backend->xdg_output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, required); } } @@ -735,7 +685,8 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) { struct wayland_backend *backend = data; - tll_foreach(backend->seats, it) { + tll_foreach(backend->seats, it) + { if (it->item.id == name) { if (backend->active_seat == &it->item) backend->active_seat = NULL; @@ -745,7 +696,8 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) } } - tll_foreach(backend->monitors, it) { + tll_foreach(backend->monitors, it) + { struct monitor *mon = &it->item; if (mon->wl_name == name) { LOG_INFO("%s disconnected/disabled", mon->name); @@ -770,8 +722,7 @@ static const struct wl_registry_listener registry_listener = { }; static void -layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, - uint32_t serial, uint32_t w, uint32_t h) +layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h) { struct wayland_backend *backend = data; backend->width = w * backend->scale; @@ -814,7 +765,6 @@ create_surface(struct wayland_backend *backend) wl_surface_add_listener(backend->surface, &surface_listener, backend); - enum zwlr_layer_shell_v1_layer layer; switch (bar->layer) { @@ -836,28 +786,22 @@ create_surface(struct wayland_backend *backend) } backend->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - backend->layer_shell, backend->surface, - backend->monitor != NULL ? backend->monitor->output : NULL, - layer, "panel"); + backend->layer_shell, backend->surface, backend->monitor != NULL ? backend->monitor->output : NULL, layer, + "panel"); if (backend->layer_surface == NULL) { LOG_ERR("failed to create layer shell surface"); return false; } - zwlr_layer_surface_v1_add_listener( - backend->layer_surface, &layer_surface_listener, backend); + zwlr_layer_surface_v1_add_listener(backend->layer_surface, &layer_surface_listener, backend); /* Aligned to top, maximum width */ - enum zwlr_layer_surface_v1_anchor top_or_bottom = bar->location == BAR_TOP - ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP - : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + enum zwlr_layer_surface_v1_anchor top_or_bottom + = bar->location == BAR_TOP ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; - zwlr_layer_surface_v1_set_anchor( - backend->layer_surface, - ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - top_or_bottom); + zwlr_layer_surface_v1_set_anchor(backend->layer_surface, ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT + | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | top_or_bottom); return true; } @@ -890,7 +834,7 @@ destroy_surface(struct wayland_backend *backend) static void buffer_release(void *data, struct wl_buffer *wl_buffer) { - //printf("buffer release\n"); + // printf("buffer release\n"); struct buffer *buffer = data; assert(buffer->busy); buffer->busy = false; @@ -903,7 +847,8 @@ static const struct wl_buffer_listener buffer_listener = { static struct buffer * get_buffer(struct wayland_backend *backend) { - tll_foreach(backend->buffers, it) { + tll_foreach(backend->buffers, it) + { if (!it->item.busy && it->item.width == backend->width && it->item.height == backend->height) { it->item.busy = true; return &it->item; @@ -936,13 +881,10 @@ get_buffer(struct wayland_backend *backend) * *with* it, and if that fails, try again *without* it. */ errno = 0; - pool_fd = memfd_create( - "yambar-wayland-shm-buffer-pool", - MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL); + pool_fd = memfd_create("yambar-wayland-shm-buffer-pool", MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL); if (pool_fd < 0 && errno == EINVAL) { - pool_fd = memfd_create( - "yambar-wayland-shm-buffer-pool", MFD_CLOEXEC | MFD_ALLOW_SEALING); + pool_fd = memfd_create("yambar-wayland-shm-buffer-pool", MFD_CLOEXEC | MFD_ALLOW_SEALING); } #elif defined(__FreeBSD__) // memfd_create on FreeBSD 13 is SHM_ANON without sealing support @@ -958,8 +900,7 @@ get_buffer(struct wayland_backend *backend) } /* Total size */ - const uint32_t stride = stride_for_format_and_width( - PIXMAN_a8r8g8b8, backend->width); + const uint32_t stride = stride_for_format_and_width(PIXMAN_a8r8g8b8, backend->width); size = stride * backend->height; if (ftruncate(pool_fd, size) == -1) { @@ -976,9 +917,7 @@ get_buffer(struct wayland_backend *backend) #if defined(MEMFD_CREATE) /* Seal file - we no longer allow any kind of resizing */ /* TODO: wayland mmaps(PROT_WRITE), for some unknown reason, hence we cannot use F_SEAL_FUTURE_WRITE */ - if (fcntl(pool_fd, F_ADD_SEALS, - F_SEAL_GROW | F_SEAL_SHRINK | /*F_SEAL_FUTURE_WRITE |*/ F_SEAL_SEAL) < 0) - { + if (fcntl(pool_fd, F_ADD_SEALS, F_SEAL_GROW | F_SEAL_SHRINK | /*F_SEAL_FUTURE_WRITE |*/ F_SEAL_SEAL) < 0) { LOG_ERRNO("failed to seal SHM backing memory file"); /* This is not a fatal error */ } @@ -990,37 +929,35 @@ get_buffer(struct wayland_backend *backend) goto err; } - buf = wl_shm_pool_create_buffer( - pool, 0, backend->width, backend->height, stride, WL_SHM_FORMAT_ARGB8888); + buf = wl_shm_pool_create_buffer(pool, 0, backend->width, backend->height, stride, WL_SHM_FORMAT_ARGB8888); if (buf == NULL) { LOG_ERR("failed to create SHM buffer"); goto err; } /* We use the entire pool for our single buffer */ - wl_shm_pool_destroy(pool); pool = NULL; - close(pool_fd); pool_fd = -1; + wl_shm_pool_destroy(pool); + pool = NULL; + close(pool_fd); + pool_fd = -1; - pix = pixman_image_create_bits_no_clear( - PIXMAN_a8r8g8b8, backend->width, backend->height, (uint32_t *)mmapped, stride); + pix = pixman_image_create_bits_no_clear(PIXMAN_a8r8g8b8, backend->width, backend->height, (uint32_t *)mmapped, + stride); if (pix == NULL) { LOG_ERR("failed to create pixman image"); goto err; } /* Push to list of available buffers, but marked as 'busy' */ - tll_push_back( - backend->buffers, - ((struct buffer){ - .busy = true, - .width = backend->width, - .height = backend->height, - .size = size, - .mmapped = mmapped, - .wl_buf = buf, - .pix = pix, - }) - ); + tll_push_back(backend->buffers, ((struct buffer){ + .busy = true, + .width = backend->width, + .height = backend->height, + .size = size, + .mmapped = mmapped, + .wl_buf = buf, + .pix = pix, + })); struct buffer *ret = &tll_back(backend->buffers); wl_buffer_add_listener(ret->wl_buf, &buffer_listener, ret); @@ -1050,7 +987,8 @@ guess_scale(const struct wayland_backend *backend) bool all_have_same_scale = true; int last_scale = -1; - tll_foreach(backend->monitors, it) { + tll_foreach(backend->monitors, it) + { if (last_scale == -1) last_scale = it->item.scale; else if (last_scale != it->item.scale) { @@ -1086,29 +1024,21 @@ update_size(struct wayland_backend *backend) bar->height = height - bar->border.top_width - bar->border.bottom_width; bar->height_with_border = height; - zwlr_layer_surface_v1_set_size( - backend->layer_surface, 0, bar->height_with_border / scale); + zwlr_layer_surface_v1_set_size(backend->layer_surface, 0, bar->height_with_border / scale); zwlr_layer_surface_v1_set_exclusive_zone( backend->layer_surface, - (bar->height_with_border + (bar->location == BAR_TOP - ? bar->border.bottom_margin - : bar->border.top_margin)) - / scale); + (bar->height_with_border + (bar->location == BAR_TOP ? bar->border.bottom_margin : bar->border.top_margin)) + / scale); - zwlr_layer_surface_v1_set_margin( - backend->layer_surface, - bar->border.top_margin / scale, - bar->border.right_margin / scale, - bar->border.bottom_margin / scale, - bar->border.left_margin / scale - ); + zwlr_layer_surface_v1_set_margin(backend->layer_surface, bar->border.top_margin / scale, + bar->border.right_margin / scale, bar->border.bottom_margin / scale, + bar->border.left_margin / scale); /* Trigger a 'configure' event, after which we'll have the width */ wl_surface_commit(backend->surface); wl_display_roundtrip(backend->display); - if (backend->width == -1 || - backend->height != bar->height_with_border) { + if (backend->width == -1 || backend->height != bar->height_with_border) { LOG_ERR("failed to get panel width"); return false; } @@ -1178,8 +1108,7 @@ setup(struct bar *_bar) return false; } - assert(backend->monitor == NULL || - backend->width / backend->monitor->scale <= backend->monitor->width_px); + assert(backend->monitor == NULL || backend->width / backend->monitor->scale <= backend->monitor->width_px); if (pipe2(backend->pipe_fds, O_CLOEXEC | O_NONBLOCK) == -1) { LOG_ERRNO("failed to create pipe"); @@ -1201,7 +1130,8 @@ cleanup(struct bar *_bar) if (backend->pipe_fds[1] >= 0) close(backend->pipe_fds[1]); - tll_foreach(backend->monitors, it) { + tll_foreach(backend->monitors, it) + { struct monitor *mon = &it->item; free(mon->name); @@ -1216,13 +1146,13 @@ cleanup(struct bar *_bar) if (backend->xdg_output_manager != NULL) zxdg_output_manager_v1_destroy(backend->xdg_output_manager); - tll_foreach(backend->seats, it) - seat_destroy(&it->item); + tll_foreach(backend->seats, it) seat_destroy(&it->item); tll_free(backend->seats); destroy_surface(backend); - tll_foreach(backend->buffers, it) { + tll_foreach(backend->buffers, it) + { if (it->item.wl_buf != NULL) wl_buffer_destroy(it->item.wl_buf); if (it->item.pix != NULL) @@ -1247,14 +1177,11 @@ cleanup(struct bar *_bar) /* Destroyed when freeing buffer list */ bar->pix = NULL; - } static void -loop(struct bar *_bar, - void (*expose)(const struct bar *bar), - void (*on_mouse)(struct bar *bar, enum mouse_event event, - enum mouse_button btn, int x, int y)) +loop(struct bar *_bar, void (*expose)(const struct bar *bar), + void (*on_mouse)(struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y)) { struct private *bar = _bar->private; struct wayland_backend *backend = bar->backend.data; @@ -1341,25 +1268,23 @@ out: if (!send_abort_to_modules) return; - if (write(_bar->abort_fd, &(uint64_t){1}, sizeof(uint64_t)) - != sizeof(uint64_t)) - { + if (write(_bar->abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) { LOG_ERRNO("failed to signal abort to modules"); } - //wl_display_cancel_read(backend->display); + // wl_display_cancel_read(backend->display); } static void -surface_enter(void *data, struct wl_surface *wl_surface, - struct wl_output *wl_output) +surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output) { struct wayland_backend *backend = data; free(backend->last_mapped_monitor); backend->last_mapped_monitor = NULL; - tll_foreach(backend->monitors, it) { + tll_foreach(backend->monitors, it) + { struct monitor *mon = &it->item; if (mon->output != wl_output) @@ -1379,8 +1304,7 @@ surface_enter(void *data, struct wl_surface *wl_surface, } static void -surface_leave(void *data, struct wl_surface *wl_surface, - struct wl_output *wl_output) +surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output) { struct wayland_backend *backend = data; const struct monitor *mon = backend->monitor; @@ -1399,8 +1323,7 @@ static const struct wl_surface_listener surface_listener = { .leave = &surface_leave, }; -static void frame_callback( - void *data, struct wl_callback *wl_callback, uint32_t callback_data); +static void frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_data); static const struct wl_callback_listener frame_listener = { .done = &frame_callback, @@ -1409,7 +1332,7 @@ static const struct wl_callback_listener frame_listener = { static void frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_data) { - //printf("frame callback\n"); + // printf("frame callback\n"); struct private *bar = data; struct wayland_backend *backend = bar->backend.data; @@ -1436,7 +1359,7 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da backend->pending_buffer = NULL; backend->render_scheduled = true; } else - ;//printf("nothing more to do\n"); + ; // printf("nothing more to do\n"); } static void @@ -1445,7 +1368,7 @@ commit(const struct bar *_bar) struct private *bar = _bar->private; struct wayland_backend *backend = bar->backend.data; - //printf("commit: %dxl%d\n", backend->width, backend->height); + // printf("commit: %dxl%d\n", backend->width, backend->height); if (backend->next_buffer == NULL) return; @@ -1454,7 +1377,7 @@ commit(const struct bar *_bar) assert(backend->next_buffer->busy); if (backend->render_scheduled) { - //printf("already scheduled\n"); + // printf("already scheduled\n"); if (backend->pending_buffer != NULL) backend->pending_buffer->busy = false; @@ -1463,7 +1386,7 @@ commit(const struct bar *_bar) backend->next_buffer = NULL; } else { - //printf("scheduling new frame callback\n"); + // printf("scheduling new frame callback\n"); struct buffer *buffer = backend->next_buffer; assert(buffer->busy); @@ -1491,9 +1414,7 @@ refresh(const struct bar *_bar) const struct private *bar = _bar->private; const struct wayland_backend *backend = bar->backend.data; - if (write(backend->pipe_fds[1], &(uint8_t){1}, sizeof(uint8_t)) - != sizeof(uint8_t)) - { + if (write(backend->pipe_fds[1], &(uint8_t){1}, sizeof(uint8_t)) != sizeof(uint8_t)) { LOG_ERRNO("failed to signal 'refresh' to main thread"); } } @@ -1513,8 +1434,7 @@ set_cursor(struct bar *_bar, const char *cursor) seat->pointer.xcursor = cursor; - seat->pointer.cursor = wl_cursor_theme_get_cursor( - seat->pointer.theme, cursor); + seat->pointer.cursor = wl_cursor_theme_get_cursor(seat->pointer.theme, cursor); if (seat->pointer.cursor == NULL) { LOG_ERR("%s: failed to load cursor '%s'", seat->name, cursor); diff --git a/bar/xcb.c b/bar/xcb.c index d8c5f9c..2552fe6 100644 --- a/bar/xcb.c +++ b/bar/xcb.c @@ -1,16 +1,16 @@ #include "xcb.h" -#include #include +#include -#include #include #include +#include #include -#include #include #include +#include #include #include #include @@ -39,7 +39,6 @@ struct xcb_backend { void *client_pixmap; size_t client_pixmap_size; pixman_image_t *pix; - }; void * @@ -55,11 +54,8 @@ setup(struct bar *_bar) struct private *bar = _bar->private; struct xcb_backend *backend = bar->backend.data; - if (bar->border.left_margin != 0 || - bar->border.right_margin != 0 || - bar->border.top_margin != 0 || - bar->border.bottom_margin) - { + if (bar->border.left_margin != 0 || bar->border.right_margin != 0 || bar->border.top_margin != 0 + || bar->border.bottom_margin) { LOG_WARN("non-zero border margins ignored in X11 backend"); } @@ -76,10 +72,8 @@ setup(struct bar *_bar) xcb_screen_t *screen = xcb_aux_get_screen(backend->conn, default_screen); - xcb_randr_get_monitors_reply_t *monitors = xcb_randr_get_monitors_reply( - backend->conn, - xcb_randr_get_monitors(backend->conn, screen->root, 0), - &e); + xcb_randr_get_monitors_reply_t *monitors + = xcb_randr_get_monitors_reply(backend->conn, xcb_randr_get_monitors(backend->conn, screen->root, 0), &e); if (e != NULL) { LOG_ERR("failed to get monitor list: %s", xcb_error(e)); @@ -90,17 +84,13 @@ setup(struct bar *_bar) /* Find monitor coordinates and width/height */ bool found_monitor = false; - for (xcb_randr_monitor_info_iterator_t it = - xcb_randr_get_monitors_monitors_iterator(monitors); - it.rem > 0; - xcb_randr_monitor_info_next(&it)) - { + for (xcb_randr_monitor_info_iterator_t it = xcb_randr_get_monitors_monitors_iterator(monitors); it.rem > 0; + xcb_randr_monitor_info_next(&it)) { const xcb_randr_monitor_info_t *mon = it.data; char *name = get_atom_name(backend->conn, mon->name); - LOG_INFO("monitor: %s: %ux%u+%u+%u (%ux%umm)", name, - mon->width, mon->height, mon->x, mon->y, - mon->width_in_millimeters, mon->height_in_millimeters); + LOG_INFO("monitor: %s: %ux%u+%u+%u (%ux%umm)", name, mon->width, mon->height, mon->x, mon->y, + mon->width_in_millimeters, mon->height_in_millimeters); /* User wants a specific monitor, and this is not the one */ if (bar->monitor != NULL && strcmp(bar->monitor, name) != 0) { @@ -111,14 +101,11 @@ setup(struct bar *_bar) backend->x = mon->x; backend->y = mon->y; bar->width = mon->width; - backend->y += bar->location == BAR_TOP ? 0 - : screen->height_in_pixels - bar->height_with_border; + backend->y += bar->location == BAR_TOP ? 0 : screen->height_in_pixels - bar->height_with_border; found_monitor = true; - if ((bar->monitor != NULL && strcmp(bar->monitor, name) == 0) || - (bar->monitor == NULL && mon->primary)) - { + if ((bar->monitor != NULL && strcmp(bar->monitor, name) == 0) || (bar->monitor == NULL && mon->primary)) { /* Exact match */ free(name); break; @@ -155,61 +142,34 @@ setup(struct bar *_bar) LOG_DBG("using a %hhu-bit visual", depth); backend->colormap = xcb_generate_id(backend->conn); - xcb_create_colormap( - backend->conn, 0, backend->colormap, screen->root, vis->visual_id); + xcb_create_colormap(backend->conn, 0, backend->colormap, screen->root, vis->visual_id); backend->win = xcb_generate_id(backend->conn); xcb_create_window( - backend->conn, - depth, backend->win, screen->root, - backend->x, backend->y, bar->width, bar->height_with_border, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, vis->visual_id, - (XCB_CW_BACK_PIXEL | - XCB_CW_BORDER_PIXEL | - XCB_CW_EVENT_MASK | - XCB_CW_COLORMAP), - (const uint32_t []){ - screen->black_pixel, - screen->white_pixel, - (XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_POINTER_MOTION | - XCB_EVENT_MASK_STRUCTURE_NOTIFY), - backend->colormap} - ); + backend->conn, depth, backend->win, screen->root, backend->x, backend->y, bar->width, bar->height_with_border, + 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, vis->visual_id, + (XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP), + (const uint32_t[]){screen->black_pixel, screen->white_pixel, + (XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS + | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_STRUCTURE_NOTIFY), + backend->colormap}); const char *title = "yambar"; - xcb_change_property( - backend->conn, - XCB_PROP_MODE_REPLACE, backend->win, - XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, - strlen(title), title); + xcb_change_property(backend->conn, XCB_PROP_MODE_REPLACE, backend->win, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, + strlen(title), title); - xcb_change_property( - backend->conn, - XCB_PROP_MODE_REPLACE, backend->win, - _NET_WM_PID, XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){getpid()}); - xcb_change_property( - backend->conn, - XCB_PROP_MODE_REPLACE, backend->win, - _NET_WM_WINDOW_TYPE, XCB_ATOM_ATOM, 32, - 1, (const uint32_t []){_NET_WM_WINDOW_TYPE_DOCK}); - xcb_change_property( - backend->conn, - XCB_PROP_MODE_REPLACE, backend->win, - _NET_WM_STATE, XCB_ATOM_ATOM, 32, - 2, (const uint32_t []){_NET_WM_STATE_ABOVE, _NET_WM_STATE_STICKY}); - xcb_change_property( - backend->conn, - XCB_PROP_MODE_REPLACE, backend->win, - _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){0xffffffff}); + xcb_change_property(backend->conn, XCB_PROP_MODE_REPLACE, backend->win, _NET_WM_PID, XCB_ATOM_CARDINAL, 32, 1, + (const uint32_t[]){getpid()}); + xcb_change_property(backend->conn, XCB_PROP_MODE_REPLACE, backend->win, _NET_WM_WINDOW_TYPE, XCB_ATOM_ATOM, 32, 1, + (const uint32_t[]){_NET_WM_WINDOW_TYPE_DOCK}); + xcb_change_property(backend->conn, XCB_PROP_MODE_REPLACE, backend->win, _NET_WM_STATE, XCB_ATOM_ATOM, 32, 2, + (const uint32_t[]){_NET_WM_STATE_ABOVE, _NET_WM_STATE_STICKY}); + xcb_change_property(backend->conn, XCB_PROP_MODE_REPLACE, backend->win, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, + (const uint32_t[]){0xffffffff}); /* Always on top */ - xcb_configure_window( - backend->conn, backend->win, XCB_CONFIG_WINDOW_STACK_MODE, - (const uint32_t []){XCB_STACK_MODE_ABOVE}); + xcb_configure_window(backend->conn, backend->win, XCB_CONFIG_WINDOW_STACK_MODE, + (const uint32_t[]){XCB_STACK_MODE_ABOVE}); uint32_t top_strut, bottom_strut; uint32_t top_pair[2], bottom_pair[2]; @@ -232,42 +192,38 @@ setup(struct bar *_bar) uint32_t strut[] = { /* left/right/top/bottom */ - 0, 0, + 0, + 0, top_strut, bottom_strut, /* start/end pairs for left/right/top/bottom */ - 0, 0, - 0, 0, - top_pair[0], top_pair[1], - bottom_pair[0], bottom_pair[1], + 0, + 0, + 0, + 0, + top_pair[0], + top_pair[1], + bottom_pair[0], + bottom_pair[1], }; - xcb_change_property( - backend->conn, - XCB_PROP_MODE_REPLACE, backend->win, - _NET_WM_STRUT, XCB_ATOM_CARDINAL, 32, - 4, strut); + xcb_change_property(backend->conn, XCB_PROP_MODE_REPLACE, backend->win, _NET_WM_STRUT, XCB_ATOM_CARDINAL, 32, 4, + strut); - xcb_change_property( - backend->conn, - XCB_PROP_MODE_REPLACE, backend->win, - _NET_WM_STRUT_PARTIAL, XCB_ATOM_CARDINAL, 32, - 12, strut); + xcb_change_property(backend->conn, XCB_PROP_MODE_REPLACE, backend->win, _NET_WM_STRUT_PARTIAL, XCB_ATOM_CARDINAL, + 32, 12, strut); backend->gc = xcb_generate_id(backend->conn); - xcb_create_gc(backend->conn, backend->gc, backend->win, - XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES, - (const uint32_t []){screen->white_pixel, 0}); + xcb_create_gc(backend->conn, backend->gc, backend->win, XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES, + (const uint32_t[]){screen->white_pixel, 0}); - const uint32_t stride = stride_for_format_and_width( - PIXMAN_a8r8g8b8, bar->width); + const uint32_t stride = stride_for_format_and_width(PIXMAN_a8r8g8b8, bar->width); backend->client_pixmap_size = stride * bar->height_with_border; backend->client_pixmap = malloc(backend->client_pixmap_size); - backend->pix = pixman_image_create_bits_no_clear( - PIXMAN_a8r8g8b8, bar->width, bar->height_with_border, - (uint32_t *)backend->client_pixmap, stride); + backend->pix = pixman_image_create_bits_no_clear(PIXMAN_a8r8g8b8, bar->width, bar->height_with_border, + (uint32_t *)backend->client_pixmap, stride); bar->pix = backend->pix; xcb_map_window(backend->conn, backend->win); @@ -310,10 +266,8 @@ cleanup(struct bar *_bar) } static void -loop(struct bar *_bar, - void (*expose)(const struct bar *bar), - void (*on_mouse)(struct bar *bar, enum mouse_event event, - enum mouse_button btn, int x, int y)) +loop(struct bar *_bar, void (*expose)(const struct bar *bar), + void (*on_mouse)(struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y)) { struct private *bar = _bar->private; struct xcb_backend *backend = bar->backend.data; @@ -323,10 +277,7 @@ loop(struct bar *_bar, const int fd = xcb_get_file_descriptor(backend->conn); while (true) { - struct pollfd fds[] = { - {.fd = _bar->abort_fd, .events = POLLIN}, - {.fd = fd, .events = POLLIN} - }; + struct pollfd fds[] = {{.fd = _bar->abort_fd, .events = POLLIN}, {.fd = fd, .events = POLLIN}}; poll(fds, sizeof(fds) / sizeof(fds[0]), -1); @@ -335,18 +286,14 @@ loop(struct bar *_bar, if (fds[1].revents & POLLHUP) { LOG_WARN("disconnected from XCB"); - if (write(_bar->abort_fd, &(uint64_t){1}, sizeof(uint64_t)) - != sizeof(uint64_t)) - { + if (write(_bar->abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) { LOG_ERRNO("failed to signal abort to modules"); } break; } - for (xcb_generic_event_t *e = xcb_wait_for_event(backend->conn); - e != NULL; - e = xcb_poll_for_event(backend->conn)) - { + for (xcb_generic_event_t *e = xcb_wait_for_event(backend->conn); e != NULL; + e = xcb_poll_for_event(backend->conn)) { switch (XCB_EVENT_RESPONSE_TYPE(e)) { case 0: LOG_ERR("XCB: %s", xcb_error((const xcb_generic_error_t *)e)); @@ -369,9 +316,12 @@ loop(struct bar *_bar, const xcb_button_release_event_t *evt = (void *)e; switch (evt->detail) { - case 1: case 2: case 3: case 4: case 5: - on_mouse(_bar, ON_MOUSE_CLICK, - evt->detail, evt->event_x, evt->event_y); + case 1: + case 2: + case 3: + case 4: + case 5: + on_mouse(_bar, ON_MOUSE_CLICK, evt->detail, evt->event_x, evt->event_y); break; } break; @@ -405,10 +355,9 @@ commit(const struct bar *_bar) const struct private *bar = _bar->private; const struct xcb_backend *backend = bar->backend.data; - xcb_put_image( - backend->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, backend->win, backend->gc, - bar->width, bar->height_with_border, 0, 0, 0, - backend->depth, backend->client_pixmap_size, backend->client_pixmap); + xcb_put_image(backend->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, backend->win, backend->gc, bar->width, + bar->height_with_border, 0, 0, 0, backend->depth, backend->client_pixmap_size, + backend->client_pixmap); xcb_flush(backend->conn); } @@ -424,19 +373,15 @@ refresh(const struct bar *_bar) * the size of the event structure */ xcb_expose_event_t *evt = calloc(32, 1); - *evt = (xcb_expose_event_t){ - .response_type = XCB_EXPOSE, - .window = backend->win, - .x = 0, - .y = 0, - .width = bar->width, - .height = bar->height, - .count = 1 - }; + *evt = (xcb_expose_event_t){.response_type = XCB_EXPOSE, + .window = backend->win, + .x = 0, + .y = 0, + .width = bar->width, + .height = bar->height, + .count = 1}; - xcb_send_event( - backend->conn, false, backend->win, XCB_EVENT_MASK_EXPOSURE, - (char *)evt); + xcb_send_event(backend->conn, false, backend->win, XCB_EVENT_MASK_EXPOSURE, (char *)evt); xcb_flush(backend->conn); free(evt); @@ -458,8 +403,7 @@ set_cursor(struct bar *_bar, const char *cursor) xcb_free_cursor(backend->conn, backend->cursor); backend->cursor = xcb_cursor_load_cursor(backend->cursor_ctx, cursor); - xcb_change_window_attributes( - backend->conn, backend->win, XCB_CW_CURSOR, &backend->cursor); + xcb_change_window_attributes(backend->conn, backend->win, XCB_CW_CURSOR, &backend->cursor); } static const char * diff --git a/char32.c b/char32.c index 0ca029a..eb3abb4 100644 --- a/char32.c +++ b/char32.c @@ -1,15 +1,15 @@ #include "char32.h" +#include #include #include -#include #include #if defined __has_include - #if __has_include () - #include - #endif +#if __has_include() +#include +#endif #endif #define LOG_MODULE "char32" @@ -24,14 +24,13 @@ * - both use the same encoding (though we require that encoding to be UTF-32) */ -_Static_assert( - sizeof(wchar_t) == sizeof(char32_t), "wchar_t vs. char32_t size mismatch"); +_Static_assert(sizeof(wchar_t) == sizeof(char32_t), "wchar_t vs. char32_t size mismatch"); #if !defined(__STDC_UTF_32__) || !__STDC_UTF_32__ - #error "char32_t does not use UTF-32" +#error "char32_t does not use UTF-32" #endif #if (!defined(__STDC_ISO_10646__) || !__STDC_ISO_10646__) && !defined(__FreeBSD__) - #error "wchar_t does not use UTF-32" +#error "wchar_t does not use UTF-32" #endif size_t diff --git a/char32.h b/char32.h index b01a7d3..1e7a9de 100644 --- a/char32.h +++ b/char32.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include size_t c32len(const char32_t *s); char32_t *ambstoc32(const char *src); diff --git a/config-verify.c b/config-verify.c index d4211f1..ed7d2f5 100644 --- a/config-verify.c +++ b/config-verify.c @@ -1,7 +1,7 @@ #include "config.h" -#include #include +#include #include @@ -16,11 +16,9 @@ conf_err_prefix(const keychain_t *chain, const struct yml_node *node) static char msg[4096]; int idx = 0; - idx += snprintf(&msg[idx], sizeof(msg) - idx, "%zu:%zu: ", - yml_source_line(node), yml_source_column(node)); + idx += snprintf(&msg[idx], sizeof(msg) - idx, "%zu:%zu: ", yml_source_line(node), yml_source_column(node)); - tll_foreach(*chain, key) - idx += snprintf(&msg[idx], sizeof(msg) - idx, "%s.", key->item); + tll_foreach(*chain, key) idx += snprintf(&msg[idx], sizeof(msg) - idx, "%s.", key->item); /* Remove trailing "." */ msg[idx - 1] = '\0'; @@ -45,8 +43,7 @@ conf_verify_int(keychain_t *chain, const struct yml_node *node) if (yml_value_is_int(node)) return true; - LOG_ERR("%s: value is not an integer: '%s'", - conf_err_prefix(chain, node), yml_value_as_string(node)); + LOG_ERR("%s: value is not an integer: '%s'", conf_err_prefix(chain, node), yml_value_as_string(node)); return false; } @@ -56,8 +53,7 @@ conf_verify_unsigned(keychain_t *chain, const struct yml_node *node) if (yml_value_is_int(node) && yml_value_as_int(node) >= 0) return true; - LOG_ERR("%s: value is not a positive integer: '%s'", - conf_err_prefix(chain, node), yml_value_as_string(node)); + LOG_ERR("%s: value is not a positive integer: '%s'", conf_err_prefix(chain, node), yml_value_as_string(node)); return false; } @@ -67,8 +63,7 @@ conf_verify_bool(keychain_t *chain, const struct yml_node *node) if (yml_value_is_bool(node)) return true; - LOG_ERR("%s: value is not a boolean: '%s'", - conf_err_prefix(chain, node), yml_value_as_string(node)); + LOG_ERR("%s: value is not a boolean: '%s'", conf_err_prefix(chain, node), yml_value_as_string(node)); return false; } @@ -81,10 +76,7 @@ conf_verify_list(keychain_t *chain, const struct yml_node *node, return false; } - for (struct yml_list_iter iter = yml_list_iter(node); - iter.node != NULL; - yml_list_next(&iter)) - { + for (struct yml_list_iter iter = yml_list_iter(node); iter.node != NULL; yml_list_next(&iter)) { if (!verify(chain, iter.node)) return false; } @@ -93,8 +85,7 @@ conf_verify_list(keychain_t *chain, const struct yml_node *node, } bool -conf_verify_enum(keychain_t *chain, const struct yml_node *node, - const char *values[], size_t count) +conf_verify_enum(keychain_t *chain, const struct yml_node *node, const char *values[], size_t count) { const char *s = yml_value_as_string(node); if (s == NULL) { @@ -115,8 +106,7 @@ conf_verify_enum(keychain_t *chain, const struct yml_node *node, } bool -conf_verify_dict(keychain_t *chain, const struct yml_node *node, - const struct attr_info info[]) +conf_verify_dict(keychain_t *chain, const struct yml_node *node, const struct attr_info info[]) { if (!yml_is_dict(node)) { LOG_ERR("%s: must be a dictionary", conf_err_prefix(chain, node)); @@ -131,10 +121,7 @@ conf_verify_dict(keychain_t *chain, const struct yml_node *node, bool exists[count]; memset(exists, 0, sizeof(exists)); - for (struct yml_dict_iter it = yml_dict_iter(node); - it.key != NULL; - yml_dict_next(&it)) - { + for (struct yml_dict_iter it = yml_dict_iter(node); it.key != NULL; yml_dict_next(&it)) { const char *key = yml_value_as_string(it.key); if (key == NULL) { LOG_ERR("%s: key must be a string", conf_err_prefix(chain, it.key)); @@ -190,8 +177,7 @@ verify_on_click_path(keychain_t *chain, const struct yml_node *node) const bool is_tilde = path[0] == '~' && path[1] == '/'; if (!is_absolute && !is_tilde) { - LOG_ERR("%s: path must be either absolute, or begin with '~/", - conf_err_prefix(chain, node)); + LOG_ERR("%s: path must be either absolute, or begin with '~/", conf_err_prefix(chain, node)); return false; } @@ -208,14 +194,10 @@ conf_verify_on_click(keychain_t *chain, const struct yml_node *node) return verify_on_click_path(chain, node); static const struct attr_info info[] = { - {"left", false, &verify_on_click_path}, - {"middle", false, &verify_on_click_path}, - {"right", false, &verify_on_click_path}, - {"wheel-up", false, &verify_on_click_path}, - {"wheel-down", false, &verify_on_click_path}, - {"previous", false, &verify_on_click_path}, - {"next", false, &verify_on_click_path}, - {NULL, false, NULL}, + {"left", false, &verify_on_click_path}, {"middle", false, &verify_on_click_path}, + {"right", false, &verify_on_click_path}, {"wheel-up", false, &verify_on_click_path}, + {"wheel-down", false, &verify_on_click_path}, {"previous", false, &verify_on_click_path}, + {"next", false, &verify_on_click_path}, {NULL, false, NULL}, }; return conf_verify_dict(chain, node, info); @@ -234,21 +216,18 @@ conf_verify_color(keychain_t *chain, const struct yml_node *node) int v = sscanf(s, "%02x%02x%02x%02x", &r, &g, &b, &a); if (strlen(s) != 8 || v != 4) { - LOG_ERR("%s: value must be a color ('rrggbbaa', e.g ff00ffff)", - conf_err_prefix(chain, node)); + LOG_ERR("%s: value must be a color ('rrggbbaa', e.g ff00ffff)", conf_err_prefix(chain, node)); return false; } return true; } - bool conf_verify_font(keychain_t *chain, const struct yml_node *node) { if (!yml_is_scalar(node)) { - LOG_ERR("%s: font must be a fontconfig-formatted string", - conf_err_prefix(chain, node)); + LOG_ERR("%s: font must be a fontconfig-formatted string", conf_err_prefix(chain, node)); return false; } @@ -258,8 +237,7 @@ conf_verify_font(keychain_t *chain, const struct yml_node *node) bool conf_verify_font_shaping(keychain_t *chain, const struct yml_node *node) { - return conf_verify_enum( - chain, node, (const char *[]){"full", /*"graphemes",*/ "none"}, 2); + return conf_verify_enum(chain, node, (const char *[]){"full", /*"graphemes",*/ "none"}, 2); } bool @@ -269,7 +247,8 @@ conf_verify_decoration(keychain_t *chain, const struct yml_node *node) if (yml_dict_length(node) != 1) { LOG_ERR("%s: decoration must be a dictionary with a single key; " - "the name of the particle", conf_err_prefix(chain, node)); + "the name of the particle", + conf_err_prefix(chain, node)); return false; } @@ -285,8 +264,7 @@ conf_verify_decoration(keychain_t *chain, const struct yml_node *node) const struct deco_iface *iface = plugin_load_deco(deco_name); if (iface == NULL) { - LOG_ERR("%s: invalid decoration name: %s", - conf_err_prefix(chain, deco), deco_name); + LOG_ERR("%s: invalid decoration name: %s", conf_err_prefix(chain, deco), deco_name); return false; } @@ -303,10 +281,7 @@ conf_verify_particle_list_items(keychain_t *chain, const struct yml_node *node) { assert(yml_is_list(node)); - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it)) - { + for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it)) { if (!conf_verify_particle(chain, it.node)) return false; } @@ -321,7 +296,8 @@ conf_verify_particle_dictionary(keychain_t *chain, const struct yml_node *node) if (yml_dict_length(node) != 1) { LOG_ERR("%s: particle must be a dictionary with a single key; " - "the name of the particle", conf_err_prefix(chain, node)); + "the name of the particle", + conf_err_prefix(chain, node)); return false; } @@ -331,15 +307,13 @@ conf_verify_particle_dictionary(keychain_t *chain, const struct yml_node *node) const char *particle_name = yml_value_as_string(particle); if (particle_name == NULL) { - LOG_ERR("%s: particle name must be a string", - conf_err_prefix(chain, particle)); + LOG_ERR("%s: particle name must be a string", conf_err_prefix(chain, particle)); return false; } const struct particle_iface *iface = plugin_load_particle(particle_name); if (iface == NULL) { - LOG_ERR("%s: invalid particle name: %s", - conf_err_prefix(chain, particle), particle_name); + LOG_ERR("%s: invalid particle name: %s", conf_err_prefix(chain, particle), particle_name); return false; } @@ -361,19 +335,18 @@ conf_verify_particle(keychain_t *chain, const struct yml_node *node) else if (yml_is_list(node)) return conf_verify_particle_list_items(chain, node); else { - LOG_ERR("%s: particle must be either a dictionary or a list", - conf_err_prefix(chain, node)); + LOG_ERR("%s: particle must be either a dictionary or a list", conf_err_prefix(chain, node)); return false; } } - static bool verify_module(keychain_t *chain, const struct yml_node *node) { if (!yml_is_dict(node) || yml_dict_length(node) != 1) { LOG_ERR("%s: module must be a dictionary with a single key; " - "the name of the module", conf_err_prefix(chain, node)); + "the name of the module", + conf_err_prefix(chain, node)); return false; } @@ -389,8 +362,7 @@ verify_module(keychain_t *chain, const struct yml_node *node) const struct module_iface *iface = plugin_load_module(mod_name); if (iface == NULL) { - LOG_ERR( - "%s: invalid module name: %s", conf_err_prefix(chain, node), mod_name); + LOG_ERR("%s: invalid module name: %s", conf_err_prefix(chain, node), mod_name); return false; } @@ -412,10 +384,7 @@ verify_module_list(keychain_t *chain, const struct yml_node *node) return false; } - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it)) - { + for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it)) { if (!verify_module(chain, it.node)) return false; } @@ -427,18 +396,12 @@ static bool verify_bar_border(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { - {"width", false, &conf_verify_unsigned}, - {"left-width", false, &conf_verify_unsigned}, - {"right-width", false, &conf_verify_unsigned}, - {"top-width", false, &conf_verify_unsigned}, - {"bottom-width", false, &conf_verify_unsigned}, - {"color", false, &conf_verify_color}, - {"margin", false, &conf_verify_unsigned}, - {"left-margin", false, &conf_verify_unsigned}, - {"right-margin", false, &conf_verify_unsigned}, - {"top-margin", false, &conf_verify_unsigned}, - {"bottom-margin", false, &conf_verify_unsigned}, - {NULL, false, NULL}, + {"width", false, &conf_verify_unsigned}, {"left-width", false, &conf_verify_unsigned}, + {"right-width", false, &conf_verify_unsigned}, {"top-width", false, &conf_verify_unsigned}, + {"bottom-width", false, &conf_verify_unsigned}, {"color", false, &conf_verify_color}, + {"margin", false, &conf_verify_unsigned}, {"left-margin", false, &conf_verify_unsigned}, + {"right-margin", false, &conf_verify_unsigned}, {"top-margin", false, &conf_verify_unsigned}, + {"bottom-margin", false, &conf_verify_unsigned}, {NULL, false, NULL}, }; return conf_verify_dict(chain, node, attrs); @@ -453,9 +416,7 @@ verify_bar_location(keychain_t *chain, const struct yml_node *node) static bool verify_bar_layer(keychain_t *chain, const struct yml_node *node) { - return conf_verify_enum( - chain, node, - (const char *[]){"overlay", "top", "bottom", "background"}, 4); + return conf_verify_enum(chain, node, (const char *[]){"overlay", "top", "bottom", "background"}, 4); } bool diff --git a/config-verify.h b/config-verify.h index 0a4ae34..8ad44ce 100644 --- a/config-verify.h +++ b/config-verify.h @@ -26,17 +26,14 @@ chain_pop(keychain_t *chain) tll_pop_back(*chain); } -const char *conf_err_prefix( - const keychain_t *chain, const struct yml_node *node); - +const char *conf_err_prefix(const keychain_t *chain, const struct yml_node *node); bool conf_verify_string(keychain_t *chain, const struct yml_node *node); bool conf_verify_int(keychain_t *chain, const struct yml_node *node); bool conf_verify_unsigned(keychain_t *chain, const struct yml_node *node); bool conf_verify_bool(keychain_t *chain, const struct yml_node *node); -bool conf_verify_enum(keychain_t *chain, const struct yml_node *node, - const char *values[], size_t count); +bool conf_verify_enum(keychain_t *chain, const struct yml_node *node, const char *values[], size_t count); bool conf_verify_list(keychain_t *chain, const struct yml_node *node, bool (*verify)(keychain_t *chain, const struct yml_node *node)); bool conf_verify_dict(keychain_t *chain, const struct yml_node *node, diff --git a/config.c b/config.c index a0eba59..0f80364 100644 --- a/config.c +++ b/config.c @@ -1,10 +1,10 @@ #include "config.h" -#include -#include -#include #include #include +#include +#include +#include #include @@ -21,9 +21,7 @@ static uint8_t hex_nibble(char hex) { - assert((hex >= '0' && hex <= '9') || - (hex >= 'a' && hex <= 'f') || - (hex >= 'A' && hex <= 'F')); + assert((hex >= '0' && hex <= '9') || (hex >= 'a' && hex <= 'f') || (hex >= 'A' && hex <= 'F')); if (hex >= '0' && hex <= '9') return hex - '0'; @@ -57,9 +55,9 @@ conf_to_color(const struct yml_node *node) alpha |= alpha << 8; return (pixman_color_t){ - .red = (uint32_t)(red << 8 | red) * alpha / 0xffff, + .red = (uint32_t)(red << 8 | red) * alpha / 0xffff, .green = (uint32_t)(green << 8 | green) * alpha / 0xffff, - .blue = (uint32_t)(blue << 8 | blue) * alpha / 0xffff, + .blue = (uint32_t)(blue << 8 | blue) * alpha / 0xffff, .alpha = alpha, }; } @@ -74,10 +72,7 @@ conf_to_font(const struct yml_node *node) const char **fonts = NULL; char *copy = strdup(font_spec); - for (const char *font = strtok(copy, ","); - font != NULL; - font = strtok(NULL, ",")) - { + for (const char *font = strtok(copy, ","); font != NULL; font = strtok(NULL, ",")) { /* Trim spaces, strictly speaking not necessary, but looks nice :) */ while (isspace(font[0])) font++; @@ -112,9 +107,7 @@ conf_to_font_shaping(const struct yml_node *node) else if (strcmp(v, "graphemes") == 0) { static bool have_warned = false; - if (!have_warned && - !(fcft_capabilities() & FCFT_CAPABILITY_GRAPHEME_SHAPING)) - { + if (!have_warned && !(fcft_capabilities() & FCFT_CAPABILITY_GRAPHEME_SHAPING)) { have_warned = true; LOG_WARN("cannot enable grapheme shaping; no support in fcft"); } @@ -124,9 +117,7 @@ conf_to_font_shaping(const struct yml_node *node) else if (strcmp(v, "full") == 0) { static bool have_warned = false; - if (!have_warned && - !(fcft_capabilities() & FCFT_CAPABILITY_TEXT_RUN_SHAPING)) - { + if (!have_warned && !(fcft_capabilities() & FCFT_CAPABILITY_TEXT_RUN_SHAPING)) { have_warned = true; LOG_WARN("cannot enable full text shaping; no support in fcft"); } @@ -154,25 +145,20 @@ conf_to_deco(const struct yml_node *node) } static struct particle * -particle_simple_list_from_config(const struct yml_node *node, - struct conf_inherit inherited) +particle_simple_list_from_config(const struct yml_node *node, struct conf_inherit inherited) { size_t count = yml_list_length(node); struct particle *parts[count]; size_t idx = 0; - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it), idx++) - { + for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it), idx++) { parts[idx] = conf_to_particle(it.node, inherited); } /* Lazy-loaded function pointer to particle_list_new() */ - static struct particle *(*particle_list_new)( - struct particle *common, - struct particle *particles[], size_t count, - int left_spacing, int right_spacing) = NULL; + static struct particle *(*particle_list_new)(struct particle *common, struct particle *particles[], size_t count, + int left_spacing, int right_spacing) + = NULL; if (particle_list_new == NULL) { const struct plugin *plug = plugin_load("list", PLUGIN_PARTICLE); @@ -181,9 +167,8 @@ particle_simple_list_from_config(const struct yml_node *node, assert(particle_list_new != NULL); } - struct particle *common = particle_common_new( - 0, 0, NULL, fcft_clone(inherited.font), inherited.font_shaping, - inherited.foreground, NULL); + struct particle *common = particle_common_new(0, 0, NULL, fcft_clone(inherited.font), inherited.font_shaping, + inherited.foreground, NULL); return particle_list_new(common, parts, count, 0, 2); } @@ -206,10 +191,8 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *foreground_node = yml_get_value(pair.value, "foreground"); const struct yml_node *deco_node = yml_get_value(pair.value, "deco"); - int left = margin != NULL ? yml_value_as_int(margin) : - left_margin != NULL ? yml_value_as_int(left_margin) : 0; - int right = margin != NULL ? yml_value_as_int(margin) : - right_margin != NULL ? yml_value_as_int(right_margin) : 0; + int left = margin != NULL ? yml_value_as_int(margin) : left_margin != NULL ? yml_value_as_int(left_margin) : 0; + int right = margin != NULL ? yml_value_as_int(margin) : right_margin != NULL ? yml_value_as_int(right_margin) : 0; char *on_click_templates[MOUSE_BTN_COUNT] = {NULL}; if (on_click != NULL) { @@ -234,10 +217,7 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) } else if (yml_is_dict(on_click)) { - for (struct yml_dict_iter it = yml_dict_iter(on_click); - it.key != NULL; - yml_dict_next(&it)) - { + for (struct yml_dict_iter it = yml_dict_iter(on_click); it.key != NULL; yml_dict_next(&it)) { const char *key = yml_value_as_string(it.key); const char *yml_template = yml_value_as_string(it.value); @@ -286,16 +266,14 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) * clone the font, since each particle takes ownership of its own * font. */ - struct fcft_font *font = font_node != NULL - ? conf_to_font(font_node) : fcft_clone(inherited.font); - enum font_shaping font_shaping = font_shaping_node != NULL - ? conf_to_font_shaping(font_shaping_node) : inherited.font_shaping; - pixman_color_t foreground = foreground_node != NULL - ? conf_to_color(foreground_node) : inherited.foreground; + struct fcft_font *font = font_node != NULL ? conf_to_font(font_node) : fcft_clone(inherited.font); + enum font_shaping font_shaping + = font_shaping_node != NULL ? conf_to_font_shaping(font_shaping_node) : inherited.font_shaping; + pixman_color_t foreground = foreground_node != NULL ? conf_to_color(foreground_node) : inherited.foreground; /* Instantiate base/common particle */ - struct particle *common = particle_common_new( - left, right, on_click_templates, font, font_shaping, foreground, deco); + struct particle *common + = particle_common_new(left, right, on_click_templates, font, font_shaping, foreground, deco); const struct particle_iface *iface = plugin_load_particle(type); @@ -323,8 +301,7 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) conf.height = yml_value_as_int(height); const struct yml_node *location = yml_get_value(bar, "location"); - conf.location = strcmp(yml_value_as_string(location), "top") == 0 - ? BAR_TOP : BAR_BOTTOM; + conf.location = strcmp(yml_value_as_string(location), "top") == 0 ? BAR_TOP : BAR_BOTTOM; const struct yml_node *background = yml_get_value(bar, "background"); conf.background = conf_to_color(background); @@ -352,7 +329,6 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) assert(false); } - const struct yml_node *spacing = yml_get_value(bar, "spacing"); if (spacing != NULL) conf.left_spacing = conf.right_spacing = yml_value_as_int(spacing); @@ -377,11 +353,8 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) if (right_margin != NULL) conf.right_margin = yml_value_as_int(right_margin); - const struct yml_node *trackpad_sensitivity = - yml_get_value(bar, "trackpad-sensitivity"); - conf.trackpad_sensitivity = trackpad_sensitivity != NULL - ? yml_value_as_int(trackpad_sensitivity) - : 30; + const struct yml_node *trackpad_sensitivity = yml_get_value(bar, "trackpad-sensitivity"); + conf.trackpad_sensitivity = trackpad_sensitivity != NULL ? yml_value_as_int(trackpad_sensitivity) : 30; const struct yml_node *border = yml_get_value(bar, "border"); if (border != NULL) { @@ -398,10 +371,8 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) const struct yml_node *bottom_margin = yml_get_value(border, "bottom-margin"); if (width != NULL) - conf.border.left_width = - conf.border.right_width = - conf.border.top_width = - conf.border.bottom_width = yml_value_as_int(width); + conf.border.left_width = conf.border.right_width = conf.border.top_width = conf.border.bottom_width + = yml_value_as_int(width); if (left_width != NULL) conf.border.left_width = yml_value_as_int(left_width); @@ -416,10 +387,8 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) conf.border.color = conf_to_color(color); if (margin != NULL) - conf.border.left_margin = - conf.border.right_margin = - conf.border.top_margin = - conf.border.bottom_margin = yml_value_as_int(margin); + conf.border.left_margin = conf.border.right_margin = conf.border.top_margin = conf.border.bottom_margin + = yml_value_as_int(margin); if (left_margin != NULL) conf.border.left_margin = yml_value_as_int(left_margin); @@ -474,10 +443,7 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) struct module **mods = calloc(count, sizeof(*mods)); size_t idx = 0; - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it), idx++) - { + for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it), idx++) { struct yml_dict_iter m = yml_dict_iter(it.node); const char *mod_name = yml_value_as_string(m.key); @@ -489,16 +455,13 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) */ const struct yml_node *mod_font = yml_get_value(m.value, "font"); const struct yml_node *mod_font_shaping = yml_get_value(m.value, "font-shaping"); - const struct yml_node *mod_foreground = yml_get_value( - m.value, "foreground"); + const struct yml_node *mod_foreground = yml_get_value(m.value, "foreground"); struct conf_inherit mod_inherit = { - .font = mod_font != NULL - ? conf_to_font(mod_font) : inherited.font, - .font_shaping = mod_font_shaping != NULL - ? conf_to_font_shaping(mod_font_shaping) : inherited.font_shaping, - .foreground = mod_foreground != NULL - ? conf_to_color(mod_foreground) : inherited.foreground, + .font = mod_font != NULL ? conf_to_font(mod_font) : inherited.font, + .font_shaping + = mod_font_shaping != NULL ? conf_to_font_shaping(mod_font_shaping) : inherited.font_shaping, + .foreground = mod_foreground != NULL ? conf_to_color(mod_foreground) : inherited.foreground, }; const struct module_iface *iface = plugin_load_module(mod_name); diff --git a/config.h b/config.h index ceb4b85..86c2f4e 100644 --- a/config.h +++ b/config.h @@ -1,9 +1,9 @@ #pragma once -#include -#include "yml.h" #include "bar/bar.h" #include "font-shaping.h" +#include "yml.h" +#include struct bar; struct particle; @@ -25,6 +25,5 @@ struct conf_inherit { pixman_color_t foreground; }; -struct particle *conf_to_particle( - const struct yml_node *node, struct conf_inherit inherited); +struct particle *conf_to_particle(const struct yml_node *node, struct conf_inherit inherited); struct deco *conf_to_deco(const struct yml_node *node); diff --git a/decoration.h b/decoration.h index efb79e2..ba44e43 100644 --- a/decoration.h +++ b/decoration.h @@ -4,10 +4,11 @@ struct deco { void *private; - void (*expose)(const struct deco *deco, pixman_image_t *pix, - int x, int y, int width, int height); + void (*expose)(const struct deco *deco, pixman_image_t *pix, int x, int y, int width, int height); void (*destroy)(struct deco *deco); }; -#define DECORATION_COMMON_ATTRS \ - {NULL, false, NULL} +#define DECORATION_COMMON_ATTRS \ + { \ + NULL, false, NULL \ + } diff --git a/decorations/background.c b/decorations/background.c index b3b9ed2..f1430f1 100644 --- a/decorations/background.c +++ b/decorations/background.c @@ -1,12 +1,13 @@ #include -#include "../config.h" #include "../config-verify.h" +#include "../config.h" #include "../decoration.h" #include "../plugin.h" -struct private { - //struct rgba color; +struct private +{ + // struct rgba color; pixman_color_t color; }; @@ -22,9 +23,7 @@ static void expose(const struct deco *deco, pixman_image_t *pix, int x, int y, int width, int height) { const struct private *d = deco->private; - pixman_image_fill_rectangles( - PIXMAN_OP_OVER, pix, &d->color, 1, - &(pixman_rectangle16_t){x, y, width, height}); + pixman_image_fill_rectangles(PIXMAN_OP_OVER, pix, &d->color, 1, &(pixman_rectangle16_t){x, y, width, height}); } static struct deco * diff --git a/decorations/border.c b/decorations/border.c index 5868e88..e93fc4e 100644 --- a/decorations/border.c +++ b/decorations/border.c @@ -1,7 +1,7 @@ #include -#include "../config.h" #include "../config-verify.h" +#include "../config.h" #include "../decoration.h" #include "../plugin.h" @@ -12,7 +12,8 @@ #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) -struct private { +struct private +{ pixman_color_t color; int size; }; @@ -29,21 +30,20 @@ static void expose(const struct deco *deco, pixman_image_t *pix, int x, int y, int width, int height) { const struct private *d = deco->private; - pixman_image_fill_rectangles( - PIXMAN_OP_OVER, pix, &d->color, 4, - (pixman_rectangle16_t []){ - /* Top */ - {x, y, width, min(d->size, height)}, + pixman_image_fill_rectangles(PIXMAN_OP_OVER, pix, &d->color, 4, + (pixman_rectangle16_t[]){ + /* Top */ + {x, y, width, min(d->size, height)}, - /* Bottom */ - {x, max(y + height - d->size, y), width, min(d->size, height)}, + /* Bottom */ + {x, max(y + height - d->size, y), width, min(d->size, height)}, - /* Left */ - {x, y, min(d->size, width), height}, + /* Left */ + {x, y, min(d->size, width), height}, - /* Right */ - {max(x + width - d->size, x), y, min(d->size, width), height}, - }); + /* Right */ + {max(x + width - d->size, x), y, min(d->size, width), height}, + }); } static struct deco * @@ -66,9 +66,7 @@ from_conf(const struct yml_node *node) { const struct yml_node *color = yml_get_value(node, "color"); const struct yml_node *size = yml_get_value(node, "size"); - return border_new( - conf_to_color(color), - size != NULL ? yml_value_as_int(size) : 1); + return border_new(conf_to_color(color), size != NULL ? yml_value_as_int(size) : 1); } static bool diff --git a/decorations/overline.c b/decorations/overline.c index 1beb896..e9ff8be 100644 --- a/decorations/overline.c +++ b/decorations/overline.c @@ -1,11 +1,12 @@ #include -#include "../config.h" #include "../config-verify.h" +#include "../config.h" #include "../decoration.h" #include "../plugin.h" -struct private { +struct private +{ int size; pixman_color_t color; }; @@ -22,9 +23,7 @@ static void expose(const struct deco *deco, pixman_image_t *pix, int x, int y, int width, int height) { const struct private *d = deco->private; - pixman_image_fill_rectangles( - PIXMAN_OP_OVER, pix, &d->color, 1, - &(pixman_rectangle16_t){x, y, width, d->size}); + pixman_image_fill_rectangles(PIXMAN_OP_OVER, pix, &d->color, 1, &(pixman_rectangle16_t){x, y, width, d->size}); } static struct deco * diff --git a/decorations/stack.c b/decorations/stack.c index 16c58ee..d8420d2 100644 --- a/decorations/stack.c +++ b/decorations/stack.c @@ -1,13 +1,14 @@ #include #define LOG_MODULE "stack" -#include "../log.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" #include "../decoration.h" +#include "../log.h" #include "../plugin.h" -struct private { +struct private +{ struct deco **decos; size_t count; }; @@ -57,10 +58,7 @@ from_conf(const struct yml_node *node) struct deco *decos[count]; size_t idx = 0; - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it), idx++) - { + for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it), idx++) { decos[idx] = conf_to_deco(it.node); } @@ -75,10 +73,7 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return false; } - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it)) - { + for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it)) { if (!conf_verify_decoration(chain, it.node)) return false; } diff --git a/decorations/underline.c b/decorations/underline.c index 5b8bbd3..0175116 100644 --- a/decorations/underline.c +++ b/decorations/underline.c @@ -1,11 +1,12 @@ #include -#include "../config.h" #include "../config-verify.h" +#include "../config.h" #include "../decoration.h" #include "../plugin.h" -struct private { +struct private +{ int size; pixman_color_t color; }; @@ -22,9 +23,8 @@ static void expose(const struct deco *deco, pixman_image_t *pix, int x, int y, int width, int height) { const struct private *d = deco->private; - pixman_image_fill_rectangles( - PIXMAN_OP_OVER, pix, &d->color, 1, - &(pixman_rectangle16_t){x, y + height - d->size, width, d->size}); + pixman_image_fill_rectangles(PIXMAN_OP_OVER, pix, &d->color, 1, + &(pixman_rectangle16_t){x, y + height - d->size, width, d->size}); } static struct deco * diff --git a/log.c b/log.c index 2d454a8..7ba4193 100644 --- a/log.c +++ b/log.c @@ -1,5 +1,6 @@ #include "log.h" +#include #include #include #include @@ -9,7 +10,6 @@ #include #include #include -#include #define ALEN(v) (sizeof(v) / sizeof((v)[0])) #define UNUSED __attribute__((unused)) @@ -32,23 +32,22 @@ static const struct { }; void -log_init(enum log_colorize _colorize, bool _do_syslog, - enum log_facility syslog_facility, enum log_class _log_level) +log_init(enum log_colorize _colorize, bool _do_syslog, enum log_facility syslog_facility, enum log_class _log_level) { static const int facility_map[] = { [LOG_FACILITY_USER] = LOG_USER, [LOG_FACILITY_DAEMON] = LOG_DAEMON, }; - colorize = _colorize == LOG_COLORIZE_NEVER - ? false : _colorize == LOG_COLORIZE_ALWAYS - ? true : isatty(STDERR_FILENO); + colorize = _colorize == LOG_COLORIZE_NEVER ? false + : _colorize == LOG_COLORIZE_ALWAYS ? true + : isatty(STDERR_FILENO); do_syslog = _do_syslog; log_level = _log_level; int slvl = log_level_map[_log_level].syslog_equivalent; if (do_syslog && slvl != -1) { - openlog(NULL, /*LOG_PID*/0, facility_map[syslog_facility]); + openlog(NULL, /*LOG_PID*/ 0, facility_map[syslog_facility]); setlogmask(LOG_UPTO(slvl)); } } @@ -61,8 +60,8 @@ log_deinit(void) } static void -_log(enum log_class log_class, const char *module, const char *file, int lineno, - const char *fmt, int sys_errno, va_list va) +_log(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, int sys_errno, + va_list va) { assert(log_class > LOG_CLASS_NONE); assert(log_class < ALEN(log_level_map)); @@ -92,9 +91,8 @@ _log(enum log_class log_class, const char *module, const char *file, int lineno, } static void -_sys_log(enum log_class log_class, const char *module, - const char UNUSED *file, int UNUSED lineno, - const char *fmt, int sys_errno, va_list va) +_sys_log(enum log_class log_class, const char *module, const char UNUSED *file, int UNUSED lineno, const char *fmt, + int sys_errno, va_list va) { assert(log_class > LOG_CLASS_NONE); assert(log_class < ALEN(log_level_map)); @@ -119,8 +117,7 @@ _sys_log(enum log_class log_class, const char *module, } void -log_msg_va(enum log_class log_class, const char *module, - const char *file, int lineno, const char *fmt, va_list va) +log_msg_va(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, va_list va) { va_list va2; va_copy(va2, va); @@ -130,8 +127,7 @@ log_msg_va(enum log_class log_class, const char *module, } void -log_msg(enum log_class log_class, const char *module, - const char *file, int lineno, const char *fmt, ...) +log_msg(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, ...) { va_list va; va_start(va, fmt); @@ -140,17 +136,13 @@ log_msg(enum log_class log_class, const char *module, } void -log_errno_va(enum log_class log_class, const char *module, - const char *file, int lineno, - const char *fmt, va_list va) +log_errno_va(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, va_list va) { log_errno_provided_va(log_class, module, file, lineno, errno, fmt, va); } void -log_errno(enum log_class log_class, const char *module, - const char *file, int lineno, - const char *fmt, ...) +log_errno(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, ...) { va_list va; va_start(va, fmt); @@ -159,8 +151,7 @@ log_errno(enum log_class log_class, const char *module, } void -log_errno_provided_va(enum log_class log_class, const char *module, - const char *file, int lineno, int errno_copy, +log_errno_provided_va(enum log_class log_class, const char *module, const char *file, int lineno, int errno_copy, const char *fmt, va_list va) { va_list va2; @@ -171,8 +162,7 @@ log_errno_provided_va(enum log_class log_class, const char *module, } void -log_errno_provided(enum log_class log_class, const char *module, - const char *file, int lineno, int errno_copy, +log_errno_provided(enum log_class log_class, const char *module, const char *file, int lineno, int errno_copy, const char *fmt, ...) { va_list va; diff --git a/log.h b/log.h index 94fd178..48f16fe 100644 --- a/log.h +++ b/log.h @@ -1,68 +1,43 @@ #pragma once -#include #include +#include enum log_colorize { LOG_COLORIZE_NEVER, LOG_COLORIZE_ALWAYS, LOG_COLORIZE_AUTO }; enum log_facility { LOG_FACILITY_USER, LOG_FACILITY_DAEMON }; -enum log_class { - LOG_CLASS_NONE, - LOG_CLASS_ERROR, - LOG_CLASS_WARNING, - LOG_CLASS_INFO, - LOG_CLASS_DEBUG -}; +enum log_class { LOG_CLASS_NONE, LOG_CLASS_ERROR, LOG_CLASS_WARNING, LOG_CLASS_INFO, LOG_CLASS_DEBUG }; -void log_init(enum log_colorize colorize, bool do_syslog, - enum log_facility syslog_facility, enum log_class log_level); +void log_init(enum log_colorize colorize, bool do_syslog, enum log_facility syslog_facility, enum log_class log_level); void log_deinit(void); -void log_msg( - enum log_class log_class, const char *module, - const char *file, int lineno, - const char *fmt, ...) __attribute__((format (printf, 5, 6))); +void log_msg(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, ...) + __attribute__((format(printf, 5, 6))); -void log_errno( - enum log_class log_class, const char *module, - const char *file, int lineno, - const char *fmt, ...) __attribute__((format (printf, 5, 6))); +void log_errno(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, ...) + __attribute__((format(printf, 5, 6))); -void log_errno_provided( - enum log_class log_class, const char *module, - const char *file, int lineno, int _errno, - const char *fmt, ...) __attribute__((format (printf, 6, 7))); - -void log_msg_va( - enum log_class log_class, const char *module, - const char *file, int lineno, const char *fmt, va_list va) __attribute__((format (printf, 5, 0))); -void log_errno_va( - enum log_class log_class, const char *module, - const char *file, int lineno, - const char *fmt, va_list va) __attribute__((format (printf, 5, 0))); -void log_errno_provided_va( - enum log_class log_class, const char *module, - const char *file, int lineno, int _errno, - const char *fmt, va_list va) __attribute__((format (printf, 6, 0))); +void log_errno_provided(enum log_class log_class, const char *module, const char *file, int lineno, int _errno, + const char *fmt, ...) __attribute__((format(printf, 6, 7))); +void log_msg_va(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, va_list va) + __attribute__((format(printf, 5, 0))); +void log_errno_va(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, + va_list va) __attribute__((format(printf, 5, 0))); +void log_errno_provided_va(enum log_class log_class, const char *module, const char *file, int lineno, int _errno, + const char *fmt, va_list va) __attribute__((format(printf, 6, 0))); int log_level_from_string(const char *str); const char *log_level_string_hint(void); -#define LOG_ERR(...) \ - log_msg(LOG_CLASS_ERROR, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_ERRNO(...) \ - log_errno(LOG_CLASS_ERROR, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_ERRNO_P(_errno, ...) \ - log_errno_provided(LOG_CLASS_ERROR, LOG_MODULE, __FILE__, __LINE__, \ - _errno, __VA_ARGS__) -#define LOG_WARN(...) \ - log_msg(LOG_CLASS_WARNING, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_INFO(...) \ - log_msg(LOG_CLASS_INFO, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) +#define LOG_ERR(...) log_msg(LOG_CLASS_ERROR, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) +#define LOG_ERRNO(...) log_errno(LOG_CLASS_ERROR, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) +#define LOG_ERRNO_P(_errno, ...) \ + log_errno_provided(LOG_CLASS_ERROR, LOG_MODULE, __FILE__, __LINE__, _errno, __VA_ARGS__) +#define LOG_WARN(...) log_msg(LOG_CLASS_WARNING, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) +#define LOG_INFO(...) log_msg(LOG_CLASS_INFO, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) #if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG - #define LOG_DBG(...) \ - log_msg(LOG_CLASS_DEBUG, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) +#define LOG_DBG(...) log_msg(LOG_CLASS_DEBUG, LOG_MODULE, __FILE__, __LINE__, __VA_ARGS__) #else - #define LOG_DBG(...) +#define LOG_DBG(...) #endif diff --git a/main.c b/main.c index 5d9df44..a9c6932 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -9,14 +11,12 @@ #include #include #include -#include -#include -#include -#include -#include #include #include +#include +#include +#include #include "bar/bar.h" #include "config.h" @@ -147,9 +147,8 @@ print_pid(const char *pid_file, bool *unlink_at_exit) int pid_fd = strtoul(pid_file, &end, 10); if (errno != 0 || *end != '\0') { - if ((pid_fd = open(pid_file, - O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + if ((pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) + < 0) { LOG_ERRNO("%s: failed to open", pid_file); return false; } else @@ -178,16 +177,16 @@ int main(int argc, char *const *argv) { static const struct option longopts[] = { - {"backend", required_argument, 0, 'b'}, - {"config", required_argument, 0, 'c'}, - {"validate", no_argument, 0, 'C'}, - {"print-pid", required_argument, 0, 'p'}, - {"log-level", required_argument, 0, 'd'}, - {"log-colorize", optional_argument, 0, 'l'}, - {"log-no-syslog", no_argument, 0, 's'}, - {"version", no_argument, 0, 'v'}, - {"help", no_argument, 0, 'h'}, - {NULL, no_argument, 0, 0}, + {"backend", required_argument, 0, 'b'}, + {"config", required_argument, 0, 'c'}, + {"validate", no_argument, 0, 'C'}, + {"print-pid", required_argument, 0, 'p'}, + {"log-level", required_argument, 0, 'd'}, + {"log-colorize", optional_argument, 0, 'l'}, + {"log-no-syslog", no_argument, 0, 's'}, + {"version", no_argument, 0, 'v'}, + {"help", no_argument, 0, 'h'}, + {NULL, no_argument, 0, 0}, }; bool unlink_pid_file = false; @@ -224,8 +223,7 @@ main(int argc, char *const *argv) fprintf(stderr, "%s: invalid configuration file: %s\n", optarg, strerror(errno)); return EXIT_FAILURE; } else if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode)) { - fprintf(stderr, "%s: invalid configuration file: neither a regular file nor a pipe or FIFO\n", - optarg); + fprintf(stderr, "%s: invalid configuration file: neither a regular file nor a pipe or FIFO\n", optarg); return EXIT_FAILURE; } @@ -244,11 +242,7 @@ main(int argc, char *const *argv) case 'd': { int lvl = log_level_from_string(optarg); if (lvl < 0) { - fprintf( - stderr, - "-d,--log-level: %s: argument must be one of %s\n", - optarg, - log_level_string_hint()); + fprintf(stderr, "-d,--log-level: %s: argument must be one of %s\n", optarg, log_level_string_hint()); return EXIT_FAILURE; } log_level = lvl; @@ -292,12 +286,9 @@ main(int argc, char *const *argv) log_init(log_colorize, log_syslog, LOG_FACILITY_DAEMON, log_level); - _Static_assert((int)LOG_CLASS_ERROR == (int)FCFT_LOG_CLASS_ERROR, - "fcft log level enum offset"); - _Static_assert((int)LOG_COLORIZE_ALWAYS == (int)FCFT_LOG_COLORIZE_ALWAYS, - "fcft colorize enum mismatch"); - fcft_init((enum fcft_log_colorize)log_colorize, log_syslog, - (enum fcft_log_class)log_level); + _Static_assert((int)LOG_CLASS_ERROR == (int)FCFT_LOG_CLASS_ERROR, "fcft log level enum offset"); + _Static_assert((int)LOG_COLORIZE_ALWAYS == (int)FCFT_LOG_COLORIZE_ALWAYS, "fcft colorize enum mismatch"); + fcft_init((enum fcft_log_colorize)log_colorize, log_syslog, (enum fcft_log_class)log_level); atexit(&fcft_fini); const struct sigaction sa = {.sa_handler = &signal_handler}; diff --git a/module.c b/module.c index 1e80c32..d3bde3b 100644 --- a/module.c +++ b/module.c @@ -1,6 +1,6 @@ #include "module.h" -#include #include +#include #include struct module * diff --git a/module.h b/module.h index 5f1bc7c..3a83cdc 100644 --- a/module.h +++ b/module.h @@ -35,9 +35,9 @@ void module_default_destroy(struct module *mod); struct exposable *module_begin_expose(struct module *mod); /* List of attributes *all* modules implement */ -#define MODULE_COMMON_ATTRS \ - {"content", true, &conf_verify_particle}, \ - {"anchors", false, NULL}, \ - {"font", false, &conf_verify_font}, \ - {"foreground", false, &conf_verify_color}, \ - {NULL, false, NULL} +#define MODULE_COMMON_ATTRS \ + {"content", true, &conf_verify_particle}, {"anchors", false, NULL}, {"font", false, &conf_verify_font}, \ + {"foreground", false, &conf_verify_color}, \ + { \ + NULL, false, NULL \ + } diff --git a/modules/alsa.c b/modules/alsa.c index 6003ae6..8d7cd25 100644 --- a/modules/alsa.c +++ b/modules/alsa.c @@ -1,8 +1,8 @@ +#include #include #include -#include -#include #include +#include #include @@ -10,10 +10,10 @@ #define LOG_MODULE "alsa" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" #include "../config-verify.h" #include "../config.h" +#include "../log.h" #include "../plugin.h" enum channel_type { CHANNEL_PLAYBACK, CHANNEL_CAPTURE }; @@ -29,7 +29,8 @@ struct channel { bool muted; }; -struct private { +struct private +{ char *card; char *mixer; char *volume_name; @@ -70,7 +71,8 @@ static void destroy(struct module *mod) { struct private *m = mod->private; - tll_foreach(m->channels, it) { + tll_foreach(m->channels, it) + { channel_free(&it->item); tll_remove(m->channels, it); } @@ -129,9 +131,7 @@ content(struct module *mod) if (use_db) { bool use_linear = db_max - db_min <= 24 * 100; if (use_linear) { - percent = db_min - db_max > 0 - ? round(100. * (db_cur - db_min) / (db_max - db_min)) - : 0; + percent = db_min - db_max > 0 ? round(100. * (db_cur - db_min) / (db_max - db_min)) : 0; } else { double normalized = pow(10, (double)(db_cur - db_max) / 6000.); if (db_min != SND_CTL_TLV_DB_GAIN_MUTE) { @@ -141,9 +141,7 @@ content(struct module *mod) percent = round(100. * normalized); } } else { - percent = vol_max - vol_min > 0 - ? round(100. * (vol_cur - vol_min) / (vol_max - vol_min)) - : 0; + percent = vol_max - vol_min > 0 ? round(100. * (vol_cur - vol_min) / (vol_max - vol_min)) : 0; } struct tag_set tags = { @@ -173,107 +171,94 @@ update_state(struct module *mod, snd_mixer_elem_t *elem) /* If volume level can be changed (i.e. this isn't just a switch; * e.g. a digital channel), get current channel levels */ - tll_foreach(m->channels, it) { + tll_foreach(m->channels, it) + { struct channel *chan = &it->item; - const bool has_volume = chan->type == CHANNEL_PLAYBACK - ? m->has_playback_volume : m->has_capture_volume; - const bool has_db = chan->type == CHANNEL_PLAYBACK - ? m->has_playback_db : m->has_capture_db; + const bool has_volume = chan->type == CHANNEL_PLAYBACK ? m->has_playback_volume : m->has_capture_volume; + const bool has_db = chan->type == CHANNEL_PLAYBACK ? m->has_playback_db : m->has_capture_db; if (!has_volume && !has_db) continue; - if (has_db) { chan->use_db = true; - const long min = chan->type == CHANNEL_PLAYBACK - ? m->playback_db_min : m->capture_db_min; - const long max = chan->type == CHANNEL_PLAYBACK - ? m->playback_db_max : m->capture_db_max; + const long min = chan->type == CHANNEL_PLAYBACK ? m->playback_db_min : m->capture_db_min; + const long max = chan->type == CHANNEL_PLAYBACK ? m->playback_db_max : m->capture_db_max; assert(min <= max); - int r = chan->type == CHANNEL_PLAYBACK - ? snd_mixer_selem_get_playback_dB(elem, chan->id, &chan->db_cur) - : snd_mixer_selem_get_capture_dB(elem, chan->id, &chan->db_cur); + int r = chan->type == CHANNEL_PLAYBACK ? snd_mixer_selem_get_playback_dB(elem, chan->id, &chan->db_cur) + : snd_mixer_selem_get_capture_dB(elem, chan->id, &chan->db_cur); if (r < 0) { - LOG_ERR("%s,%s: %s: failed to get current dB", - m->card, m->mixer, chan->name); + LOG_ERR("%s,%s: %s: failed to get current dB", m->card, m->mixer, chan->name); } if (chan->db_cur < min) { - LOG_WARN( - "%s,%s: %s: current dB is less than the indicated minimum: " - "%ld < %ld", m->card, m->mixer, chan->name, chan->db_cur, min); + LOG_WARN("%s,%s: %s: current dB is less than the indicated minimum: " + "%ld < %ld", + m->card, m->mixer, chan->name, chan->db_cur, min); chan->db_cur = min; } if (chan->db_cur > max) { - LOG_WARN( - "%s,%s: %s: current dB is greater than the indicated maximum: " - "%ld > %ld", m->card, m->mixer, chan->name, chan->db_cur, max); + LOG_WARN("%s,%s: %s: current dB is greater than the indicated maximum: " + "%ld > %ld", + m->card, m->mixer, chan->name, chan->db_cur, max); chan->db_cur = max; } assert(chan->db_cur >= min); - assert(chan->db_cur <= max ); + assert(chan->db_cur <= max); - LOG_DBG("%s,%s: %s: dB: %ld", - m->card, m->mixer, chan->name, chan->db_cur); + LOG_DBG("%s,%s: %s: dB: %ld", m->card, m->mixer, chan->name, chan->db_cur); } else chan->use_db = false; - const long min = chan->type == CHANNEL_PLAYBACK - ? m->playback_vol_min : m->capture_vol_min; - const long max = chan->type == CHANNEL_PLAYBACK - ? m->playback_vol_max : m->capture_vol_max; + const long min = chan->type == CHANNEL_PLAYBACK ? m->playback_vol_min : m->capture_vol_min; + const long max = chan->type == CHANNEL_PLAYBACK ? m->playback_vol_max : m->capture_vol_max; assert(min <= max); - int r = chan->type == CHANNEL_PLAYBACK - ? snd_mixer_selem_get_playback_volume(elem, chan->id, &chan->vol_cur) - : snd_mixer_selem_get_capture_volume(elem, chan->id, &chan->vol_cur); + int r = chan->type == CHANNEL_PLAYBACK ? snd_mixer_selem_get_playback_volume(elem, chan->id, &chan->vol_cur) + : snd_mixer_selem_get_capture_volume(elem, chan->id, &chan->vol_cur); if (r < 0) { - LOG_ERR("%s,%s: %s: failed to get current volume", - m->card, m->mixer, chan->name); + LOG_ERR("%s,%s: %s: failed to get current volume", m->card, m->mixer, chan->name); } if (chan->vol_cur < min) { - LOG_WARN( - "%s,%s: %s: current volume is less than the indicated minimum: " - "%ld < %ld", m->card, m->mixer, chan->name, chan->vol_cur, min); + LOG_WARN("%s,%s: %s: current volume is less than the indicated minimum: " + "%ld < %ld", + m->card, m->mixer, chan->name, chan->vol_cur, min); chan->vol_cur = min; } if (chan->vol_cur > max) { - LOG_WARN( - "%s,%s: %s: current volume is greater than the indicated maximum: " - "%ld > %ld", m->card, m->mixer, chan->name, chan->vol_cur, max); + LOG_WARN("%s,%s: %s: current volume is greater than the indicated maximum: " + "%ld > %ld", + m->card, m->mixer, chan->name, chan->vol_cur, max); chan->vol_cur = max; } assert(chan->vol_cur >= min); - assert(chan->vol_cur <= max ); + assert(chan->vol_cur <= max); - LOG_DBG("%s,%s: %s: volume: %ld", - m->card, m->mixer, chan->name, chan->vol_cur); + LOG_DBG("%s,%s: %s: volume: %ld", m->card, m->mixer, chan->name, chan->vol_cur); } /* Get channels’ muted state */ - tll_foreach(m->channels, it) { + tll_foreach(m->channels, it) + { struct channel *chan = &it->item; int unmuted; - int r = chan->type == CHANNEL_PLAYBACK - ? snd_mixer_selem_get_playback_switch(elem, chan->id, &unmuted) - : snd_mixer_selem_get_capture_switch(elem, chan->id, &unmuted); + int r = chan->type == CHANNEL_PLAYBACK ? snd_mixer_selem_get_playback_switch(elem, chan->id, &unmuted) + : snd_mixer_selem_get_capture_switch(elem, chan->id, &unmuted); if (r < 0) { - LOG_WARN("%s,%s: %s: failed to get muted state", - m->card, m->mixer, chan->name); + LOG_WARN("%s,%s: %s: failed to get muted state", m->card, m->mixer, chan->name); unmuted = 1; } @@ -309,10 +294,8 @@ run_while_online(struct module *mod) return ret; } - if (snd_mixer_attach(handle, m->card) != 0 || - snd_mixer_selem_register(handle, NULL, NULL) != 0 || - snd_mixer_load(handle) != 0) - { + if (snd_mixer_attach(handle, m->card) != 0 || snd_mixer_selem_register(handle, NULL, NULL) != 0 + || snd_mixer_load(handle) != 0) { LOG_ERR("failed to attach to card"); ret = RUN_FAILED_CONNECT; goto err; @@ -323,7 +306,7 @@ run_while_online(struct module *mod) snd_mixer_selem_id_set_index(sid, 0); snd_mixer_selem_id_set_name(sid, m->mixer); - snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid); + snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid); if (elem == NULL) { LOG_ERR("failed to find mixer"); goto err; @@ -332,30 +315,24 @@ run_while_online(struct module *mod) /* Get playback volume range */ m->has_playback_volume = snd_mixer_selem_has_playback_volume(elem) > 0; if (m->has_playback_volume) { - if (snd_mixer_selem_get_playback_volume_range( - elem, &m->playback_vol_min, &m->playback_vol_max) < 0) - { - LOG_ERR("%s,%s: failed to get playback volume range", - m->card, m->mixer); + if (snd_mixer_selem_get_playback_volume_range(elem, &m->playback_vol_min, &m->playback_vol_max) < 0) { + LOG_ERR("%s,%s: failed to get playback volume range", m->card, m->mixer); assert(m->playback_vol_min == 0); assert(m->playback_vol_max == 0); } if (m->playback_vol_min > m->playback_vol_max) { - LOG_WARN( - "%s,%s: indicated minimum playback volume is greater than the " - "maximum: %ld > %ld", - m->card, m->mixer, m->playback_vol_min, m->playback_vol_max); + LOG_WARN("%s,%s: indicated minimum playback volume is greater than the " + "maximum: %ld > %ld", + m->card, m->mixer, m->playback_vol_min, m->playback_vol_max); m->playback_vol_min = m->playback_vol_max; } } - if (snd_mixer_selem_get_playback_dB_range( - elem, &m->playback_db_min, &m->playback_db_max) < 0) - { - LOG_WARN( - "%s,%s: failed to get playback dB range, " - "will use raw volume values instead", m->card, m->mixer); + if (snd_mixer_selem_get_playback_dB_range(elem, &m->playback_db_min, &m->playback_db_max) < 0) { + LOG_WARN("%s,%s: failed to get playback dB range, " + "will use raw volume values instead", + m->card, m->mixer); m->has_playback_db = false; } else m->has_playback_db = true; @@ -363,30 +340,24 @@ run_while_online(struct module *mod) /* Get capture volume range */ m->has_capture_volume = snd_mixer_selem_has_capture_volume(elem) > 0; if (m->has_capture_volume) { - if (snd_mixer_selem_get_capture_volume_range( - elem, &m->capture_vol_min, &m->capture_vol_max) < 0) - { - LOG_ERR("%s,%s: failed to get capture volume range", - m->card, m->mixer); + if (snd_mixer_selem_get_capture_volume_range(elem, &m->capture_vol_min, &m->capture_vol_max) < 0) { + LOG_ERR("%s,%s: failed to get capture volume range", m->card, m->mixer); assert(m->capture_vol_min == 0); assert(m->capture_vol_max == 0); } if (m->capture_vol_min > m->capture_vol_max) { - LOG_WARN( - "%s,%s: indicated minimum capture volume is greater than the " - "maximum: %ld > %ld", - m->card, m->mixer, m->capture_vol_min, m->capture_vol_max); + LOG_WARN("%s,%s: indicated minimum capture volume is greater than the " + "maximum: %ld > %ld", + m->card, m->mixer, m->capture_vol_min, m->capture_vol_max); m->capture_vol_min = m->capture_vol_max; } } - if (snd_mixer_selem_get_capture_dB_range( - elem, &m->capture_db_min, &m->capture_db_max) < 0) - { - LOG_WARN( - "%s,%s: failed to get capture dB range, " - "will use raw volume values instead", m->card, m->mixer); + if (snd_mixer_selem_get_capture_dB_range(elem, &m->capture_db_min, &m->capture_db_max) < 0) { + LOG_WARN("%s,%s: failed to get capture dB range, " + "will use raw volume values instead", + m->card, m->mixer); m->has_capture_db = false; } else m->has_capture_db = true; @@ -400,7 +371,7 @@ run_while_online(struct module *mod) struct channel chan = { .id = i, .type = is_playback ? CHANNEL_PLAYBACK : CHANNEL_CAPTURE, - .name = strdup(snd_mixer_selem_channel_name( i)), + .name = strdup(snd_mixer_selem_channel_name(i)), }; tll_push_back(m->channels, chan); } @@ -413,13 +384,13 @@ run_while_online(struct module *mod) char channels_str[1024]; int channels_idx = 0; - tll_foreach(m->channels, it) { + tll_foreach(m->channels, it) + { const struct channel *chan = &it->item; - channels_idx += snprintf( - &channels_str[channels_idx], sizeof(channels_str) - channels_idx, - channels_idx == 0 ? "%s (%s)" : ", %s (%s)", - chan->name, chan->type == CHANNEL_PLAYBACK ? "🔊" : "🎤"); + channels_idx += snprintf(&channels_str[channels_idx], sizeof(channels_str) - channels_idx, + channels_idx == 0 ? "%s (%s)" : ", %s (%s)", chan->name, + chan->type == CHANNEL_PLAYBACK ? "🔊" : "🎤"); assert(channels_idx <= sizeof(channels_str)); } @@ -429,7 +400,8 @@ run_while_online(struct module *mod) bool volume_channel_is_valid = m->volume_name == NULL; bool muted_channel_is_valid = m->muted_name == NULL; - tll_foreach(m->channels, it) { + tll_foreach(m->channels, it) + { const struct channel *chan = &it->item; if (m->volume_name != NULL && strcmp(chan->name, m->volume_name) == 0) { m->volume_chan = chan; @@ -462,26 +434,14 @@ run_while_online(struct module *mod) update_state(mod, elem); LOG_INFO( - "%s,%s: %s range=%ld-%ld, current=%ld%s (sources: volume=%s, muted=%s)", - m->card, m->mixer, + "%s,%s: %s range=%ld-%ld, current=%ld%s (sources: volume=%s, muted=%s)", m->card, m->mixer, m->volume_chan->use_db ? "dB" : "volume", - (m->volume_chan->type == CHANNEL_PLAYBACK - ? (m->volume_chan->use_db - ? m->playback_db_min - : m->playback_vol_min) - : (m->volume_chan->use_db - ? m->capture_db_min - : m->capture_vol_min)), - (m->volume_chan->type == CHANNEL_PLAYBACK - ? (m->volume_chan->use_db - ? m->playback_db_max - : m->playback_vol_max) - : (m->volume_chan->use_db - ? m->capture_db_max - : m->capture_vol_max)), + (m->volume_chan->type == CHANNEL_PLAYBACK ? (m->volume_chan->use_db ? m->playback_db_min : m->playback_vol_min) + : (m->volume_chan->use_db ? m->capture_db_min : m->capture_vol_min)), + (m->volume_chan->type == CHANNEL_PLAYBACK ? (m->volume_chan->use_db ? m->playback_db_max : m->playback_vol_max) + : (m->volume_chan->use_db ? m->capture_db_max : m->capture_vol_max)), m->volume_chan->use_db ? m->volume_chan->db_cur : m->volume_chan->vol_cur, - m->muted_chan->muted ? " (muted)" : "", - m->volume_chan->name, m->muted_chan->name); + m->muted_chan->muted ? " (muted)" : "", m->volume_chan->name, m->muted_chan->name); mod->bar->refresh(mod->bar); @@ -595,8 +555,7 @@ run(struct module *mod) bool have_create_event = false; while (!have_create_event) { - struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, - {.fd = ifd, .events = POLLIN}}; + struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = ifd, .events = POLLIN}}; int r = poll(fds, sizeof(fds) / sizeof(fds[0]), -1); if (r < 0) { @@ -638,7 +597,7 @@ run(struct module *mod) break; /* Consume inotify data */ - for (const char *ptr = buf; ptr < buf + len; ) { + for (const char *ptr = buf; ptr < buf + len;) { const struct inotify_event *e = (const struct inotify_event *)ptr; if (e->mask & IN_CREATE) { @@ -656,23 +615,20 @@ out: if (wd >= 0) inotify_rm_watch(ifd, wd); if (ifd >= 0) - close (ifd); + close(ifd); return ret; } static struct module * -alsa_new(const char *card, const char *mixer, - const char *volume_channel_name, const char *muted_channel_name, +alsa_new(const char *card, const char *mixer, const char *volume_channel_name, const char *muted_channel_name, struct particle *label) { struct private *priv = calloc(1, sizeof(*priv)); priv->label = label; priv->card = strdup(card); priv->mixer = strdup(mixer); - priv->volume_name = - volume_channel_name != NULL ? strdup(volume_channel_name) : NULL; - priv->muted_name = - muted_channel_name != NULL ? strdup(muted_channel_name) : NULL; + priv->volume_name = volume_channel_name != NULL ? strdup(volume_channel_name) : NULL; + priv->muted_name = muted_channel_name != NULL ? strdup(muted_channel_name) : NULL; struct module *mod = module_common_new(); mod->private = priv; @@ -692,12 +648,9 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *muted = yml_get_value(node, "muted"); const struct yml_node *content = yml_get_value(node, "content"); - return alsa_new( - yml_value_as_string(card), - yml_value_as_string(mixer), - volume != NULL ? yml_value_as_string(volume) : NULL, - muted != NULL ? yml_value_as_string(muted) : NULL, - conf_to_particle(content, inherited)); + return alsa_new(yml_value_as_string(card), yml_value_as_string(mixer), + volume != NULL ? yml_value_as_string(volume) : NULL, + muted != NULL ? yml_value_as_string(muted) : NULL, conf_to_particle(content, inherited)); } static bool diff --git a/modules/backlight.c b/modules/backlight.c index 9f26a14..0fa1787 100644 --- a/modules/backlight.c +++ b/modules/backlight.c @@ -1,25 +1,26 @@ +#include +#include +#include +#include #include #include #include -#include -#include #include -#include -#include -#include #include +#include #include #define LOG_MODULE "backlight" -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../plugin.h" -struct private { +struct private +{ struct particle *label; char *device; @@ -145,8 +146,7 @@ initialize(struct private *m) m->current_brightness = readint_from_fd(current_fd); - LOG_INFO("%s: brightness: %ld (max: %ld)", m->device, m->current_brightness, - m->max_brightness); + LOG_INFO("%s: brightness: %ld (max: %ld)", m->device, m->current_brightness, m->max_brightness); return current_fd; } @@ -244,8 +244,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *name = yml_get_value(node, "name"); const struct yml_node *c = yml_get_value(node, "content"); - return backlight_new( - yml_value_as_string(name), conf_to_particle(c, inherited)); + return backlight_new(yml_value_as_string(name), conf_to_particle(c, inherited)); } static bool diff --git a/modules/battery.c b/modules/battery.c index c947649..c3507d7 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -1,26 +1,26 @@ +#include +#include +#include #include #include #include #include #include -#include -#include -#include #include -#include #include +#include #include #include #define LOG_MODULE "battery" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../plugin.h" #define max(x, y) ((x) > (y) ? (x) : (y)) @@ -37,7 +37,8 @@ struct current_state { struct timespec time; }; -struct private { +struct private +{ struct particle *label; long poll_interval; @@ -65,7 +66,7 @@ static int64_t difftimespec_ns(const struct timespec after, const struct timespec before) { return ((int64_t)after.tv_sec - (int64_t)before.tv_sec) * (int64_t)one_sec_in_ns - + ((int64_t)after.tv_nsec - (int64_t)before.tv_nsec); + + ((int64_t)after.tv_nsec - (int64_t)before.tv_nsec); } // Linear Exponential Moving Average (unevenly spaced time series) @@ -88,7 +89,7 @@ ema_linear(struct current_state *state, struct current_state curr, long tau) w2 = (1 - w) / tmp; } else { // Use taylor expansion for numerical stability - w2 = 1 - tmp/2 + tmp*tmp/6 - tmp*tmp*tmp/24; + w2 = 1 - tmp / 2 + tmp * tmp / 6 - tmp * tmp * tmp / 24; } double ema = state->ema * w + curr.current * (1 - w2) + state->current * (w2 - w); @@ -101,8 +102,7 @@ ema_linear(struct current_state *state, struct current_state curr, long tau) } static void -timespec_sub(const struct timespec *a, const struct timespec *b, - struct timespec *res) +timespec_sub(const struct timespec *a, const struct timespec *b, struct timespec *res) { res->tv_sec = a->tv_sec - b->tv_sec; @@ -145,11 +145,8 @@ content(struct module *mod) mtx_lock(&mod->lock); - assert(m->state == STATE_FULL || - m->state == STATE_NOTCHARGING || - m->state == STATE_CHARGING || - m->state == STATE_DISCHARGING || - m->state == STATE_UNKNOWN); + assert(m->state == STATE_FULL || m->state == STATE_NOTCHARGING || m->state == STATE_CHARGING + || m->state == STATE_DISCHARGING || m->state == STATE_UNKNOWN); unsigned long hours; unsigned long minutes; @@ -162,9 +159,8 @@ content(struct module *mod) minutes = m->time_to_full / 60; hours = minutes / 60; minutes = minutes % 60; - } else if (m->energy_full >= 0 && m->charge && m->power >= 0) { - unsigned long energy = m->state == STATE_CHARGING - ? m->energy_full - m->energy : m->energy; + } else if (m->energy_full >= 0 && m->charge && m->power >= 0) { + unsigned long energy = m->state == STATE_CHARGING ? m->energy_full - m->energy : m->energy; double hours_as_float; if (m->state == STATE_FULL || m->state == STATE_NOTCHARGING) @@ -177,8 +173,7 @@ content(struct module *mod) hours = hours_as_float; minutes = (hours_as_float - (double)hours) * 60; } else if (m->charge_full >= 0 && m->charge >= 0 && m->ema_current.current >= 0) { - unsigned long charge = m->state == STATE_CHARGING - ? m->charge_full - m->charge : m->charge; + unsigned long charge = m->state == STATE_CHARGING ? m->charge_full - m->charge : m->charge; double hours_as_float; if (m->state == STATE_FULL || m->state == STATE_NOTCHARGING) @@ -281,8 +276,7 @@ initialize(struct private *m) { int fd = openat(base_dir_fd, "manufacturer", O_RDONLY); if (fd == -1) { - LOG_WARN("/sys/class/power_supply/%s/manufacturer: %s", - m->battery, strerror(errno)); + LOG_WARN("/sys/class/power_supply/%s/manufacturer: %s", m->battery, strerror(errno)); m->manufacturer = NULL; } else { m->manufacturer = strdup(readline_from_fd(fd, sizeof(line_buf), line_buf)); @@ -293,8 +287,7 @@ initialize(struct private *m) { int fd = openat(base_dir_fd, "model_name", O_RDONLY); if (fd == -1) { - LOG_WARN("/sys/class/power_supply/%s/model_name: %s", - m->battery, strerror(errno)); + LOG_WARN("/sys/class/power_supply/%s/model_name: %s", m->battery, strerror(errno)); m->model = NULL; } else { m->model = strdup(readline_from_fd(fd, sizeof(line_buf), line_buf)); @@ -302,9 +295,8 @@ initialize(struct private *m) } } - if (faccessat(base_dir_fd, "energy_full_design", O_RDONLY, 0) == 0 && - faccessat(base_dir_fd, "energy_full", O_RDONLY, 0) == 0) - { + if (faccessat(base_dir_fd, "energy_full_design", O_RDONLY, 0) == 0 + && faccessat(base_dir_fd, "energy_full", O_RDONLY, 0) == 0) { { int fd = openat(base_dir_fd, "energy_full_design", O_RDONLY); if (fd == -1) { @@ -330,9 +322,8 @@ initialize(struct private *m) m->energy_full = m->energy_full_design = -1; } - if (faccessat(base_dir_fd, "charge_full_design", O_RDONLY, 0) == 0 && - faccessat(base_dir_fd, "charge_full", O_RDONLY, 0) == 0) - { + if (faccessat(base_dir_fd, "charge_full_design", O_RDONLY, 0) == 0 + && faccessat(base_dir_fd, "charge_full", O_RDONLY, 0) == 0) { { int fd = openat(base_dir_fd, "charge_full_design", O_RDONLY); if (fd == -1) { @@ -462,8 +453,8 @@ update_status(struct module *mod) } LOG_DBG("capacity: %ld, energy: %ld, power: %ld, charge=%ld, current=%ld, " - "time-to-empty: %ld, time-to-full: %ld", capacity, - energy, power, charge, current, time_to_empty, time_to_full); + "time-to-empty: %ld, time-to-full: %ld", + capacity, energy, power, charge, current, time_to_empty, time_to_full); mtx_lock(&mod->lock); if (m->state != state) { @@ -494,13 +485,10 @@ run(struct module *mod) if (!initialize(m)) return -1; - LOG_INFO("%s: %s %s (at %.1f%% of original capacity)", - m->battery, m->manufacturer, m->model, - (m->energy_full > 0 - ? 100.0 * m->energy_full / m->energy_full_design - : m->charge_full > 0 - ? 100.0 * m->charge_full / m->charge_full_design - : 0.0)); + LOG_INFO("%s: %s %s (at %.1f%% of original capacity)", m->battery, m->manufacturer, m->model, + (m->energy_full > 0 ? 100.0 * m->energy_full / m->energy_full_design + : m->charge_full > 0 ? 100.0 * m->charge_full / m->charge_full_design + : 0.0)); int ret = 1; @@ -555,12 +543,11 @@ run(struct module *mod) struct udev_device *dev = udev_monitor_receive_device(mon); if (dev != NULL) { const char *sysname = udev_device_get_sysname(dev); - udev_for_us = - sysname != NULL && strcmp(sysname, m->battery) == 0; + udev_for_us = sysname != NULL && strcmp(sysname, m->battery) == 0; if (!udev_for_us) { - LOG_DBG("udev notification not for us (%s != %s)", - m->battery, sysname != sysname ? sysname : "NULL"); + LOG_DBG("udev notification not for us (%s != %s)", m->battery, + sysname != sysname ? sysname : "NULL"); } else LOG_DBG("triggering update due to udev notification"); @@ -586,11 +573,9 @@ run(struct module *mod) struct timespec timeout_consumed; timespec_sub(&time_after_poll, &time_before_poll, &timeout_consumed); - const int timeout_consumed_ms = - timeout_consumed.tv_sec * 1000 + timeout_consumed.tv_nsec / 1000000; + const int timeout_consumed_ms = timeout_consumed.tv_sec * 1000 + timeout_consumed.tv_nsec / 1000000; - LOG_DBG("timeout-left before: %dms, consumed: %dms, updated: %dms", - timeout_left_ms, timeout_consumed_ms, + LOG_DBG("timeout-left before: %dms, consumed: %dms, updated: %dms", timeout_left_ms, timeout_consumed_ms, max(timeout_left_ms - timeout_consumed_ms, 0)); timeout_left_ms -= timeout_consumed_ms; @@ -608,7 +593,8 @@ out: } static struct module * -battery_new(const char *battery, struct particle *label, long poll_interval_msecs, int battery_scale, long smoothing_secs) +battery_new(const char *battery, struct particle *label, long poll_interval_msecs, int battery_scale, + long smoothing_secs) { struct private *m = calloc(1, sizeof(*m)); m->label = label; @@ -617,7 +603,7 @@ battery_new(const char *battery, struct particle *label, long poll_interval_msec m->smoothing_scale = smoothing_secs * one_sec_in_ns; m->battery = strdup(battery); m->state = STATE_UNKNOWN; - m->ema_current = (struct current_state){ -1, 0, (struct timespec){0, 0} }; + m->ema_current = (struct current_state){-1, 0, (struct timespec){0, 0}}; struct module *mod = module_common_new(); mod->private = m; @@ -637,18 +623,10 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *battery_scale = yml_get_value(node, "battery-scale"); const struct yml_node *smoothing_secs = yml_get_value(node, "smoothing-secs"); - return battery_new( - yml_value_as_string(name), - conf_to_particle(c, inherited), - (poll_interval != NULL - ? yml_value_as_int(poll_interval) - : default_poll_interval), - (battery_scale != NULL - ? yml_value_as_int(battery_scale) - : 1), - (smoothing_secs != NULL - ? yml_value_as_int(smoothing_secs) - : 100)); + return battery_new(yml_value_as_string(name), conf_to_particle(c, inherited), + (poll_interval != NULL ? yml_value_as_int(poll_interval) : default_poll_interval), + (battery_scale != NULL ? yml_value_as_int(battery_scale) : 1), + (smoothing_secs != NULL ? yml_value_as_int(smoothing_secs) : 100)); } static bool @@ -660,8 +638,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node) const long value = yml_value_as_int(node); if (value != 0 && value < min_poll_interval) { - LOG_ERR("%s: interval value cannot be less than %ldms", - conf_err_prefix(chain, node), min_poll_interval); + LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval); return false; } diff --git a/modules/clock.c b/modules/clock.c index 0487a9d..1758c0a 100644 --- a/modules/clock.c +++ b/modules/clock.c @@ -1,21 +1,22 @@ +#include +#include #include #include #include -#include -#include #include #include #define LOG_MODULE "clock" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../plugin.h" -struct private { +struct private +{ struct particle *label; enum { UPDATE_GRANULARITY_SECONDS, @@ -57,8 +58,7 @@ content(struct module *mod) strftime(time_str, sizeof(time_str), m->time_format, tm); struct tag_set tags = { - .tags = (struct tag *[]){tag_new_string(mod, "time", time_str), - tag_new_string(mod, "date", date_str)}, + .tags = (struct tag *[]){tag_new_string(mod, "time", time_str), tag_new_string(mod, "date", date_str)}, .count = 2, }; @@ -90,15 +90,12 @@ run(struct module *mod) switch (m->update_granularity) { case UPDATE_GRANULARITY_SECONDS: { - const struct timeval next_second = { - .tv_sec = now.tv_sec + 1, - .tv_usec = 0}; + const struct timeval next_second = {.tv_sec = now.tv_sec + 1, .tv_usec = 0}; struct timeval _timeout; timersub(&next_second, &now, &_timeout); - assert(_timeout.tv_sec == 0 || - (_timeout.tv_sec == 1 && _timeout.tv_usec == 0)); + assert(_timeout.tv_sec == 0 || (_timeout.tv_sec == 1 && _timeout.tv_usec == 0)); timeout_ms = _timeout.tv_usec / 1000; break; } @@ -118,8 +115,7 @@ run(struct module *mod) /* Add 1ms to account for rounding errors */ timeout_ms++; - LOG_DBG("now: %lds %ldµs -> timeout: %dms", - now.tv_sec, now.tv_usec, timeout_ms); + LOG_DBG("now: %lds %ldµs -> timeout: %dms", now.tv_sec, now.tv_usec, timeout_ms); struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}}; if (poll(fds, 1, timeout_ms) < 0) { @@ -142,8 +138,7 @@ run(struct module *mod) } static struct module * -clock_new(struct particle *label, const char *date_format, - const char *time_format, bool utc) +clock_new(struct particle *label, const char *date_format, const char *time_format, bool utc) { struct private *m = calloc(1, sizeof(*m)); m->label = label; @@ -152,20 +147,12 @@ clock_new(struct particle *label, const char *date_format, m->utc = utc; static const char *const seconds_formatters[] = { - "%c", - "%s", - "%S", - "%T", - "%r", - "%X", + "%c", "%s", "%S", "%T", "%r", "%X", }; m->update_granularity = UPDATE_GRANULARITY_MINUTES; - for (size_t i = 0; - i < sizeof(seconds_formatters) / sizeof(seconds_formatters[0]); - i++) - { + for (size_t i = 0; i < sizeof(seconds_formatters) / sizeof(seconds_formatters[0]); i++) { if (strstr(time_format, seconds_formatters[i]) != NULL) { m->update_granularity = UPDATE_GRANULARITY_SECONDS; break; @@ -173,8 +160,7 @@ clock_new(struct particle *label, const char *date_format, } LOG_DBG("using %s update granularity", - (m->update_granularity == UPDATE_GRANULARITY_MINUTES - ? "minutes" : "seconds")); + (m->update_granularity == UPDATE_GRANULARITY_MINUTES ? "minutes" : "seconds")); struct module *mod = module_common_new(); mod->private = m; @@ -193,11 +179,9 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *time_format = yml_get_value(node, "time-format"); const struct yml_node *utc = yml_get_value(node, "utc"); - return clock_new( - conf_to_particle(c, inherited), - date_format != NULL ? yml_value_as_string(date_format) : "%x", - time_format != NULL ? yml_value_as_string(time_format) : "%H:%M", - utc != NULL ? yml_value_as_bool(utc) : false); + return clock_new(conf_to_particle(c, inherited), date_format != NULL ? yml_value_as_string(date_format) : "%x", + time_format != NULL ? yml_value_as_string(time_format) : "%H:%M", + utc != NULL ? yml_value_as_bool(utc) : false); } static bool diff --git a/modules/cpu.c b/modules/cpu.c index 455d45d..833c188 100644 --- a/modules/cpu.c +++ b/modules/cpu.c @@ -31,7 +31,8 @@ struct cpu_stats { uint32_t *cur_cores_nidle; }; -struct private { +struct private +{ struct particle *template; uint16_t interval; size_t core_count; @@ -69,28 +70,22 @@ get_cpu_nb_cores() } static bool -parse_proc_stat_line(const char *line, uint32_t *user, uint32_t *nice, - uint32_t *system, uint32_t *idle, uint32_t *iowait, - uint32_t *irq, uint32_t *softirq, uint32_t *steal, - uint32_t *guest, uint32_t *guestnice) +parse_proc_stat_line(const char *line, uint32_t *user, uint32_t *nice, uint32_t *system, uint32_t *idle, + uint32_t *iowait, uint32_t *irq, uint32_t *softirq, uint32_t *steal, uint32_t *guest, + uint32_t *guestnice) { int32_t core_id; if (line[sizeof("cpu") - 1] == ' ') { - int read = sscanf( - line, - "cpu %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 - " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32, - user, nice, system, idle, iowait, irq, softirq, steal, guest, - guestnice); + int read = sscanf(line, + "cpu %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 + " %" SCNu32 " %" SCNu32 " %" SCNu32, + user, nice, system, idle, iowait, irq, softirq, steal, guest, guestnice); return read == 10; } else { - int read = sscanf( - line, - "cpu%" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 - " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 - " %" SCNu32, - &core_id, user, nice, system, idle, iowait, irq, softirq, steal, - guest, guestnice); + int read = sscanf(line, + "cpu%" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 + " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32, + &core_id, user, nice, system, idle, iowait, irq, softirq, steal, guest, guestnice); return read == 11; } } @@ -98,18 +93,12 @@ parse_proc_stat_line(const char *line, uint32_t *user, uint32_t *nice, static uint8_t get_cpu_usage_percent(const struct cpu_stats *cpu_stats, int8_t core_idx) { - uint32_t prev_total = - cpu_stats->prev_cores_idle[core_idx + 1] + - cpu_stats->prev_cores_nidle[core_idx + 1]; + uint32_t prev_total = cpu_stats->prev_cores_idle[core_idx + 1] + cpu_stats->prev_cores_nidle[core_idx + 1]; - uint32_t cur_total = - cpu_stats->cur_cores_idle[core_idx + 1] + - cpu_stats->cur_cores_nidle[core_idx + 1]; + uint32_t cur_total = cpu_stats->cur_cores_idle[core_idx + 1] + cpu_stats->cur_cores_nidle[core_idx + 1]; double totald = cur_total - prev_total; - double nidled = - cpu_stats->cur_cores_nidle[core_idx + 1] - - cpu_stats->prev_cores_nidle[core_idx + 1]; + double nidled = cpu_stats->cur_cores_nidle[core_idx + 1] - cpu_stats->prev_cores_nidle[core_idx + 1]; double percent = (nidled * 100) / (totald + 1); return round(percent); @@ -143,10 +132,8 @@ refresh_cpu_stats(struct cpu_stats *cpu_stats, size_t core_count) while ((read = getline(&line, &len, fp)) != -1 && core <= core_count) { if (strncmp(line, "cpu", sizeof("cpu") - 1) == 0) { - if (!parse_proc_stat_line( - line, &user, &nice, &system, &idle, &iowait, &irq, &softirq, - &steal, &guest, &guestnice)) - { + if (!parse_proc_stat_line(line, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal, &guest, + &guestnice)) { LOG_ERR("unable to parse /proc/stat line"); goto exit; } @@ -251,15 +238,11 @@ cpu_new(uint16_t interval, struct particle *template) p->interval = interval; p->core_count = nb_cores; - p->cpu_stats.prev_cores_nidle = calloc( - nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_nidle)); - p->cpu_stats.prev_cores_idle = calloc( - nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_idle)); + p->cpu_stats.prev_cores_nidle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_nidle)); + p->cpu_stats.prev_cores_idle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_idle)); - p->cpu_stats.cur_cores_nidle = calloc( - nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_nidle)); - p->cpu_stats.cur_cores_idle = calloc( - nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_idle)); + p->cpu_stats.cur_cores_nidle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_nidle)); + p->cpu_stats.cur_cores_idle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_idle)); struct module *mod = module_common_new(); mod->private = p; @@ -276,9 +259,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *interval = yml_get_value(node, "poll-interval"); const struct yml_node *c = yml_get_value(node, "content"); - return cpu_new( - interval == NULL ? min_poll_interval : yml_value_as_int(interval), - conf_to_particle(c, inherited)); + return cpu_new(interval == NULL ? min_poll_interval : yml_value_as_int(interval), conf_to_particle(c, inherited)); } static bool @@ -288,8 +269,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node) return false; if (yml_value_as_int(node) < min_poll_interval) { - LOG_ERR("%s: interval value cannot be less than %ldms", - conf_err_prefix(chain, node), min_poll_interval); + LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval); return false; } diff --git a/modules/disk-io.c b/modules/disk-io.c index 7bf48e8..90abdba 100644 --- a/modules/disk-io.c +++ b/modules/disk-io.c @@ -1,9 +1,9 @@ +#include #include #include #include #include #include -#include #include @@ -34,7 +34,8 @@ struct device_stats { bool exists; }; -struct private { +struct private +{ struct particle *label; uint16_t interval; tll(struct device_stats *) devices; @@ -63,7 +64,7 @@ is_disk(char const *name) return found; } -static struct device_stats* +static struct device_stats * new_device_stats(char const *name) { struct device_stats *dev = malloc(sizeof(*dev)); @@ -84,9 +85,7 @@ destroy(struct module *mod) { struct private *m = mod->private; m->label->destroy(m->label); - tll_foreach(m->devices, it) { - free_device_stats(it->item); - } + tll_foreach(m->devices, it) { free_device_stats(it->item); } tll_free(m->devices); free(m); module_default_destroy(mod); @@ -126,9 +125,7 @@ refresh_device_stats(struct private *m) * The 'exists' variable is what keep tracks of whether or not /proc/diskstats * is still reporting the device (i.e., it is still connected). */ - tll_foreach(m->devices, it) { - it->item->exists = false; - } + tll_foreach(m->devices, it) { it->item->exists = false; } while ((read = getline(&line, &len, fp)) != -1) { /* @@ -156,25 +153,23 @@ refresh_device_stats(struct private *m) uint32_t completed_flushes = 0; uint32_t flushing_time = 0; if (!sscanf(line, - " %" SCNu8 " %" SCNu8 " %ms %" SCNu32 " %" SCNu32 " %" SCNu64 " %" SCNu32 - " %" SCNu32 " %" SCNu32 " %" SCNu64 " %" SCNu32 " %" SCNu32 " %" SCNu32 - " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 - " %" SCNu32, - &major_number, &minor_number, &device_name, &completed_reads, - &merged_reads, §ors_read, &reading_time, &completed_writes, - &merged_writes, §ors_written, &writting_time, &ios_in_progress, - &io_time, &io_weighted_time, &completed_discards, &merged_discards, - §ors_discarded, &discarding_time, &completed_flushes, &flushing_time)) - { + " %" SCNu8 " %" SCNu8 " %ms %" SCNu32 " %" SCNu32 " %" SCNu64 " %" SCNu32 " %" SCNu32 " %" SCNu32 + " %" SCNu64 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 + " %" SCNu32 " %" SCNu32 " %" SCNu32, + &major_number, &minor_number, &device_name, &completed_reads, &merged_reads, §ors_read, + &reading_time, &completed_writes, &merged_writes, §ors_written, &writting_time, + &ios_in_progress, &io_time, &io_weighted_time, &completed_discards, &merged_discards, + §ors_discarded, &discarding_time, &completed_flushes, &flushing_time)) { LOG_ERR("unable to parse /proc/diskstats line"); free(device_name); goto exit; } bool found = false; - tll_foreach(m->devices, it) { + tll_foreach(m->devices, it) + { struct device_stats *dev = it->item; - if (strcmp(dev->name, device_name) == 0){ + if (strcmp(dev->name, device_name) == 0) { dev->prev_sectors_read = dev->cur_sectors_read; dev->prev_sectors_written = dev->cur_sectors_written; dev->ios_in_progress = ios_in_progress; @@ -200,8 +195,9 @@ refresh_device_stats(struct private *m) free(device_name); } - tll_foreach(m->devices, it) { - if (!it->item->exists){ + tll_foreach(m->devices, it) + { + if (!it->item->exists) { free_device_stats(it->item); tll_remove(m->devices, it); } @@ -221,12 +217,13 @@ content(struct module *mod) mtx_lock(&mod->lock); struct exposable *tag_parts[p->devices.length + 1]; int i = 0; - tll_foreach(p->devices, it) { + tll_foreach(p->devices, it) + { struct device_stats *dev = it->item; uint64_t bytes_read = (dev->cur_sectors_read - dev->prev_sectors_read) * 512; uint64_t bytes_written = (dev->cur_sectors_written - dev->prev_sectors_written) * 512; - if (dev->is_disk){ + if (dev->is_disk) { total_bytes_read += bytes_read; total_bytes_written += bytes_written; total_ios_in_progress += dev->ios_in_progress; @@ -314,9 +311,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *interval = yml_get_value(node, "poll-interval"); const struct yml_node *c = yml_get_value(node, "content"); - return disk_io_new( - interval == NULL ? min_poll_interval : yml_value_as_int(interval), - conf_to_particle(c, inherited)); + return disk_io_new(interval == NULL ? min_poll_interval : yml_value_as_int(interval), + conf_to_particle(c, inherited)); } static bool @@ -326,9 +322,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node) return false; if (yml_value_as_int(node) < min_poll_interval) { - LOG_ERR( - "%s: poll-interval value cannot be less than %ldms", - conf_err_prefix(chain, node), min_poll_interval); + LOG_ERR("%s: poll-interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval); return false; } diff --git a/modules/dwl.c b/modules/dwl.c index a9a5bab..4d9e8fa 100644 --- a/modules/dwl.c +++ b/modules/dwl.c @@ -249,13 +249,16 @@ process_line(char *line, struct module *module) assert(false); /* unreachable */ break; case LINE_MODE_FULLSCREEN: - private->fullscreen = (strcmp(string, "0") != 0); + private + ->fullscreen = (strcmp(string, "0") != 0); break; case LINE_MODE_FLOATING: - private->floating = (strcmp(string, "0") != 0); + private + ->floating = (strcmp(string, "0") != 0); break; case LINE_MODE_SELMON: - private->selmon = (strcmp(string, "0") != 0); + private + ->selmon = (strcmp(string, "0") != 0); break; case LINE_MODE_LAYOUT: free(private->layout); @@ -438,8 +441,7 @@ run(struct module *module) } static struct module * -dwl_new(struct particle *label, int number_of_tags, - struct yml_node const *name_of_tags, char const *dwl_info_filename) +dwl_new(struct particle *label, int number_of_tags, struct yml_node const *name_of_tags, char const *dwl_info_filename) { struct private *private = calloc(1, sizeof(struct private)); private->label = label; @@ -480,8 +482,8 @@ from_conf(struct yml_node const *node, struct conf_inherit inherited) struct yml_node const *name_of_tags = yml_get_value(node, "name-of-tags"); struct yml_node const *dwl_info_filename = yml_get_value(node, "dwl-info-filename"); - return dwl_new(conf_to_particle(content, inherited), yml_value_as_int(number_of_tags), - name_of_tags, yml_value_as_string(dwl_info_filename)); + return dwl_new(conf_to_particle(content, inherited), yml_value_as_int(number_of_tags), name_of_tags, + yml_value_as_string(dwl_info_filename)); } static bool diff --git a/modules/foreign-toplevel.c b/modules/foreign-toplevel.c index d454a39..ccd6d5b 100644 --- a/modules/foreign-toplevel.c +++ b/modules/foreign-toplevel.c @@ -1,7 +1,7 @@ -#include -#include #include #include +#include +#include #include @@ -11,8 +11,8 @@ #define LOG_MODULE "foreign-toplevel" #define LOG_ENABLE_DBG 0 #include "../log.h" -#include "../plugin.h" #include "../particles/dynlist.h" +#include "../plugin.h" #include "wlr-foreign-toplevel-management-unstable-v1.h" #include "xdg-output-unstable-v1.h" @@ -46,7 +46,8 @@ struct toplevel { tll(const struct output *) outputs; }; -struct private { +struct private +{ struct particle *template; uint32_t manager_wl_name; struct zwlr_foreign_toplevel_manager_v1 *manager; @@ -110,7 +111,8 @@ content(struct module *mod) const char *current_output = mod->bar->output_name(mod->bar); - tll_foreach(m->toplevels, it) { + tll_foreach(m->toplevels, it) + { const struct toplevel *top = &it->item; bool show = false; @@ -118,11 +120,10 @@ content(struct module *mod) if (m->all_monitors) show = true; else if (current_output != NULL) { - tll_foreach(top->outputs, it2) { + tll_foreach(top->outputs, it2) + { const struct output *output = it2->item; - if (output->name != NULL && - strcmp(output->name, current_output) == 0) - { + if (output->name != NULL && strcmp(output->name, current_output) == 0) { show = true; break; } @@ -158,22 +159,18 @@ verify_iface_version(const char *iface, uint32_t version, uint32_t wanted) if (version >= wanted) return true; - LOG_ERR("%s: need interface version %u, but compositor only implements %u", - iface, wanted, version); + LOG_ERR("%s: need interface version %u, but compositor only implements %u", iface, wanted, version); return false; } static void -xdg_output_handle_logical_position(void *data, - struct zxdg_output_v1 *xdg_output, - int32_t x, int32_t y) +xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) { } static void -xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, - int32_t width, int32_t height) +xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) { } @@ -183,8 +180,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) } static void -xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, - const char *name) +xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name) { struct output *output = data; struct module *mod = output->mod; @@ -198,8 +194,7 @@ xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, } static void -xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, - const char *description) +xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, const char *description) { } @@ -238,8 +233,7 @@ app_id(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, const char *a } static void -output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, - struct wl_output *wl_output) +output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct wl_output *wl_output) { struct toplevel *top = data; struct module *mod = top->mod; @@ -248,7 +242,8 @@ output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, mtx_lock(&mod->lock); const struct output *output = NULL; - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { if (it->item.wl_output == wl_output) { output = &it->item; break; @@ -260,7 +255,8 @@ output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, goto out; } - tll_foreach(top->outputs, it) { + tll_foreach(top->outputs, it) + { if (it->item == output) { LOG_ERR("output-enter event on output we're already on"); goto out; @@ -275,8 +271,7 @@ out: } static void -output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, - struct wl_output *wl_output) +output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct wl_output *wl_output) { struct toplevel *top = data; struct module *mod = top->mod; @@ -285,7 +280,8 @@ output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, mtx_lock(&mod->lock); const struct output *output = NULL; - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { if (it->item.wl_output == wl_output) { output = &it->item; break; @@ -298,10 +294,10 @@ output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, } bool output_removed = false; - tll_foreach(top->outputs, it) { + tll_foreach(top->outputs, it) + { if (it->item == output) { - LOG_DBG("unmapped: %s:%s from %s", - top->app_id, top->title, output->name); + LOG_DBG("unmapped: %s:%s from %s", top->app_id, top->title, output->name); tll_remove(top->outputs, it); output_removed = true; break; @@ -318,8 +314,7 @@ out: } static void -state(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, - struct wl_array *states) +state(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct wl_array *states) { struct toplevel *top = data; @@ -329,12 +324,21 @@ state(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, bool fullscreen = false; enum zwlr_foreign_toplevel_handle_v1_state *state; - wl_array_for_each(state, states) { + wl_array_for_each(state, states) + { switch (*state) { - case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED: maximized = true; break; - case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED: minimized = true; break; - case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED: activated = true; break; - case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN: fullscreen = true; break; + case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED: + maximized = true; + break; + case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED: + minimized = true; + break; + case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED: + activated = true; + break; + case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN: + fullscreen = true; + break; } } @@ -364,7 +368,8 @@ closed(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle) struct private *m = mod->private; mtx_lock(&mod->lock); - tll_foreach(m->toplevels, it) { + tll_foreach(m->toplevels, it) + { if (it->item.handle == handle) { toplevel_free(top); tll_remove(m->toplevels, it); @@ -378,9 +383,7 @@ closed(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle) } static void -parent(void *data, - struct zwlr_foreign_toplevel_handle_v1 *handle, - struct zwlr_foreign_toplevel_handle_v1 *parent) +parent(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct zwlr_foreign_toplevel_handle_v1 *parent) { } @@ -396,9 +399,7 @@ static const struct zwlr_foreign_toplevel_handle_v1_listener toplevel_listener = }; static void -toplevel(void *data, - struct zwlr_foreign_toplevel_manager_v1 *manager, - struct zwlr_foreign_toplevel_handle_v1 *handle) +toplevel(void *data, struct zwlr_foreign_toplevel_manager_v1 *manager, struct zwlr_foreign_toplevel_handle_v1 *handle) { struct module *mod = data; struct private *m = mod->private; @@ -412,15 +413,13 @@ toplevel(void *data, { tll_push_back(m->toplevels, toplevel); - zwlr_foreign_toplevel_handle_v1_add_listener( - handle, &toplevel_listener, &tll_back(m->toplevels)); + zwlr_foreign_toplevel_handle_v1_add_listener(handle, &toplevel_listener, &tll_back(m->toplevels)); } mtx_unlock(&mod->lock); } static void -finished(void *data, - struct zwlr_foreign_toplevel_manager_v1 *manager) +finished(void *data, struct zwlr_foreign_toplevel_manager_v1 *manager) { struct module *mod = data; struct private *m = mod->private; @@ -445,15 +444,12 @@ output_xdg_output(struct output *output) if (output->xdg_output != NULL) return; - output->xdg_output = zxdg_output_manager_v1_get_xdg_output( - m->xdg_output_manager, output->wl_output); - zxdg_output_v1_add_listener( - output->xdg_output, &xdg_output_listener, output); + output->xdg_output = zxdg_output_manager_v1_get_xdg_output(m->xdg_output_manager, output->wl_output); + zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output); } static void -handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) +handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct module *mod = data; struct private *m = mod->private; @@ -473,8 +469,7 @@ handle_global(void *data, struct wl_registry *registry, struct output output = { .mod = mod, .wl_name = name, - .wl_output = wl_registry_bind( - registry, name, &wl_output_interface, required), + .wl_output = wl_registry_bind(registry, name, &wl_output_interface, required), }; mtx_lock(&mod->lock); @@ -488,12 +483,10 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - m->xdg_output_manager = wl_registry_bind( - registry, name, &zxdg_output_manager_v1_interface, required); + m->xdg_output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, required); mtx_lock(&mod->lock); - tll_foreach(m->outputs, it) - output_xdg_output(&it->item); + tll_foreach(m->outputs, it) output_xdg_output(&it->item); mtx_unlock(&mod->lock); } } @@ -506,16 +499,19 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) mtx_lock(&mod->lock); - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { const struct output *output = &it->item; if (output->wl_name == name) { /* Loop all toplevels */ - tll_foreach(m->toplevels, it2) { + tll_foreach(m->toplevels, it2) + { /* And remove this output from their list of tracked * outputs */ - tll_foreach(it2->item.outputs, it3) { + tll_foreach(it2->item.outputs, it3) + { if (it3->item == output) { tll_remove(it2->item.outputs, it3); break; @@ -551,9 +547,8 @@ run(struct module *mod) goto out; } - if ((registry = wl_display_get_registry(display)) == NULL || - wl_registry_add_listener(registry, ®istry_listener, mod) != 0) - { + if ((registry = wl_display_get_registry(display)) == NULL + || wl_registry_add_listener(registry, ®istry_listener, mod) != 0) { LOG_ERR("failed to get Wayland registry"); goto out; } @@ -561,18 +556,14 @@ run(struct module *mod) wl_display_roundtrip(display); if (m->manager_wl_name == 0) { - LOG_ERR( - "compositor does not implement the foreign-toplevel-manager interface"); + LOG_ERR("compositor does not implement the foreign-toplevel-manager interface"); goto out; } - m->manager = wl_registry_bind( - registry, m->manager_wl_name, - &zwlr_foreign_toplevel_manager_v1_interface, - required_manager_interface_version); + m->manager = wl_registry_bind(registry, m->manager_wl_name, &zwlr_foreign_toplevel_manager_v1_interface, + required_manager_interface_version); - zwlr_foreign_toplevel_manager_v1_add_listener( - m->manager, &manager_listener, mod); + zwlr_foreign_toplevel_manager_v1_add_listener(m->manager, &manager_listener, mod); while (true) { wl_display_flush(display); @@ -606,12 +597,14 @@ run(struct module *mod) } out: - tll_foreach(m->toplevels, it) { + tll_foreach(m->toplevels, it) + { toplevel_free(&it->item); tll_remove(m->toplevels, it); } - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { output_free(&it->item); tll_remove(m->outputs, it); } @@ -649,9 +642,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *c = yml_get_value(node, "content"); const struct yml_node *all_monitors = yml_get_value(node, "all-monitors"); - return ftop_new( - conf_to_particle(c, inherited), - all_monitors != NULL ? yml_value_as_bool(all_monitors) : false); + return ftop_new(conf_to_particle(c, inherited), all_monitors != NULL ? yml_value_as_bool(all_monitors) : false); } static bool diff --git a/modules/i3-common.c b/modules/i3-common.c index a0769f2..957a4d2 100644 --- a/modules/i3-common.c +++ b/modules/i3-common.c @@ -1,15 +1,15 @@ #include "i3-common.h" +#include #include #include #include -#include #include #if defined(ENABLE_X11) - #include - #include +#include +#include #endif #include @@ -19,7 +19,7 @@ #include "../log.h" #if defined(ENABLE_X11) - #include "../xcb.h" +#include "../xcb.h" #endif #include "i3-ipc.h" @@ -41,14 +41,11 @@ get_socket_address_x11(struct sockaddr_un *addr) xcb_atom_t atom = get_atom(conn, "I3_SOCKET_PATH"); assert(atom != XCB_ATOM_NONE); - xcb_get_property_cookie_t cookie - = xcb_get_property_unchecked( - conn, false, screen->root, atom, - XCB_GET_PROPERTY_TYPE_ANY, 0, sizeof(addr->sun_path)); + xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(conn, false, screen->root, atom, + XCB_GET_PROPERTY_TYPE_ANY, 0, sizeof(addr->sun_path)); xcb_generic_error_t *err = NULL; - xcb_get_property_reply_t *reply = - xcb_get_property_reply(conn, cookie, &err); + xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, cookie, &err); bool ret = false; if (err != NULL) { @@ -102,11 +99,7 @@ bool i3_send_pkg(int sock, int cmd, char *data) { const size_t size = data != NULL ? strlen(data) : 0; - const i3_ipc_header_t hdr = { - .magic = I3_IPC_MAGIC, - .size = size, - .type = cmd - }; + const i3_ipc_header_t hdr = {.magic = I3_IPC_MAGIC, .size = size, .type = cmd}; if (write(sock, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) return false; @@ -120,8 +113,7 @@ i3_send_pkg(int sock, int cmd, char *data) } bool -i3_receive_loop(int abort_fd, int sock, - const struct i3_ipc_callbacks *cbs, void *data) +i3_receive_loop(int abort_fd, int sock, const struct i3_ipc_callbacks *cbs, void *data) { /* Initial reply typically requires a couple of KB. But we often * need more later. For example, switching workspaces can result @@ -133,10 +125,7 @@ i3_receive_loop(int abort_fd, int sock, bool err = false; while (!err) { - struct pollfd fds[] = { - {.fd = abort_fd, .events = POLLIN}, - {.fd = sock, .events = POLLIN} - }; + struct pollfd fds[] = {{.fd = abort_fd, .events = POLLIN}, {.fd = sock, .events = POLLIN}}; int res = poll(fds, 2, -1); if (res <= 0) { @@ -159,13 +148,11 @@ i3_receive_loop(int abort_fd, int sock, /* Grow receive buffer, if necessary */ if (buf_idx == reply_buf_size) { - LOG_DBG("growing reply buffer: %zu -> %zu", - reply_buf_size, reply_buf_size * 2); + LOG_DBG("growing reply buffer: %zu -> %zu", reply_buf_size, reply_buf_size * 2); char *new_buf = realloc(buf, reply_buf_size * 2); if (new_buf == NULL) { - LOG_ERR("failed to grow reply buffer from %zu to %zu bytes", - reply_buf_size, reply_buf_size * 2); + LOG_ERR("failed to grow reply buffer from %zu to %zu bytes", reply_buf_size, reply_buf_size * 2); err = true; break; } @@ -188,10 +175,8 @@ i3_receive_loop(int abort_fd, int sock, while (!err && buf_idx >= sizeof(i3_ipc_header_t)) { const i3_ipc_header_t *hdr = (const i3_ipc_header_t *)buf; if (strncmp(hdr->magic, I3_IPC_MAGIC, sizeof(hdr->magic)) != 0) { - LOG_ERR( - "i3 IPC header magic mismatch: expected \"%.*s\", got \"%.*s\"", - (int)sizeof(hdr->magic), I3_IPC_MAGIC, - (int)sizeof(hdr->magic), hdr->magic); + LOG_ERR("i3 IPC header magic mismatch: expected \"%.*s\", got \"%.*s\"", (int)sizeof(hdr->magic), + I3_IPC_MAGIC, (int)sizeof(hdr->magic), hdr->magic); err = true; break; @@ -210,10 +195,10 @@ i3_receive_loop(int abort_fd, int sock, char json_str[hdr->size + 1]; memcpy(json_str, &buf[sizeof(*hdr)], hdr->size); json_str[hdr->size] = '\0'; - //printf("raw: %s\n", json_str); + // printf("raw: %s\n", json_str); LOG_DBG("raw: %s\n", json_str); - //json_tokener *tokener = json_tokener_new(); + // json_tokener *tokener = json_tokener_new(); struct json_object *json = json_tokener_parse(json_str); if (json == NULL) { LOG_ERR("failed to parse json"); @@ -262,13 +247,13 @@ i3_receive_loop(int abort_fd, int sock, break; #endif /* Sway extensions */ - case 100: /* IPC_GET_INPUTS */ + case 100: /* IPC_GET_INPUTS */ pkt_handler = cbs->reply_inputs; break; - /* - * Events - */ + /* + * Events + */ case I3_IPC_EVENT_WORKSPACE: pkt_handler = cbs->event_workspace; @@ -295,7 +280,7 @@ i3_receive_loop(int abort_fd, int sock, pkt_handler = cbs->event_tick; break; - /* Sway extensions */ + /* Sway extensions */ #define SWAY_IPC_EVENT_INPUT ((1u << 31) | 21) case SWAY_IPC_EVENT_INPUT: pkt_handler = cbs->event_input; diff --git a/modules/i3-common.h b/modules/i3-common.h index 0cbfa3e..6ba6721 100644 --- a/modules/i3-common.h +++ b/modules/i3-common.h @@ -2,8 +2,8 @@ #include -#include #include +#include #include #include @@ -43,6 +43,4 @@ struct i3_ipc_callbacks { i3_ipc_callback_t event_input; }; -bool i3_receive_loop( - int abort_fd, int sock, - const struct i3_ipc_callbacks *callbacks, void *data); +bool i3_receive_loop(int abort_fd, int sock, const struct i3_ipc_callbacks *callbacks, void *data); diff --git a/modules/i3.c b/modules/i3.c index d62db5e..73bd9d6 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -1,27 +1,27 @@ +#include #include #include -#include -#include #include +#include -#include #include +#include #include #define LOG_MODULE "i3" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../particles/dynlist.h" #include "../plugin.h" -#include "i3-ipc.h" #include "i3-common.h" +#include "i3-ipc.h" -enum sort_mode {SORT_NONE, SORT_NATIVE, SORT_ASCENDING, SORT_DESCENDING}; +enum sort_mode { SORT_NONE, SORT_NATIVE, SORT_ASCENDING, SORT_DESCENDING }; struct ws_content { char *name; @@ -48,7 +48,8 @@ struct workspace { } window; }; -struct private { +struct private +{ int left_spacing; int right_spacing; @@ -105,10 +106,8 @@ workspace_from_json(const struct json_object *json, struct workspace *ws) { /* Always present */ struct json_object *id, *name, *output; - if (!json_object_object_get_ex(json, "id", &id) || - !json_object_object_get_ex(json, "name", &name) || - !json_object_object_get_ex(json, "output", &output)) - { + if (!json_object_object_get_ex(json, "id", &id) || !json_object_object_get_ex(json, "name", &name) + || !json_object_object_get_ex(json, "output", &output)) { LOG_ERR("workspace reply/event without 'name' and/or 'output' " "properties"); return false; @@ -126,14 +125,12 @@ workspace_from_json(const struct json_object *json, struct workspace *ws) const char *name_as_string = json_object_get_string(name); - const size_t node_count = focus != NULL - ? json_object_array_length(focus) - : 0; + const size_t node_count = focus != NULL ? json_object_array_length(focus) : 0; const bool is_empty = node_count == 0; int name_as_int = workspace_name_as_int(name_as_string); - *ws = (struct workspace) { + *ws = (struct workspace){ .id = json_object_get_int(id), .name = strdup(name_as_string), .name_as_int = name_as_int, @@ -152,9 +149,12 @@ workspace_from_json(const struct json_object *json, struct workspace *ws) static void workspace_free_persistent(struct workspace *ws) { - free(ws->output); ws->output = NULL; - free(ws->window.title); ws->window.title = NULL; - free(ws->window.application); ws->window.application = NULL; + free(ws->output); + ws->output = NULL; + free(ws->window.title); + ws->window.title = NULL; + free(ws->window.application); + ws->window.application = NULL; ws->id = -1; } @@ -162,13 +162,15 @@ static void workspace_free(struct workspace *ws) { workspace_free_persistent(ws); - free(ws->name); ws->name = NULL; + free(ws->name); + ws->name = NULL; } static void workspaces_free(struct private *m, bool free_persistent) { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { if (free_persistent || !it->item.persistent) { workspace_free(&it->item); tll_remove(m->workspaces, it); @@ -176,7 +178,6 @@ workspaces_free(struct private *m, bool free_persistent) } } - static void workspace_add(struct private *m, struct workspace ws) { @@ -187,7 +188,8 @@ workspace_add(struct private *m, struct workspace ws) case SORT_NATIVE: if (ws.name_as_int >= 0) { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { if (it->item.name_as_int < 0) continue; if (it->item.name_as_int > ws.name_as_int) { @@ -202,7 +204,8 @@ workspace_add(struct private *m, struct workspace ws) case SORT_ASCENDING: if (ws.name_as_int >= 0) { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { if (it->item.name_as_int < 0) continue; if (it->item.name_as_int > ws.name_as_int) { @@ -211,10 +214,9 @@ workspace_add(struct private *m, struct workspace ws) } } } else { - tll_foreach(m->workspaces, it) { - if (strcoll(it->item.name, ws.name) > 0 || - it->item.name_as_int >= 0) - { + tll_foreach(m->workspaces, it) + { + if (strcoll(it->item.name, ws.name) > 0 || it->item.name_as_int >= 0) { tll_insert_before(m->workspaces, it, ws); return; } @@ -225,14 +227,16 @@ workspace_add(struct private *m, struct workspace ws) case SORT_DESCENDING: if (ws.name_as_int >= 0) { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { if (it->item.name_as_int < ws.name_as_int) { tll_insert_before(m->workspaces, it, ws); return; } } } else { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { if (it->item.name_as_int >= 0) continue; if (strcoll(it->item.name, ws.name) < 0) { @@ -249,7 +253,8 @@ workspace_add(struct private *m, struct workspace ws) static void workspace_del(struct private *m, int id) { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { struct workspace *ws = &it->item; if (ws->id != id) @@ -264,7 +269,8 @@ workspace_del(struct private *m, int id) static struct workspace * workspace_lookup(struct private *m, int id) { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { struct workspace *ws = &it->item; if (ws->id == id) return ws; @@ -275,7 +281,8 @@ workspace_lookup(struct private *m, int id) static struct workspace * workspace_lookup_by_name(struct private *m, const char *name) { - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { struct workspace *ws = &it->item; if (strcmp(ws->name, name) == 0) return ws; @@ -339,13 +346,9 @@ workspace_update_or_add(struct private *m, const struct json_object *ws_json) if (json_object_object_get_ex(ws_json, "name", &_name)) { const char *name = json_object_get_string(_name); if (name != NULL) { - struct workspace *maybe_persistent = - workspace_lookup_by_name(m, name); + struct workspace *maybe_persistent = workspace_lookup_by_name(m, name); - if (maybe_persistent != NULL && - maybe_persistent->persistent && - maybe_persistent->id < 0) - { + if (maybe_persistent != NULL && maybe_persistent->persistent && maybe_persistent->id < 0) { already_exists = maybe_persistent; } } @@ -421,10 +424,9 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void bool is_reload = strcmp(change_str, "reload") == 0; struct json_object *current, *_current_id; - if ((!json_object_object_get_ex(json, "current", ¤t) || - !json_object_object_get_ex(current, "id", &_current_id)) && - !is_reload) - { + if ((!json_object_object_get_ex(json, "current", ¤t) + || !json_object_object_get_ex(current, "id", &_current_id)) + && !is_reload) { LOG_ERR("workspace event without 'current' and/or 'id' properties"); return false; } @@ -452,10 +454,8 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void else if (is_focused) { struct json_object *old, *_old_id, *urgent; - if (!json_object_object_get_ex(json, "old", &old) || - !json_object_object_get_ex(old, "id", &_old_id) || - !json_object_object_get_ex(current, "urgent", &urgent)) - { + if (!json_object_object_get_ex(json, "old", &old) || !json_object_object_get_ex(old, "id", &_old_id) + || !json_object_object_get_ex(current, "urgent", &urgent)) { LOG_ERR("workspace 'focused' event without 'old', 'name' and/or 'urgent' property"); mtx_unlock(&mod->lock); return false; @@ -467,7 +467,8 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void LOG_DBG("w: %s", w->name); /* Mark all workspaces on current's output invisible */ - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { struct workspace *ws = &it->item; if (ws->output != NULL && strcmp(ws->output, w->output) == 0) ws->visible = false; @@ -501,7 +502,8 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void /* Re-add the workspace to ensure correct sorting */ struct workspace ws = *w; - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { if (it->item.id == current_id) { tll_remove(m->workspaces, it); break; @@ -588,7 +590,8 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m struct workspace *ws = NULL; size_t focused = 0; - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { if (it->item.focused) { ws = &it->item; focused++; @@ -599,10 +602,8 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m assert(ws != NULL); struct json_object *container, *id, *name; - if (!json_object_object_get_ex(json, "container", &container) || - !json_object_object_get_ex(container, "id", &id) || - !json_object_object_get_ex(container, "name", &name)) - { + if (!json_object_object_get_ex(json, "container", &container) || !json_object_object_get_ex(container, "id", &id) + || !json_object_object_get_ex(container, "name", &name)) { mtx_unlock(&mod->lock); LOG_ERR("window event without 'container' with 'id' and 'name'"); return false; @@ -645,18 +646,14 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m struct json_object *app_id; struct json_object *pid; - if (json_object_object_get_ex(container, "app_id", &app_id) && - json_object_get_string(app_id) != NULL) - { + if (json_object_object_get_ex(container, "app_id", &app_id) && json_object_get_string(app_id) != NULL) { free(ws->window.application); ws->window.application = strdup(json_object_get_string(app_id)); LOG_DBG("application: \"%s\", via 'app_id'", ws->window.application); } /* If PID has changed, update application name from /proc//comm */ - else if (json_object_object_get_ex(container, "pid", &pid) && - ws->window.pid != json_object_get_int(pid)) - { + else if (json_object_object_get_ex(container, "pid", &pid) && ws->window.pid != json_object_get_int(pid)) { ws->window.pid = json_object_get_int(pid); char path[64]; @@ -665,7 +662,8 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m int fd = open(path, O_RDONLY); if (fd == -1) { /* Application may simply have terminated */ - free(ws->window.application); ws->window.application = NULL; + free(ws->window.application); + ws->window.application = NULL; ws->window.pid = -1; m->dirty = true; @@ -837,7 +835,8 @@ content(struct module *mod) struct exposable *particles[tll_length(m->workspaces) + 1]; struct exposable *current = NULL; - tll_foreach(m->workspaces, it) { + tll_foreach(m->workspaces, it) + { struct workspace *ws = &it->item; const struct ws_content *template = NULL; @@ -853,21 +852,12 @@ content(struct module *mod) template = ws_content_for_name(m, ""); } - const char *state = - ws->urgent ? "urgent" : - ws->visible ? ws->focused ? "focused" : "unfocused" : - "invisible"; + const char *state = ws->urgent ? "urgent" : ws->visible ? ws->focused ? "focused" : "unfocused" : "invisible"; LOG_DBG("name=%s (name-as-int=%d): visible=%s, focused=%s, urgent=%s, empty=%s, state=%s, " "application=%s, title=%s, mode=%s", - ws->name, ws->name_as_int, - ws->visible ? "yes" : "no", - ws->focused ? "yes" : "no", - ws->urgent ? "yes" : "no", - ws->empty ? "yes" : "no", - state, - ws->window.application, - ws->window.title, + ws->name, ws->name_as_int, ws->visible ? "yes" : "no", ws->focused ? "yes" : "no", + ws->urgent ? "yes" : "no", ws->empty ? "yes" : "no", state, ws->window.application, ws->window.title, m->mode); const char *name = ws->name; @@ -902,12 +892,9 @@ content(struct module *mod) } if (template == NULL) { - LOG_WARN( - "no ws template for %s, and no default template available", - ws->name); + LOG_WARN("no ws template for %s, and no default template available", ws->name); } else { - particles[particle_count++] = template->content->instantiate( - template->content, &tags); + particles[particle_count++] = template->content->instantiate(template->content, &tags); } tag_set_destroy(&tags); @@ -917,8 +904,7 @@ content(struct module *mod) particles[particle_count++] = current; mtx_unlock(&mod->lock); - return dynlist_exposable_new( - particles, particle_count, m->left_spacing, m->right_spacing); + return dynlist_exposable_new(particles, particle_count, m->left_spacing, m->right_spacing); } /* Maps workspace name to a content particle. */ @@ -928,10 +914,8 @@ struct i3_workspaces { }; static struct module * -i3_new(struct i3_workspaces workspaces[], size_t workspace_count, - int left_spacing, int right_spacing, enum sort_mode sort_mode, - size_t persistent_count, - const char *persistent_workspaces[static persistent_count], +i3_new(struct i3_workspaces workspaces[], size_t workspace_count, int left_spacing, int right_spacing, + enum sort_mode sort_mode, size_t persistent_count, const char *persistent_workspaces[static persistent_count], bool strip_workspace_numbers) { struct private *m = calloc(1, sizeof(*m)); @@ -952,8 +936,7 @@ i3_new(struct i3_workspaces workspaces[], size_t workspace_count, m->sort_mode = sort_mode; m->persistent_count = persistent_count; - m->persistent_workspaces = calloc( - persistent_count, sizeof(m->persistent_workspaces[0])); + m->persistent_workspaces = calloc(persistent_count, sizeof(m->persistent_workspaces[0])); for (size_t i = 0; i < persistent_count; i++) m->persistent_workspaces[i] = strdup(persistent_workspaces[i]); @@ -976,31 +959,26 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *right_spacing = yml_get_value(node, "right-spacing"); const struct yml_node *sort = yml_get_value(node, "sort"); const struct yml_node *persistent = yml_get_value(node, "persistent"); - const struct yml_node *strip_workspace_number = yml_get_value( - node, "strip-workspace-numbers"); + const struct yml_node *strip_workspace_number = yml_get_value(node, "strip-workspace-numbers"); - int left = spacing != NULL ? yml_value_as_int(spacing) : - left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; - int right = spacing != NULL ? yml_value_as_int(spacing) : - right_spacing != NULL ? yml_value_as_int(right_spacing) : 0; + int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; + int right = spacing != NULL ? yml_value_as_int(spacing) + : right_spacing != NULL ? yml_value_as_int(right_spacing) + : 0; const char *sort_value = sort != NULL ? yml_value_as_string(sort) : NULL; - enum sort_mode sort_mode = - sort_value == NULL ? SORT_NONE : - strcmp(sort_value, "none") == 0 ? SORT_NONE : - strcmp(sort_value, "native") == 0 ? SORT_NATIVE : - strcmp(sort_value, "ascending") == 0 ? SORT_ASCENDING : SORT_DESCENDING; + enum sort_mode sort_mode = sort_value == NULL ? SORT_NONE + : strcmp(sort_value, "none") == 0 ? SORT_NONE + : strcmp(sort_value, "native") == 0 ? SORT_NATIVE + : strcmp(sort_value, "ascending") == 0 ? SORT_ASCENDING + : SORT_DESCENDING; - const size_t persistent_count = - persistent != NULL ? yml_list_length(persistent) : 0; + const size_t persistent_count = persistent != NULL ? yml_list_length(persistent) : 0; const char *persistent_workspaces[persistent_count]; if (persistent != NULL) { size_t idx = 0; - for (struct yml_list_iter it = yml_list_iter(persistent); - it.node != NULL; - yml_list_next(&it), idx++) - { + for (struct yml_list_iter it = yml_list_iter(persistent); it.node != NULL; yml_list_next(&it), idx++) { persistent_workspaces[idx] = yml_value_as_string(it.node); } } @@ -1008,38 +986,27 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) struct i3_workspaces workspaces[yml_dict_length(c)]; size_t idx = 0; - for (struct yml_dict_iter it = yml_dict_iter(c); - it.key != NULL; - yml_dict_next(&it), idx++) - { + for (struct yml_dict_iter it = yml_dict_iter(c); it.key != NULL; yml_dict_next(&it), idx++) { workspaces[idx].name = yml_value_as_string(it.key); workspaces[idx].content = conf_to_particle(it.value, inherited); } - return i3_new(workspaces, yml_dict_length(c), left, right, sort_mode, - persistent_count, persistent_workspaces, - (strip_workspace_number != NULL - ? yml_value_as_bool(strip_workspace_number) : false)); + return i3_new(workspaces, yml_dict_length(c), left, right, sort_mode, persistent_count, persistent_workspaces, + (strip_workspace_number != NULL ? yml_value_as_bool(strip_workspace_number) : false)); } static bool verify_content(keychain_t *chain, const struct yml_node *node) { if (!yml_is_dict(node)) { - LOG_ERR( - "%s: must be a dictionary of workspace-name: particle mappings", - conf_err_prefix(chain, node)); + LOG_ERR("%s: must be a dictionary of workspace-name: particle mappings", conf_err_prefix(chain, node)); return false; } - for (struct yml_dict_iter it = yml_dict_iter(node); - it.key != NULL; - yml_dict_next(&it)) - { + for (struct yml_dict_iter it = yml_dict_iter(node); it.key != NULL; yml_dict_next(&it)) { const char *key = yml_value_as_string(it.key); if (key == NULL) { - LOG_ERR("%s: key must be a string (a i3 workspace name)", - conf_err_prefix(chain, it.key)); + LOG_ERR("%s: key must be a string (a i3 workspace name)", conf_err_prefix(chain, it.key)); return false; } @@ -1055,8 +1022,7 @@ verify_content(keychain_t *chain, const struct yml_node *node) static bool verify_sort(keychain_t *chain, const struct yml_node *node) { - return conf_verify_enum( - chain, node, (const char *[]){"none", "native", "ascending", "descending"}, 4); + return conf_verify_enum(chain, node, (const char *[]){"none", "native", "ascending", "descending"}, 4); } static bool @@ -1089,5 +1055,5 @@ const struct module_iface module_i3_iface = { }; #if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) -extern const struct module_iface iface __attribute__((weak, alias("module_i3_iface"))) ; +extern const struct module_iface iface __attribute__((weak, alias("module_i3_iface"))); #endif diff --git a/modules/label.c b/modules/label.c index 7e8ee09..5f1f158 100644 --- a/modules/label.c +++ b/modules/label.c @@ -1,16 +1,14 @@ -#include #include +#include #include -#include "../config.h" #include "../config-verify.h" +#include "../config.h" #include "../module.h" #include "../plugin.h" -struct private { - struct particle *label; -}; +struct private { struct particle *label; }; static void destroy(struct module *mod) diff --git a/modules/mem.c b/modules/mem.c index 6a196c6..dc9bcf8 100644 --- a/modules/mem.c +++ b/modules/mem.c @@ -162,9 +162,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *interval = yml_get_value(node, "poll-interval"); const struct yml_node *c = yml_get_value(node, "content"); - return mem_new( - interval == NULL ? min_poll_interval : yml_value_as_int(interval), - conf_to_particle(c, inherited)); + return mem_new(interval == NULL ? min_poll_interval : yml_value_as_int(interval), conf_to_particle(c, inherited)); } static bool @@ -174,8 +172,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node) return false; if (yml_value_as_int(node) < min_poll_interval) { - LOG_ERR("%s: interval value cannot be less than %ldms", - conf_err_prefix(chain, node), min_poll_interval); + LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval); return false; } diff --git a/modules/mpd.c b/modules/mpd.c index 604bf88..22c0e6b 100644 --- a/modules/mpd.c +++ b/modules/mpd.c @@ -1,33 +1,34 @@ -#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include -#include #include +#include -#include -#include -#include #include #include +#include +#include +#include #include #define LOG_MODULE "mpd" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../plugin.h" -struct private { +struct private +{ char *host; uint16_t port; struct particle *label; @@ -38,7 +39,7 @@ struct private { bool repeat; bool random; bool consume; - int volume; + int volume; char *album; char *artist; char *title; @@ -60,11 +61,9 @@ destroy(struct module *mod) struct private *m = mod->private; if (m->refresh_thread_id != 0) { assert(m->refresh_abort_fd != -1); - if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t)) - != sizeof(uint64_t)) - { + if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) { LOG_ERRNO("failed to signal abort to refresher thread"); - } else{ + } else { int res; thrd_join(m->refresh_thread_id, &res); } @@ -132,12 +131,11 @@ content(struct module *mod) if (m->state == MPD_STATE_PLAY) { elapsed += timespec_diff_milli_seconds(&now, &m->elapsed.when); if (elapsed > m->duration) { - LOG_DBG( - "dynamic update of elapsed overflowed: " - "elapsed=%"PRIu64", duration=%"PRIu64, elapsed, m->duration); + LOG_DBG("dynamic update of elapsed overflowed: " + "elapsed=%" PRIu64 ", duration=%" PRIu64, + elapsed, m->duration); elapsed = m->duration; } - } unsigned elapsed_secs = elapsed / 1000; @@ -154,16 +152,23 @@ content(struct module *mod) state_str = "offline"; else { switch (m->state) { - case MPD_STATE_UNKNOWN: state_str = "unknown"; break; - case MPD_STATE_STOP: state_str = "stopped"; break; - case MPD_STATE_PAUSE: state_str = "paused"; break; - case MPD_STATE_PLAY: state_str = "playing"; break; + case MPD_STATE_UNKNOWN: + state_str = "unknown"; + break; + case MPD_STATE_STOP: + state_str = "stopped"; + break; + case MPD_STATE_PAUSE: + state_str = "paused"; + break; + case MPD_STATE_PLAY: + state_str = "playing"; + break; } } /* Tell particle to real-time track? */ - enum tag_realtime_unit realtime = m->state == MPD_STATE_PLAY - ? TAG_REALTIME_MSECS : TAG_REALTIME_NONE; + enum tag_realtime_unit realtime = m->state == MPD_STATE_PLAY ? TAG_REALTIME_MSECS : TAG_REALTIME_NONE; struct tag_set tags = { .tags = (struct tag *[]){ @@ -237,8 +242,7 @@ wait_for_socket_create(const struct module *mod) LOG_DBG("%s: already exists, and is connectable", m->host); have_mpd_socket = true; } else { - LOG_DBG("%s: already exists, but isn't connectable: %s", - m->host, strerror(errno)); + LOG_DBG("%s: already exists, but isn't connectable: %s", m->host, strerror(errno)); } close(s); @@ -249,10 +253,7 @@ wait_for_socket_create(const struct module *mod) bool ret = false; while (!have_mpd_socket) { - struct pollfd fds[] = { - {.fd = mod->abort_fd, .events = POLLIN}, - {.fd = fd, .events = POLLIN} - }; + struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = fd, .events = POLLIN}}; if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) < 0) { if (errno == EINTR) @@ -272,7 +273,7 @@ wait_for_socket_create(const struct module *mod) char buf[1024]; ssize_t len = read(fd, buf, sizeof(buf)); - for (const char *ptr = buf; ptr < buf + len; ) { + for (const char *ptr = buf; ptr < buf + len;) { const struct inotify_event *e = (const struct inotify_event *)ptr; LOG_DBG("inotify: CREATED: %s/%.*s", directory, e->len, e->name); @@ -282,7 +283,7 @@ wait_for_socket_create(const struct module *mod) break; } - ptr += sizeof(*e) + e->len; + ptr += sizeof(*e) + e->len; } } @@ -305,8 +306,7 @@ connect_to_mpd(const struct module *mod) enum mpd_error merr = mpd_connection_get_error(conn); if (merr != MPD_ERROR_SUCCESS) { - LOG_WARN("failed to connect to MPD: %s", - mpd_connection_get_error_message(conn)); + LOG_WARN("failed to connect to MPD: %s", mpd_connection_get_error_message(conn)); mpd_connection_free(conn); return NULL; } @@ -324,8 +324,7 @@ update_status(struct module *mod) struct mpd_status *status = mpd_run_status(m->conn); if (status == NULL) { - LOG_ERR("failed to get status: %s", - mpd_connection_get_error_message(m->conn)); + LOG_ERR("failed to get status: %s", mpd_connection_get_error_message(m->conn)); return false; } @@ -347,17 +346,20 @@ update_status(struct module *mod) struct mpd_song *song = mpd_run_current_song(m->conn); if (song == NULL && mpd_connection_get_error(m->conn) != MPD_ERROR_SUCCESS) { - LOG_ERR("failed to get current song: %s", - mpd_connection_get_error_message(m->conn)); + LOG_ERR("failed to get current song: %s", mpd_connection_get_error_message(m->conn)); return false; } if (song == NULL) { mtx_lock(&mod->lock); - free(m->album); m->album = NULL; - free(m->artist); m->artist = NULL; - free(m->title); m->title = NULL; - free(m->file); m->file = NULL; + free(m->album); + m->album = NULL; + free(m->artist); + m->artist = NULL; + free(m->title); + m->title = NULL; + free(m->file); + m->file = NULL; mtx_unlock(&mod->lock); } else { const char *album = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0); @@ -401,10 +403,14 @@ run(struct module *mod) /* Reset state */ mtx_lock(&mod->lock); - free(m->album); m->album = NULL; - free(m->artist); m->artist = NULL; - free(m->title); m->title = NULL; - free(m->file); m->file = NULL; + free(m->album); + m->album = NULL; + free(m->artist); + m->artist = NULL; + free(m->title); + m->title = NULL; + free(m->file); + m->file = NULL; m->state = MPD_STATE_UNKNOWN; m->elapsed.value = m->duration = 0; m->elapsed.when.tv_sec = m->elapsed.when.tv_nsec = 0; @@ -467,8 +473,7 @@ run(struct module *mod) }; if (!mpd_send_idle(m->conn)) { - LOG_ERR("failed to send IDLE command: %s", - mpd_connection_get_error_message(m->conn)); + LOG_ERR("failed to send IDLE command: %s", mpd_connection_get_error_message(m->conn)); break; } @@ -492,8 +497,7 @@ run(struct module *mod) } if (fds[1].revents & POLLIN) { - enum mpd_idle idle __attribute__ ((unused)) = - mpd_recv_idle(m->conn, true); + enum mpd_idle idle __attribute__((unused)) = mpd_recv_idle(m->conn, true); LOG_DBG("IDLE mask: %d", idle); @@ -565,9 +569,7 @@ refresh_in(struct module *mod, long milli_seconds) /* Signal abort to thread */ assert(m->refresh_abort_fd != -1); - if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t)) - != sizeof(uint64_t)) - { + if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) { LOG_ERRNO("failed to signal abort to refresher thread"); return false; } @@ -607,7 +609,7 @@ refresh_in(struct module *mod, long milli_seconds) } /* Detach - we don't want to have to thrd_join() it */ - //thrd_detach(tid); + // thrd_detach(tid); return r == 0; } @@ -638,10 +640,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *port = yml_get_value(node, "port"); const struct yml_node *c = yml_get_value(node, "content"); - return mpd_new( - yml_value_as_string(host), - port != NULL ? yml_value_as_int(port) : 0, - conf_to_particle(c, inherited)); + return mpd_new(yml_value_as_string(host), port != NULL ? yml_value_as_int(port) : 0, + conf_to_particle(c, inherited)); } static bool diff --git a/modules/network.c b/modules/network.c index 24e811f..4bb0fb2 100644 --- a/modules/network.c +++ b/modules/network.c @@ -1,34 +1,34 @@ +#include +#include +#include #include #include -#include #include #include -#include #include -#include -#include #include #include +#include -#include #include +#include #include +#include #include #include -#include -#include #include +#include #include #define LOG_MODULE "network" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../module.h" #include "../particles/dynlist.h" #include "../plugin.h" @@ -58,7 +58,7 @@ struct iface { int index; uint8_t mac[6]; bool carrier; - uint8_t state; /* IFLA_OPERSTATE */ + uint8_t state; /* IFLA_OPERSTATE */ /* IPv4 and IPv6 addresses */ tll(struct af_addr) addrs; @@ -76,7 +76,8 @@ struct iface { uint64_t dl_bits; }; -struct private { +struct private +{ struct particle *label; int poll_interval; @@ -118,8 +119,7 @@ destroy(struct module *mod) if (m->urandom_fd >= 0) close(m->urandom_fd); - tll_foreach(m->ifaces, it) - free_iface(it->item); + tll_foreach(m->ifaces, it) free_iface(it->item); free(m); module_default_destroy(mod); @@ -141,35 +141,53 @@ content(struct module *mod) struct exposable *exposables[max(tll_length(m->ifaces), 1)]; size_t idx = 0; - tll_foreach(m->ifaces, it) { + tll_foreach(m->ifaces, it) + { struct iface *iface = &it->item; const char *state = NULL; switch (iface->state) { - case IF_OPER_UNKNOWN: state = "unknown"; break; - case IF_OPER_NOTPRESENT: state = "not present"; break; - case IF_OPER_DOWN: state = "down"; break; - case IF_OPER_LOWERLAYERDOWN: state = "lower layers down"; break; - case IF_OPER_TESTING: state = "testing"; break; - case IF_OPER_DORMANT: state = "dormant"; break; - case IF_OPER_UP: state = "up"; break; - default: state = "unknown"; break; + case IF_OPER_UNKNOWN: + state = "unknown"; + break; + case IF_OPER_NOTPRESENT: + state = "not present"; + break; + case IF_OPER_DOWN: + state = "down"; + break; + case IF_OPER_LOWERLAYERDOWN: + state = "lower layers down"; + break; + case IF_OPER_TESTING: + state = "testing"; + break; + case IF_OPER_DORMANT: + state = "dormant"; + break; + case IF_OPER_UP: + state = "up"; + break; + default: + state = "unknown"; + break; } char mac_str[6 * 2 + 5 + 1]; char ipv4_str[INET_ADDRSTRLEN] = {0}; char ipv6_str[INET6_ADDRSTRLEN] = {0}; - snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", - iface->mac[0], iface->mac[1], iface->mac[2], iface->mac[3], iface->mac[4], iface->mac[5]); + snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", iface->mac[0], iface->mac[1], iface->mac[2], + iface->mac[3], iface->mac[4], iface->mac[5]); /* TODO: this exposes the *last* added address of each kind. Can * we expose all in some way? */ - tll_foreach(iface->addrs, it) { + tll_foreach(iface->addrs, it) + { if (it->item.family == AF_INET) inet_ntop(AF_INET, &it->item.addr.ipv4, ipv4_str, sizeof(ipv4_str)); else if (it->item.family == AF_INET6) - if(!IN6_IS_ADDR_LINKLOCAL(&it->item.addr.ipv6)) + if (!IN6_IS_ADDR_LINKLOCAL(&it->item.addr.ipv6)) inet_ntop(AF_INET6, &it->item.addr.ipv6, ipv6_str, sizeof(ipv6_str)); } @@ -208,8 +226,7 @@ content(struct module *mod) mtx_unlock(&mod->lock); - return dynlist_exposable_new( - exposables, idx, m->left_spacing, m->right_spacing); + return dynlist_exposable_new(exposables, idx, m->left_spacing, m->right_spacing); } /* Returns a value suitable for nl_pid/nlmsg_pid */ @@ -254,8 +271,7 @@ netlink_connect_genl(void) } const struct sockaddr_nl addr = { - .nl_family = AF_NETLINK, - .nl_pid = nl_pid_value(), + .nl_family = AF_NETLINK, .nl_pid = nl_pid_value(), /* no multicast notifications by default, will be added later */ }; @@ -271,10 +287,8 @@ netlink_connect_genl(void) static bool send_nlmsg(int sock, const void *nlmsg, size_t len) { - int r = sendto( - sock, nlmsg, len, 0, - (struct sockaddr *)&(struct sockaddr_nl){.nl_family = AF_NETLINK}, - sizeof(struct sockaddr_nl)); + int r = sendto(sock, nlmsg, len, 0, (struct sockaddr *)&(struct sockaddr_nl){.nl_family = AF_NETLINK}, + sizeof(struct sockaddr_nl)); return r == len; } @@ -300,8 +314,7 @@ send_rt_request(struct private *m, int request) }; if (!send_nlmsg(m->rt_sock, &req, req.hdr.nlmsg_len)) { - LOG_ERRNO("failed to send netlink RT request (%d)", - request); + LOG_ERRNO("failed to send netlink RT request (%d)", request); return false; } @@ -312,8 +325,7 @@ static bool send_rt_getstats_request(struct private *m, struct iface *iface) { if (iface->get_stats_seq_nr > 0) { - LOG_DBG( - "%s: RT get-stats request already in progress", iface->name); + LOG_DBG("%s: RT get-stats request already in progress", iface->name); return true; } @@ -345,8 +357,7 @@ send_rt_getstats_request(struct private *m, struct iface *iface) }; if (!send_nlmsg(m->rt_sock, &req, req.hdr.nlmsg_len)) { - LOG_ERRNO("%s: failed to send netlink RT getstats request (%d)", - iface->name, RTM_GETSTATS); + LOG_ERRNO("%s: failed to send netlink RT getstats request (%d)", iface->name, RTM_GETSTATS); return false; } iface->get_stats_seq_nr = seq; @@ -391,10 +402,8 @@ send_ctrl_get_family_request(struct private *m) }, }; - _Static_assert( - sizeof(req.msg.family_name_attr) == - NLA_HDRLEN + NLA_ALIGN(sizeof(req.msg.family_name_attr.data)), - ""); + _Static_assert(sizeof(req.msg.family_name_attr) == NLA_HDRLEN + NLA_ALIGN(sizeof(req.msg.family_name_attr.data)), + ""); if (!send_nlmsg(m->genl_sock, &req, req.hdr.nlmsg_len)) { LOG_ERRNO("failed to send netlink ctrl-get-family request"); @@ -538,15 +547,15 @@ send_nl80211_get_scan(struct private *m) } static void -handle_link(struct module *mod, uint16_t type, - const struct ifinfomsg *msg, size_t len) +handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len) { assert(type == RTM_NEWLINK || type == RTM_DELLINK); struct private *m = mod->private; if (type == RTM_DELLINK) { - tll_foreach(m->ifaces, it) { + tll_foreach(m->ifaces, it) + { if (msg->ifi_index != it->item.index) continue; mtx_lock(&mod->lock); @@ -560,7 +569,8 @@ handle_link(struct module *mod, uint16_t type, } struct iface *iface = NULL; - tll_foreach(m->ifaces, it) { + tll_foreach(m->ifaces, it) + { if (msg->ifi_index != it->item.index) continue; iface = &it->item; @@ -568,21 +578,17 @@ handle_link(struct module *mod, uint16_t type, } if (iface == NULL) { - mtx_lock(&mod->lock); - tll_push_back(m->ifaces, - ((struct iface){ - .index = msg->ifi_index, - .state = IF_OPER_DOWN, - .addrs = tll_init(), - })); - mtx_unlock(&mod->lock); - iface = &tll_back(m->ifaces); + mtx_lock(&mod->lock); + tll_push_back(m->ifaces, ((struct iface){ + .index = msg->ifi_index, + .state = IF_OPER_DOWN, + .addrs = tll_init(), + })); + mtx_unlock(&mod->lock); + iface = &tll_back(m->ifaces); } - for (const struct rtattr *attr = IFLA_RTA(msg); - RTA_OK(attr, len); - attr = RTA_NEXT(attr, len)) - { + for (const struct rtattr *attr = IFLA_RTA(msg); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) { switch (attr->rta_type) { case IFLA_IFNAME: mtx_lock(&mod->lock); @@ -623,9 +629,8 @@ handle_link(struct module *mod, uint16_t type, if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0) break; - LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", - iface->name, - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", iface->name, mac[0], mac[1], mac[2], mac[3], + mac[4], mac[5]); mtx_lock(&mod->lock); memcpy(iface->mac, mac, sizeof(iface->mac)); @@ -645,8 +650,7 @@ handle_link(struct module *mod, uint16_t type, } static void -handle_address(struct module *mod, uint16_t type, - const struct ifaddrmsg *msg, size_t len) +handle_address(struct module *mod, uint16_t type, const struct ifaddrmsg *msg, size_t len) { assert(type == RTM_NEWADDR || type == RTM_DELADDR); @@ -656,7 +660,8 @@ handle_address(struct module *mod, uint16_t type, struct iface *iface = NULL; - tll_foreach(m->ifaces, it) { + tll_foreach(m->ifaces, it) + { if (msg->ifa_index != it->item.index) continue; iface = &it->item; @@ -668,10 +673,7 @@ handle_address(struct module *mod, uint16_t type, return; } - for (const struct rtattr *attr = IFA_RTA(msg); - RTA_OK(attr, len); - attr = RTA_NEXT(attr, len)) - { + for (const struct rtattr *attr = IFA_RTA(msg); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) { switch (attr->rta_type) { case IFA_ADDRESS: { const void *raw_addr = RTA_DATA(attr); @@ -681,14 +683,14 @@ handle_address(struct module *mod, uint16_t type, char s[INET6_ADDRSTRLEN]; inet_ntop(msg->ifa_family, raw_addr, s, sizeof(s)); #endif - LOG_DBG("%s: IFA_ADDRESS (%s): %s", iface->name, - type == RTM_NEWADDR ? "add" : "del", s); + LOG_DBG("%s: IFA_ADDRESS (%s): %s", iface->name, type == RTM_NEWADDR ? "add" : "del", s); mtx_lock(&mod->lock); if (type == RTM_DELADDR) { /* Find address in our list and remove it */ - tll_foreach(iface->addrs, it) { + tll_foreach(iface->addrs, it) + { if (it->item.family != msg->ifa_family) continue; @@ -719,19 +721,18 @@ handle_address(struct module *mod, uint16_t type, static bool foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len, - bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *ctx), + bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, + size_t len, void *ctx), void *ctx) { const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN; const uint8_t *end = (const uint8_t *)genl + len; - for (const struct nlattr *attr = (const struct nlattr *)raw; - raw < end; - raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) - { + for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end; + raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) { uint16_t type = attr->nla_type & NLA_TYPE_MASK; - bool nested = (attr->nla_type & NLA_F_NESTED) != 0;; + bool nested = (attr->nla_type & NLA_F_NESTED) != 0; + ; const void *payload = raw + NLA_HDRLEN; if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) @@ -743,18 +744,15 @@ foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr static bool foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len, - bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, - bool nested, const void *payload, size_t len, - void *ctx), + bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, + const void *payload, size_t len, void *ctx), void *ctx) { const uint8_t *raw = parent_payload; const uint8_t *end = parent_payload + len; - for (const struct nlattr *attr = (const struct nlattr *)raw; - raw < end; - raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) - { + for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end; + raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) { uint16_t type = attr->nla_type & NLA_TYPE_MASK; bool nested = (attr->nla_type & NLA_F_NESTED) != 0; const void *payload = raw + NLA_HDRLEN; @@ -772,8 +770,8 @@ struct mcast_group { }; static bool -parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, + void *_ctx) { struct mcast_group *ctx = _ctx; @@ -790,7 +788,8 @@ parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool n default: LOG_WARN("unrecognized GENL MCAST GRP attribute: " - "type=%hu, nested=%d, len=%zu", type, nested, len); + "type=%hu, nested=%d, len=%zu", + type, nested, len); break; } @@ -798,8 +797,8 @@ parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool n } static bool -parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, + void *_ctx) { struct private *m = mod->private; @@ -814,9 +813,7 @@ parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool * CONNECT/DISCONNECT events. */ - int r = setsockopt( - m->genl_sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, - &group.id, sizeof(int)); + int r = setsockopt(m->genl_sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group.id, sizeof(int)); if (r < 0) LOG_ERRNO("failed to joint the nl80211 MLME mcast group"); @@ -826,8 +823,8 @@ parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool } static bool -handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, + void *_ctx) { struct private *m = mod->private; @@ -839,7 +836,7 @@ handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool ne } case CTRL_ATTR_FAMILY_NAME: - //LOG_INFO("NAME: %.*s (%zu bytes)", (int)len, (const char *)payload, len); + // LOG_INFO("NAME: %.*s (%zu bytes)", (int)len, (const char *)payload, len); break; case CTRL_ATTR_MCAST_GROUPS: @@ -848,17 +845,17 @@ handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool ne default: LOG_DBG("unrecognized GENL CTRL attribute: " - "type=%hu, nested=%d, len=%zu", type, nested, len); + "type=%hu, nested=%d, len=%zu", + type, nested, len); break; } return true; } - static bool -find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool nested, - const void *payload, size_t len, void *ctx) +find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool nested, const void *payload, + size_t len, void *ctx) { struct private *m = mod->private; struct iface **iface = ctx; @@ -868,7 +865,8 @@ find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool if (*iface != NULL) if (*(uint32_t *)payload == (*iface)->index) return false; - tll_foreach(m->ifaces, it) { + tll_foreach(m->ifaces, it) + { if (*(uint32_t *)payload != it->item.index) continue; *iface = &it->item; @@ -882,8 +880,8 @@ find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool } static bool -handle_nl80211_new_interface(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +handle_nl80211_new_interface(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, + size_t len, void *_ctx) { switch (type) { case NL80211_ATTR_IFINDEX: @@ -907,7 +905,8 @@ handle_nl80211_new_interface(struct module *mod, struct iface *iface, uint16_t t default: LOG_DBG("%s: unrecognized nl80211 attribute: " - "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); + "type=%hu, nested=%d, len=%zu", + iface->name, type, nested, len); break; } @@ -919,8 +918,8 @@ struct rate_info_ctx { }; static bool -handle_nl80211_rate_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +handle_nl80211_rate_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, + size_t len, void *_ctx) { struct rate_info_ctx *ctx = _ctx; @@ -942,7 +941,8 @@ handle_nl80211_rate_info(struct module *mod, struct iface *iface, uint16_t type, default: LOG_DBG("%s: unrecognized nl80211 rate info attribute: " - "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); + "type=%hu, nested=%d, len=%zu", + iface->name, type, nested, len); break; } @@ -954,8 +954,8 @@ struct station_info_ctx { }; static bool -handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, + size_t len, void *_ctx) { struct station_info_ctx *ctx = _ctx; @@ -974,8 +974,7 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty case NL80211_STA_INFO_TX_BITRATE: { struct rate_info_ctx rctx = {0}; - foreach_nlattr_nested( - mod, iface, payload, len, &handle_nl80211_rate_info, &rctx); + foreach_nlattr_nested(mod, iface, payload, len, &handle_nl80211_rate_info, &rctx); LOG_DBG("TX bitrate: %.1f Mbit/s", rctx.bitrate / 1000. / 1000.); mtx_lock(&mod->lock); @@ -987,8 +986,7 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty case NL80211_STA_INFO_RX_BITRATE: { struct rate_info_ctx rctx = {0}; - foreach_nlattr_nested( - mod, iface, payload, len, &handle_nl80211_rate_info, &rctx); + foreach_nlattr_nested(mod, iface, payload, len, &handle_nl80211_rate_info, &rctx); LOG_DBG("RX bitrate: %.1f Mbit/s", rctx.bitrate / 1000. / 1000.); mtx_lock(&mod->lock); @@ -1000,7 +998,8 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty default: LOG_DBG("%s: unrecognized nl80211 station info attribute: " - "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); + "type=%hu, nested=%d, len=%zu", + iface->name, type, nested, len); break; } @@ -1008,8 +1007,8 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty } static bool -handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, + size_t len, void *_ctx) { switch (type) { case NL80211_ATTR_IFINDEX: @@ -1017,8 +1016,7 @@ handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t typ case NL80211_ATTR_STA_INFO: { struct station_info_ctx ctx = {0}; - foreach_nlattr_nested( - mod, iface, payload, len, &handle_nl80211_station_info, &ctx); + foreach_nlattr_nested(mod, iface, payload, len, &handle_nl80211_station_info, &ctx); if (ctx.update_bar) mod->bar->refresh(mod->bar); @@ -1027,7 +1025,8 @@ handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t typ default: LOG_DBG("%s: unrecognized nl80211 attribute: " - "type=%hu, nested=%d, len=%zu", iface->name, type, nested, len); + "type=%hu, nested=%d, len=%zu", + iface->name, type, nested, len); break; } @@ -1041,7 +1040,7 @@ handle_ies(struct module *mod, struct iface *iface, const void *_ies, size_t len while (len >= 2 && len - 2 >= ies[1]) { switch (ies[0]) { - case 0: { /* SSID */ + case 0: { /* SSID */ const char *ssid = (const char *)&ies[2]; const size_t ssid_len = ies[1]; @@ -1072,8 +1071,8 @@ struct scan_results_context { }; static bool -handle_nl80211_bss(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +handle_nl80211_bss(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len, + void *_ctx) { struct scan_results_context *ctx = _ctx; @@ -1113,8 +1112,8 @@ handle_nl80211_bss(struct module *mod, struct iface *iface, uint16_t type, bool } static bool -handle_nl80211_scan_results(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *_ctx) +handle_nl80211_scan_results(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, + size_t len, void *_ctx) { struct scan_results_context ctx = {0}; @@ -1172,7 +1171,8 @@ handle_stats(struct module *mod, uint32_t seq, struct rt_stats_msg *msg) struct iface *iface = NULL; - tll_foreach(m->ifaces, it) { + tll_foreach(m->ifaces, it) + { if (seq != it->item.get_stats_seq_nr) continue; iface = &it->item; @@ -1241,16 +1241,14 @@ parse_rt_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) break; } - case NLMSG_ERROR:{ + case NLMSG_ERROR: { const struct nlmsgerr *err = NLMSG_DATA(hdr); LOG_ERRNO_P(-err->error, "netlink RT reply"); return false; } default: - LOG_WARN( - "unrecognized netlink message type: 0x%x", - hdr->nlmsg_type); + LOG_WARN("unrecognized netlink message type: 0x%x", hdr->nlmsg_type); return false; } } @@ -1288,8 +1286,7 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) /* Current request is now considered complete */ m->nl80211.get_scan_seq_nr = 0; - tll_foreach(m->ifaces, it) - send_nl80211_get_station(m, &it->item); + tll_foreach(m->ifaces, it) send_nl80211_get_station(m, &it->item); } } @@ -1300,11 +1297,10 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) switch (genl->cmd) { case NL80211_CMD_NEW_INTERFACE: if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) - continue; + continue; LOG_DBG("%s: got interface information", iface->name); - foreach_nlattr( - mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL); + foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL); break; case NL80211_CMD_CONNECT: @@ -1324,7 +1320,7 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) case NL80211_CMD_DISCONNECT: if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) - continue; + continue; LOG_DBG("%s: disconnected, resetting SSID etc", iface->name); @@ -1338,20 +1334,18 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) case NL80211_CMD_NEW_STATION: if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) - continue; + continue; LOG_DBG("%s: got station information", iface->name); foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_station, NULL); - LOG_DBG("%s: signal: %d dBm, RX=%u Mbit/s, TX=%u Mbit/s", - iface->name, iface->signal_strength_dbm, - iface->rx_bitrate / 1000 / 1000, - iface->tx_bitrate / 1000 / 1000); + LOG_DBG("%s: signal: %d dBm, RX=%u Mbit/s, TX=%u Mbit/s", iface->name, iface->signal_strength_dbm, + iface->rx_bitrate / 1000 / 1000, iface->tx_bitrate / 1000 / 1000); break; case NL80211_CMD_NEW_SCAN_RESULTS: if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface)) - continue; + continue; LOG_DBG("%s: got scan results", iface->name); foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_scan_results, NULL); @@ -1372,15 +1366,12 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) else if (nl_errno == ENOENT) ; /* iface down? */ else { - LOG_ERRNO_P(nl_errno, "nl80211 reply (seq-nr: %u)", - hdr->nlmsg_seq); + LOG_ERRNO_P(nl_errno, "nl80211 reply (seq-nr: %u)", hdr->nlmsg_seq); } } else { - LOG_WARN( - "unrecognized netlink message type: 0x%x", - hdr->nlmsg_type); + LOG_WARN("unrecognized netlink message type: 0x%x", hdr->nlmsg_type); return false; } } @@ -1422,9 +1413,7 @@ run(struct module *mod) if (m->rt_sock < 0 || m->genl_sock < 0) goto out; - if (!send_rt_request(m, RTM_GETLINK) || - !send_ctrl_get_family_request(m)) - { + if (!send_rt_request(m, RTM_GETLINK) || !send_ctrl_get_family_request(m)) { goto out; } @@ -1442,9 +1431,7 @@ run(struct module *mod) if (fds[0].revents & (POLLIN | POLLHUP)) break; - if ((fds[1].revents & POLLHUP) || - (fds[2].revents & POLLHUP)) - { + if ((fds[1].revents & POLLHUP) || (fds[2].revents & POLLHUP)) { LOG_ERR("disconnected from netlink socket"); break; } @@ -1493,7 +1480,8 @@ run(struct module *mod) break; } - tll_foreach(m->ifaces, it) { + tll_foreach(m->ifaces, it) + { send_nl80211_get_station(m, &it->item); send_rt_getstats_request(m, &it->item); }; @@ -1502,7 +1490,7 @@ run(struct module *mod) ret = 0; - out: +out: if (m->rt_sock >= 0) close(m->rt_sock); if (m->genl_sock >= 0) @@ -1552,14 +1540,12 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *left_spacing = yml_get_value(node, "left-spacing"); const struct yml_node *right_spacing = yml_get_value(node, "right-spacing"); - int left = spacing != NULL ? yml_value_as_int(spacing) : - left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; - int right = spacing != NULL ? yml_value_as_int(spacing) : - right_spacing != NULL ? yml_value_as_int(right_spacing) : 0; + int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; + int right = spacing != NULL ? yml_value_as_int(spacing) + : right_spacing != NULL ? yml_value_as_int(right_spacing) + : 0; - return network_new( - conf_to_particle(content, inherited), - poll != NULL ? yml_value_as_int(poll) : 0, left, right); + return network_new(conf_to_particle(content, inherited), poll != NULL ? yml_value_as_int(poll) : 0, left, right); } static bool @@ -1570,8 +1556,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node) int interval = yml_value_as_int(node); if (interval > 0 && interval < min_poll_interval) { - LOG_ERR("%s: interval value cannot be less than %ldms", - conf_err_prefix(chain, node), min_poll_interval); + LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval); return false; } diff --git a/modules/pipewire.c b/modules/pipewire.c index 2300e7c..1a6ab1f 100644 --- a/modules/pipewire.c +++ b/modules/pipewire.c @@ -867,9 +867,7 @@ content(struct module *module) /* sink */ output_informations - = (private->data->target_sink == NULL - ? &output_informations_null - : &private->sink_informations); + = (private->data->target_sink == NULL ? &output_informations_null : &private->sink_informations); struct tag_set sink_tag_set = (struct tag_set){ .tags = (struct tag *[]){ @@ -888,9 +886,7 @@ content(struct module *module) /* source */ output_informations - = (private->data->target_source == NULL - ? &output_informations_null - : &private->source_informations); + = (private->data->target_source == NULL ? &output_informations_null : &private->source_informations); struct tag_set source_tag_set = (struct tag_set){ .tags = (struct tag *[]){ diff --git a/modules/pulse.c b/modules/pulse.c index 9eba3a5..e605dea 100644 --- a/modules/pulse.c +++ b/modules/pulse.c @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include @@ -17,7 +17,8 @@ #include "../log.h" #include "../plugin.h" -struct private { +struct private +{ char *sink_name; char *source_name; struct particle *label; @@ -69,9 +70,9 @@ content(struct module *mod) mtx_lock(&mod->lock); - pa_volume_t sink_volume_max = pa_cvolume_max(&priv->sink_volume); + pa_volume_t sink_volume_max = pa_cvolume_max(&priv->sink_volume); pa_volume_t source_volume_max = pa_cvolume_max(&priv->source_volume); - int sink_percent = round(100.0 * sink_volume_max / PA_VOLUME_NORM); + int sink_percent = round(100.0 * sink_volume_max / PA_VOLUME_NORM); int source_percent = round(100.0 * source_volume_max / PA_VOLUME_NORM); struct tag_set tags = { @@ -106,11 +107,7 @@ context_error(pa_context *c) } static void -abort_event_cb(pa_mainloop_api *api, - pa_io_event *event, - int fd, - pa_io_event_flags_t flags, - void *userdata) +abort_event_cb(pa_mainloop_api *api, pa_io_event *event, int fd, pa_io_event_flags_t flags, void *userdata) { struct module *mod = userdata; struct private *priv = mod->private; @@ -119,11 +116,7 @@ abort_event_cb(pa_mainloop_api *api, } static void -refresh_timer_cb(pa_mainloop_api *api, - pa_io_event *event, - int fd, - pa_io_event_flags_t flags, - void *userdata) +refresh_timer_cb(pa_mainloop_api *api, pa_io_event *event, int fd, pa_io_event_flags_t flags, void *userdata) { struct module *mod = userdata; struct private *priv = mod->private; @@ -155,8 +148,8 @@ schedule_refresh(struct module *mod) // Start the refresh timer. struct itimerspec t = { - .it_interval = { .tv_sec = 0, .tv_nsec = 0 }, - .it_value = { .tv_sec = 0, .tv_nsec = 50000000 }, + .it_interval = {.tv_sec = 0, .tv_nsec = 0}, + .it_value = {.tv_sec = 0, .tv_nsec = 50000000}, }; timerfd_settime(priv->refresh_timer_fd, 0, &t, NULL); @@ -200,12 +193,10 @@ set_sink_info(struct module *mod, const pa_sink_info *sink_info) free(priv->sink_port); priv->sink_online = true; - priv->sink_index = sink_info->index; + priv->sink_index = sink_info->index; priv->sink_volume = sink_info->volume; - priv->sink_muted = sink_info->mute; - priv->sink_port = sink_info->active_port != NULL - ? strdup(sink_info->active_port->description) - : NULL; + priv->sink_muted = sink_info->mute; + priv->sink_port = sink_info->active_port != NULL ? strdup(sink_info->active_port->description) : NULL; mtx_unlock(&mod->lock); @@ -234,12 +225,10 @@ set_source_info(struct module *mod, const pa_source_info *source_info) free(priv->source_port); priv->source_online = true; - priv->source_index = source_info->index; + priv->source_index = source_info->index; priv->source_volume = source_info->volume; - priv->source_muted = source_info->mute; - priv->source_port = source_info->active_port != NULL - ? strdup(source_info->active_port->description) - : NULL; + priv->source_muted = source_info->mute; + priv->source_port = source_info->active_port != NULL ? strdup(source_info->active_port->description) : NULL; mtx_unlock(&mod->lock); @@ -293,32 +282,28 @@ server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) static void get_sink_info_by_name(pa_context *c, const char *name, void *userdata) { - pa_operation *o = - pa_context_get_sink_info_by_name(c, name, sink_info_cb, userdata); + pa_operation *o = pa_context_get_sink_info_by_name(c, name, sink_info_cb, userdata); pa_operation_unref(o); } static void get_source_info_by_name(pa_context *c, const char *name, void *userdata) { - pa_operation *o = - pa_context_get_source_info_by_name(c, name, source_info_cb, userdata); + pa_operation *o = pa_context_get_source_info_by_name(c, name, source_info_cb, userdata); pa_operation_unref(o); } static void get_sink_info_by_index(pa_context *c, uint32_t index, void *userdata) { - pa_operation *o = - pa_context_get_sink_info_by_index(c, index, sink_info_cb, userdata); + pa_operation *o = pa_context_get_sink_info_by_index(c, index, sink_info_cb, userdata); pa_operation_unref(o); } static void get_source_info_by_index(pa_context *c, uint32_t index, void *userdata) { - pa_operation *o = - pa_context_get_source_info_by_index(c, index, source_info_cb, userdata); + pa_operation *o = pa_context_get_source_info_by_index(c, index, source_info_cb, userdata); pa_operation_unref(o); } @@ -332,15 +317,12 @@ get_server_info(pa_context *c, void *userdata) static void subscribe(pa_context *c, void *userdata) { - pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SERVER - | PA_SUBSCRIPTION_MASK_SINK - | PA_SUBSCRIPTION_MASK_SOURCE; + pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SERVER | PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE; pa_operation *o = pa_context_subscribe(c, mask, NULL, userdata); pa_operation_unref(o); } -static pa_context * -connect_to_server(struct module *mod); +static pa_context *connect_to_server(struct module *mod); static void context_state_change_cb(pa_context *c, void *userdata) @@ -380,16 +362,13 @@ context_state_change_cb(pa_context *c, void *userdata) } static void -subscription_event_cb(pa_context *c, - pa_subscription_event_type_t event_type, - uint32_t index, - void *userdata) +subscription_event_cb(pa_context *c, pa_subscription_event_type_t event_type, uint32_t index, void *userdata) { struct module *mod = userdata; struct private *priv = mod->private; int facility = event_type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; - int type = event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK; + int type = event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK; switch (facility) { case PA_SUBSCRIPTION_EVENT_SERVER: @@ -435,8 +414,7 @@ connect_to_server(struct module *mod) pa_context_set_subscribe_callback(c, subscription_event_cb, mod); // Connect to server. - pa_context_flags_t flags = PA_CONTEXT_NOFAIL - | PA_CONTEXT_NOAUTOSPAWN; + pa_context_flags_t flags = PA_CONTEXT_NOFAIL | PA_CONTEXT_NOAUTOSPAWN; if (pa_context_connect(c, NULL, flags, NULL) < 0) { LOG_ERR("failed to connect to PulseAudio server: %s", context_error(c)); pa_context_unref(c); @@ -477,10 +455,8 @@ run(struct module *mod) // Poll refresh timer and abort event. pa_mainloop_api *api = pa_mainloop_get_api(priv->mainloop); - api->io_new(api, priv->refresh_timer_fd, PA_IO_EVENT_INPUT, - refresh_timer_cb, mod); - api->io_new(api, mod->abort_fd, PA_IO_EVENT_INPUT | PA_IO_EVENT_HANGUP, - abort_event_cb, mod); + api->io_new(api, priv->refresh_timer_fd, PA_IO_EVENT_INPUT, refresh_timer_cb, mod); + api->io_new(api, mod->abort_fd, PA_IO_EVENT_INPUT | PA_IO_EVENT_HANGUP, abort_event_cb, mod); // Run main loop. if (pa_mainloop_run(priv->mainloop, &ret) < 0) { @@ -497,9 +473,7 @@ run(struct module *mod) } static struct module * -pulse_new(const char *sink_name, - const char *source_name, - struct particle *label) +pulse_new(const char *sink_name, const char *source_name, struct particle *label) { struct private *priv = calloc(1, sizeof *priv); priv->label = label; @@ -522,10 +496,9 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *source = yml_get_value(node, "source"); const struct yml_node *content = yml_get_value(node, "content"); - return pulse_new( - sink != NULL ? yml_value_as_string(sink) : "@DEFAULT_SINK@", - source != NULL ? yml_value_as_string(source) : "@DEFAULT_SOURCE@", - conf_to_particle(content, inherited)); + return pulse_new(sink != NULL ? yml_value_as_string(sink) : "@DEFAULT_SINK@", + source != NULL ? yml_value_as_string(source) : "@DEFAULT_SOURCE@", + conf_to_particle(content, inherited)); } static bool diff --git a/modules/removables.c b/modules/removables.c index 4d1d508..e4ef98e 100644 --- a/modules/removables.c +++ b/modules/removables.c @@ -1,15 +1,15 @@ -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include -#include #include @@ -17,10 +17,10 @@ #define LOG_MODULE "removables" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../particles/dynlist.h" #include "../plugin.h" @@ -54,7 +54,8 @@ struct block_device { tll(struct partition) partitions; }; -struct private { +struct private +{ struct particle *label; int left_spacing; int right_spacing; @@ -75,8 +76,7 @@ free_partition(struct partition *p) static void free_device(struct block_device *b) { - tll_foreach(b->partitions, it) - free_partition(&it->item); + tll_foreach(b->partitions, it) free_partition(&it->item); tll_free(b->partitions); free(b->sys_path); @@ -91,8 +91,7 @@ destroy(struct module *mod) struct private *m = mod->private; m->label->destroy(m->label); - tll_foreach(m->devices, it) - free_device(&it->item); + tll_foreach(m->devices, it) free_device(&it->item); tll_free(m->devices); tll_free_and_free(m->ignore, free); @@ -113,24 +112,23 @@ content(struct module *mod) tll(const struct partition *) partitions = tll_init(); - tll_foreach(m->devices, dev) { - tll_foreach(dev->item.partitions, part) { - tll_push_back(partitions, &part->item); - } + tll_foreach(m->devices, dev) + { + tll_foreach(dev->item.partitions, part) { tll_push_back(partitions, &part->item); } } struct exposable *exposables[max(tll_length(partitions), 1)]; size_t idx = 0; - tll_foreach(partitions, it) { + tll_foreach(partitions, it) + { const struct partition *p = it->item; char dummy_label[16]; const char *label = p->label; if (label == NULL) { - snprintf(dummy_label, sizeof(dummy_label), - "%.1f GB", (double)p->size / 1024 / 1024 / 1024 * 512); + snprintf(dummy_label, sizeof(dummy_label), "%.1f GB", (double)p->size / 1024 / 1024 / 1024 * 512); label = dummy_label; } @@ -157,8 +155,7 @@ content(struct module *mod) } tll_free(partitions); - return dynlist_exposable_new( - exposables, idx, m->left_spacing, m->right_spacing); + return dynlist_exposable_new(exposables, idx, m->left_spacing, m->right_spacing); } static void @@ -178,9 +175,7 @@ find_mount_points(const char *dev_path, mount_point_list_t *mount_points) while (fgets(line, sizeof(line), f) != NULL) { char *dev = NULL, *path = NULL; - if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-] - %*s %ms %*s", - &path, &dev) != 2) - { + if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-] - %*s %ms %*s", &path, &dev) != 2) { LOG_ERR("failed to parse /proc/self/mountinfo: %s", line); free(dev); free(path); @@ -207,9 +202,11 @@ update_mount_points(struct partition *partition) /* Remove mount points that no longer exists (i.e. old mount * points that aren't in the new list) */ - tll_foreach(partition->mount_points, old) { + tll_foreach(partition->mount_points, old) + { bool gone = true; - tll_foreach(new_mounts, new) { + tll_foreach(new_mounts, new) + { if (strcmp(new->item, old->item) == 0) { /* Remove from new list, as it's already in the * partitions list */ @@ -228,7 +225,8 @@ update_mount_points(struct partition *partition) /* Add new mount points (i.e. mount points in the new list, that * aren't in the old list) */ - tll_foreach(new_mounts, new) { + tll_foreach(new_mounts, new) + { LOG_DBG("%s: mounted on %s", partition->dev_path, new->item); tll_push_back(partition->mount_points, new->item); @@ -242,14 +240,13 @@ update_mount_points(struct partition *partition) } static struct partition * -add_partition(struct module *mod, struct block_device *block, - struct udev_device *dev) +add_partition(struct module *mod, struct block_device *block, struct udev_device *dev) { struct private *m = mod->private; const char *_size = udev_device_get_sysattr_value(dev, "size"); uint64_t size = 0; if (_size != NULL) - sscanf(_size, "%"SCNu64, &size); + sscanf(_size, "%" SCNu64, &size); #if 0 struct udev_list_entry *e = NULL; @@ -260,7 +257,8 @@ add_partition(struct module *mod, struct block_device *block, const char *devname = udev_device_get_property_value(dev, "DEVNAME"); if (devname != NULL) { - tll_foreach(m->ignore, it) { + tll_foreach(m->ignore, it) + { if (strcmp(it->item, devname) == 0) { LOG_DBG("ignoring %s because it is on the ignore list", devname); return NULL; @@ -272,21 +270,17 @@ add_partition(struct module *mod, struct block_device *block, if (label == NULL) label = udev_device_get_property_value(dev, "ID_LABEL"); - LOG_INFO("partition: add: %s: label=%s, size=%"PRIu64, - udev_device_get_devnode(dev), label, size); + LOG_INFO("partition: add: %s: label=%s, size=%" PRIu64, udev_device_get_devnode(dev), label, size); mtx_lock(&mod->lock); - tll_push_back( - block->partitions, - ((struct partition){ - .block = block, - .sys_path = strdup(udev_device_get_devpath(dev)), - .dev_path = strdup(udev_device_get_devnode(dev)), - .label = label != NULL ? strdup(label) : NULL, - .size = size, - .audio_cd = false, - .mount_points = tll_init()})); + tll_push_back(block->partitions, ((struct partition){.block = block, + .sys_path = strdup(udev_device_get_devpath(dev)), + .dev_path = strdup(udev_device_get_devnode(dev)), + .label = label != NULL ? strdup(label) : NULL, + .size = size, + .audio_cd = false, + .mount_points = tll_init()})); struct partition *p = &tll_back(block->partitions); update_mount_points(p); @@ -296,14 +290,13 @@ add_partition(struct module *mod, struct block_device *block, } static struct partition * -add_audio_cd(struct module *mod, struct block_device *block, - struct udev_device *dev) +add_audio_cd(struct module *mod, struct block_device *block, struct udev_device *dev) { struct private *m = mod->private; const char *_size = udev_device_get_sysattr_value(dev, "size"); uint64_t size = 0; if (_size != NULL) - sscanf(_size, "%"SCNu64, &size); + sscanf(_size, "%" SCNu64, &size); #if 0 struct udev_list_entry *e = NULL; @@ -314,7 +307,8 @@ add_audio_cd(struct module *mod, struct block_device *block, const char *devname = udev_device_get_property_value(dev, "DEVNAME"); if (devname != NULL) { - tll_foreach(m->ignore, it) { + tll_foreach(m->ignore, it) + { if (strcmp(it->item, devname) == 0) { LOG_DBG("ignoring %s because it is on the ignore list", devname); return NULL; @@ -322,28 +316,24 @@ add_audio_cd(struct module *mod, struct block_device *block, } } - const char *_track_count = udev_device_get_property_value( - dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); + const char *_track_count = udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); unsigned long track_count = strtoul(_track_count, NULL, 10); char label[64]; snprintf(label, sizeof(label), "Audio CD - %lu tracks", track_count); - LOG_INFO("audio CD: add: %s: tracks=%lu, label=%s, size=%"PRIu64, - udev_device_get_devnode(dev), track_count, label, size); + LOG_INFO("audio CD: add: %s: tracks=%lu, label=%s, size=%" PRIu64, udev_device_get_devnode(dev), track_count, label, + size); mtx_lock(&mod->lock); - tll_push_back( - block->partitions, - ((struct partition){ - .block = block, - .sys_path = strdup(udev_device_get_devpath(dev)), - .dev_path = strdup(udev_device_get_devnode(dev)), - .label = label != NULL ? strdup(label) : NULL, - .size = size, - .audio_cd = true, - .mount_points = tll_init()})); + tll_push_back(block->partitions, ((struct partition){.block = block, + .sys_path = strdup(udev_device_get_devpath(dev)), + .dev_path = strdup(udev_device_get_devnode(dev)), + .label = label != NULL ? strdup(label) : NULL, + .size = size, + .audio_cd = true, + .mount_points = tll_init()})); struct partition *p = &tll_back(block->partitions); update_mount_points(p); @@ -353,17 +343,15 @@ add_audio_cd(struct module *mod, struct block_device *block, } static bool -del_partition(struct module *mod, struct block_device *block, - struct udev_device *dev) +del_partition(struct module *mod, struct block_device *block, struct udev_device *dev) { const char *sys_path = udev_device_get_devpath(dev); mtx_lock(&mod->lock); - tll_foreach(block->partitions, it) { + tll_foreach(block->partitions, it) + { if (strcmp(it->item.sys_path, sys_path) == 0) { - LOG_INFO("%s: del: %s", - it->item.audio_cd ? "audio CD" : "partition", - it->item.dev_path); + LOG_INFO("%s: del: %s", it->item.audio_cd ? "audio CD" : "partition", it->item.dev_path); free_partition(&it->item); tll_remove(block->partitions, it); @@ -392,7 +380,8 @@ add_device(struct module *mod, struct udev_device *dev) const char *devname = udev_device_get_property_value(dev, "DEVNAME"); if (devname != NULL) { - tll_foreach(m->ignore, it) { + tll_foreach(m->ignore, it) + { if (strcmp(it->item, devname) == 0) { LOG_DBG("ignoring %s because it is on the ignore list", devname); return NULL; @@ -403,11 +392,12 @@ add_device(struct module *mod, struct udev_device *dev) const char *_size = udev_device_get_sysattr_value(dev, "size"); uint64_t size = 0; if (_size != NULL) - sscanf(_size, "%"SCNu64, &size); + sscanf(_size, "%" SCNu64, &size); #if 1 struct udev_list_entry *e = NULL; - udev_list_entry_foreach(e, udev_device_get_properties_list_entry(dev)) { + udev_list_entry_foreach(e, udev_device_get_properties_list_entry(dev)) + { LOG_DBG("%s -> %s", udev_list_entry_get_name(e), udev_list_entry_get_value(e)); } #endif @@ -424,27 +414,22 @@ add_device(struct module *mod, struct udev_device *dev) const char *_fs_usage = udev_device_get_property_value(dev, "ID_FS_USAGE"); bool have_fs = _fs_usage != NULL && strcmp(_fs_usage, "filesystem") == 0; - const char *_audio_track_count = udev_device_get_property_value( - dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); - unsigned long audio_track_count = - _audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0; + const char *_audio_track_count = udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); + unsigned long audio_track_count = _audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0; - LOG_DBG("device: add: %s: vendor=%s, model=%s, optical=%d, size=%"PRIu64, - udev_device_get_devnode(dev), vendor, model, optical, size); + LOG_DBG("device: add: %s: vendor=%s, model=%s, optical=%d, size=%" PRIu64, udev_device_get_devnode(dev), vendor, + model, optical, size); mtx_lock(&mod->lock); - tll_push_back( - m->devices, - ((struct block_device){ - .sys_path = strdup(udev_device_get_devpath(dev)), - .dev_path = strdup(udev_device_get_devnode(dev)), - .size = size, - .vendor = vendor != NULL ? strdup(vendor) : NULL, - .model = model != NULL ? strdup(model) : NULL, - .optical = optical, - .media = media, - .partitions = tll_init()})); + tll_push_back(m->devices, ((struct block_device){.sys_path = strdup(udev_device_get_devpath(dev)), + .dev_path = strdup(udev_device_get_devnode(dev)), + .size = size, + .vendor = vendor != NULL ? strdup(vendor) : NULL, + .model = model != NULL ? strdup(model) : NULL, + .optical = optical, + .media = media, + .partitions = tll_init()})); mtx_unlock(&mod->lock); @@ -466,7 +451,8 @@ del_device(struct module *mod, struct udev_device *dev) const char *sys_path = udev_device_get_devpath(dev); mtx_lock(&mod->lock); - tll_foreach(m->devices, it) { + tll_foreach(m->devices, it) + { if (strcmp(it->item.sys_path, sys_path) == 0) { LOG_DBG("device: del: %s", it->item.dev_path); @@ -490,7 +476,8 @@ change_device(struct module *mod, struct udev_device *dev) struct block_device *block = NULL; - tll_foreach(m->devices, it) { + tll_foreach(m->devices, it) + { if (strcmp(it->item.sys_path, sys_path) == 0) { block = &it->item; break; @@ -511,10 +498,8 @@ change_device(struct module *mod, struct udev_device *dev) const char *_fs_usage = udev_device_get_property_value(dev, "ID_FS_USAGE"); bool have_fs = _fs_usage != NULL && strcmp(_fs_usage, "filesystem") == 0; - const char *_audio_track_count = udev_device_get_property_value( - dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); - unsigned long audio_track_count = - _audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0; + const char *_audio_track_count = udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); + unsigned long audio_track_count = _audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0; bool media_change = media != block->media; @@ -522,8 +507,7 @@ change_device(struct module *mod, struct udev_device *dev) mtx_unlock(&mod->lock); if (media_change) { - LOG_INFO("device: change: %s: media %s", - block->dev_path, media ? "inserted" : "removed"); + LOG_INFO("device: change: %s: media %s", block->dev_path, media ? "inserted" : "removed"); if (media) { if (have_fs) @@ -569,7 +553,8 @@ handle_udev_event(struct module *mod, struct udev_device *dev) struct udev_device *parent = udev_device_get_parent(dev); const char *parent_sys_path = udev_device_get_devpath(parent); - tll_foreach(m->devices, it) { + tll_foreach(m->devices, it) + { if (strcmp(it->item.sys_path, parent_sys_path) != 0) continue; @@ -578,8 +563,7 @@ handle_udev_event(struct module *mod, struct udev_device *dev) else if (del) return del_partition(mod, &it->item, dev); else { - LOG_ERR("unimplemented: 'change' event on partition: %s", - udev_device_get_devpath(dev)); + LOG_ERR("unimplemented: 'change' event on partition: %s", udev_device_get_devpath(dev)); return false; } break; @@ -606,15 +590,15 @@ run(struct module *mod) udev_enumerate_add_match_subsystem(dev_enum, "block"); /* TODO: verify how an optical presents itself */ - //udev_enumerate_add_match_sysattr(dev_enum, "removable", "1"); + // udev_enumerate_add_match_sysattr(dev_enum, "removable", "1"); udev_enumerate_add_match_property(dev_enum, "DEVTYPE", "disk"); udev_enumerate_scan_devices(dev_enum); /* Loop list, and for each device, enumerate its partitions */ struct udev_list_entry *entry = NULL; - udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(dev_enum)) { - struct udev_device *dev = udev_device_new_from_syspath( - udev, udev_list_entry_get_name(entry)); + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(dev_enum)) + { + struct udev_device *dev = udev_device_new_from_syspath(udev, udev_list_entry_get_name(entry)); struct block_device *block = add_device(mod, dev); if (block == NULL) { @@ -631,9 +615,9 @@ run(struct module *mod) udev_enumerate_scan_devices(part_enum); struct udev_list_entry *sub_entry = NULL; - udev_list_entry_foreach(sub_entry, udev_enumerate_get_list_entry(part_enum)) { - struct udev_device *partition = udev_device_new_from_syspath( - udev, udev_list_entry_get_name(sub_entry)); + udev_list_entry_foreach(sub_entry, udev_enumerate_get_list_entry(part_enum)) + { + struct udev_device *partition = udev_device_new_from_syspath(udev, udev_list_entry_get_name(sub_entry)); add_partition(mod, block, partition); udev_device_unref(partition); } @@ -673,8 +657,10 @@ run(struct module *mod) bool update = false; if (fds[2].revents & POLLPRI) { - tll_foreach(m->devices, dev) { - tll_foreach(dev->item.partitions, part) { + tll_foreach(m->devices, dev) + { + tll_foreach(dev->item.partitions, part) + { if (update_mount_points(&part->item)) update = true; } @@ -703,8 +689,8 @@ run(struct module *mod) } static struct module * -removables_new(struct particle *label, int left_spacing, int right_spacing, - size_t ignore_count, const char *ignore[static ignore_count]) +removables_new(struct particle *label, int left_spacing, int right_spacing, size_t ignore_count, + const char *ignore[static ignore_count]) { struct private *priv = calloc(1, sizeof(*priv)); priv->label = label; @@ -732,26 +718,22 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *right_spacing = yml_get_value(node, "right-spacing"); const struct yml_node *ignore_list = yml_get_value(node, "ignore"); - int left = spacing != NULL ? yml_value_as_int(spacing) : - left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; - int right = spacing != NULL ? yml_value_as_int(spacing) : - right_spacing != NULL ? yml_value_as_int(right_spacing) : 0; + int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; + int right = spacing != NULL ? yml_value_as_int(spacing) + : right_spacing != NULL ? yml_value_as_int(right_spacing) + : 0; size_t ignore_count = ignore_list != NULL ? yml_list_length(ignore_list) : 0; const char *ignore[max(ignore_count, 1)]; if (ignore_list != NULL) { size_t i = 0; - for (struct yml_list_iter iter = yml_list_iter(ignore_list); - iter.node != NULL; - yml_list_next(&iter), i++) - { + for (struct yml_list_iter iter = yml_list_iter(ignore_list); iter.node != NULL; yml_list_next(&iter), i++) { ignore[i] = yml_value_as_string(iter.node); } } - return removables_new( - conf_to_particle(content, inherited), left, right, ignore_count, ignore); + return removables_new(conf_to_particle(content, inherited), left, right, ignore_count, ignore); } static bool diff --git a/modules/river.c b/modules/river.c index 2273166..2619c62 100644 --- a/modules/river.c +++ b/modules/river.c @@ -1,17 +1,17 @@ +#include +#include +#include #include #include -#include -#include -#include -#include #include +#include #define LOG_MODULE "river" #define LOG_ENABLE_DBG 0 #include "../log.h" -#include "../plugin.h" #include "../particles/dynlist.h" +#include "../plugin.h" #include "river-status-unstable-v1.h" #include "xdg-output-unstable-v1.h" @@ -49,7 +49,8 @@ struct seat { struct output *output; }; -struct private { +struct private +{ struct module *mod; struct zxdg_output_manager_v1 *xdg_output_manager; struct zriver_status_manager_v1 *status_manager; @@ -92,13 +93,12 @@ content(struct module *mod) uint32_t output_focused = 0; uint32_t seat_focused = 0; - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { const struct output *output = &it->item; - if (!m->all_monitors && - output_bar_is_on != NULL && output->name != NULL && - strcmp(output->name, output_bar_is_on) != 0) - { + if (!m->all_monitors && output_bar_is_on != NULL && output->name != NULL + && strcmp(output->name, output_bar_is_on) != 0) { continue; } @@ -106,7 +106,8 @@ content(struct module *mod) urgent |= output->urgent; occupied |= output->occupied; - tll_foreach(m->seats, it2) { + tll_foreach(m->seats, it2) + { const struct seat *seat = &it2->item; if (seat->output == output) { seat_focused |= output->focused; @@ -127,10 +128,7 @@ content(struct module *mod) bool is_urgent = urgent & (1u << i); bool is_occupied = occupied & (1u << i); - const char *state = - is_urgent ? "urgent" : - is_visible ? is_focused ? "focused" : "unfocused" : - "invisible"; + const char *state = is_urgent ? "urgent" : is_visible ? is_focused ? "focused" : "unfocused" : "invisible"; #if 0 LOG_DBG("tag: #%u, visible=%d, focused=%d, occupied=%d, state=%s", @@ -155,12 +153,10 @@ content(struct module *mod) if (m->title != NULL) { size_t i = 32; - tll_foreach(m->seats, it) { + tll_foreach(m->seats, it) + { const struct seat *seat = &it->item; - const char *layout = - seat->output != NULL && seat->output->layout != NULL - ? seat->output->layout - : ""; + const char *layout = seat->output != NULL && seat->output->layout != NULL ? seat->output->layout : ""; struct tag_set tags = { .tags = (struct tag *[]){ @@ -187,15 +183,15 @@ verify_iface_version(const char *iface, uint32_t version, uint32_t wanted) if (version >= wanted) return true; - LOG_ERR("%s: need interface version %u, but compositor only implements %u", - iface, wanted, version); + LOG_ERR("%s: need interface version %u, but compositor only implements %u", iface, wanted, version); return false; } static void output_destroy(struct output *output) { - tll_foreach(output->m->seats, it) { + tll_foreach(output->m->seats, it) + { struct seat *seat = &it->item; if (seat->output == output) seat->output = NULL; @@ -223,8 +219,7 @@ seat_destroy(struct seat *seat) } static void -focused_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, - uint32_t tags) +focused_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, uint32_t tags) { struct output *output = data; @@ -241,8 +236,7 @@ focused_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1 } static void -view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, - struct wl_array *tags) +view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, struct wl_array *tags) { struct output *output = data; struct module *mod = output->m->mod; @@ -254,9 +248,7 @@ view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, /* Each entry in the list is a view, and the value is the tags * associated with that view */ uint32_t *set; - wl_array_for_each(set, tags) { - output->occupied |= *set; - } + wl_array_for_each(set, tags) { output->occupied |= *set; } LOG_DBG("output: %s: occupied tags: 0x%0x", output->name, output->occupied); } @@ -265,8 +257,7 @@ view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, } static void -urgent_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, - uint32_t tags) +urgent_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, uint32_t tags) { struct output *output = data; struct module *mod = output->m->mod; @@ -281,9 +272,7 @@ urgent_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, #if defined(ZRIVER_OUTPUT_STATUS_V1_LAYOUT_NAME_SINCE_VERSION) static void -layout_name(void *data, - struct zriver_output_status_v1 *zriver_output_status_v1, - const char *name) +layout_name(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, const char *name) { struct output *output = data; struct module *mod = output->m->mod; @@ -300,8 +289,7 @@ layout_name(void *data, #if defined(ZRIVER_OUTPUT_STATUS_V1_LAYOUT_NAME_CLEAR_SINCE_VERSION) static void -layout_name_clear(void *data, - struct zriver_output_status_v1 *zriver_output_status_v1) +layout_name_clear(void *data, struct zriver_output_status_v1 *zriver_output_status_v1) { struct output *output = data; struct module *mod = output->m->mod; @@ -329,15 +317,12 @@ static const struct zriver_output_status_v1_listener river_status_output_listene }; static void -xdg_output_handle_logical_position(void *data, - struct zxdg_output_v1 *xdg_output, - int32_t x, int32_t y) +xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) { } static void -xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, - int32_t width, int32_t height) +xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) { } @@ -347,8 +332,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) } static void -xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, - const char *name) +xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name) { struct output *output = data; struct module *mod = output->m->mod; @@ -363,8 +347,7 @@ xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, } static void -xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, - const char *description) +xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, const char *description) { } @@ -391,36 +374,32 @@ update_output(struct output *output) output->status = NULL; } - output->status = zriver_status_manager_v1_get_river_output_status( - output->m->status_manager, output->wl_output); + output->status = zriver_status_manager_v1_get_river_output_status(output->m->status_manager, output->wl_output); if (output->status != NULL) { - zriver_output_status_v1_add_listener( - output->status, &river_status_output_listener, output); + zriver_output_status_v1_add_listener(output->status, &river_status_output_listener, output); } } if (output->m->xdg_output_manager != NULL && output->xdg_output == NULL) { - output->xdg_output = zxdg_output_manager_v1_get_xdg_output( - output->m->xdg_output_manager, output->wl_output); + output->xdg_output = zxdg_output_manager_v1_get_xdg_output(output->m->xdg_output_manager, output->wl_output); if (output->xdg_output != NULL) { - zxdg_output_v1_add_listener( - output->xdg_output, &xdg_output_listener, output); + zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output); } } } static void -focused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, - struct wl_output *wl_output) +focused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, struct wl_output *wl_output) { struct seat *seat = data; struct private *m = seat->m; struct module *mod = m->mod; struct output *output = NULL; - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { if (it->item.wl_output == wl_output) { output = &it->item; break; @@ -441,8 +420,7 @@ focused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, } static void -unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, - struct wl_output *wl_output) +unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, struct wl_output *wl_output) { struct seat *seat = data; struct private *m = seat->m; @@ -451,7 +429,8 @@ unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1 mtx_lock(&mod->lock); { struct output *output = NULL; - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { if (it->item.wl_output == wl_output) { output = &it->item; break; @@ -469,8 +448,7 @@ unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1 } static void -focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, - const char *title) +focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, const char *title) { struct seat *seat = data; struct module *mod = seat->m->mod; @@ -485,11 +463,9 @@ focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, const char *output_bar_is_on = mod->bar->output_name(mod->bar); - if (seat->m->all_monitors || - (output_bar_is_on != NULL && - seat->output != NULL && seat->output->name != NULL && - strcmp(output_bar_is_on, seat->output->name) == 0)) - { + if (seat->m->all_monitors + || (output_bar_is_on != NULL && seat->output != NULL && seat->output->name != NULL + && strcmp(output_bar_is_on, seat->output->name) == 0)) { mtx_lock(&mod->lock); { free(seat->title); @@ -502,8 +478,7 @@ focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, #if defined(ZRIVER_SEAT_STATUS_V1_MODE_SINCE_VERSION) static void -mode(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, - const char *name) +mode(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, const char *name) { struct seat *seat = data; struct module *mod = seat->m->mod; @@ -531,8 +506,7 @@ static const struct zriver_seat_status_v1_listener river_seat_status_listener = }; static void -seat_handle_capabilities(void *data, struct wl_seat *wl_seat, - enum wl_seat_capability caps) +seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { } @@ -569,19 +543,16 @@ update_seat(struct seat *seat) seat->status = NULL; } - seat->status = zriver_status_manager_v1_get_river_seat_status( - seat->m->status_manager, seat->wl_seat); + seat->status = zriver_status_manager_v1_get_river_seat_status(seat->m->status_manager, seat->wl_seat); if (seat->status == NULL) return; - zriver_seat_status_v1_add_listener( - seat->status, &river_seat_status_listener, seat); + zriver_seat_status_v1_add_listener(seat->status, &river_seat_status_listener, seat); } static void -handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) +handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct private *m = data; @@ -590,8 +561,7 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - struct wl_output *wl_output = wl_registry_bind( - registry, name, &wl_output_interface, required); + struct wl_output *wl_output = wl_registry_bind(registry, name, &wl_output_interface, required); if (wl_output == NULL) return; @@ -605,8 +575,7 @@ handle_global(void *data, struct wl_registry *registry, mtx_lock(&m->mod->lock); tll_push_back(m->outputs, output); update_output(&tll_back(m->outputs)); - tll_foreach(m->seats, it) - update_seat(&it->item); + tll_foreach(m->seats, it) update_seat(&it->item); mtx_unlock(&m->mod->lock); } @@ -615,12 +584,10 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - m->xdg_output_manager = wl_registry_bind( - registry, name, &zxdg_output_manager_v1_interface, required); + m->xdg_output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, required); mtx_lock(&m->mod->lock); - tll_foreach(m->outputs, it) - update_output(&it->item); + tll_foreach(m->outputs, it) update_output(&it->item); mtx_unlock(&m->mod->lock); } @@ -629,8 +596,7 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - struct wl_seat *wl_seat = wl_registry_bind( - registry, name, &wl_seat_interface, required); + struct wl_seat *wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, required); if (wl_seat == NULL) return; @@ -649,14 +615,11 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - m->status_manager = wl_registry_bind( - registry, name, &zriver_status_manager_v1_interface, min(version, 4)); + m->status_manager = wl_registry_bind(registry, name, &zriver_status_manager_v1_interface, min(version, 4)); mtx_lock(&m->mod->lock); - tll_foreach(m->outputs, it) - update_output(&it->item); - tll_foreach(m->seats, it) - update_seat(&it->item); + tll_foreach(m->outputs, it) update_output(&it->item); + tll_foreach(m->seats, it) update_seat(&it->item); mtx_unlock(&m->mod->lock); } } @@ -667,7 +630,8 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) struct private *m = data; mtx_lock(&m->mod->lock); - tll_foreach(m->outputs, it) { + tll_foreach(m->outputs, it) + { if (it->item.wl_name == name) { output_destroy(&it->item); tll_remove(m->outputs, it); @@ -676,7 +640,8 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) } } - tll_foreach(m->seats, it) { + tll_foreach(m->seats, it) + { if (it->item.wl_name == name) { seat_destroy(&it->item); tll_remove(m->seats, it); @@ -707,9 +672,8 @@ run(struct module *mod) goto out; } - if ((registry = wl_display_get_registry(display)) == NULL || - wl_registry_add_listener(registry, ®istry_listener, m) != 0) - { + if ((registry = wl_display_get_registry(display)) == NULL + || wl_registry_add_listener(registry, ®istry_listener, m) != 0) { LOG_ERR("failed to get Wayland registry"); goto out; } @@ -754,11 +718,9 @@ run(struct module *mod) ret = 0; out: - tll_foreach(m->seats, it) - seat_destroy(&it->item); + tll_foreach(m->seats, it) seat_destroy(&it->item); tll_free(m->seats); - tll_foreach(m->outputs, it) - output_destroy(&it->item); + tll_foreach(m->outputs, it) output_destroy(&it->item); tll_free(m->outputs); if (m->xdg_output_manager != NULL) @@ -797,10 +759,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *title = yml_get_value(node, "title"); const struct yml_node *all_monitors = yml_get_value(node, "all-monitors"); - return river_new( - conf_to_particle(c, inherited), - title != NULL ? conf_to_particle(title, inherited) : NULL, - all_monitors != NULL ? yml_value_as_bool(all_monitors) : false); + return river_new(conf_to_particle(c, inherited), title != NULL ? conf_to_particle(title, inherited) : NULL, + all_monitors != NULL ? yml_value_as_bool(all_monitors) : false); } static bool diff --git a/modules/script.c b/modules/script.c index 0932cb2..9f9b40a 100644 --- a/modules/script.c +++ b/modules/script.c @@ -1,14 +1,14 @@ -#include -#include -#include -#include #include -#include +#include #include #include +#include +#include +#include +#include -#include #include +#include #include #include @@ -16,15 +16,16 @@ #define LOG_MODULE "script" #define LOG_ENABLE_DBG 0 -#include "../log.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../module.h" #include "../plugin.h" static const long min_poll_interval = 250; -struct private { +struct private +{ char *path; size_t argc; char **argv; @@ -110,9 +111,8 @@ process_line(struct module *mod, const char *line, size_t len) size_t value_len = line + len - _value; - LOG_DBG("%.*s: name=\"%.*s\", type=\"%.*s\", value=\"%.*s\"", - (int)len, line, - (int)name_len, _name, (int)type_len, type, (int)value_len, _value); + LOG_DBG("%.*s: name=\"%.*s\", type=\"%.*s\", value=\"%.*s\"", (int)len, line, (int)name_len, _name, (int)type_len, + type, (int)value_len, _value); name = malloc(name_len + 1); memcpy(name, _name, name_len); @@ -165,16 +165,12 @@ process_line(struct module *mod, const char *line, size_t len) tag = tag_new_float(mod, name, v); } - else if ((type_len > 6 && memcmp(type, "range:", 6) == 0) || - (type_len > 9 && memcmp(type, "realtime:", 9) == 0)) - { + else if ((type_len > 6 && memcmp(type, "range:", 6) == 0) || (type_len > 9 && memcmp(type, "realtime:", 9) == 0)) { const char *_start = type + 6; const char *split = memchr(_start, '-', type_len - 6); if (split == NULL || split == _start || (split + 1) - type >= type_len) { - LOG_ERR( - "tag range delimiter ('-') not found in type: %.*s", - (int)type_len, type); + LOG_ERR("tag range delimiter ('-') not found in type: %.*s", (int)type_len, type); goto bad_tag; } @@ -186,9 +182,7 @@ process_line(struct module *mod, const char *line, size_t len) long start = 0; for (size_t i = 0; i < start_len; i++) { if (!(_start[i] >= '0' && _start[i] <= '9')) { - LOG_ERR( - "tag range start is not an integer: %.*s", - (int)start_len, _start); + LOG_ERR("tag range start is not an integer: %.*s", (int)start_len, _start); goto bad_tag; } @@ -199,9 +193,7 @@ process_line(struct module *mod, const char *line, size_t len) long end = 0; for (size_t i = 0; i < end_len; i++) { if (!(_end[i] >= '0' && _end[i] <= '9')) { - LOG_ERR( - "tag range end is not an integer: %.*s", - (int)end_len, _end); + LOG_ERR("tag range end is not an integer: %.*s", (int)end_len, _end); goto bad_tag; } @@ -223,8 +215,7 @@ process_line(struct module *mod, const char *line, size_t len) } if (v < start || v > end) { - LOG_ERR("tag value is outside range: %ld <= %ld <= %ld", - start, v, end); + LOG_ERR("tag value is outside range: %ld <= %ld <= %ld", start, v, end); goto bad_tag; } @@ -326,9 +317,7 @@ data_received(struct module *mod, const char *data, size_t len) process_transaction(mod, transaction_size); assert(m->recv_buf.idx >= transaction_size + 1); - memmove(m->recv_buf.data, - &m->recv_buf.data[transaction_size + 1], - m->recv_buf.idx - (transaction_size + 1)); + memmove(m->recv_buf.data, &m->recv_buf.data[transaction_size + 1], m->recv_buf.idx - (transaction_size + 1)); m->recv_buf.idx -= transaction_size + 1; } @@ -432,11 +421,8 @@ execute_script(struct module *mod) sigemptyset(&mask); const struct sigaction sa = {.sa_handler = SIG_DFL}; - if (sigaction(SIGINT, &sa, NULL) < 0 || - sigaction(SIGTERM, &sa, NULL) < 0 || - sigaction(SIGCHLD, &sa, NULL) < 0 || - sigprocmask(SIG_SETMASK, &mask, NULL) < 0) - { + if (sigaction(SIGINT, &sa, NULL) < 0 || sigaction(SIGTERM, &sa, NULL) < 0 || sigaction(SIGCHLD, &sa, NULL) < 0 + || sigprocmask(SIG_SETMASK, &mask, NULL) < 0) { goto fail; } @@ -452,9 +438,7 @@ execute_script(struct module *mod) if (dev_null < 0) goto fail; - if (dup2(dev_null, STDIN_FILENO) < 0 || - dup2(comm_pipe[1], STDOUT_FILENO) < 0) - { + if (dup2(dev_null, STDIN_FILENO) < 0 || dup2(comm_pipe[1], STDOUT_FILENO) < 0) { goto fail; } @@ -533,9 +517,7 @@ execute_script(struct module *mod) usleep(10000); pid_t waited_pid; - while ((waited_pid = waitpid( - pid, NULL, timeout > 0 ? WNOHANG : 0)) == 0) - { + while ((waited_pid = waitpid(pid, NULL, timeout > 0 ? WNOHANG : 0)) == 0) { struct timeval now; gettimeofday(&now, NULL); @@ -547,7 +529,7 @@ execute_script(struct module *mod) /* Don't spinning */ thrd_yield(); - usleep(100000); /* 100ms */ + usleep(100000); /* 100ms */ } if (waited_pid == pid) { @@ -580,7 +562,7 @@ run(struct module *mod) break; struct timeval now; - if (gettimeofday(&now, NULL) < 0) { + if (gettimeofday(&now, NULL) < 0) { LOG_ERRNO("failed to get current time"); break; } @@ -631,8 +613,7 @@ run(struct module *mod) } static struct module * -script_new(char *path, size_t argc, const char *const argv[static argc], - int poll_interval, struct particle *_content) +script_new(char *path, size_t argc, const char *const argv[static argc], int poll_interval, struct particle *_content) { struct private *m = calloc(1, sizeof(*m)); m->path = path; @@ -665,10 +646,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) if (args != NULL) { size_t i = 0; - for (struct yml_list_iter iter = yml_list_iter(args); - iter.node != NULL; - yml_list_next(&iter), i++) - { + for (struct yml_list_iter iter = yml_list_iter(args); iter.node != NULL; yml_list_next(&iter), i++) { argv[i] = yml_value_as_string(iter.node); } } @@ -691,10 +669,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } else path = strdup(yml_path); - return script_new( - path, argc, argv, - poll_interval != NULL ? yml_value_as_int(poll_interval) : 0, - conf_to_particle(c, inherited)); + return script_new(path, argc, argv, poll_interval != NULL ? yml_value_as_int(poll_interval) : 0, + conf_to_particle(c, inherited)); } static bool @@ -709,8 +685,7 @@ conf_verify_path(keychain_t *chain, const struct yml_node *node) const bool is_absolute = path[0] == '/'; if (!is_tilde && !is_absolute) { - LOG_ERR("%s: path must either be absolute, or begin with '~/'", - conf_err_prefix(chain, node)); + LOG_ERR("%s: path must either be absolute, or begin with '~/'", conf_err_prefix(chain, node)); return false; } @@ -730,8 +705,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node) return false; if (yml_value_as_int(node) < min_poll_interval) { - LOG_ERR("%s: interval value cannot be less than %ldms", - conf_err_prefix(chain, node), min_poll_interval); + LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval); return false; } diff --git a/modules/sway-xkb.c b/modules/sway-xkb.c index 96d8388..1507241 100644 --- a/modules/sway-xkb.c +++ b/modules/sway-xkb.c @@ -3,15 +3,15 @@ #define LOG_MODULE "sway-xkb" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" #include "../config-verify.h" #include "../config.h" +#include "../log.h" #include "../particles/dynlist.h" #include "../plugin.h" -#include "i3-ipc.h" #include "i3-common.h" +#include "i3-ipc.h" #define max(x, y) ((x) > (y) ? (x) : (y)) @@ -21,7 +21,8 @@ struct input { char *layout; }; -struct private { +struct private +{ struct particle *template; int left_spacing; int right_spacing; @@ -89,8 +90,7 @@ content(struct module *mod) } mtx_unlock(&mod->lock); - return dynlist_exposable_new( - particles, m->num_existing_inputs, m->left_spacing, m->right_spacing); + return dynlist_exposable_new(particles, m->num_existing_inputs, m->left_spacing, m->right_spacing); } static bool @@ -121,8 +121,7 @@ handle_input_reply(int sock, int type, const struct json_object *json, void *_mo struct input *input = NULL; for (size_t i = 0; i < m->num_inputs; i++) { struct input *maybe_input = &m->inputs[i]; - if (strcmp(maybe_input->identifier, id) == 0 && !maybe_input->exists) - { + if (strcmp(maybe_input->identifier, id) == 0 && !maybe_input->exists) { input = maybe_input; LOG_DBG("adding: %s", id); @@ -142,8 +141,7 @@ handle_input_reply(int sock, int type, const struct json_object *json, void *_mo /* Get current/active layout */ struct json_object *layout; - if (!json_object_object_get_ex( - obj, "xkb_active_layout_name", &layout)) + if (!json_object_object_get_ex(obj, "xkb_active_layout_name", &layout)) return false; const char *new_layout_str = json_object_get_string(layout); @@ -240,8 +238,7 @@ handle_input_event(int sock, int type, const struct json_object *json, void *_mo /* Get current/active layout */ struct json_object *layout; - if (!json_object_object_get_ex( - obj, "xkb_active_layout_name", &layout)) + if (!json_object_object_get_ex(obj, "xkb_active_layout_name", &layout)) return false; const char *new_layout_str = json_object_get_string(layout); @@ -309,8 +306,8 @@ run(struct module *mod) } static struct module * -sway_xkb_new(struct particle *template, const char *identifiers[], - size_t num_identifiers, int left_spacing, int right_spacing) +sway_xkb_new(struct particle *template, const char *identifiers[], size_t num_identifiers, int left_spacing, + int right_spacing) { struct private *m = calloc(1, sizeof(*m)); m->template = template; @@ -343,40 +340,32 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *left_spacing = yml_get_value(node, "left-spacing"); const struct yml_node *right_spacing = yml_get_value(node, "right-spacing"); - int left = spacing != NULL ? yml_value_as_int(spacing) : - left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; - int right = spacing != NULL ? yml_value_as_int(spacing) : - right_spacing != NULL ? yml_value_as_int(right_spacing) : 0; + int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; + int right = spacing != NULL ? yml_value_as_int(spacing) + : right_spacing != NULL ? yml_value_as_int(right_spacing) + : 0; const struct yml_node *ids = yml_get_value(node, "identifiers"); const size_t num_ids = yml_list_length(ids); const char *identifiers[num_ids]; size_t i = 0; - for (struct yml_list_iter it = yml_list_iter(ids); - it.node != NULL; - yml_list_next(&it), i++) - { + for (struct yml_list_iter it = yml_list_iter(ids); it.node != NULL; yml_list_next(&it), i++) { identifiers[i] = yml_value_as_string(it.node); } - return sway_xkb_new( - conf_to_particle(c, inherited), identifiers, num_ids, left, right); + return sway_xkb_new(conf_to_particle(c, inherited), identifiers, num_ids, left, right); } static bool verify_identifiers(keychain_t *chain, const struct yml_node *node) { if (!yml_is_list(node)) { - LOG_ERR("%s: identifiers must be a list of strings", - conf_err_prefix(chain, node)); + LOG_ERR("%s: identifiers must be a list of strings", conf_err_prefix(chain, node)); return false; } - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it)) - { + for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it)) { if (!conf_verify_string(chain, it.node)) return false; } @@ -404,5 +393,5 @@ const struct module_iface module_sway_xkb_iface = { }; #if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) -extern const struct module_iface iface __attribute__((weak, alias("module_sway_xkb_iface"))) ; +extern const struct module_iface iface __attribute__((weak, alias("module_sway_xkb_iface"))); #endif diff --git a/modules/xkb.c b/modules/xkb.c index edd0afe..e8e3c91 100644 --- a/modules/xkb.c +++ b/modules/xkb.c @@ -1,7 +1,7 @@ -#include -#include #include #include +#include +#include #include @@ -10,10 +10,10 @@ #define LOG_MODULE "xkb" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../plugin.h" #include "../xcb.h" @@ -32,7 +32,8 @@ struct indicators { char **names; }; -struct private { +struct private +{ struct particle *label; struct indicators indicators; struct layouts layouts; @@ -117,10 +118,8 @@ xkb_enable(xcb_connection_t *conn) { xcb_generic_error_t *err; - xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension( - conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); - xcb_xkb_use_extension_reply_t *reply = xcb_xkb_use_extension_reply( - conn, cookie, &err); + xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); + xcb_xkb_use_extension_reply_t *reply = xcb_xkb_use_extension_reply(conn, cookie, &err); if (err != NULL) { LOG_ERR("failed to query for XKB extension: %s", xcb_error(err)); @@ -142,8 +141,7 @@ xkb_enable(xcb_connection_t *conn) static int get_xkb_event_base(xcb_connection_t *conn) { - const struct xcb_query_extension_reply_t *reply = xcb_get_extension_data( - conn, &xcb_xkb_id); + const struct xcb_query_extension_reply_t *reply = xcb_get_extension_data(conn, &xcb_xkb_id); if (reply == NULL) { LOG_ERR("failed to get XKB extension data"); @@ -159,19 +157,14 @@ get_xkb_event_base(xcb_connection_t *conn) } static bool -get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, - struct indicators *indicators) +get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, struct indicators *indicators) { xcb_generic_error_t *err; - xcb_xkb_get_names_cookie_t cookie = xcb_xkb_get_names( - conn, - XCB_XKB_ID_USE_CORE_KBD, - XCB_XKB_NAME_DETAIL_GROUP_NAMES | - XCB_XKB_NAME_DETAIL_SYMBOLS | - XCB_XKB_NAME_DETAIL_INDICATOR_NAMES); + xcb_xkb_get_names_cookie_t cookie = xcb_xkb_get_names(conn, XCB_XKB_ID_USE_CORE_KBD, + XCB_XKB_NAME_DETAIL_GROUP_NAMES | XCB_XKB_NAME_DETAIL_SYMBOLS + | XCB_XKB_NAME_DETAIL_INDICATOR_NAMES); - xcb_xkb_get_names_reply_t *reply = xcb_xkb_get_names_reply( - conn, cookie, &err); + xcb_xkb_get_names_reply_t *reply = xcb_xkb_get_names_reply(conn, cookie, &err); if (err != NULL) { LOG_ERR("failed to get layouts and indicators: %s", xcb_error(err)); @@ -181,22 +174,18 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, xcb_xkb_get_names_value_list_t vlist; void *buf = xcb_xkb_get_names_value_list(reply); - xcb_xkb_get_names_value_list_unpack( - buf, reply->nTypes, reply->indicators, reply->virtualMods, - reply->groupNames, reply->nKeys, reply->nKeyAliases, - reply->nRadioGroups, reply->which, &vlist); + xcb_xkb_get_names_value_list_unpack(buf, reply->nTypes, reply->indicators, reply->virtualMods, reply->groupNames, + reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &vlist); /* Number of groups (aka layouts) */ layouts->count = xcb_xkb_get_names_value_list_groups_length(reply, &vlist); layouts->layouts = calloc(layouts->count, sizeof(layouts->layouts[0])); /* Number of indicators */ - indicators->count = xcb_xkb_get_names_value_list_indicator_names_length( - reply, &vlist); + indicators->count = xcb_xkb_get_names_value_list_indicator_names_length(reply, &vlist); indicators->names = calloc(indicators->count, sizeof(indicators->names[0])); - xcb_get_atom_name_cookie_t symbols_name_cookie = xcb_get_atom_name( - conn, vlist.symbolsName); + xcb_get_atom_name_cookie_t symbols_name_cookie = xcb_get_atom_name(conn, vlist.symbolsName); xcb_get_atom_name_cookie_t group_name_cookies[layouts->count]; for (size_t i = 0; i < layouts->count; i++) @@ -209,17 +198,14 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, char *symbols = NULL; /* Get layout short names (e.g. "us") */ - xcb_get_atom_name_reply_t *atom_name = xcb_get_atom_name_reply( - conn, symbols_name_cookie, &err); + xcb_get_atom_name_reply_t *atom_name = xcb_get_atom_name_reply(conn, symbols_name_cookie, &err); if (err != NULL) { LOG_ERR("failed to get 'symbols' atom name: %s", xcb_error(err)); free(err); goto err; } - symbols = strndup( - xcb_get_atom_name_name(atom_name), - xcb_get_atom_name_name_length(atom_name)); + symbols = strndup(xcb_get_atom_name_name(atom_name), xcb_get_atom_name_name_length(atom_name)); LOG_DBG("symbols: %s", symbols); free(atom_name); @@ -232,9 +218,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, goto err; } - layouts->layouts[i].name = strndup( - xcb_get_atom_name_name(atom_name), - xcb_get_atom_name_name_length(atom_name)); + layouts->layouts[i].name = strndup(xcb_get_atom_name_name(atom_name), xcb_get_atom_name_name_length(atom_name)); LOG_DBG("layout #%zd: long name: %s", i, layouts->layouts[i].name); free(atom_name); @@ -249,9 +233,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, goto err; } - indicators->names[i] = strndup( - xcb_get_atom_name_name(atom_name), - xcb_get_atom_name_name_length(atom_name)); + indicators->names[i] = strndup(xcb_get_atom_name_name(atom_name), xcb_get_atom_name_name_length(atom_name)); LOG_DBG("indicator #%zd: %s", i, indicators->names[i]); free(atom_name); @@ -259,8 +241,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, /* e.g. pc+us+inet(evdev)+group(..) */ size_t layout_idx = 0; - for (char *tok_ctx = NULL, *tok = strtok_r(symbols, "+", &tok_ctx); - tok != NULL; + for (char *tok_ctx = NULL, *tok = strtok_r(symbols, "+", &tok_ctx); tok != NULL; tok = strtok_r(NULL, "+", &tok_ctx)) { char *fname = strtok(tok, "()"); @@ -279,8 +260,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, continue; if (layout_idx >= layouts->count) { - LOG_ERR("layout vs group name count mismatch: %zd > %zd", - layout_idx + 1, layouts->count); + LOG_ERR("layout vs group name count mismatch: %zd > %zd", layout_idx + 1, layouts->count); goto err; } @@ -290,8 +270,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, } if (layout_idx != layouts->count) { - LOG_ERR("layout vs group name count mismatch: %zd != %zd", - layout_idx, layouts->count); + LOG_ERR("layout vs group name count mismatch: %zd != %zd", layout_idx, layouts->count); goto err; } @@ -312,10 +291,8 @@ get_current_layout(xcb_connection_t *conn) { xcb_generic_error_t *err; - xcb_xkb_get_state_cookie_t cookie = xcb_xkb_get_state( - conn, XCB_XKB_ID_USE_CORE_KBD); - xcb_xkb_get_state_reply_t *reply = xcb_xkb_get_state_reply( - conn, cookie, &err); + xcb_xkb_get_state_cookie_t cookie = xcb_xkb_get_state(conn, XCB_XKB_ID_USE_CORE_KBD); + xcb_xkb_get_state_reply_t *reply = xcb_xkb_get_state_reply(conn, cookie, &err); if (err != NULL) { LOG_ERR("failed to get XKB state: %s", xcb_error(err)); @@ -332,10 +309,8 @@ static uint32_t get_indicator_state(xcb_connection_t *conn) { xcb_generic_error_t *err; - xcb_xkb_get_indicator_state_cookie_t cookie = xcb_xkb_get_indicator_state( - conn, XCB_XKB_ID_USE_CORE_KBD); - xcb_xkb_get_indicator_state_reply_t *reply = xcb_xkb_get_indicator_state_reply( - conn, cookie, &err); + xcb_xkb_get_indicator_state_cookie_t cookie = xcb_xkb_get_indicator_state(conn, XCB_XKB_ID_USE_CORE_KBD); + xcb_xkb_get_indicator_state_reply_t *reply = xcb_xkb_get_indicator_state_reply(conn, cookie, &err); if (err != NULL) { LOG_ERR("failed to get indicator state: %s", xcb_error(err)); @@ -353,23 +328,14 @@ get_indicator_state(xcb_connection_t *conn) static bool register_for_events(xcb_connection_t *conn) { - xcb_void_cookie_t cookie = xcb_xkb_select_events_checked( - conn, - XCB_XKB_ID_USE_CORE_KBD, - ( - XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | - XCB_XKB_EVENT_TYPE_STATE_NOTIFY | - XCB_XKB_EVENT_TYPE_MAP_NOTIFY | - XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY - ), - 0, - ( - XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | - XCB_XKB_EVENT_TYPE_STATE_NOTIFY | - XCB_XKB_EVENT_TYPE_MAP_NOTIFY | - XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY - ), - 0, 0, NULL); + xcb_void_cookie_t cookie + = xcb_xkb_select_events_checked(conn, XCB_XKB_ID_USE_CORE_KBD, + (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY + | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY), + 0, + (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY + | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY), + 0, 0, NULL); xcb_generic_error_t *err = xcb_request_check(conn, cookie); if (err != NULL) { @@ -393,10 +359,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base) assert(xcb_fd >= 0); while (!has_error) { - struct pollfd pfds[] = { - {.fd = mod->abort_fd, .events = POLLIN }, - {.fd = xcb_fd, .events = POLLIN | POLLHUP } - }; + struct pollfd pfds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = xcb_fd, .events = POLLIN | POLLHUP}}; /* Use poll() since xcb_wait_for_events() doesn't return on signals */ if (poll(pfds, sizeof(pfds) / sizeof(pfds[0]), -1) < 0) { @@ -425,9 +388,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base) * not for long though... */ - for (xcb_generic_event_t *_evt = xcb_wait_for_event(conn); - _evt != NULL; - _evt = xcb_poll_for_event(conn)) { + for (xcb_generic_event_t *_evt = xcb_wait_for_event(conn); _evt != NULL; _evt = xcb_poll_for_event(conn)) { if (_evt->response_type != xkb_event_base) { LOG_WARN("non-XKB event ignored: %d", _evt->response_type); @@ -435,7 +396,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base) continue; } - switch(_evt->pad0) { + switch (_evt->pad0) { default: LOG_WARN("unimplemented XKB event: %d", _evt->pad0); break; @@ -463,7 +424,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base) mtx_unlock(&mod->lock); bar->refresh(bar); } else { - /* Can happen while transitioning to a new map */ + /* Can happen while transitioning to a new map */ free_layouts(layouts); free_indicators(indicators); } @@ -472,8 +433,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base) } case XCB_XKB_STATE_NOTIFY: { - const xcb_xkb_state_notify_event_t *evt = - (const xcb_xkb_state_notify_event_t *)_evt; + const xcb_xkb_state_notify_event_t *evt = (const xcb_xkb_state_notify_event_t *)_evt; if (evt->changed & XCB_XKB_STATE_PART_GROUP_STATE) { mtx_lock(&mod->lock); @@ -490,8 +450,8 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base) break; case XCB_XKB_INDICATOR_STATE_NOTIFY: { - const xcb_xkb_indicator_state_notify_event_t *evt = - (const xcb_xkb_indicator_state_notify_event_t *)_evt; + const xcb_xkb_indicator_state_notify_event_t *evt + = (const xcb_xkb_indicator_state_notify_event_t *)_evt; #if 0 size_t idx = __builtin_ctz(evt->stateChanged); @@ -508,8 +468,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base) continue; bool enabled = (evt->state >> i) & 1; - LOG_DBG("%s: %s", m->indicators.names[i], - enabled ? "enabled" : "disabled"); + LOG_DBG("%s: %s", m->indicators.names[i], enabled ? "enabled" : "disabled"); const char *name = m->indicators.names[i]; bool is_caps = strcasecmp(name, "caps lock") == 0; @@ -609,18 +568,12 @@ talk_to_xkb(struct module *mod, xcb_connection_t *conn) size_t idx = 0; for (size_t i = 0; i < layouts.count; i++) { - idx += snprintf(&buf[idx], sizeof(buf) - idx, "%s%s (%s)%s", - i == m->current ? "*" : "", - layouts.layouts[i].name, - layouts.layouts[i].symbol, - i + 1 < layouts.count ? ", " : ""); + idx += snprintf(&buf[idx], sizeof(buf) - idx, "%s%s (%s)%s", i == m->current ? "*" : "", + layouts.layouts[i].name, layouts.layouts[i].symbol, i + 1 < layouts.count ? ", " : ""); } - LOG_INFO("layouts: %s, caps-lock:%s, num-lock:%s, scroll-lock:%s", - buf, - caps_lock ? "on" : "off", - num_lock ? "on" : "off", - scroll_lock ? "on" : "off"); + LOG_INFO("layouts: %s, caps-lock:%s, num-lock:%s, scroll-lock:%s", buf, caps_lock ? "on" : "off", + num_lock ? "on" : "off", scroll_lock ? "on" : "off"); } mtx_lock(&mod->lock); diff --git a/modules/xwindow.c b/modules/xwindow.c index e53114e..ffae527 100644 --- a/modules/xwindow.c +++ b/modules/xwindow.c @@ -1,29 +1,30 @@ +#include +#include +#include #include #include #include -#include -#include -#include #include -#include +#include -#include #include #include +#include #include #include #include #define LOG_MODULE "xwindow" -#include "../log.h" #include "../bar/bar.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../plugin.h" #include "../xcb.h" -struct private { +struct private +{ /* Accessed from bar thread only */ struct particle *label; @@ -48,23 +49,19 @@ static void update_active_window(struct private *m) { if (m->active_win != 0) { - xcb_void_cookie_t c = xcb_change_window_attributes_checked( - m->conn, m->active_win, XCB_CW_EVENT_MASK, - (const uint32_t []){XCB_EVENT_MASK_NO_EVENT}); + xcb_void_cookie_t c = xcb_change_window_attributes_checked(m->conn, m->active_win, XCB_CW_EVENT_MASK, + (const uint32_t[]){XCB_EVENT_MASK_NO_EVENT}); xcb_generic_error_t *e = xcb_request_check(m->conn, c); if (e != NULL) { - LOG_DBG( - "failed to de-register events on previous active window: %s", - xcb_error(e)); + LOG_DBG("failed to de-register events on previous active window: %s", xcb_error(e)); free(e); } m->active_win = 0; } - xcb_get_property_cookie_t c = xcb_get_property( - m->conn, 0, m->root_win, _NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 0, 32); + xcb_get_property_cookie_t c = xcb_get_property(m->conn, 0, m->root_win, _NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 0, 32); xcb_generic_error_t *e; xcb_get_property_reply_t *r = xcb_get_property_reply(m->conn, c, &e); @@ -86,9 +83,8 @@ update_active_window(struct private *m) free(r); if (m->active_win != 0) { - xcb_change_window_attributes( - m->conn, m->active_win, XCB_CW_EVENT_MASK, - (const uint32_t []){XCB_EVENT_MASK_PROPERTY_CHANGE}); + xcb_change_window_attributes(m->conn, m->active_win, XCB_CW_EVENT_MASK, + (const uint32_t[]){XCB_EVENT_MASK_PROPERTY_CHANGE}); } } @@ -105,8 +101,7 @@ update_application(struct module *mod) if (m->active_win == 0) return; - xcb_get_property_cookie_t c = xcb_get_property( - m->conn, 0, m->active_win, _NET_WM_PID, XCB_ATOM_CARDINAL, 0, 32); + xcb_get_property_cookie_t c = xcb_get_property(m->conn, 0, m->active_win, _NET_WM_PID, XCB_ATOM_CARDINAL, 0, 32); xcb_generic_error_t *e; xcb_get_property_reply_t *r = xcb_get_property_reply(m->conn, c, &e); @@ -164,12 +159,11 @@ update_title(struct module *mod) if (m->active_win == 0) return; - xcb_get_property_cookie_t c1 = xcb_get_property( - m->conn, 0, m->active_win, _NET_WM_VISIBLE_NAME, UTF8_STRING, 0, 1000); - xcb_get_property_cookie_t c2 = xcb_get_property( - m->conn, 0, m->active_win, _NET_WM_NAME, UTF8_STRING, 0, 1000); - xcb_get_property_cookie_t c3 = xcb_get_property( - m->conn, 0, m->active_win, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 1000); + xcb_get_property_cookie_t c1 + = xcb_get_property(m->conn, 0, m->active_win, _NET_WM_VISIBLE_NAME, UTF8_STRING, 0, 1000); + xcb_get_property_cookie_t c2 = xcb_get_property(m->conn, 0, m->active_win, _NET_WM_NAME, UTF8_STRING, 0, 1000); + xcb_get_property_cookie_t c3 + = xcb_get_property(m->conn, 0, m->active_win, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 1000); xcb_generic_error_t *e1, *e2, *e3; xcb_get_property_reply_t *r1 = xcb_get_property_reply(m->conn, c1, &e1); @@ -207,7 +201,7 @@ update_title(struct module *mod) free(r1); free(r2); free(r3); - } +} static int run(struct module *mod) @@ -227,19 +221,16 @@ run(struct module *mod) /* Need a window(?) to be able to process events */ m->monitor_win = xcb_generate_id(m->conn); - xcb_create_window(m->conn, screen->root_depth, m->monitor_win, screen->root, - -1, -1, 1, 1, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, - XCB_CW_OVERRIDE_REDIRECT, (const uint32_t []){1}); + xcb_create_window(m->conn, screen->root_depth, m->monitor_win, screen->root, -1, -1, 1, 1, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, XCB_CW_OVERRIDE_REDIRECT, + (const uint32_t[]){1}); xcb_map_window(m->conn, m->monitor_win); /* Register for property changes on root window. This allows us to * catch e.g. window switches etc */ - xcb_change_window_attributes( - m->conn, screen->root, XCB_CW_EVENT_MASK, - (const uint32_t []){XCB_EVENT_MASK_PROPERTY_CHANGE}); + xcb_change_window_attributes(m->conn, screen->root, XCB_CW_EVENT_MASK, + (const uint32_t[]){XCB_EVENT_MASK_PROPERTY_CHANGE}); xcb_flush(m->conn); @@ -252,8 +243,7 @@ run(struct module *mod) int xcb_fd = xcb_get_file_descriptor(m->conn); while (true) { - struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, - {.fd = xcb_fd, .events = POLLIN}}; + struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = xcb_fd, .events = POLLIN}}; if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) < 0) { if (errno == EINTR) continue; @@ -267,10 +257,7 @@ run(struct module *mod) break; } - for (xcb_generic_event_t *_e = xcb_wait_for_event(m->conn); - _e != NULL; - _e = xcb_poll_for_event(m->conn)) - { + for (xcb_generic_event_t *_e = xcb_wait_for_event(m->conn); _e != NULL; _e = xcb_poll_for_event(m->conn)) { switch (XCB_EVENT_RESPONSE_TYPE(_e)) { case 0: LOG_ERR("XCB: %s", xcb_error((const xcb_generic_error_t *)_e)); @@ -278,18 +265,13 @@ run(struct module *mod) case XCB_PROPERTY_NOTIFY: { xcb_property_notify_event_t *e = (xcb_property_notify_event_t *)_e; - if (e->atom == _NET_ACTIVE_WINDOW || - e->atom == _NET_CURRENT_DESKTOP) - { + if (e->atom == _NET_ACTIVE_WINDOW || e->atom == _NET_CURRENT_DESKTOP) { /* Active desktop and/or window changed */ update_active_window(m); update_application(mod); update_title(mod); mod->bar->refresh(mod->bar); - } else if (e->atom == _NET_WM_VISIBLE_NAME || - e->atom == _NET_WM_NAME || - e->atom == XCB_ATOM_WM_NAME) - { + } else if (e->atom == _NET_WM_VISIBLE_NAME || e->atom == _NET_WM_NAME || e->atom == XCB_ATOM_WM_NAME) { assert(e->window == m->active_win); update_title(mod); mod->bar->refresh(mod->bar); diff --git a/particle.c b/particle.c index 2035d9a..f35b5d1 100644 --- a/particle.c +++ b/particle.c @@ -1,21 +1,21 @@ #include "particle.h" -#include -#include -#include #include #include #include +#include +#include +#include -#include -#include -#include #include +#include +#include +#include #define LOG_MODULE "particle" #define LOG_ENABLE_DBG 0 -#include "log.h" #include "bar/bar.h" +#include "log.h" void particle_default_destroy(struct particle *particle) @@ -29,10 +29,8 @@ particle_default_destroy(struct particle *particle) } struct particle * -particle_common_new(int left_margin, int right_margin, - char **on_click_templates, - struct fcft_font *font, enum font_shaping font_shaping, - pixman_color_t foreground, struct deco *deco) +particle_common_new(int left_margin, int right_margin, char **on_click_templates, struct fcft_font *font, + enum font_shaping font_shaping, pixman_color_t foreground, struct deco *deco) { struct particle *p = calloc(1, sizeof(*p)); p->left_margin = left_margin; @@ -63,13 +61,11 @@ exposable_default_destroy(struct exposable *exposable) } void -exposable_render_deco(const struct exposable *exposable, - pixman_image_t *pix, int x, int y, int height) +exposable_render_deco(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int height) { const struct deco *deco = exposable->particle->deco; if (deco != NULL) deco->expose(deco, pix, x, y, exposable->width, height); - } static bool @@ -114,9 +110,7 @@ tokenize_cmdline(char *cmdline, char ***argv) return false; } - if (!push_argv(argv, &argv_size, p, &idx) || - !push_argv(argv, &argv_size, NULL, &idx)) - { + if (!push_argv(argv, &argv_size, p, &idx) || !push_argv(argv, &argv_size, NULL, &idx)) { goto err; } else return true; @@ -152,8 +146,7 @@ err: } void -exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, - enum mouse_event event, enum mouse_button btn, +exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { #if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG @@ -168,17 +161,13 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, [MOUSE_BTN_PREVIOUS] = "previous", [MOUSE_BTN_NEXT] = "next", }; - LOG_DBG("on_mouse: exposable=%p, event=%s, btn=%s, x=%d, y=%d (on-click=%s)", - exposable, event == ON_MOUSE_MOTION ? "motion" : "click", - button_name[btn], x, y, exposable->on_click[btn]); + LOG_DBG("on_mouse: exposable=%p, event=%s, btn=%s, x=%d, y=%d (on-click=%s)", exposable, + event == ON_MOUSE_MOTION ? "motion" : "click", button_name[btn], x, y, exposable->on_click[btn]); #endif /* If we have a handler, change cursor to a hand */ - const char *cursor = - (exposable->particle != NULL && - exposable->particle->have_on_click_template) - ? "hand2" - : "left_ptr"; + const char *cursor + = (exposable->particle != NULL && exposable->particle->have_on_click_template) ? "hand2" : "left_ptr"; bar->set_cursor(bar, cursor); /* If this is a mouse click, and we have a handler, execute it */ @@ -246,7 +235,7 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, case 0: /* Child */ - close(pipe_fds[0]); /* Close read end */ + close(pipe_fds[0]); /* Close read end */ LOG_DBG("executing on-click handler: %s", cmd); @@ -254,11 +243,8 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, sigemptyset(&mask); const struct sigaction sa = {.sa_handler = SIG_DFL}; - if (sigaction(SIGINT, &sa, NULL) < 0 || - sigaction(SIGTERM, &sa, NULL) < 0 || - sigaction(SIGCHLD, &sa, NULL) < 0 || - sigprocmask(SIG_SETMASK, &mask, NULL) < 0) - { + if (sigaction(SIGINT, &sa, NULL) < 0 || sigaction(SIGTERM, &sa, NULL) < 0 + || sigaction(SIGCHLD, &sa, NULL) < 0 || sigprocmask(SIG_SETMASK, &mask, NULL) < 0) { goto fail; } @@ -271,10 +257,8 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, goto fail; } - if (dup2(dev_null_r, STDIN_FILENO) == -1 || - dup2(dev_null_w, STDOUT_FILENO) == -1 || - dup2(dev_null_w, STDERR_FILENO) == -1) - { + if (dup2(dev_null_r, STDIN_FILENO) == -1 || dup2(dev_null_w, STDOUT_FILENO) == -1 + || dup2(dev_null_w, STDERR_FILENO) == -1) { LOG_ERRNO("failed to redirect stdin/stdout/stderr"); goto fail; } @@ -316,10 +300,7 @@ exposable_common_new(const struct particle *particle, const struct tag_set *tags exposable->particle = particle; if (particle != NULL && particle->have_on_click_template) { - tags_expand_templates( - exposable->on_click, - (const char **)particle->on_click_templates, - MOUSE_BTN_COUNT, tags); + tags_expand_templates(exposable->on_click, (const char **)particle->on_click_templates, MOUSE_BTN_COUNT, tags); } exposable->destroy = &exposable_default_destroy; exposable->on_mouse = &exposable_default_on_mouse; diff --git a/particle.h b/particle.h index a2b55a8..bc8648d 100644 --- a/particle.h +++ b/particle.h @@ -42,11 +42,9 @@ struct particle { struct deco *deco; void (*destroy)(struct particle *particle); - struct exposable *(*instantiate)(const struct particle *particle, - const struct tag_set *tags); + struct exposable *(*instantiate)(const struct particle *particle, const struct tag_set *tags); }; - struct exposable { const struct particle *particle; void *private; @@ -56,38 +54,31 @@ struct exposable { void (*destroy)(struct exposable *exposable); int (*begin_expose)(struct exposable *exposable); - void (*expose)(const struct exposable *exposable, pixman_image_t *pix, - int x, int y, int height); + void (*expose)(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int height); - void (*on_mouse)(struct exposable *exposable, struct bar *bar, - enum mouse_event event, enum mouse_button btn, int x, int y); + void (*on_mouse)(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, + int y); }; -struct particle *particle_common_new( - int left_margin, int right_margin, char *on_click_templates[], - struct fcft_font *font, enum font_shaping font_shaping, - pixman_color_t foreground, struct deco *deco); +struct particle *particle_common_new(int left_margin, int right_margin, char *on_click_templates[], + struct fcft_font *font, enum font_shaping font_shaping, pixman_color_t foreground, + struct deco *deco); void particle_default_destroy(struct particle *particle); -struct exposable *exposable_common_new( - const struct particle *particle, const struct tag_set *tags); +struct exposable *exposable_common_new(const struct particle *particle, const struct tag_set *tags); void exposable_default_destroy(struct exposable *exposable); -void exposable_render_deco( - const struct exposable *exposable, pixman_image_t *pix, int x, int y, int height); +void exposable_render_deco(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int height); -void exposable_default_on_mouse( - struct exposable *exposable, struct bar *bar, - enum mouse_event event, enum mouse_button btn, int x, int y); +void exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, + enum mouse_button btn, int x, int y); /* List of attributes *all* particles implement */ -#define PARTICLE_COMMON_ATTRS \ - {"margin", false, &conf_verify_unsigned}, \ - {"left-margin", false, &conf_verify_unsigned}, \ - {"right-margin", false, &conf_verify_unsigned}, \ - {"on-click", false, &conf_verify_on_click}, \ - {"font", false, &conf_verify_font}, \ - {"font-shaping", false, &conf_verify_font_shaping}, \ - {"foreground", false, &conf_verify_color}, \ - {"deco", false, &conf_verify_decoration}, \ - {NULL, false, NULL} +#define PARTICLE_COMMON_ATTRS \ + {"margin", false, &conf_verify_unsigned}, {"left-margin", false, &conf_verify_unsigned}, \ + {"right-margin", false, &conf_verify_unsigned}, {"on-click", false, &conf_verify_on_click}, \ + {"font", false, &conf_verify_font}, {"font-shaping", false, &conf_verify_font_shaping}, \ + {"foreground", false, &conf_verify_color}, {"deco", false, &conf_verify_decoration}, \ + { \ + NULL, false, NULL \ + } diff --git a/particles/dynlist.c b/particles/dynlist.c index 85cad7b..fcd0066 100644 --- a/particles/dynlist.c +++ b/particles/dynlist.c @@ -1,13 +1,14 @@ #include "dynlist.h" -#include #include +#include #define LOG_MODULE "dynlist" #include "../log.h" #include "../particle.h" -struct private { +struct private +{ int left_spacing; int right_spacing; @@ -77,8 +78,7 @@ dynlist_expose(const struct exposable *exposable, pixman_image_t *pix, int x, in } static void -on_mouse(struct exposable *exposable, struct bar *bar, - enum mouse_event event, enum mouse_button btn, int x, int y) +on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { const struct private *e = exposable->private; @@ -87,12 +87,11 @@ on_mouse(struct exposable *exposable, struct bar *bar, return; } - int px = /*p->left_margin;*/0; + int px = /*p->left_margin;*/ 0; for (size_t i = 0; i < e->count; i++) { if (x >= px && x < px + e->exposables[i]->width) { if (e->exposables[i]->on_mouse != NULL) { - e->exposables[i]->on_mouse( - e->exposables[i], bar, event, btn, x - px, y); + e->exposables[i]->on_mouse(e->exposables[i], bar, event, btn, x - px, y); } return; } @@ -105,8 +104,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, } struct exposable * -dynlist_exposable_new(struct exposable **exposables, size_t count, - int left_spacing, int right_spacing) +dynlist_exposable_new(struct exposable **exposables, size_t count, int left_spacing, int right_spacing) { struct private *e = calloc(1, sizeof(*e)); e->count = count; diff --git a/particles/dynlist.h b/particles/dynlist.h index 4867997..810df45 100644 --- a/particles/dynlist.h +++ b/particles/dynlist.h @@ -3,5 +3,5 @@ #include struct particle; -struct exposable *dynlist_exposable_new( - struct exposable **exposables, size_t count, int left_spacing, int right_spacing); +struct exposable *dynlist_exposable_new(struct exposable **exposables, size_t count, int left_spacing, + int right_spacing); diff --git a/particles/empty.c b/particles/empty.c index 5c0be16..052eacd 100644 --- a/particles/empty.c +++ b/particles/empty.c @@ -1,15 +1,14 @@ #include -#include "../config.h" #include "../config-verify.h" +#include "../config.h" #include "../particle.h" #include "../plugin.h" static int begin_expose(struct exposable *exposable) { - exposable->width = exposable->particle->left_margin + - exposable->particle->right_margin; + exposable->width = exposable->particle->left_margin + exposable->particle->right_margin; return exposable->width; } diff --git a/particles/list.c b/particles/list.c index 2887d3c..83b5d0c 100644 --- a/particles/list.c +++ b/particles/list.c @@ -2,13 +2,14 @@ #define LOG_MODULE "list" #define LOG_ENABLE_DBG 0 -#include "../log.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../particle.h" #include "../plugin.h" -struct private { +struct private +{ struct particle **particles; size_t count; int left_spacing, right_spacing; @@ -21,7 +22,6 @@ struct eprivate { int left_spacing, right_spacing; }; - static void exposable_destroy(struct exposable *exposable) { @@ -86,16 +86,12 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int } static void -on_mouse(struct exposable *exposable, struct bar *bar, - enum mouse_event event, enum mouse_button btn, int x, int y) +on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if ((event == ON_MOUSE_MOTION && - exposable->particle->have_on_click_template) || - exposable->on_click[btn] != NULL) - { + if ((event == ON_MOUSE_MOTION && exposable->particle->have_on_click_template) || exposable->on_click[btn] != NULL) { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; @@ -105,8 +101,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, for (size_t i = 0; i < e->count; i++) { if (x >= px && x < px + e->exposables[i]->width) { if (e->exposables[i]->on_mouse != NULL) { - e->exposables[i]->on_mouse( - e->exposables[i], bar, event, btn, x - px, y); + e->exposables[i]->on_mouse(e->exposables[i], bar, event, btn, x - px, y); } return; } @@ -157,9 +152,8 @@ particle_destroy(struct particle *particle) } struct particle * -particle_list_new(struct particle *common, - struct particle *particles[], size_t count, - int left_spacing, int right_spacing) +particle_list_new(struct particle *common, struct particle *particles[], size_t count, int left_spacing, + int right_spacing) { struct private *p = calloc(1, sizeof(*p)); p->particles = malloc(count * sizeof(p->particles[0])); @@ -184,21 +178,20 @@ from_conf(const struct yml_node *node, struct particle *common) const struct yml_node *_left_spacing = yml_get_value(node, "left-spacing"); const struct yml_node *_right_spacing = yml_get_value(node, "right-spacing"); - int left_spacing = spacing != NULL ? yml_value_as_int(spacing) : - _left_spacing != NULL ? yml_value_as_int(_left_spacing) : 0; - int right_spacing = spacing != NULL ? yml_value_as_int(spacing) : - _right_spacing != NULL ? yml_value_as_int(_right_spacing) : 2; + int left_spacing = spacing != NULL ? yml_value_as_int(spacing) + : _left_spacing != NULL ? yml_value_as_int(_left_spacing) + : 0; + int right_spacing = spacing != NULL ? yml_value_as_int(spacing) + : _right_spacing != NULL ? yml_value_as_int(_right_spacing) + : 2; size_t count = yml_list_length(items); struct particle *parts[count]; size_t idx = 0; - for (struct yml_list_iter it = yml_list_iter(items); - it.node != NULL; - yml_list_next(&it), idx++) - { - parts[idx] = conf_to_particle( - it.node, (struct conf_inherit){common->font, common->font_shaping, common->foreground}); + for (struct yml_list_iter it = yml_list_iter(items); it.node != NULL; yml_list_next(&it), idx++) { + parts[idx] + = conf_to_particle(it.node, (struct conf_inherit){common->font, common->font_shaping, common->foreground}); } return particle_list_new(common, parts, count, left_spacing, right_spacing); diff --git a/particles/map.c b/particles/map.c index 1c1cc9a..51fc744 100644 --- a/particles/map.c +++ b/particles/map.c @@ -1,12 +1,12 @@ +#include +#include #include #include -#include -#include #define LOG_MODULE "map" -#include "../log.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../particle.h" #include "../plugin.h" #include "dynlist.h" @@ -17,14 +17,22 @@ static bool int_condition(const long tag_value, const long cond_value, enum map_op op) { switch (op) { - case MAP_OP_EQ: return tag_value == cond_value; - case MAP_OP_NE: return tag_value != cond_value; - case MAP_OP_LE: return tag_value <= cond_value; - case MAP_OP_LT: return tag_value < cond_value; - case MAP_OP_GE: return tag_value >= cond_value; - case MAP_OP_GT: return tag_value > cond_value; - case MAP_OP_SELF: LOG_WARN("using int tag as bool"); - default: return false; + case MAP_OP_EQ: + return tag_value == cond_value; + case MAP_OP_NE: + return tag_value != cond_value; + case MAP_OP_LE: + return tag_value <= cond_value; + case MAP_OP_LT: + return tag_value < cond_value; + case MAP_OP_GE: + return tag_value >= cond_value; + case MAP_OP_GT: + return tag_value > cond_value; + case MAP_OP_SELF: + LOG_WARN("using int tag as bool"); + default: + return false; } } @@ -32,34 +40,50 @@ static bool float_condition(const double tag_value, const double cond_value, enum map_op op) { switch (op) { - case MAP_OP_EQ: return tag_value == cond_value; - case MAP_OP_NE: return tag_value != cond_value; - case MAP_OP_LE: return tag_value <= cond_value; - case MAP_OP_LT: return tag_value < cond_value; - case MAP_OP_GE: return tag_value >= cond_value; - case MAP_OP_GT: return tag_value > cond_value; - case MAP_OP_SELF: LOG_WARN("using float tag as bool"); - default: return false; + case MAP_OP_EQ: + return tag_value == cond_value; + case MAP_OP_NE: + return tag_value != cond_value; + case MAP_OP_LE: + return tag_value <= cond_value; + case MAP_OP_LT: + return tag_value < cond_value; + case MAP_OP_GE: + return tag_value >= cond_value; + case MAP_OP_GT: + return tag_value > cond_value; + case MAP_OP_SELF: + LOG_WARN("using float tag as bool"); + default: + return false; } } static bool -str_condition(const char* tag_value, const char* cond_value, enum map_op op) +str_condition(const char *tag_value, const char *cond_value, enum map_op op) { switch (op) { - case MAP_OP_EQ: return strcmp(tag_value, cond_value) == 0; - case MAP_OP_NE: return strcmp(tag_value, cond_value) != 0; - case MAP_OP_LE: return strcmp(tag_value, cond_value) <= 0; - case MAP_OP_LT: return strcmp(tag_value, cond_value) < 0; - case MAP_OP_GE: return strcmp(tag_value, cond_value) >= 0; - case MAP_OP_GT: return strcmp(tag_value, cond_value) > 0; - case MAP_OP_SELF: LOG_WARN("using String tag as bool"); - default: return false; + case MAP_OP_EQ: + return strcmp(tag_value, cond_value) == 0; + case MAP_OP_NE: + return strcmp(tag_value, cond_value) != 0; + case MAP_OP_LE: + return strcmp(tag_value, cond_value) <= 0; + case MAP_OP_LT: + return strcmp(tag_value, cond_value) < 0; + case MAP_OP_GE: + return strcmp(tag_value, cond_value) >= 0; + case MAP_OP_GT: + return strcmp(tag_value, cond_value) > 0; + case MAP_OP_SELF: + LOG_WARN("using String tag as bool"); + default: + return false; } } static bool -eval_comparison(const struct map_condition* map_cond, const struct tag_set *tags) +eval_comparison(const struct map_condition *map_cond, const struct tag_set *tags) { const struct tag *tag = tag_for_name(tags, map_cond->tag); if (tag == NULL) { @@ -108,7 +132,7 @@ eval_comparison(const struct map_condition* map_cond, const struct tag_set *tags return false; } case TAG_TYPE_STRING: { - const char* tag_value = tag->as_string(tag); + const char *tag_value = tag->as_string(tag); return str_condition(tag_value, map_cond->value, map_cond->op); } } @@ -116,19 +140,17 @@ eval_comparison(const struct map_condition* map_cond, const struct tag_set *tags } static bool -eval_map_condition(const struct map_condition* map_cond, const struct tag_set *tags) +eval_map_condition(const struct map_condition *map_cond, const struct tag_set *tags) { - switch(map_cond->op) { + switch (map_cond->op) { case MAP_OP_NOT: return !eval_map_condition(map_cond->cond1, tags); case MAP_OP_AND: - return eval_map_condition(map_cond->cond1, tags) && - eval_map_condition(map_cond->cond2, tags); + return eval_map_condition(map_cond->cond1, tags) && eval_map_condition(map_cond->cond2, tags); case MAP_OP_OR: - return eval_map_condition(map_cond->cond1, tags) || - eval_map_condition(map_cond->cond2, tags); + return eval_map_condition(map_cond->cond1, tags) || eval_map_condition(map_cond->cond2, tags); default: return eval_comparison(map_cond, tags); @@ -136,28 +158,27 @@ eval_map_condition(const struct map_condition* map_cond, const struct tag_set *t } void -free_map_condition(struct map_condition* c) +free_map_condition(struct map_condition *c) { - switch (c->op) - { - case MAP_OP_EQ: - case MAP_OP_NE: - case MAP_OP_LE: - case MAP_OP_LT: - case MAP_OP_GE: - case MAP_OP_GT: - free(c->value); - /* FALLTHROUGH */ - case MAP_OP_SELF: - free(c->tag); - break; - case MAP_OP_AND: - case MAP_OP_OR: - free_map_condition(c->cond2); - /* FALLTHROUGH */ - case MAP_OP_NOT: - free_map_condition(c->cond1); - break; + switch (c->op) { + case MAP_OP_EQ: + case MAP_OP_NE: + case MAP_OP_LE: + case MAP_OP_LT: + case MAP_OP_GE: + case MAP_OP_GT: + free(c->value); + /* FALLTHROUGH */ + case MAP_OP_SELF: + free(c->tag); + break; + case MAP_OP_AND: + case MAP_OP_OR: + free_map_condition(c->cond2); + /* FALLTHROUGH */ + case MAP_OP_NOT: + free_map_condition(c->cond1); + break; } free(c); } @@ -167,7 +188,8 @@ struct particle_map { struct particle *particle; }; -struct private { +struct private +{ struct particle *default_particle; struct particle_map *map; size_t count; @@ -208,21 +230,16 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int struct eprivate *e = exposable->private; exposable_render_deco(exposable, pix, x, y, height); - e->exposable->expose( - e->exposable, pix, x + exposable->particle->left_margin, y, height); + e->exposable->expose(e->exposable, pix, x + exposable->particle->left_margin, y, height); } static void -on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, - enum mouse_button btn, int x, int y) +on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if ((event == ON_MOUSE_MOTION && - exposable->particle->have_on_click_template) || - exposable->on_click[btn] != NULL) - { + if ((event == ON_MOUSE_MOTION && exposable->particle->have_on_click_template) || exposable->on_click[btn] != NULL) { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; @@ -295,8 +312,8 @@ particle_destroy(struct particle *particle) } static struct particle * -map_new(struct particle *common, const struct particle_map particle_map[], - size_t count, struct particle *default_particle) +map_new(struct particle *common, const struct particle_map particle_map[], size_t count, + struct particle *default_particle) { struct private *priv = calloc(1, sizeof(*priv)); priv->default_particle = default_particle; @@ -314,22 +331,16 @@ map_new(struct particle *common, const struct particle_map particle_map[], return common; } - static bool verify_map_conditions(keychain_t *chain, const struct yml_node *node) { if (!yml_is_dict(node)) { - LOG_ERR( - "%s: must be a dictionary of workspace-name: particle mappings", - conf_err_prefix(chain, node)); + LOG_ERR("%s: must be a dictionary of workspace-name: particle mappings", conf_err_prefix(chain, node)); return false; } bool result = true; - for (struct yml_dict_iter it = yml_dict_iter(node); - it.key != NULL; - yml_dict_next(&it)) - { + for (struct yml_dict_iter it = yml_dict_iter(node); it.key != NULL; yml_dict_next(&it)) { const char *key = yml_value_as_string(it.key); if (key == NULL) { LOG_ERR("%s: key must be a string", conf_err_prefix(chain, it.key)); @@ -363,17 +374,11 @@ from_conf(const struct yml_node *node, struct particle *common) struct particle_map particle_map[yml_dict_length(conditions)]; - struct conf_inherit inherited = { - .font = common->font, - .font_shaping = common->font_shaping, - .foreground = common->foreground - }; + struct conf_inherit inherited + = {.font = common->font, .font_shaping = common->font_shaping, .foreground = common->foreground}; size_t idx = 0; - for (struct yml_dict_iter it = yml_dict_iter(conditions); - it.key != NULL; - yml_dict_next(&it), idx++) - { + for (struct yml_dict_iter it = yml_dict_iter(conditions); it.key != NULL; yml_dict_next(&it), idx++) { /* Note we can skip the error checking here */ char *key_clone = strdup(yml_value_as_string(it.key)); YY_BUFFER_STATE buffer = yy_scan_string(key_clone); @@ -384,8 +389,7 @@ from_conf(const struct yml_node *node, struct particle *common) particle_map[idx].particle = conf_to_particle(it.value, inherited); } - struct particle *default_particle = def != NULL - ? conf_to_particle(def, inherited) : NULL; + struct particle *default_particle = def != NULL ? conf_to_particle(def, inherited) : NULL; return map_new(common, particle_map, yml_dict_length(conditions), default_particle); } diff --git a/particles/map.h b/particles/map.h index a6d35b4..23670a5 100644 --- a/particles/map.h +++ b/particles/map.h @@ -28,7 +28,7 @@ struct map_condition { void free_map_condition(struct map_condition *c); -typedef struct yy_buffer_state* YY_BUFFER_STATE; +typedef struct yy_buffer_state *YY_BUFFER_STATE; YY_BUFFER_STATE yy_scan_string(const char *str); int yyparse(); void yy_delete_buffer(YY_BUFFER_STATE buffer); diff --git a/particles/progress-bar.c b/particles/progress-bar.c index f9e3999..f0bacbf 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -1,16 +1,17 @@ +#include #include #include -#include #define LOG_MODULE "progress_bar" #define LOG_ENABLE_DBG 0 -#include "../log.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../particle.h" #include "../plugin.h" -struct private { +struct private +{ char *tag; int width; @@ -74,8 +75,7 @@ begin_expose(struct exposable *exposable) /* Margins */ if (have_at_least_one) { - exposable->width += exposable->particle->left_margin + - exposable->particle->right_margin; + exposable->width += exposable->particle->left_margin + exposable->particle->right_margin; } else assert(exposable->width == 0); @@ -97,8 +97,7 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int } static void -on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, - enum mouse_button btn, int x, int y) +on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; @@ -161,18 +160,14 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, original[i] = exposable->on_click[i]; if (event == ON_MOUSE_CLICK) { - long where = clickable_width > 0 - ? 100 * (x - x_offset) / clickable_width - : 0; + long where = clickable_width > 0 ? 100 * (x - x_offset) / clickable_width : 0; struct tag_set tags = { .tags = (struct tag *[]){tag_new_int(NULL, "where", where)}, .count = 1, }; - tags_expand_templates( - exposable->on_click, (const char **)exposable->on_click, - MOUSE_BTN_COUNT, &tags); + tags_expand_templates(exposable->on_click, (const char **)exposable->on_click, MOUSE_BTN_COUNT, &tags); tag_set_destroy(&tags); } @@ -198,19 +193,17 @@ instantiate(const struct particle *particle, const struct tag_set *tags) long min = tag != NULL ? tag->min(tag) : 0; long max = tag != NULL ? tag->max(tag) : 0; - LOG_DBG("%s: value=%ld, min=%ld, max=%ld", - tag != NULL ? tag->name(tag) : "", value, min, max); + LOG_DBG("%s: value=%ld, min=%ld, max=%ld", tag != NULL ? tag->name(tag) : "", value, min, max); long fill_count = max == min ? 0 : p->width * value / (max - min); long empty_count = p->width - fill_count; struct eprivate *epriv = calloc(1, sizeof(*epriv)); - epriv->count = ( - 1 + /* Start marker */ - fill_count + /* Before current position */ - 1 + /* Current position indicator */ - empty_count + /* After current position */ - 1); /* End marker */ + epriv->count = (1 + /* Start marker */ + fill_count + /* Before current position */ + 1 + /* Current position indicator */ + empty_count + /* After current position */ + 1); /* End marker */ epriv->exposables = malloc(epriv->count * sizeof(epriv->exposables[0])); @@ -259,8 +252,7 @@ instantiate(const struct particle *particle, const struct tag_set *tags) LOG_DBG("tag: %s, value: %ld, " "units-per-segment: %f, units-filled: %f, units-til-next: %f", - tag->name(tag), value, - units_per_segment, units_filled, units_til_next_segment); + tag->name(tag), value, units_per_segment, units_filled, units_til_next_segment); #endif @@ -271,10 +263,8 @@ instantiate(const struct particle *particle, const struct tag_set *tags) } static struct particle * -progress_bar_new(struct particle *common, const char *tag, int width, - struct particle *start_marker, struct particle *end_marker, - struct particle *fill, struct particle *empty, - struct particle *indicator) +progress_bar_new(struct particle *common, const char *tag, int width, struct particle *start_marker, + struct particle *end_marker, struct particle *fill, struct particle *empty, struct particle *indicator) { struct private *priv = calloc(1, sizeof(*priv)); priv->tag = strdup(tag); @@ -308,15 +298,10 @@ from_conf(const struct yml_node *node, struct particle *common) .foreground = common->foreground, }; - return progress_bar_new( - common, - yml_value_as_string(tag), - yml_value_as_int(length), - conf_to_particle(start, inherited), - conf_to_particle(end, inherited), - conf_to_particle(fill, inherited), - conf_to_particle(empty, inherited), - conf_to_particle(indicator, inherited)); + return progress_bar_new(common, yml_value_as_string(tag), yml_value_as_int(length), + conf_to_particle(start, inherited), conf_to_particle(end, inherited), + conf_to_particle(fill, inherited), conf_to_particle(empty, inherited), + conf_to_particle(indicator, inherited)); } static bool diff --git a/particles/ramp.c b/particles/ramp.c index 0127519..befe1d9 100644 --- a/particles/ramp.c +++ b/particles/ramp.c @@ -1,18 +1,19 @@ +#include #include #include -#include #include #define LOG_MODULE "ramp" #define LOG_ENABLE_DBG 0 -#include "../log.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../particle.h" #include "../plugin.h" -struct private { +struct private +{ char *tag; bool use_custom_min; long min; @@ -57,21 +58,16 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int struct eprivate *e = exposable->private; exposable_render_deco(exposable, pix, x, y, height); - e->exposable->expose( - e->exposable, pix, x + exposable->particle->left_margin, y, height); + e->exposable->expose(e->exposable, pix, x + exposable->particle->left_margin, y, height); } static void -on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, - enum mouse_button btn, int x, int y) +on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if ((event == ON_MOUSE_MOTION && - exposable->particle->have_on_click_template) || - exposable->on_click[btn] != NULL) - { + if ((event == ON_MOUSE_MOTION && exposable->particle->have_on_click_template) || exposable->on_click[btn] != NULL) { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; @@ -118,22 +114,22 @@ instantiate(const struct particle *particle, const struct tag_set *tags) max = p->use_custom_max ? p->max : max; if (min > max) { - LOG_WARN( - "tag's minimum value is greater than its maximum: " - "tag=\"%s\", min=%ld, max=%ld", p->tag, min, max); + LOG_WARN("tag's minimum value is greater than its maximum: " + "tag=\"%s\", min=%ld, max=%ld", + p->tag, min, max); min = max; } if (value < min) { - LOG_WARN( - "tag's value is less than its minimum value: " - "tag=\"%s\", min=%ld, value=%ld", p->tag, min, value); + LOG_WARN("tag's value is less than its minimum value: " + "tag=\"%s\", min=%ld, value=%ld", + p->tag, min, value); value = min; } if (value > max) { - LOG_WARN( - "tag's value is greater than its maximum value: " - "tag=\"%s\", max=%ld, value=%ld", p->tag, max, value); + LOG_WARN("tag's value is greater than its maximum value: " + "tag=\"%s\", max=%ld, value=%ld", + p->tag, max, value); value = max; } @@ -168,10 +164,8 @@ instantiate(const struct particle *particle, const struct tag_set *tags) } static struct particle * -ramp_new(struct particle *common, const char *tag, - struct particle *particles[], size_t count, - bool use_custom_min, long min, - bool use_custom_max, long max) +ramp_new(struct particle *common, const char *tag, struct particle *particles[], size_t count, bool use_custom_min, + long min, bool use_custom_max, long max) { struct private *priv = calloc(1, sizeof(*priv)); @@ -204,19 +198,15 @@ from_conf(const struct yml_node *node, struct particle *common) struct particle *parts[count]; size_t idx = 0; - for (struct yml_list_iter it = yml_list_iter(items); - it.node != NULL; - yml_list_next(&it), idx++) - { - parts[idx] = conf_to_particle( - it.node, (struct conf_inherit){common->font, common->font_shaping, common->foreground}); + for (struct yml_list_iter it = yml_list_iter(items); it.node != NULL; yml_list_next(&it), idx++) { + parts[idx] + = conf_to_particle(it.node, (struct conf_inherit){common->font, common->font_shaping, common->foreground}); } long min_v = min != NULL ? yml_value_as_int(min) : 0; long max_v = max != NULL ? yml_value_as_int(max) : 0; - return ramp_new(common, yml_value_as_string(tag), parts, count, min != NULL, - min_v, max != NULL, max_v); + return ramp_new(common, yml_value_as_string(tag), parts, count, min != NULL, min_v, max != NULL, max_v); } static bool diff --git a/particles/string.c b/particles/string.c index 186d50e..4922d7d 100644 --- a/particles/string.c +++ b/particles/string.c @@ -1,13 +1,13 @@ +#include #include #include -#include #define LOG_MODULE "string" #define LOG_ENABLE_DBG 0 -#include "../log.h" #include "../char32.h" -#include "../config.h" #include "../config-verify.h" +#include "../config.h" +#include "../log.h" #include "../particle.h" #include "../plugin.h" @@ -18,7 +18,8 @@ struct text_run_cache { bool in_use; }; -struct private { +struct private +{ char *text; size_t max_len; @@ -51,9 +52,7 @@ begin_expose(struct exposable *exposable) struct eprivate *e = exposable->private; struct private *p = exposable->particle->private; - exposable->width = - exposable->particle->left_margin + - exposable->particle->right_margin; + exposable->width = exposable->particle->left_margin + exposable->particle->right_margin; if (e->cache_idx >= 0) { exposable->width += p->cache[e->cache_idx].width; @@ -97,9 +96,8 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int * any real facts, but works very well with e.g. the "Awesome 6" * font family. */ - const double baseline = (double)y + - (double)(height + font->ascent + font->descent) / 2.0 - - (font->descent > 0 ? font->descent : 0); + const double baseline + = (double)y + (double)(height + font->ascent + font->descent) / 2.0 - (font->descent > 0 ? font->descent : 0); x += exposable->particle->left_margin; @@ -112,17 +110,13 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int if (pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) { /* Glyph surface is a pre-rendered image (typically a color emoji...) */ - pixman_image_composite32( - PIXMAN_OP_OVER, glyph->pix, NULL, pix, 0, 0, 0, 0, - x + glyph->x, baseline - glyph->y, - glyph->width, glyph->height); + pixman_image_composite32(PIXMAN_OP_OVER, glyph->pix, NULL, pix, 0, 0, 0, 0, x + glyph->x, + baseline - glyph->y, glyph->width, glyph->height); } else { /* Glyph surface is an alpha mask */ pixman_image_t *src = pixman_image_create_solid_fill(&exposable->particle->foreground); - pixman_image_composite32( - PIXMAN_OP_OVER, src, glyph->pix, pix, 0, 0, 0, 0, - x + glyph->x, baseline - glyph->y, - glyph->width, glyph->height); + pixman_image_composite32(PIXMAN_OP_OVER, src, glyph->pix, pix, 0, 0, 0, 0, x + glyph->x, + baseline - glyph->y, glyph->width, glyph->height); pixman_image_unref(src); } @@ -188,11 +182,8 @@ instantiate(const struct particle *particle, const struct tag_set *tags) e->kern_x = calloc(chars, sizeof(e->kern_x[0])); - if (particle->font_shaping == FONT_SHAPE_FULL && - fcft_capabilities() & FCFT_CAPABILITY_TEXT_RUN_SHAPING) - { - struct fcft_text_run *run = fcft_rasterize_text_run_utf32( - font, chars, wtext, FCFT_SUBPIXEL_NONE); + if (particle->font_shaping == FONT_SHAPE_FULL && fcft_capabilities() & FCFT_CAPABILITY_TEXT_RUN_SHAPING) { + struct fcft_text_run *run = fcft_rasterize_text_run_utf32(font, chars, wtext, FCFT_SUBPIXEL_NONE); if (run != NULL) { int w = 0; @@ -210,8 +201,7 @@ instantiate(const struct particle *particle, const struct tag_set *tags) if (cache_idx < 0) { size_t new_size = p->cache_size + 1; - struct text_run_cache *new_cache = realloc( - p->cache, new_size * sizeof(new_cache[0])); + struct text_run_cache *new_cache = realloc(p->cache, new_size * sizeof(new_cache[0])); p->cache_size = new_size; p->cache = new_cache; @@ -235,8 +225,7 @@ instantiate(const struct particle *particle, const struct tag_set *tags) /* Convert text to glyph masks/images. */ for (size_t i = 0; i < chars; i++) { - const struct fcft_glyph *glyph = fcft_rasterize_char_utf32( - font, wtext[i], FCFT_SUBPIXEL_NONE); + const struct fcft_glyph *glyph = fcft_rasterize_char_utf32(font, wtext[i], FCFT_SUBPIXEL_NONE); if (glyph == NULL) continue; @@ -297,10 +286,7 @@ from_conf(const struct yml_node *node, struct particle *common) const struct yml_node *text = yml_get_value(node, "text"); const struct yml_node *max = yml_get_value(node, "max"); - return string_new( - common, - yml_value_as_string(text), - max != NULL ? yml_value_as_int(max) : 0); + return string_new(common, yml_value_as_string(text), max != NULL ? yml_value_as_int(max) : 0); } static bool diff --git a/plugin.c b/plugin.c index 20dfbbf..8e75389 100644 --- a/plugin.c +++ b/plugin.c @@ -1,99 +1,94 @@ #include "plugin.h" -#include #include +#include #include #define LOG_MODULE "plugin" #define LOG_ENABLE_DBG 0 -#include "log.h" #include "config.h" +#include "log.h" #if !defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) -#define EXTERN_MODULE(plug_name) \ - extern const struct module_iface module_##plug_name##_iface; \ - extern bool plug_name##_verify_conf( \ - keychain_t *chain, const struct yml_node *node); \ - extern struct module *plug_name##_from_conf( \ - const struct yml_node *node, struct conf_inherit inherited); +#define EXTERN_MODULE(plug_name) \ + extern const struct module_iface module_##plug_name##_iface; \ + extern bool plug_name##_verify_conf(keychain_t *chain, const struct yml_node *node); \ + extern struct module *plug_name##_from_conf(const struct yml_node *node, struct conf_inherit inherited); -#define EXTERN_PARTICLE(plug_name) \ - extern const struct particle_iface particle_##plug_name##_iface; \ - extern bool plug_name##_verify_conf( \ - keychain_t *chain, const struct yml_node *node); \ - extern struct particle *plug_name##_from_conf( \ - const struct yml_node *node, struct particle *common); +#define EXTERN_PARTICLE(plug_name) \ + extern const struct particle_iface particle_##plug_name##_iface; \ + extern bool plug_name##_verify_conf(keychain_t *chain, const struct yml_node *node); \ + extern struct particle *plug_name##_from_conf(const struct yml_node *node, struct particle *common); -#define EXTERN_DECORATION(plug_name) \ - extern const struct deco_iface deco_##plug_name##_iface; \ - extern bool plug_name##_verify_conf( \ - keychain_t *chain, const struct yml_node *node); \ +#define EXTERN_DECORATION(plug_name) \ + extern const struct deco_iface deco_##plug_name##_iface; \ + extern bool plug_name##_verify_conf(keychain_t *chain, const struct yml_node *node); \ extern struct deco *plug_name##_from_conf(const struct yml_node *node); #if defined(HAVE_PLUGIN_alsa) - EXTERN_MODULE(alsa); +EXTERN_MODULE(alsa); #endif #if defined(HAVE_PLUGIN_backlight) - EXTERN_MODULE(backlight); +EXTERN_MODULE(backlight); #endif #if defined(HAVE_PLUGIN_battery) - EXTERN_MODULE(battery); +EXTERN_MODULE(battery); #endif #if defined(HAVE_PLUGIN_clock) - EXTERN_MODULE(clock); +EXTERN_MODULE(clock); #endif #if defined(HAVE_PLUGIN_cpu) - EXTERN_MODULE(cpu); +EXTERN_MODULE(cpu); #endif #if defined(HAVE_PLUGIN_disk_io) - EXTERN_MODULE(disk_io); +EXTERN_MODULE(disk_io); #endif #if defined(HAVE_PLUGIN_dwl) - EXTERN_MODULE(dwl); +EXTERN_MODULE(dwl); #endif #if defined(HAVE_PLUGIN_foreign_toplevel) - EXTERN_MODULE(foreign_toplevel); +EXTERN_MODULE(foreign_toplevel); #endif #if defined(HAVE_PLUGIN_mem) - EXTERN_MODULE(mem); +EXTERN_MODULE(mem); #endif #if defined(HAVE_PLUGIN_mpd) - EXTERN_MODULE(mpd); +EXTERN_MODULE(mpd); #endif #if defined(HAVE_PLUGIN_i3) - EXTERN_MODULE(i3); +EXTERN_MODULE(i3); #endif #if defined(HAVE_PLUGIN_label) - EXTERN_MODULE(label); +EXTERN_MODULE(label); #endif #if defined(HAVE_PLUGIN_network) - EXTERN_MODULE(network); +EXTERN_MODULE(network); #endif #if defined(HAVE_PLUGIN_pipewire) - EXTERN_MODULE(pipewire); +EXTERN_MODULE(pipewire); #endif #if defined(HAVE_PLUGIN_pulse) - EXTERN_MODULE(pulse); +EXTERN_MODULE(pulse); #endif #if defined(HAVE_PLUGIN_removables) - EXTERN_MODULE(removables); +EXTERN_MODULE(removables); #endif #if defined(HAVE_PLUGIN_river) - EXTERN_MODULE(river); +EXTERN_MODULE(river); #endif #if defined(HAVE_PLUGIN_script) - EXTERN_MODULE(script); +EXTERN_MODULE(script); #endif #if defined(HAVE_PLUGIN_sway_xkb) - EXTERN_MODULE(sway_xkb); +EXTERN_MODULE(sway_xkb); #endif #if defined(HAVE_PLUGIN_xkb) - EXTERN_MODULE(xkb); +EXTERN_MODULE(xkb); #endif #if defined(HAVE_PLUGIN_xwindow) - EXTERN_MODULE(xwindow); +EXTERN_MODULE(xwindow); #endif EXTERN_PARTICLE(empty); @@ -121,42 +116,45 @@ static const char * type2str(enum plugin_type type) { switch (type) { - case PLUGIN_MODULE: return "module"; - case PLUGIN_PARTICLE: return "particle"; - case PLUGIN_DECORATION: return "decoration"; + case PLUGIN_MODULE: + return "module"; + case PLUGIN_PARTICLE: + return "particle"; + case PLUGIN_DECORATION: + return "decoration"; } assert(false && "invalid type"); return ""; } -static void __attribute__((constructor)) -init(void) +static void __attribute__((constructor)) init(void) { #if !defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) -#define REGISTER_CORE_PLUGIN(plug_name, func_prefix, plug_type) \ - do { \ - tll_push_back( \ - plugins, \ - ((struct plugin){ \ - .name = strdup(#plug_name), \ - .type = (plug_type), \ - .lib = RTLD_DEFAULT, \ - })); \ +#define REGISTER_CORE_PLUGIN(plug_name, func_prefix, plug_type) \ + do { \ + tll_push_back(plugins, ((struct plugin){ \ + .name = strdup(#plug_name), \ + .type = (plug_type), \ + .lib = RTLD_DEFAULT, \ + })); \ } while (0) -#define REGISTER_CORE_MODULE(plug_name, func_prefix) do { \ - REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_MODULE); \ - tll_back(plugins).module = &module_##func_prefix##_iface; \ +#define REGISTER_CORE_MODULE(plug_name, func_prefix) \ + do { \ + REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_MODULE); \ + tll_back(plugins).module = &module_##func_prefix##_iface; \ } while (0) -#define REGISTER_CORE_PARTICLE(plug_name, func_prefix) do { \ - REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_PARTICLE); \ - tll_back(plugins).particle = &particle_##func_prefix##_iface; \ +#define REGISTER_CORE_PARTICLE(plug_name, func_prefix) \ + do { \ + REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_PARTICLE); \ + tll_back(plugins).particle = &particle_##func_prefix##_iface; \ } while (0) -#define REGISTER_CORE_DECORATION(plug_name, func_prefix) do { \ - REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_DECORATION); \ - tll_back(plugins).decoration = &deco_##func_prefix##_iface; \ +#define REGISTER_CORE_DECORATION(plug_name, func_prefix) \ + do { \ + REGISTER_CORE_PLUGIN(plug_name, func_prefix, PLUGIN_DECORATION); \ + tll_back(plugins).decoration = &deco_##func_prefix##_iface; \ } while (0) #if defined(HAVE_PLUGIN_alsa) @@ -258,16 +256,13 @@ free_plugin(struct plugin plug) free(plug.name); } -static void __attribute__((destructor)) -fini(void) -{ - tll_free_and_free(plugins, free_plugin); -} +static void __attribute__((destructor)) fini(void) { tll_free_and_free(plugins, free_plugin); } const struct plugin * plugin_load(const char *name, enum plugin_type type) { - tll_foreach(plugins, plug) { + tll_foreach(plugins, plug) + { if (plug->item.type == type && strcmp(plug->item.name, name) == 0) { LOG_DBG("%s: %s already loaded: %p", type2str(type), name, plug->item.lib); assert(plug->item.dummy != NULL); @@ -275,7 +270,6 @@ plugin_load(const char *name, enum plugin_type type) } } - char path[128]; snprintf(path, sizeof(path), "%s_%s.so", type2str(type), name); diff --git a/plugin.h b/plugin.h index 1b2da24..4c49caa 100644 --- a/plugin.h +++ b/plugin.h @@ -1,7 +1,7 @@ #pragma once -#include "config.h" #include "config-verify.h" +#include "config.h" #include "module.h" #include "particle.h" @@ -9,14 +9,12 @@ typedef bool (*verify_func_t)(keychain_t *chain, const struct yml_node *node); struct module_iface { verify_func_t verify_conf; - struct module *(*from_conf)( - const struct yml_node *node, struct conf_inherit inherited); + struct module *(*from_conf)(const struct yml_node *node, struct conf_inherit inherited); }; struct particle_iface { verify_func_t verify_conf; - struct particle *(*from_conf)( - const struct yml_node *node, struct particle *common); + struct particle *(*from_conf)(const struct yml_node *node, struct particle *common); }; struct deco_iface { diff --git a/tag.c b/tag.c index 0f44d7e..e95b1c7 100644 --- a/tag.c +++ b/tag.c @@ -1,19 +1,20 @@ #include "tag.h" -#include -#include -#include -#include -#include -#include #include -#include +#include +#include +#include +#include +#include +#include +#include #define LOG_MODULE "tag" #define LOG_ENABLE_DBG 1 #include "log.h" #include "module.h" -struct private { +struct private +{ char *name; union { struct { @@ -156,8 +157,8 @@ int_refresh_in(const struct tag *tag, long units) if (tag->owner == NULL || tag->owner->refresh_in == NULL) return false; - assert(priv->value_as_int.realtime_unit == TAG_REALTIME_SECS || - priv->value_as_int.realtime_unit == TAG_REALTIME_MSECS); + assert(priv->value_as_int.realtime_unit == TAG_REALTIME_SECS + || priv->value_as_int.realtime_unit == TAG_REALTIME_MSECS); long milli_seconds = units; if (priv->value_as_int.realtime_unit == TAG_REALTIME_SECS) @@ -269,15 +270,14 @@ tag_new_int(struct module *owner, const char *name, long value) } struct tag * -tag_new_int_range(struct module *owner, const char *name, long value, - long min, long max) +tag_new_int_range(struct module *owner, const char *name, long value, long min, long max) { return tag_new_int_realtime(owner, name, value, min, max, TAG_REALTIME_NONE); } struct tag * -tag_new_int_realtime(struct module *owner, const char *name, long value, - long min, long max, enum tag_realtime_unit unit) +tag_new_int_realtime(struct module *owner, const char *name, long value, long min, long max, + enum tag_realtime_unit unit) { struct private *priv = malloc(sizeof(*priv)); priv->name = strdup(name); @@ -414,7 +414,7 @@ sbuf_append_at_most(struct sbuf *s1, const char *s2, size_t n) s1->size = 2 * required_size; s1->s = realloc(s1->s, s1->size); - //s1->s[s1->len] = '\0'; + // s1->s[s1->len] = '\0'; } memcpy(&s1->s[s1->len], s2, n); @@ -516,14 +516,16 @@ tags_expand_template(const char *template, const struct tag_set *tags) FMT_KIBYTE, FMT_MIBYTE, FMT_GIBYTE, - } format = FMT_DEFAULT; + } format + = FMT_DEFAULT; enum { VALUE_VALUE, VALUE_MIN, VALUE_MAX, VALUE_UNIT, - } kind = VALUE_VALUE; + } kind + = VALUE_VALUE; int digits = 0; int decimals = 2; @@ -567,22 +569,17 @@ tags_expand_template(const char *template, const struct tag_set *tags) if (digits_str[0] != '\0') { // guards against i.e. "{tag:.3}" if (!is_number(digits_str, &digits)) { - LOG_WARN( - "tag `%s`: invalid field width formatter. Ignoring...", - tag_name); + LOG_WARN("tag `%s`: invalid field width formatter. Ignoring...", tag_name); } } if (decimals_str[0] != '\0') { // guards against i.e. "{tag:3.}" if (!is_number(decimals_str, &decimals)) { - LOG_WARN( - "tag `%s`: invalid decimals formatter. Ignoring...", - tag_name); + LOG_WARN("tag `%s`: invalid decimals formatter. Ignoring...", tag_name); } } zero_pad = digits_str[0] == '0'; - } - else + } else LOG_WARN("invalid tag formatter: %s", tag_args[i]); } @@ -593,7 +590,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) case FMT_DEFAULT: { switch (tag->type(tag)) { case TAG_TYPE_FLOAT: { - const char* fmt = zero_pad ? "%0*.*f" : "%*.*f"; + const char *fmt = zero_pad ? "%0*.*f" : "%*.*f"; char str[24]; snprintf(str, sizeof(str), fmt, digits, decimals, tag->as_float(tag)); sbuf_append(&formatted, str); @@ -601,7 +598,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) } case TAG_TYPE_INT: { - const char* fmt = zero_pad ? "%0*ld" : "%*ld"; + const char *fmt = zero_pad ? "%0*ld" : "%*ld"; char str[24]; snprintf(str, sizeof(str), fmt, digits, tag->as_int(tag)); sbuf_append(&formatted, str); @@ -618,9 +615,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) case FMT_HEX: case FMT_OCT: { - const char* fmt = format == FMT_HEX ? - zero_pad ? "%0*lx" : "%*lx" : - zero_pad ? "%0*lo" : "%*lo"; + const char *fmt = format == FMT_HEX ? zero_pad ? "%0*lx" : "%*lx" : zero_pad ? "%0*lo" : "%*lo"; char str[24]; snprintf(str, sizeof(str), fmt, digits, tag->as_int(tag)); sbuf_append(&formatted, str); @@ -632,7 +627,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) const long max = tag->max(tag); const long cur = tag->as_int(tag); - const char* fmt = zero_pad ? "%0*lu" : "%*lu"; + const char *fmt = zero_pad ? "%0*lu" : "%*lu"; char str[4]; snprintf(str, sizeof(str), fmt, digits, (cur - min) * 100 / (max - min)); sbuf_append(&formatted, str); @@ -645,21 +640,20 @@ tags_expand_template(const char *template, const struct tag_set *tags) case FMT_KIBYTE: case FMT_MIBYTE: case FMT_GIBYTE: { - const long divider = - format == FMT_KBYTE ? 1000 : - format == FMT_MBYTE ? 1000 * 1000 : - format == FMT_GBYTE ? 1000 * 1000 * 1000 : - format == FMT_KIBYTE ? 1024 : - format == FMT_MIBYTE ? 1024 * 1024 : - format == FMT_GIBYTE ? 1024 * 1024 * 1024 : - 1; + const long divider = format == FMT_KBYTE ? 1000 + : format == FMT_MBYTE ? 1000 * 1000 + : format == FMT_GBYTE ? 1000 * 1000 * 1000 + : format == FMT_KIBYTE ? 1024 + : format == FMT_MIBYTE ? 1024 * 1024 + : format == FMT_GIBYTE ? 1024 * 1024 * 1024 + : 1; char str[24]; if (tag->type(tag) == TAG_TYPE_FLOAT) { - const char* fmt = zero_pad ? "%0*.*f" : "%*.*f"; + const char *fmt = zero_pad ? "%0*.*f" : "%*.*f"; snprintf(str, sizeof(str), fmt, digits, decimals, tag->as_float(tag) / (double)divider); } else { - const char* fmt = zero_pad ? "%0*lu" : "%*lu"; + const char *fmt = zero_pad ? "%0*lu" : "%*lu"; snprintf(str, sizeof(str), fmt, digits, tag->as_int(tag) / divider); } sbuf_append(&formatted, str); @@ -676,9 +670,15 @@ tags_expand_template(const char *template, const struct tag_set *tags) const char *fmt = NULL; switch (format) { - case FMT_DEFAULT: fmt = zero_pad ? "%0*ld" : "%*ld"; break; - case FMT_HEX: fmt = zero_pad ? "%0*lx" : "%*lx"; break; - case FMT_OCT: fmt = zero_pad ? "%0*lo" : "%*lo"; break; + case FMT_DEFAULT: + fmt = zero_pad ? "%0*ld" : "%*ld"; + break; + case FMT_HEX: + fmt = zero_pad ? "%0*lx" : "%*lx"; + break; + case FMT_OCT: + fmt = zero_pad ? "%0*lo" : "%*lo"; + break; case FMT_PERCENT: value = (value - min) * 100 / (max - min); fmt = zero_pad ? "%0*lu" : "%*lu"; @@ -690,14 +690,13 @@ tags_expand_template(const char *template, const struct tag_set *tags) case FMT_KIBYTE: case FMT_MIBYTE: case FMT_GIBYTE: { - const long divider = - format == FMT_KBYTE ? 1024 : - format == FMT_MBYTE ? 1024 * 1024 : - format == FMT_GBYTE ? 1024 * 1024 * 1024 : - format == FMT_KIBYTE ? 1000 : - format == FMT_MIBYTE ? 1000 * 1000 : - format == FMT_GIBYTE ? 1000 * 1000 * 1000 : - 1; + const long divider = format == FMT_KBYTE ? 1024 + : format == FMT_MBYTE ? 1024 * 1024 + : format == FMT_GBYTE ? 1024 * 1024 * 1024 + : format == FMT_KIBYTE ? 1000 + : format == FMT_MIBYTE ? 1000 * 1000 + : format == FMT_GIBYTE ? 1000 * 1000 * 1000 + : 1; value /= divider; fmt = zero_pad ? "%0*lu" : "%*lu"; break; @@ -716,9 +715,15 @@ tags_expand_template(const char *template, const struct tag_set *tags) const char *value = NULL; switch (tag->realtime(tag)) { - case TAG_REALTIME_NONE: value = ""; break; - case TAG_REALTIME_SECS: value = "s"; break; - case TAG_REALTIME_MSECS: value = "ms"; break; + case TAG_REALTIME_NONE: + value = ""; + break; + case TAG_REALTIME_SECS: + value = "s"; + break; + case TAG_REALTIME_MSECS: + value = "ms"; + break; } sbuf_append(&formatted, value); @@ -734,8 +739,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) } void -tags_expand_templates(char *expanded[], const char *template[], size_t nmemb, - const struct tag_set *tags) +tags_expand_templates(char *expanded[], const char *template[], size_t nmemb, const struct tag_set *tags) { for (size_t i = 0; i < nmemb; i++) expanded[i] = tags_expand_template(template[i], tags); diff --git a/tag.h b/tag.h index 1e9742a..6149b1e 100644 --- a/tag.h +++ b/tag.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include enum tag_type { TAG_TYPE_BOOL, @@ -43,21 +43,16 @@ struct tag_set { }; struct tag *tag_new_int(struct module *owner, const char *name, long value); -struct tag *tag_new_int_range( - struct module *owner, const char *name, long value, long min, long max); -struct tag *tag_new_int_realtime( - struct module *owner, const char *name, long value, long min, - long max, enum tag_realtime_unit unit); +struct tag *tag_new_int_range(struct module *owner, const char *name, long value, long min, long max); +struct tag *tag_new_int_realtime(struct module *owner, const char *name, long value, long min, long max, + enum tag_realtime_unit unit); struct tag *tag_new_bool(struct module *owner, const char *name, bool value); struct tag *tag_new_float(struct module *owner, const char *name, double value); -struct tag *tag_new_string( - struct module *owner, const char *name, const char *value); +struct tag *tag_new_string(struct module *owner, const char *name, const char *value); const struct tag *tag_for_name(const struct tag_set *set, const char *name); void tag_set_destroy(struct tag_set *set); /* Utility functions */ char *tags_expand_template(const char *template, const struct tag_set *tags); -void tags_expand_templates( - char *expanded[], const char *template[], size_t nmemb, - const struct tag_set *tags); +void tags_expand_templates(char *expanded[], const char *template[], size_t nmemb, const struct tag_set *tags); diff --git a/xcb.c b/xcb.c index a157c1a..d3d2e30 100644 --- a/xcb.c +++ b/xcb.c @@ -1,16 +1,16 @@ #include "xcb.h" +#include #include #include #include -#include -#include #include #include +#include #if defined(HAVE_XCB_ERRORS) - #include +#include #endif #define LOG_MODULE "xcb" @@ -36,8 +36,7 @@ xcb_atom_t _NET_WM_NAME; static xcb_errors_context_t *err_context; #endif -static void __attribute__((destructor)) -fini(void) +static void __attribute__((destructor)) fini(void) { #if defined(HAVE_XCB_ERRORS) xcb_errors_context_free(err_context); @@ -63,19 +62,17 @@ xcb_init(void) /* Vendor release number */ unsigned release = setup->release_number; - unsigned major = release / 10000000; release %= 10000000; - unsigned minor = release / 100000; release %= 100000; + unsigned major = release / 10000000; + release %= 10000000; + unsigned minor = release / 100000; + release %= 100000; unsigned patch = release / 1000; #endif - LOG_DBG("%.*s %u.%u.%u (protocol: %u.%u)", - xcb_setup_vendor_length(setup), xcb_setup_vendor(setup), - major, minor, patch, - setup->protocol_major_version, - setup->protocol_minor_version); + LOG_DBG("%.*s %u.%u.%u (protocol: %u.%u)", xcb_setup_vendor_length(setup), xcb_setup_vendor(setup), major, minor, + patch, setup->protocol_major_version, setup->protocol_minor_version); - const xcb_query_extension_reply_t *randr = - xcb_get_extension_data(conn, &xcb_randr_id); + const xcb_query_extension_reply_t *randr = xcb_get_extension_data(conn, &xcb_randr_id); if (randr == NULL || !randr->present) { LOG_ERR("RANDR extension not present"); @@ -83,8 +80,7 @@ xcb_init(void) return false; } - const xcb_query_extension_reply_t *render = - xcb_get_extension_data(conn, &xcb_render_id); + const xcb_query_extension_reply_t *render = xcb_get_extension_data(conn, &xcb_render_id); if (render == NULL || !render->present) { LOG_ERR("RENDER extension not present"); @@ -92,18 +88,15 @@ xcb_init(void) return false; } - xcb_randr_query_version_cookie_t randr_cookie = - xcb_randr_query_version(conn, XCB_RANDR_MAJOR_VERSION, - XCB_RANDR_MINOR_VERSION); - xcb_render_query_version_cookie_t render_cookie = - xcb_render_query_version(conn, XCB_RENDER_MAJOR_VERSION, - XCB_RENDER_MINOR_VERSION); + xcb_randr_query_version_cookie_t randr_cookie + = xcb_randr_query_version(conn, XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION); + xcb_render_query_version_cookie_t render_cookie + = xcb_render_query_version(conn, XCB_RENDER_MAJOR_VERSION, XCB_RENDER_MINOR_VERSION); xcb_flush(conn); xcb_generic_error_t *e; - xcb_randr_query_version_reply_t *randr_version = - xcb_randr_query_version_reply(conn, randr_cookie, &e); + xcb_randr_query_version_reply_t *randr_version = xcb_randr_query_version_reply(conn, randr_cookie, &e); if (e != NULL) { LOG_ERR("failed to query RANDR version: %s", xcb_error(e)); free(e); @@ -111,8 +104,7 @@ xcb_init(void) return false; } - xcb_render_query_version_reply_t *render_version = - xcb_render_query_version_reply(conn, render_cookie, &e); + xcb_render_query_version_reply_t *render_version = xcb_render_query_version_reply(conn, render_cookie, &e); if (e != NULL) { LOG_ERR("failed to query RENDER version: %s", xcb_error(e)); free(e); @@ -120,10 +112,8 @@ xcb_init(void) return false; } - LOG_DBG("RANDR: %u.%u", - randr_version->major_version, randr_version->minor_version); - LOG_DBG("RENDER: %u.%u", - render_version->major_version, render_version->minor_version); + LOG_DBG("RANDR: %u.%u", randr_version->major_version, randr_version->minor_version); + LOG_DBG("RENDER: %u.%u", render_version->major_version, render_version->minor_version); free(randr_version); free(render_version); @@ -131,7 +121,7 @@ xcb_init(void) /* Cache atoms */ UTF8_STRING = get_atom(conn, "UTF8_STRING"); _NET_WM_PID = get_atom(conn, "_NET_WM_PID"); - _NET_WM_WINDOW_TYPE = get_atom(conn, "_NET_WM_WINDOW_TYPE"); + _NET_WM_WINDOW_TYPE = get_atom(conn, "_NET_WM_WINDOW_TYPE"); _NET_WM_WINDOW_TYPE_DOCK = get_atom(conn, "_NET_WM_WINDOW_TYPE_DOCK"); _NET_WM_STATE = get_atom(conn, "_NET_WM_STATE"); _NET_WM_STATE_ABOVE = get_atom(conn, "_NET_WM_STATE_ABOVE"); @@ -153,10 +143,7 @@ xcb_atom_t get_atom(xcb_connection_t *conn, const char *name) { xcb_generic_error_t *e; - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply( - conn, - xcb_intern_atom(conn, 0, strlen(name), name), - &e); + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, xcb_intern_atom(conn, 0, strlen(name), name), &e); if (e != NULL) { LOG_ERR("%s: failed to get atom for %s", name, xcb_error(e)); @@ -182,8 +169,7 @@ char * get_atom_name(xcb_connection_t *conn, xcb_atom_t atom) { xcb_generic_error_t *e; - xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply( - conn, xcb_get_atom_name(conn, atom), &e); + xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(conn, xcb_get_atom_name(conn, atom), &e); if (e != NULL) { LOG_ERR("failed to get atom name: %s", xcb_error(e)); @@ -192,8 +178,7 @@ get_atom_name(xcb_connection_t *conn, xcb_atom_t atom) return NULL; } - char *name = strndup( - xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply)); + char *name = strndup(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply)); LOG_DBG("atom name: %s", name); @@ -207,22 +192,17 @@ xcb_error(const xcb_generic_error_t *error) static char msg[1024]; #if defined(HAVE_XCB_ERRORS) - const char *major = xcb_errors_get_name_for_major_code( - err_context, error->major_code); - const char *minor = xcb_errors_get_name_for_minor_code( - err_context, error->major_code, error->minor_code); + const char *major = xcb_errors_get_name_for_major_code(err_context, error->major_code); + const char *minor = xcb_errors_get_name_for_minor_code(err_context, error->major_code, error->minor_code); const char *extension; - const char *name = xcb_errors_get_name_for_error( - err_context, error->error_code, &extension); + const char *name = xcb_errors_get_name_for_error(err_context, error->error_code, &extension); - snprintf(msg, sizeof(msg), - "major=%s, minor=%s), code=%s, extension=%s, sequence=%u", - major, minor, name, extension, error->sequence); -#else - snprintf(msg, sizeof(msg), "op %hhu:%hu, code %hhu, sequence %hu", - error->major_code, error->minor_code, error->error_code, + snprintf(msg, sizeof(msg), "major=%s, minor=%s), code=%s, extension=%s, sequence=%u", major, minor, name, extension, error->sequence); +#else + snprintf(msg, sizeof(msg), "op %hhu:%hu, code %hhu, sequence %hu", error->major_code, error->minor_code, + error->error_code, error->sequence); #endif return msg; diff --git a/yml.c b/yml.c index a81bdad..ec08101 100644 --- a/yml.c +++ b/yml.c @@ -1,13 +1,13 @@ #include "yml.h" -#include -#include -#include -#include #include +#include +#include +#include +#include -#include #include +#include #define UNUSED __attribute__((unused)) @@ -78,7 +78,8 @@ clone_node(struct yml_node *parent, const struct yml_node *node) break; case DICT: - tll_foreach(node->dict.pairs, it) { + tll_foreach(node->dict.pairs, it) + { struct dict_pair p = { .key = clone_node(clone, it->item.key), .value = clone_node(clone, it->item.value), @@ -88,8 +89,7 @@ clone_node(struct yml_node *parent, const struct yml_node *node) break; case LIST: - tll_foreach(node->list.values, it) - tll_push_back(clone->list.values, clone_node(clone, it->item)); + tll_foreach(node->list.values, it) tll_push_back(clone->list.values, clone_node(clone, it->item)); break; case ROOT: @@ -119,7 +119,8 @@ dict_has_key(const struct yml_node *node, const struct yml_node *key) { assert(node->type == DICT); - tll_foreach(node->dict.pairs, pair) { + tll_foreach(node->dict.pairs, pair) + { if (node_equal(pair->item.key, key)) return true; } @@ -130,7 +131,7 @@ dict_has_key(const struct yml_node *node, const struct yml_node *key) static enum yml_error add_node(struct yml_node *parent, struct yml_node *new_node, yaml_mark_t loc) { - new_node->line = loc.line + 1; /* yaml uses 0-based line numbers */ + new_node->line = loc.line + 1; /* yaml uses 0-based line numbers */ new_node->column = loc.column; switch (parent->type) { @@ -168,8 +169,7 @@ add_node(struct yml_node *parent, struct yml_node *new_node, yaml_mark_t loc) } static void -add_anchor(struct yml_node *root, const char *anchor, - const struct yml_node *node) +add_anchor(struct yml_node *root, const char *anchor, const struct yml_node *node) { assert(root->type == ROOT); @@ -190,25 +190,23 @@ post_process(struct yml_node *node, char **error) break; case SCALAR: - //assert(strcmp(node->scalar.value, "<<") != 0); + // assert(strcmp(node->scalar.value, "<<") != 0); break; case LIST: - tll_foreach(node->list.values, it) - if (!post_process(it->item, error)) - return false; + tll_foreach(node->list.values, it) if (!post_process(it->item, error)) return false; break; case DICT: - tll_foreach(node->dict.pairs, it) { - if (!post_process(it->item.key, error) || - !post_process(it->item.value, error)) - { + tll_foreach(node->dict.pairs, it) + { + if (!post_process(it->item.key, error) || !post_process(it->item.value, error)) { return false; } } - tll_foreach(node->dict.pairs, it) { + tll_foreach(node->dict.pairs, it) + { if (it->item.key->type != SCALAR) continue; @@ -220,19 +218,19 @@ post_process(struct yml_node *node, char **error) * Merge value is a list (of dictionaries) * e.g. <<: [*foo, *bar] */ - tll_foreach(it->item.value->list.values, v_it) { + tll_foreach(it->item.value->list.values, v_it) + { if (v_it->item->type != DICT) { - int cnt = snprintf( - NULL, 0, "%zu:%zu: cannot merge non-dictionary anchor", - v_it->item->line, v_it->item->column); + int cnt = snprintf(NULL, 0, "%zu:%zu: cannot merge non-dictionary anchor", v_it->item->line, + v_it->item->column); *error = malloc(cnt + 1); - snprintf( - *error, cnt + 1, "%zu:%zu: cannot merge non-dictionary anchor", - v_it->item->line, v_it->item->column); + snprintf(*error, cnt + 1, "%zu:%zu: cannot merge non-dictionary anchor", v_it->item->line, + v_it->item->column); return false; } - tll_foreach(v_it->item->dict.pairs, vv_it) { + tll_foreach(v_it->item->dict.pairs, vv_it) + { struct dict_pair p = { .key = vv_it->item.key, .value = vv_it->item.value, @@ -261,17 +259,16 @@ post_process(struct yml_node *node, char **error) * e.g. <<: *foo */ if (it->item.value->type != DICT) { - int cnt = snprintf( - NULL, 0, "%zu:%zu: cannot merge non-dictionary anchor", - it->item.value->line, it->item.value->column); + int cnt = snprintf(NULL, 0, "%zu:%zu: cannot merge non-dictionary anchor", it->item.value->line, + it->item.value->column); *error = malloc(cnt + 1); - snprintf( - *error, cnt + 1, "%zu:%zu: cannot merge non-dictionary anchor", - it->item.value->line, it->item.value->column); + snprintf(*error, cnt + 1, "%zu:%zu: cannot merge non-dictionary anchor", it->item.value->line, + it->item.value->column); return false; } - tll_foreach(it->item.value->dict.pairs, v_it) { + tll_foreach(it->item.value->dict.pairs, v_it) + { struct dict_pair p = { .key = v_it->item.key, .value = v_it->item.value, @@ -307,10 +304,7 @@ post_process(struct yml_node *node, char **error) } static const char * -format_error(enum yml_error err, - const struct yml_node *parent, - const struct yml_node *node, - const char *anchor) +format_error(enum yml_error err, const struct yml_node *parent, const struct yml_node *node, const char *anchor) { static char err_str[512]; @@ -321,11 +315,9 @@ format_error(enum yml_error err, case YML_ERR_DUPLICATE_KEY: { /* Find parent's key (i.e its name) */ - if (parent->parent != NULL && - parent->parent->type == DICT && - node->type == SCALAR) - { - tll_foreach(parent->parent->dict.pairs, pair) { + if (parent->parent != NULL && parent->parent->type == DICT && node->type == SCALAR) { + tll_foreach(parent->parent->dict.pairs, pair) + { if (pair->item.value != parent) continue; @@ -335,17 +327,14 @@ format_error(enum yml_error err, assert(pair->item.key->type == SCALAR); assert(node->type == SCALAR); - snprintf(err_str, sizeof(err_str), - "%s: duplicate key: '%s'", - pair->item.key->scalar.value, + snprintf(err_str, sizeof(err_str), "%s: duplicate key: '%s'", pair->item.key->scalar.value, node->scalar.value); return err_str; } } if (node->type == SCALAR) { - snprintf(err_str, sizeof(err_str), - "duplicate key: %s", node->scalar.value); + snprintf(err_str, sizeof(err_str), "duplicate key: %s", node->scalar.value); } else snprintf(err_str, sizeof(err_str), "duplicate key"); break; @@ -353,22 +342,20 @@ format_error(enum yml_error err, case YML_ERR_INVALID_ANCHOR: if (parent->parent != NULL && parent->parent->type == DICT) { - tll_foreach(parent->parent->dict.pairs, pair) { + tll_foreach(parent->parent->dict.pairs, pair) + { if (pair->item.value != parent) continue; if (pair->item.key->type != SCALAR) break; - snprintf(err_str, sizeof(err_str), - "%s: invalid anchor: %s", - pair->item.key->scalar.value, + snprintf(err_str, sizeof(err_str), "%s: invalid anchor: %s", pair->item.key->scalar.value, anchor != NULL ? anchor : ""); return err_str; } } - snprintf(err_str, sizeof(err_str), "invalid anchor: %s", - anchor != NULL ? anchor : ""); + snprintf(err_str, sizeof(err_str), "invalid anchor: %s", anchor != NULL ? anchor : ""); break; case YML_ERR_UNKNOWN: @@ -403,19 +390,12 @@ yml_load(FILE *yml, char **error) yaml_event_t event; if (!yaml_parser_parse(&yaml, &event)) { if (error != NULL) { - int cnt = snprintf( - NULL, 0, "%zu:%zu: %s %s", - yaml.problem_mark.line + 1, - yaml.problem_mark.column, - yaml.problem, - yaml.context != NULL ? yaml.context : ""); + int cnt = snprintf(NULL, 0, "%zu:%zu: %s %s", yaml.problem_mark.line + 1, yaml.problem_mark.column, + yaml.problem, yaml.context != NULL ? yaml.context : ""); *error = malloc(cnt + 1); - snprintf(*error, cnt + 1, "%zu:%zu: %s %s", - yaml.problem_mark.line + 1, - yaml.problem_mark.column, - yaml.problem, - yaml.context != NULL ? yaml.context : ""); + snprintf(*error, cnt + 1, "%zu:%zu: %s %s", yaml.problem_mark.line + 1, yaml.problem_mark.column, + yaml.problem, yaml.context != NULL ? yaml.context : ""); } goto err_no_error_formatting; @@ -466,9 +446,7 @@ yml_load(FILE *yml, char **error) } if (!got_match) { - error_str = format_error( - YML_ERR_INVALID_ANCHOR, n, NULL, - (const char *)event.data.alias.anchor); + error_str = format_error(YML_ERR_INVALID_ANCHOR, n, NULL, (const char *)event.data.alias.anchor); yaml_event_delete(&event); goto err; } @@ -478,8 +456,7 @@ yml_load(FILE *yml, char **error) case YAML_SCALAR_EVENT: { struct yml_node *new_scalar = calloc(1, sizeof(*new_scalar)); new_scalar->type = SCALAR; - new_scalar->scalar.value = strndup( - (const char*)event.data.scalar.value, event.data.scalar.length); + new_scalar->scalar.value = strndup((const char *)event.data.scalar.value, event.data.scalar.length); enum yml_error err = add_node(n, new_scalar, event.start_mark); if (err != YML_ERR_NONE) { @@ -569,23 +546,13 @@ yml_load(FILE *yml, char **error) err: if (error_str != NULL) { - int cnt = snprintf( - NULL, 0, "%zu:%zu: %s", - yaml.mark.line + 1, - yaml.mark.column, - error_str); + int cnt = snprintf(NULL, 0, "%zu:%zu: %s", yaml.mark.line + 1, yaml.mark.column, error_str); *error = malloc(cnt + 1); - snprintf( - *error, cnt + 1, "%zu:%zu: %s", - yaml.mark.line + 1, - yaml.mark.column, - error_str); + snprintf(*error, cnt + 1, "%zu:%zu: %s", yaml.mark.line + 1, yaml.mark.column, error_str); } else { - int cnt = snprintf(NULL, 0, "%zu:%zu: unknown error", - yaml.mark.line + 1, yaml.mark.column); + int cnt = snprintf(NULL, 0, "%zu:%zu: unknown error", yaml.mark.line + 1, yaml.mark.column); *error = malloc(cnt + 1); - snprintf(*error, cnt + 1, "%zu:%zu: unknown error", - yaml.mark.line + 1, yaml.mark.column); + snprintf(*error, cnt + 1, "%zu:%zu: unknown error", yaml.mark.line + 1, yaml.mark.column); } err_no_error_formatting: @@ -617,7 +584,8 @@ yml_destroy(struct yml_node *node) break; case DICT: - tll_foreach(node->dict.pairs, it) { + tll_foreach(node->dict.pairs, it) + { yml_destroy(it->item.key); yml_destroy(it->item.value); } @@ -659,13 +627,12 @@ yml_get_(struct yml_node const *node, char const *_path, bool value) char *path = strdup(_path); - for (const char *part = strtok(path, "."), *next_part = strtok(NULL, "."); - part != NULL; - part = next_part, next_part = strtok(NULL, ".")) - { + for (const char *part = strtok(path, "."), *next_part = strtok(NULL, "."); part != NULL; + part = next_part, next_part = strtok(NULL, ".")) { assert(yml_is_dict(node)); - tll_foreach(node->dict.pairs, it) { + tll_foreach(node->dict.pairs, it) + { assert(yml_is_scalar(it->item.key)); if (strcmp(it->item.key->scalar.value, part) == 0) { if (next_part == NULL) { @@ -694,7 +661,8 @@ yml_get_value(const struct yml_node *node, const char *_path) } struct yml_node const * -yml_get_key(struct yml_node const *node, char const *_path) { +yml_get_key(struct yml_node const *node, char const *_path) +{ return yml_get_(node, _path, false); } @@ -702,7 +670,8 @@ struct yml_list_iter yml_list_iter(const struct yml_node *list) { assert(yml_is_list(list)); - tll_foreach(list->list.values, it) { + tll_foreach(list->list.values, it) + { return (struct yml_list_iter){ .node = it->item, .private = it, @@ -735,9 +704,7 @@ yml_list_length(const struct yml_node *list) assert(yml_is_list(list)); size_t length = 0; - for (struct yml_list_iter it = yml_list_iter(list); - it.node != NULL; - yml_list_next(&it), length++) + for (struct yml_list_iter it = yml_list_iter(list); it.node != NULL; yml_list_next(&it), length++) ; return length; @@ -748,7 +715,8 @@ yml_dict_iter(const struct yml_node *dict) { assert(yml_is_dict(dict)); - tll_foreach(dict->dict.pairs, it) { + tll_foreach(dict->dict.pairs, it) + { return (struct yml_dict_iter){ .key = it->item.key, .value = it->item.value, @@ -756,7 +724,7 @@ yml_dict_iter(const struct yml_node *dict) }; } - return (struct yml_dict_iter) { + return (struct yml_dict_iter){ .key = NULL, .value = NULL, .private1 = NULL, @@ -827,18 +795,12 @@ _as_bool(const struct yml_node *value, bool *ret) return false; const char *v = yml_value_as_string(value); - if (strcasecmp(v, "y") == 0 || - strcasecmp(v, "yes") == 0 || - strcasecmp(v, "true") == 0 || - strcasecmp(v, "on") == 0) - { + if (strcasecmp(v, "y") == 0 || strcasecmp(v, "yes") == 0 || strcasecmp(v, "true") == 0 + || strcasecmp(v, "on") == 0) { *ret = true; return true; - } else if (strcasecmp(v, "n") == 0 || - strcasecmp(v, "no") == 0 || - strcasecmp(v, "false") == 0 || - strcasecmp(v, "off") == 0) - { + } else if (strcasecmp(v, "n") == 0 || strcasecmp(v, "no") == 0 || strcasecmp(v, "false") == 0 + || strcasecmp(v, "off") == 0) { *ret = false; return true; } @@ -885,7 +847,8 @@ _print_node(const struct yml_node *n, int indent) break; case DICT: - tll_foreach(n->dict.pairs, it) { + tll_foreach(n->dict.pairs, it) + { _print_node(it->item.key, indent); printf(": "); @@ -900,7 +863,8 @@ _print_node(const struct yml_node *n, int indent) break; case LIST: - tll_foreach(n->list.values, it) { + tll_foreach(n->list.values, it) + { printf("%*s- ", indent, ""); if (it->item->type != SCALAR) { printf("\n"); diff --git a/yml.h b/yml.h index 0e5eca4..784252c 100644 --- a/yml.h +++ b/yml.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include struct yml_node; @@ -11,10 +11,8 @@ bool yml_is_scalar(const struct yml_node *node); bool yml_is_dict(const struct yml_node *node); bool yml_is_list(const struct yml_node *node); -const struct yml_node *yml_get_value( - const struct yml_node *node, const char *path); -const struct yml_node *yml_get_key( - struct yml_node const *node, char const *path); +const struct yml_node *yml_get_value(const struct yml_node *node, const char *path); +const struct yml_node *yml_get_key(struct yml_node const *node, char const *path); struct yml_list_iter { const struct yml_node *node; From 3c572c70c98f01cbfb892a1bb18da3f17d2db81c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 9 Apr 2024 16:34:53 +0200 Subject: [PATCH 043/112] wayland: silence compiler warning ... by ensuring 'layer' is always initialized, to _something_. --- bar/wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar/wayland.c b/bar/wayland.c index 50dc62d..3d8e4e0 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -765,7 +765,7 @@ create_surface(struct wayland_backend *backend) wl_surface_add_listener(backend->surface, &surface_listener, backend); - enum zwlr_layer_shell_v1_layer layer; + enum zwlr_layer_shell_v1_layer layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; switch (bar->layer) { case BAR_LAYER_BACKGROUND: From 13f46a314a433e899671212545c5468a37f3150f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 11 Apr 2024 15:47:38 +0200 Subject: [PATCH 044/112] examples: conf: laptop: repair network modules Closes #374 --- examples/configurations/laptop.conf | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/configurations/laptop.conf b/examples/configurations/laptop.conf index cee2639..e57ebb3 100644 --- a/examples/configurations/laptop.conf +++ b/examples/configurations/laptop.conf @@ -174,13 +174,14 @@ bar: default: {empty: {}} conditions: name == enp1s0: - conditions: - ~carrier: {empty: {}} - carrier: - map: - default: {string: {text: , font: *awesome, foreground: ffffff66}} - conditions: - state == up && ipv4 != "": {string: {text: , font: *awesome}} + map: + conditions: + ~carrier: {empty: {}} + carrier: + map: + default: {string: {text: , font: *awesome, foreground: ffffff66}} + conditions: + state == up && ipv4 != "": {string: {text: , font: *awesome}} - network: poll-interval: 1000 content: @@ -198,10 +199,10 @@ bar: - string: {text: , font: *awesome} - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s"} - conditions: - ipv4 == "": - - string: {text: , font: *awesome, foreground: ffffff66} - - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s", foreground: ffffff66} + conditions: + ipv4 == "": + - string: {text: , font: *awesome, foreground: ffffff66} + - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s", foreground: ffffff66} - alsa: card: hw:PCH mixer: Master From be01eeb1de4e143e6ee370891219fae368cbc484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 17 Apr 2024 09:52:46 +0200 Subject: [PATCH 045/112] ci: set 'event' filters on all 'when'-statements --- .woodpecker.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.woodpecker.yaml b/.woodpecker.yaml index ca65b29..0f3a16b 100644 --- a/.woodpecker.yaml +++ b/.woodpecker.yaml @@ -1,9 +1,9 @@ steps: - name: codespell when: - branch: - - master - - releases/* + - event: [manual, pull_request] + - event: [push, tag] + branch: [master, releases/*] image: alpine:latest commands: - apk add python3 @@ -16,9 +16,9 @@ steps: - name: subprojects when: - branch: - - master - - releases/* + - event: [manual, pull_request] + - event: [push, tag] + branch: [master, releases/*] image: alpine:latest commands: - apk add git @@ -29,9 +29,9 @@ steps: - name: x64 when: - branch: - - master - - releases/* + - event: [manual, pull_request] + - event: [push, tag] + branch: [master, releases/*] depends_on: [subprojects] image: alpine:latest commands: @@ -88,9 +88,9 @@ steps: - name: x86 when: - branch: - - master - - releases/* + - event: [manual, pull_request] + - event: [push, tag] + branch: [master, releases/*] depends_on: [subprojects] image: i386/alpine:latest commands: From 3136310aded817a4e7e23c0441eb64882dd99d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 17 Apr 2024 09:53:00 +0200 Subject: [PATCH 046/112] ci: install openssl explicitly, to fix missing SSL module in Python --- .woodpecker.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.woodpecker.yaml b/.woodpecker.yaml index 0f3a16b..8aee7ee 100644 --- a/.woodpecker.yaml +++ b/.woodpecker.yaml @@ -6,6 +6,7 @@ steps: branch: [master, releases/*] image: alpine:latest commands: + - apk add openssl - apk add python3 - apk add py3-pip - python3 -m venv codespell-venv From cae07a36ff79bc2b22bf757105a30bba9f975686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 17 Apr 2024 10:30:29 +0200 Subject: [PATCH 047/112] changelog: prepare for 1.11.0 --- CHANGELOG.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09f8c93..0e07a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -* [Unreleased](#unreleased) +* [1.11.0](#1-11-0) * [1.10.0](#1-10-0) * [1.9.0](#1-9-0) * [1.8.0](#1-8-0) @@ -11,7 +11,8 @@ * [1.5.0](#1-5-0) -## Unreleased +## 1.11.0 + ### Added * battery: current smoothing, for improved discharge estimates. @@ -35,8 +36,6 @@ [355]: https://codeberg.org/dnkl/yambar/pulls/355 -### Deprecated -### Removed ### Fixed * Compiler error _‘fmt’ may be used uninitialized_ ([#311][311]). @@ -63,9 +62,20 @@ [369]: https://codeberg.org/dnkl/yambar/issues/369 -### Security ### Contributors +* Delgan +* Haden Collins +* Jordan Isaacs +* kotyk +* Leonardo Hernández Hernández +* oob +* rdbo +* Sertonix +* steovd +* Väinö Mäkelä +* Yiyu Zhou + ## 1.10.0 From a2d30b96fbb026621ec11692272f0117f35a00fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 17 Apr 2024 10:30:54 +0200 Subject: [PATCH 048/112] meson/pkgbuild: bump version to 1.11.0 --- PKGBUILD | 2 +- PKGBUILD.wayland-only | 2 +- meson.build | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PKGBUILD b/PKGBUILD index 5aaea5d..6fc2d69 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,5 +1,5 @@ pkgname=yambar -pkgver=1.10.0 +pkgver=1.11.0 pkgrel=1 pkgdesc="Simplistic and highly configurable status panel for X and Wayland" changelog=CHANGELOG.md diff --git a/PKGBUILD.wayland-only b/PKGBUILD.wayland-only index 4d11120..266fc06 100644 --- a/PKGBUILD.wayland-only +++ b/PKGBUILD.wayland-only @@ -1,5 +1,5 @@ pkgname=yambar-wayland -pkgver=1.10.0 +pkgver=1.11.0 pkgrel=1 pkgdesc="Simplistic and highly configurable status panel for Wayland" arch=('x86_64' 'aarch64') diff --git a/meson.build b/meson.build index f0369cd..d760e94 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('yambar', 'c', - version: '1.10.0', + version: '1.11.0', license: 'MIT', meson_version: '>=0.59.0', default_options: ['c_std=c18', From 6f3952819f23698fd4b7fe11bb3c62a5d84b49d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 17 Apr 2024 10:42:56 +0200 Subject: [PATCH 049/112] changelog: add new 'unreleased' section --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e07a35..5221a37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +* [Unreleased](#unreleased) * [1.11.0](#1-11-0) * [1.10.0](#1-10-0) * [1.9.0](#1-9-0) @@ -11,6 +12,16 @@ * [1.5.0](#1-5-0) +## Unreleased +### Added +### Changed +### Deprecated +### Removed +### Fixed +### Security +### Contributors + + ## 1.11.0 ### Added From 547cef5afbfbcbf9fe78705c7b5661059b706346 Mon Sep 17 00:00:00 2001 From: Sertonix Date: Mon, 22 Apr 2024 15:47:10 +0200 Subject: [PATCH 050/112] network: fix missing break in switch statement This can cause the first character of the string to be read as an iface state. Fixes https://codeberg.org/dnkl/yambar/issues/377 --- CHANGELOG.md | 6 ++++++ modules/network.c | 1 + 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5221a37..3152882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,12 @@ ### Deprecated ### Removed ### Fixed + +* network: fix missing break in switch statement([#377][377]) + +[377]: https://codeberg.org/dnkl/yambar/issues/377 + + ### Security ### Contributors diff --git a/modules/network.c b/modules/network.c index 4bb0fb2..adb8f68 100644 --- a/modules/network.c +++ b/modules/network.c @@ -595,6 +595,7 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size iface->name = strdup((const char *)RTA_DATA(attr)); LOG_DBG("%s: index=%d", iface->name, iface->index); mtx_unlock(&mod->lock); + break; case IFLA_OPERSTATE: { uint8_t operstate = *(const uint8_t *)RTA_DATA(attr); if (iface->state == operstate) From 3a7455913f85f4f8887a4fb3aecc4f8306a2010a Mon Sep 17 00:00:00 2001 From: Birger Schacht Date: Sat, 20 Apr 2024 10:13:05 +0000 Subject: [PATCH 051/112] fix: typo Probaly -> Probably --- modules/network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/network.c b/modules/network.c index adb8f68..9ed9964 100644 --- a/modules/network.c +++ b/modules/network.c @@ -670,7 +670,7 @@ handle_address(struct module *mod, uint16_t type, const struct ifaddrmsg *msg, s } if (iface == NULL) { - LOG_ERR("failed to find network interface with index %d. Probaly a yambar bug", msg->ifa_index); + LOG_ERR("failed to find network interface with index %d. Probably a yambar bug", msg->ifa_index); return; } From 00234696fe5b09a1088254d2ee62955b3273e5a2 Mon Sep 17 00:00:00 2001 From: betazoid Date: Thu, 25 Apr 2024 21:02:03 +0000 Subject: [PATCH 052/112] Add examples/river-minimal.yml --- examples/river-minimal.yml | 69 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 examples/river-minimal.yml diff --git a/examples/river-minimal.yml b/examples/river-minimal.yml new file mode 100644 index 0000000..2ca225f --- /dev/null +++ b/examples/river-minimal.yml @@ -0,0 +1,69 @@ +bg_default: &bg_default {stack: [{background: {color: 81A1C1ff}}, {underline: {size: 4, color: D8DEE9ff}}]} +bar: + height: 32 + location: top + background: 000000ff + font: NotoSans:pixelsize=16 + + right: + - clock: + content: + - string: {text: , font: "Font Awesome 6 Free:style=solid:size=12"} + - string: {text: "{date}", right-margin: 5} + - string: {text: , font: "Font Awesome 6 Free:style=solid:size=12"} + - string: {text: "{time} "} + left: + - river: + anchors: + - base: &river_base + left-margin: 10 + right-margin: 13 + default: {string: {text: }} + conditions: + id == 1: {string: {text: 1}} + id == 2: {string: {text: 2}} + id == 3: {string: {text: 3}} + id == 4: {string: {text: 4}} + id == 5: {string: {text: 5}} + + content: + map: + on-click: + left: sh -c "riverctl set-focused-tags $((1 << ({id} - 1)))" + right: sh -c "riverctl toggle-focused-tags $((1 << ({id} -1)))" + middle: sh -c "riverctl toggle-view-tags $((1 << ({id} -1)))" + conditions: + state == urgent: + map: + <<: *river_base + deco: {background: {color: D08770ff}} + state == focused: + map: + <<: *river_base + deco: *bg_default + state == visible && ~occupied: + map: + <<: *river_base + state == visible && occupied: + map: + <<: *river_base + deco: *bg_default + state == unfocused: + map: + <<: *river_base + state == invisible && ~occupied: {empty: {}} + state == invisible && occupied: + map: + <<: *river_base + deco: {underline: {size: 3, color: ea6962ff}} + + + center: + - foreign-toplevel: + content: + map: + conditions: + ~activated: {empty: {}} + activated: + - string: {text: " {app-id}", foreground: ffa0a0ff} + - string: {text: ": {title}"} From b3313cefc67dfe6da61667b6b2ed9d8ebb0a829c Mon Sep 17 00:00:00 2001 From: Delgan Date: Thu, 2 May 2024 16:28:51 +0000 Subject: [PATCH 053/112] Fix remaining typos in the codebase (and update CI checks) --- .woodpecker.yaml | 2 +- bar/bar.c | 2 +- examples/scripts/dwl-tags.sh | 2 +- examples/scripts/pacman.sh | 2 +- modules/disk-io.c | 2 +- modules/dwl.c | 2 +- modules/pipewire.c | 12 ++++++------ 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.woodpecker.yaml b/.woodpecker.yaml index 8aee7ee..e7c9151 100644 --- a/.woodpecker.yaml +++ b/.woodpecker.yaml @@ -12,7 +12,7 @@ steps: - python3 -m venv codespell-venv - source codespell-venv/bin/activate - pip install codespell - - codespell README.md CHANGELOG.md *.c *.h doc/*.scd + - codespell README.md CHANGELOG.md *.c *.h doc/*.scd bar decorations modules particles examples - deactivate - name: subprojects diff --git a/bar/bar.c b/bar/bar.c index 3890bc0..109f210 100644 --- a/bar/bar.c +++ b/bar/bar.c @@ -28,7 +28,7 @@ #define max(x, y) ((x) > (y) ? (x) : (y)) /* - * Calculate total width of left/center/rigth groups. + * Calculate total width of left/center/right groups. * Note: begin_expose() must have been called */ static void diff --git a/examples/scripts/dwl-tags.sh b/examples/scripts/dwl-tags.sh index b1dbe4c..4999548 100755 --- a/examples/scripts/dwl-tags.sh +++ b/examples/scripts/dwl-tags.sh @@ -19,7 +19,7 @@ # # Now the fun part # -# Exemple configuration: +# Example configuration: # # - script: # path: /absolute/path/to/dwl-tags.sh diff --git a/examples/scripts/pacman.sh b/examples/scripts/pacman.sh index 83e2a3f..5026b5a 100755 --- a/examples/scripts/pacman.sh +++ b/examples/scripts/pacman.sh @@ -12,7 +12,7 @@ # {aur} int number of aur packages # {pkg} int sum of both # -# Exemples configuration: +# Examples configuration: # - script: # path: /absolute/path/to/pacman.sh # args: [] diff --git a/modules/disk-io.c b/modules/disk-io.c index 90abdba..015715f 100644 --- a/modules/disk-io.c +++ b/modules/disk-io.c @@ -129,7 +129,7 @@ refresh_device_stats(struct private *m) while ((read = getline(&line, &len, fp)) != -1) { /* - * For an explanation of the fields bellow, see + * For an explanation of the fields below, see * https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats */ uint8_t major_number = 0; diff --git a/modules/dwl.c b/modules/dwl.c index 4d9e8fa..a0d5797 100644 --- a/modules/dwl.c +++ b/modules/dwl.c @@ -231,7 +231,7 @@ process_line(char *line, struct module *module) /* No need to check error IMHO */ *target = strtoul(string, NULL, 10); - /* Populate informations */ + /* Populate information */ if (index == 6) { for (size_t id = 1; id <= private->number_of_tags; ++id) { uint32_t mask = 1 << (id - 1); diff --git a/modules/pipewire.c b/modules/pipewire.c index 1a6ab1f..e614a0a 100644 --- a/modules/pipewire.c +++ b/modules/pipewire.c @@ -33,7 +33,7 @@ struct output_informations { uint32_t device_id; uint32_t card_profile_device_id; - /* informations */ + /* information */ bool muted; uint16_t linear_volume; /* classic volume */ uint16_t cubic_volume; /* volume a la pulseaudio */ @@ -333,7 +333,7 @@ device_events_param(void *userdata, int seq, uint32_t id, uint32_t index, uint32 X_FREE_SET(route->icon_name, X_STRDUP(data.icon_name)); route->direction = data.direction; - /* set missing informations if possible */ + /* set missing information if possible */ struct private *private = device->data->module->private; struct node *binded_node = NULL; struct output_informations *output_informations = NULL; @@ -358,7 +358,7 @@ device_events_param(void *userdata, int seq, uint32_t id, uint32_t index, uint32 if (output_informations->card_profile_device_id != route->profile_device_id) return; - /* Update missing informations */ + /* Update missing information */ X_FREE_SET(output_informations->form_factor, X_STRDUP(route->form_factor)); X_FREE_SET(output_informations->icon, X_STRDUP(route->icon_name)); @@ -384,7 +384,7 @@ node_events_info(void *userdata, struct pw_node_info const *info) for (size_t i = 0; i < info->n_params; ++i) { if (info->params[i].id == SPA_PARAM_Props) { void *target_node = (node_data->is_sink ? data->node_sink : data->node_source); - /* Found it, will emit a param event, the parem will then be handled + /* Found it, will emit a param event, the param will then be handled * in node_events_param */ pw_node_enum_params(target_node, 0, info->params[i].id, 0, -1, NULL); break; @@ -419,7 +419,7 @@ node_events_info(void *userdata, struct pw_node_info const *info) output_informations->card_profile_device_id = value; } - /* Device's informations has an more important priority than node's informations */ + /* Device's information has an more important priority than node's information */ /* icon_name */ struct route *route = node_find_route(data, node_data->is_sink); if (route != NULL && route->icon_name != NULL) @@ -659,7 +659,7 @@ static void try_to_bind_node(struct node_data *node_data, char const *target_name, struct node **target_node, void **target_proxy, struct spa_hook *target_listener) { - /* profile deactived */ + /* profile deactivated */ if (target_name == NULL) return; From a467f5667769a323dea2f64391969f8d979087df Mon Sep 17 00:00:00 2001 From: QuincePie Date: Sat, 18 May 2024 18:17:10 -0500 Subject: [PATCH 054/112] i3: Handle FALLBACK output for workspaces. sway moves the workspace to fallback_output when there is no output. For example: when all the screens are off. This commit adds an ignore for the fallback output. --- modules/i3.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/modules/i3.c b/modules/i3.c index 73bd9d6..5cb6e01 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -514,7 +514,6 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void else if (is_move) { struct workspace *w = workspace_lookup(m, current_id); - assert(w != NULL); struct json_object *_current_output; if (!json_object_object_get_ex(current, "output", &_current_output)) { @@ -522,16 +521,22 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void mtx_unlock(&mod->lock); return false; } + const char *current_output_string = json_object_get_string(_current_output); - free(w->output); - w->output = strdup(json_object_get_string(_current_output)); + /* Ignore fallback_output ("For when there's no connected outputs") */ + if (strcmp(current_output_string, "FALLBACK") != 0) { - /* - * If the moved workspace was focused, schedule a full update because - * visibility for other workspaces may have changed. - */ - if (w->focused) { - i3_send_pkg(sock, I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL); + assert(w != NULL); + free(w->output); + w->output = strdup(current_output_string); + + /* + * If the moved workspace was focused, schedule a full update because + * visibility for other workspaces may have changed. + */ + if (w->focused) { + i3_send_pkg(sock, I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL); + } } } From b8a93a26736c076d071bfc402fd1de6b136fe5ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 20 May 2024 07:45:49 +0200 Subject: [PATCH 055/112] changelog: i3/sway crash fix for output being turned on/off --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3152882..de5c52a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,9 +19,11 @@ ### Removed ### Fixed -* network: fix missing break in switch statement([#377][377]) +* network: fix missing break in switch statement ([#377][377]). +* i3/sway: crash when output is turned off an on ([#300][300]). [377]: https://codeberg.org/dnkl/yambar/issues/377 +[300]: https://codeberg.org/dnkl/yambar/issues/300 ### Security From 70efd7d15c7752754bab0c518321cdef5289126e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 20 May 2024 09:21:29 +0200 Subject: [PATCH 056/112] doc: yambar-particles: document the hard-coded spacing of short-form lists Closes #385 --- doc/yambar-particles.5.scd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/yambar-particles.5.scd b/doc/yambar-particles.5.scd index 5dc858b..d9b0e56 100644 --- a/doc/yambar-particles.5.scd +++ b/doc/yambar-particles.5.scd @@ -214,6 +214,11 @@ content: - string: ... ``` +Note that the short form has a hard-coded *right-spacing* of 2. This +cannot be changed. If you want a different spacing, you must use an +explicit list particle (i.e. the long form). + + # MAP This particle maps the values of a specific tag to different From 0bea49b75e2cf3fe347bce3447e9dfbaaaaf2c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 20 May 2024 09:33:45 +0200 Subject: [PATCH 057/112] module/river: return empty particle list when river is not running Closes #384 --- CHANGELOG.md | 7 +++++++ modules/river.c | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de5c52a..eedc5f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,13 @@ ## Unreleased ### Added ### Changed + +* `river`: expand to an empty list of particles when river is not + running ([#384][384]). + +[384]: https://codeberg.org/dnkl/yambar/issues/384 + + ### Deprecated ### Removed ### Fixed diff --git a/modules/river.c b/modules/river.c index 2619c62..ec25f9f 100644 --- a/modules/river.c +++ b/modules/river.c @@ -52,6 +52,7 @@ struct seat { struct private { struct module *mod; + bool is_running; struct zxdg_output_manager_v1 *xdg_output_manager; struct zriver_status_manager_v1 *status_manager; struct particle *template; @@ -88,6 +89,11 @@ content(struct module *mod) mtx_lock(&m->mod->lock); + if (!m->is_running) { + mtx_unlock(&m->mod->lock); + return dynlist_exposable_new(NULL, 0, 0, 0); + } + uint32_t urgent = 0; uint32_t occupied = 0; uint32_t output_focused = 0; @@ -685,6 +691,8 @@ run(struct module *mod) goto out; } + m->is_running = true; + wl_display_roundtrip(display); while (true) { From 20659d3350ab0044c41b781fa4df64e1164d2051 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 9 May 2024 03:55:25 +0200 Subject: [PATCH 058/112] Add support for environment variable references The format is key: ${env_variable} Closes #96 Signed-off-by: Tomas Slusny --- CHANGELOG.md | 5 +++++ doc/yambar.5.scd | 5 +++++ yml.c | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eedc5f6..3c13106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ ## Unreleased ### Added + +* environment variable substitution in config files ([#388][388]). + +[388]: https://codeberg.org/dnkl/yambar/issues/388 + ### Changed * `river`: expand to an empty list of particles when river is not diff --git a/doc/yambar.5.scd b/doc/yambar.5.scd index 1b06939..cc03f8c 100644 --- a/doc/yambar.5.scd +++ b/doc/yambar.5.scd @@ -23,6 +23,11 @@ types that are frequently used: - 000000ff: black, no transparency - 00ff00ff: green, no transparency - ff000099: red, semi-transparent +- *environment reference*: a string that contains format ${VAR}. This will be + replaced by the value of the environment variable VAR. Example: + - ${HOME} + - ${HOME}/.config/yambar + - ENV is ${ENV}, ENV2 is ${ENV2} # FORMAT [[ *Name* diff --git a/yml.c b/yml.c index ec08101..73dba66 100644 --- a/yml.c +++ b/yml.c @@ -366,6 +366,44 @@ format_error(enum yml_error err, const struct yml_node *parent, const struct yml return err_str; } +static char * +replace_env_variables(const char *str, size_t len) +{ + char *result = strndup(str, len); + char *start, *end, *key, *env_value; + char* prefix = "${"; + char* suffix = "}"; + size_t pref_len = 2; + size_t suff_len = 1; + size_t key_len; + + while ((start = strstr(result, prefix)) && (end = strstr(start, suffix))) { + key_len = end - start - pref_len; + key = strndup(start + pref_len, key_len); + env_value = getenv(key); + + if (env_value) { + size_t result_len = strlen(result); + size_t new_len = result_len - key_len - pref_len - suff_len + strlen(env_value); + char *new_result = malloc(new_len + 1); + + strncpy(new_result, result, start - result); + new_result[start - result] = '\0'; + strcat(new_result, env_value); + strcat(new_result, end + 1); + + free(result); + result = new_result; + } else { + memmove(start, end + 1, strlen(end + 1) + 1); + } + + free(key); + } + + return result; +} + struct yml_node * yml_load(FILE *yml, char **error) { @@ -456,7 +494,7 @@ yml_load(FILE *yml, char **error) case YAML_SCALAR_EVENT: { struct yml_node *new_scalar = calloc(1, sizeof(*new_scalar)); new_scalar->type = SCALAR; - new_scalar->scalar.value = strndup((const char *)event.data.scalar.value, event.data.scalar.length); + new_scalar->scalar.value = replace_env_variables((const char *)event.data.scalar.value, event.data.scalar.length); enum yml_error err = add_node(n, new_scalar, event.start_mark); if (err != YML_ERR_NONE) { From 3431d5fc7526a7c160bb12a158773b39927845f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 9 Jun 2024 10:05:21 +0200 Subject: [PATCH 059/112] yml: replace_env_variables(): const:ify function variables --- yml.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/yml.c b/yml.c index 73dba66..4769d38 100644 --- a/yml.c +++ b/yml.c @@ -370,14 +370,17 @@ static char * replace_env_variables(const char *str, size_t len) { char *result = strndup(str, len); - char *start, *end, *key, *env_value; - char* prefix = "${"; - char* suffix = "}"; - size_t pref_len = 2; - size_t suff_len = 1; + char *start, *key; + const char *end, *env_value; + const char* prefix = "${"; + const char* suffix = "}"; + const size_t pref_len = 2; + const size_t suff_len = 1; size_t key_len; - while ((start = strstr(result, prefix)) && (end = strstr(start, suffix))) { + while ((start = strstr(result, prefix)) != NULL && + (end = strstr(start, suffix)) != NULL) + { key_len = end - start - pref_len; key = strndup(start + pref_len, key_len); env_value = getenv(key); From 9cc5e0f7a7398f88f80a3520d44feecb645a0e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 9 Jun 2024 10:08:38 +0200 Subject: [PATCH 060/112] module/network: plug memory leak Free the 'ifaces' list, not just its contents. --- modules/network.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/network.c b/modules/network.c index 9ed9964..c2f6ec3 100644 --- a/modules/network.c +++ b/modules/network.c @@ -119,7 +119,10 @@ destroy(struct module *mod) if (m->urandom_fd >= 0) close(m->urandom_fd); - tll_foreach(m->ifaces, it) free_iface(it->item); + tll_foreach(m->ifaces, it) { + free_iface(it->item); + tll_remove(m->ifaces, it); + } free(m); module_default_destroy(mod); From 8422e7e0b1baebb9addf9d18244bdbacb3e539f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 9 Jun 2024 10:12:23 +0200 Subject: [PATCH 061/112] doc: yambar(5): remove trailing whitespace --- doc/yambar.5.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/yambar.5.scd b/doc/yambar.5.scd index cc03f8c..38c521d 100644 --- a/doc/yambar.5.scd +++ b/doc/yambar.5.scd @@ -24,7 +24,7 @@ types that are frequently used: - 00ff00ff: green, no transparency - ff000099: red, semi-transparent - *environment reference*: a string that contains format ${VAR}. This will be - replaced by the value of the environment variable VAR. Example: + replaced by the value of the environment variable VAR. Example: - ${HOME} - ${HOME}/.config/yambar - ENV is ${ENV}, ENV2 is ${ENV2} From 739dc30323adbb93cfad1918eca4bb0f18b41359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 9 Jun 2024 10:12:32 +0200 Subject: [PATCH 062/112] changelog: env var substitution: fix issue reference Reference the issue, not the PR. --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c13106..9c0a0f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,9 +15,10 @@ ## Unreleased ### Added -* environment variable substitution in config files ([#388][388]). +* environment variable substitution in config files ([#96][96]). + +[96]: https://codeberg.org/dnkl/yambar/issues/96 -[388]: https://codeberg.org/dnkl/yambar/issues/388 ### Changed From 1a323c6d21d337e710534559682e2459a5db591b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 18 Jul 2024 08:31:46 +0200 Subject: [PATCH 063/112] log: respect the NO_COLOR environment variable http://no-color.org/ --- CHANGELOG.md | 2 ++ log.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c0a0f4..c6bb179 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ ### Added * environment variable substitution in config files ([#96][96]). +* Log output now respects the [`NO_COLOR`](http://no-color.org/) + environment variable. [96]: https://codeberg.org/dnkl/yambar/issues/96 diff --git a/log.c b/log.c index 7ba4193..ba4ebd9 100644 --- a/log.c +++ b/log.c @@ -39,9 +39,15 @@ log_init(enum log_colorize _colorize, bool _do_syslog, enum log_facility syslog_ [LOG_FACILITY_DAEMON] = LOG_DAEMON, }; - colorize = _colorize == LOG_COLORIZE_NEVER ? false - : _colorize == LOG_COLORIZE_ALWAYS ? true - : isatty(STDERR_FILENO); + /* Don't use colors if NO_COLOR is defined and not empty */ + const char *no_color_str = getenv("NO_COLOR"); + const bool no_color = no_color_str != NULL && no_color_str[0] != '\0'; + + colorize = _colorize == LOG_COLORIZE_NEVER + ? false + : _colorize == LOG_COLORIZE_ALWAYS + ? true + : !no_color && isatty(STDERR_FILENO); do_syslog = _do_syslog; log_level = _log_level; From 3e0a65f1852eb6a17ed2e8e5e381eb54b96bb8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 7 Aug 2024 17:27:26 +0200 Subject: [PATCH 064/112] meson: fix misdetection of memfd_create() --- meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index d760e94..d9b1364 100644 --- a/meson.build +++ b/meson.build @@ -12,7 +12,9 @@ plugs_as_libs = get_option('core-plugins-as-shared-libraries') cc = meson.get_compiler('c') -if cc.has_function('memfd_create') +if cc.has_function('memfd_create', + args: ['-D_GNU_SOURCE=200809L'], + prefix: '#include ') add_project_arguments('-DMEMFD_CREATE', language: 'c') endif From 568eb1140fe2296bbb45368902acf98868a15fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 20 Aug 2024 07:32:51 +0200 Subject: [PATCH 065/112] modules/mpd: fix reconnect when we're not using inotify When we're not able to use inotify, we rely on polling. However, we never detected poll() timeouts, which meant we never re-attempted to reconnect to MPD. Maybe #394 --- CHANGELOG.md | 2 ++ modules/mpd.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6bb179..f7c2ec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ * network: fix missing break in switch statement ([#377][377]). * i3/sway: crash when output is turned off an on ([#300][300]). +* mpd: yambar never attempting to reconnect after MPD closed the + connection (for example, when MPD is restarted). [377]: https://codeberg.org/dnkl/yambar/issues/377 [300]: https://codeberg.org/dnkl/yambar/issues/300 diff --git a/modules/mpd.c b/modules/mpd.c index 22c0e6b..63da818 100644 --- a/modules/mpd.c +++ b/modules/mpd.c @@ -437,7 +437,7 @@ run(struct module *mod) */ while (!aborted) { struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}}; - int res = poll(fds, sizeof(fds) / sizeof(fds[0]), 10 * 1000); + int res = poll(fds, sizeof(fds) / sizeof(fds[0]), 2 * 1000); if (res < 0) { if (errno == EINTR) @@ -448,10 +448,16 @@ run(struct module *mod) break; } - if (res == 1) { + if (res == 0) { + ret = 0; + break; + } + + else if (res == 1) { assert(fds[0].revents & POLLIN); aborted = true; } + } } From a5ae61b5df3b3e04b79741927f3e70a809257a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 30 Apr 2024 10:00:46 +0200 Subject: [PATCH 066/112] module: network: add 'type` tag This tag maps to the ifinfomsg->ifi_type member, which is set to one of the ARPHRD_xyz values, defined in linux/if_arp.h. There's a *ton* of them, and we can't possibly add a string mapping for _all_ of them, so for now, set to one of: * loopback * ether * wlan * ARPHRD_NNN, where N is a number --- CHANGELOG.md | 2 ++ doc/yambar-modules-network.5.scd | 4 ++++ modules/network.c | 34 +++++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7c2ec8..5dff40c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,8 +18,10 @@ * environment variable substitution in config files ([#96][96]). * Log output now respects the [`NO_COLOR`](http://no-color.org/) environment variable. +* network: `type` tag ([#380][380]). [96]: https://codeberg.org/dnkl/yambar/issues/96 +[380]: https://codeberg.org/dnkl/yambar/issues/380 ### Changed diff --git a/doc/yambar-modules-network.5.scd b/doc/yambar-modules-network.5.scd index cdc5530..eda6fd5 100644 --- a/doc/yambar-modules-network.5.scd +++ b/doc/yambar-modules-network.5.scd @@ -21,6 +21,10 @@ address per network interface. | name : string : Network interface name +| type +: string +: Interface type (*ether*, *wlan*, *loopback*, or *ARPHRD_NNN*, where + *N* is a number). | index : int : Network interface index diff --git a/modules/network.c b/modules/network.c index c2f6ec3..8a05dd7 100644 --- a/modules/network.c +++ b/modules/network.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,7 @@ #include #define LOG_MODULE "network" -#define LOG_ENABLE_DBG 0 +#define LOG_ENABLE_DBG 1 #include "../bar/bar.h" #include "../config-verify.h" #include "../config.h" @@ -52,6 +53,7 @@ struct af_addr { struct iface { char *name; + char *type; uint32_t get_stats_seq_nr; @@ -104,6 +106,7 @@ free_iface(struct iface iface) { tll_free(iface.addrs); free(iface.ssid); + free(iface.type); free(iface.name); } @@ -207,6 +210,7 @@ content(struct module *mod) struct tag_set tags = { .tags = (struct tag *[]){ tag_new_string(mod, "name", iface->name), + tag_new_string(mod, "type", iface->type), tag_new_int(mod, "index", iface->index), tag_new_bool(mod, "carrier", iface->carrier), tag_new_string(mod, "state", state), @@ -221,7 +225,7 @@ content(struct module *mod) tag_new_float(mod, "dl-speed", iface->dl_speed), tag_new_float(mod, "ul-speed", iface->ul_speed), }, - .count = 14, + .count = 15, }; exposables[idx++] = m->label->instantiate(m->label, &tags); tag_set_destroy(&tags); @@ -549,6 +553,7 @@ send_nl80211_get_scan(struct private *m) return true; } + static void handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len) { @@ -581,9 +586,31 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size } if (iface == NULL) { + char *type = NULL; + + switch (msg->ifi_type) { + case ARPHRD_ETHER: + type = strdup("ether"); + break; + + case ARPHRD_LOOPBACK: + type = strdup("loopback"); + break; + + case ARPHRD_IEEE80211: + type = strdup("wlan"); + break; + + default: + if (asprintf(&type, "ARPHRD_%hu", msg->ifi_type) < 0) + type = strdup("unknown"); + break; + } + mtx_lock(&mod->lock); tll_push_back(m->ifaces, ((struct iface){ .index = msg->ifi_index, + .type = type, .state = IF_OPER_DOWN, .addrs = tll_init(), })); @@ -596,9 +623,10 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size case IFLA_IFNAME: mtx_lock(&mod->lock); iface->name = strdup((const char *)RTA_DATA(attr)); - LOG_DBG("%s: index=%d", iface->name, iface->index); + LOG_DBG("%s: index=%d, type=%s", iface->name, iface->index, iface->type); mtx_unlock(&mod->lock); break; + case IFLA_OPERSTATE: { uint8_t operstate = *(const uint8_t *)RTA_DATA(attr); if (iface->state == operstate) From 699c5630511641c931e1d287c606da14d09ea2dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 30 Apr 2024 10:22:04 +0200 Subject: [PATCH 067/112] module: network: add 'kind' tag The tag maps to the IFLA_INFO_KIND (part of the IFLA_LINKINFO) netlink attribute. This attribute is only available on virtual interfaces. Examples of valid values are: * bond * bridge * gre * tun * veth --- CHANGELOG.md | 1 + doc/yambar-modules-network.5.scd | 6 ++ modules/network.c | 134 ++++++++++++++++++++----------- 3 files changed, 93 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dff40c..461e6db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * Log output now respects the [`NO_COLOR`](http://no-color.org/) environment variable. * network: `type` tag ([#380][380]). +* network: `type` and `kind` tags ([#380][380]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 diff --git a/doc/yambar-modules-network.5.scd b/doc/yambar-modules-network.5.scd index eda6fd5..7e500f0 100644 --- a/doc/yambar-modules-network.5.scd +++ b/doc/yambar-modules-network.5.scd @@ -25,6 +25,12 @@ address per network interface. : string : Interface type (*ether*, *wlan*, *loopback*, or *ARPHRD_NNN*, where *N* is a number). +| kind +: string +: Interface kind. Empty for non-virtual interfaces. For virtual + interfaces, this value is taken from the _IFLA\_INFO\_KIND_ netlink + attribute. Examples of valid values are *bond*, *bridge*, *gre*, *tun* + and *veth*. | index : int : Network interface index diff --git a/modules/network.c b/modules/network.c index 8a05dd7..dfbd5da 100644 --- a/modules/network.c +++ b/modules/network.c @@ -53,7 +53,8 @@ struct af_addr { struct iface { char *name; - char *type; + char *type; /* ARPHRD_NNN */ + char *kind; /* IFLA_LINKINFO::IFLA_INFO_KIND */ uint32_t get_stats_seq_nr; @@ -106,6 +107,7 @@ free_iface(struct iface iface) { tll_free(iface.addrs); free(iface.ssid); + free(iface.kind); free(iface.type); free(iface.name); } @@ -211,6 +213,7 @@ content(struct module *mod) .tags = (struct tag *[]){ tag_new_string(mod, "name", iface->name), tag_new_string(mod, "type", iface->type), + tag_new_string(mod, "kind", iface->kind), tag_new_int(mod, "index", iface->index), tag_new_bool(mod, "carrier", iface->carrier), tag_new_string(mod, "state", state), @@ -225,7 +228,7 @@ content(struct module *mod) tag_new_float(mod, "dl-speed", iface->dl_speed), tag_new_float(mod, "ul-speed", iface->ul_speed), }, - .count = 15, + .count = 16, }; exposables[idx++] = m->label->instantiate(m->label, &tags); tag_set_destroy(&tags); @@ -553,6 +556,78 @@ send_nl80211_get_scan(struct private *m) return true; } +static bool +foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len, + bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, + size_t len, void *ctx), + void *ctx) +{ + const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN; + const uint8_t *end = (const uint8_t *)genl + len; + + for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end; + raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) { + uint16_t type = attr->nla_type & NLA_TYPE_MASK; + bool nested = (attr->nla_type & NLA_F_NESTED) != 0; + ; + const void *payload = raw + NLA_HDRLEN; + + if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) + return false; + } + + return true; +} + +static bool +foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len, + bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, + const void *payload, size_t len, void *ctx), + void *ctx) +{ + const uint8_t *raw = parent_payload; + const uint8_t *end = parent_payload + len; + + for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end; + raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) { + uint16_t type = attr->nla_type & NLA_TYPE_MASK; + bool nested = (attr->nla_type & NLA_F_NESTED) != 0; + const void *payload = raw + NLA_HDRLEN; + + if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) + return false; + } + + return true; +} + +static bool +parse_linkinfo(struct module *mod, struct iface *iface, uint16_t type, + bool nested, const void *payload, size_t len, void *_void) +{ + switch (type) { + case IFLA_INFO_KIND: { + const char *kind = payload; + free(iface->kind); + iface->kind = strndup(kind, len); + + LOG_DBG("%s: IFLA_INFO_KIND: %s", iface->name, iface->kind); + break; + } + + case IFLA_INFO_DATA: + //LOG_DBG("%s: IFLA_INFO_DATA", iface->name); + break; + + default: + LOG_WARN("unrecognized IFLA_LINKINFO attribute: " + "type=%hu, nested=%d, len=%zu", + type, nested, len); + break; + } + + return true; +} static void handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len) @@ -661,7 +736,8 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0) break; - LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", iface->name, mac[0], mac[1], mac[2], mac[3], + LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", + iface->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); mtx_lock(&mod->lock); @@ -669,6 +745,13 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size mtx_unlock(&mod->lock); break; } + + case IFLA_LINKINFO: { + foreach_nlattr_nested( + mod, iface, RTA_DATA(attr), RTA_PAYLOAD(attr), + &parse_linkinfo, NULL); + break; + } } } @@ -751,51 +834,6 @@ handle_address(struct module *mod, uint16_t type, const struct ifaddrmsg *msg, s mod->bar->refresh(mod->bar); } -static bool -foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len, - bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, - size_t len, void *ctx), - void *ctx) -{ - const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN; - const uint8_t *end = (const uint8_t *)genl + len; - - for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end; - raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) { - uint16_t type = attr->nla_type & NLA_TYPE_MASK; - bool nested = (attr->nla_type & NLA_F_NESTED) != 0; - ; - const void *payload = raw + NLA_HDRLEN; - - if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) - return false; - } - - return true; -} - -static bool -foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len, - bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, - const void *payload, size_t len, void *ctx), - void *ctx) -{ - const uint8_t *raw = parent_payload; - const uint8_t *end = parent_payload + len; - - for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end; - raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) { - uint16_t type = attr->nla_type & NLA_TYPE_MASK; - bool nested = (attr->nla_type & NLA_F_NESTED) != 0; - const void *payload = raw + NLA_HDRLEN; - - if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx)) - return false; - } - - return true; -} - struct mcast_group { uint32_t id; const char *name; From 54902f46ab3cfa5c72dbf3bd8e08886fd8fa0021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 30 Apr 2024 10:40:14 +0200 Subject: [PATCH 068/112] module: network: hardcode type to "wlan" when we see NL80211_CMD_NEW_INTERFACE Wlan interfaces apparently report themselves as ARPHRD_ETHER in their ifinfomsg struct (despite there being a ARPHRD_IEEE80211 type...). "Fix" by hardcoding the type to "wlan" when we receive a NL80211_CMD_NEW_INTERFACE message. --- modules/network.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/network.c b/modules/network.c index dfbd5da..1b2ceba 100644 --- a/modules/network.c +++ b/modules/network.c @@ -1370,6 +1370,8 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len) continue; LOG_DBG("%s: got interface information", iface->name); + free(iface->type); + iface->type = strdup("wlan"); foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL); break; From 887e770202e2839027bfa138bfc5d5b4bbec688a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 30 Apr 2024 12:03:33 +0200 Subject: [PATCH 069/112] doc: network: update example Only display Ethernet and WLAN devices (not loopback, bridges etc). --- doc/yambar-modules-network.5.scd | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/yambar-modules-network.5.scd b/doc/yambar-modules-network.5.scd index 7e500f0..afbbae3 100644 --- a/doc/yambar-modules-network.5.scd +++ b/doc/yambar-modules-network.5.scd @@ -101,17 +101,23 @@ address per network interface. # EXAMPLES +Display all Ethernet (including WLAN) devices. This excludes loopback, +bridges etc. + ``` bar: left: - network: content: map: - default: - string: {text: "{name}: {state} ({ipv4})"} conditions: - ipv4 == "": - string: {text: "{name}: {state}"} + type == ether || type == wlan: + map: + default: + string: {text: "{name}: {state} ({ipv4})"} + conditions: + ipv4 == "": + string: {text: "{name}: {state}"} ``` # SEE ALSO From f8ba887dcd5d063c9a069e6bd61b00d7c9f55439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 20 Aug 2024 09:11:17 +0200 Subject: [PATCH 070/112] readme: repology: use four columns --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2887f53..48566dc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Yambar -[![Packaging status](https://repology.org/badge/vertical-allrepos/yambar.svg)](https://repology.org/project/yambar/versions) +[![Packaging status](https://repology.org/badge/vertical-allrepos/yambar.svg?columns=4)](https://repology.org/project/yambar/versions) ## Index From 700bf5b28c3f060ed629ac9bf782e0ff2ec76636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 20 Aug 2024 14:34:45 +0200 Subject: [PATCH 071/112] tag: add 'b' formatter Divides the tag's decimal value by 8. Closes #392 --- CHANGELOG.md | 3 +++ doc/yambar-tags.5.scd | 7 +++++- tag.c | 51 +++++++++++++++++++++++++++++++------------ 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 461e6db..33e12b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,9 +20,12 @@ environment variable. * network: `type` tag ([#380][380]). * network: `type` and `kind` tags ([#380][380]). +* tags: `b` tag formatter; divides the tag's decimal value with `8` + ([#392][392]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 +[392]: https://codeberg.org/dnkl/yambar/issues/392 ### Changed diff --git a/doc/yambar-tags.5.scd b/doc/yambar-tags.5.scd index b778154..adda208 100644 --- a/doc/yambar-tags.5.scd +++ b/doc/yambar-tags.5.scd @@ -86,11 +86,16 @@ be used. : format : Range tags : Renders a range tag's value as a percentage value +| b +: format +: All tag types +: Renders a tag's value (in decimal) divided by 8. Note: no unit + suffix is appended | kb, mb, gb : format : All tag types : Renders a tag's value (in decimal) divided by 1000, 1000^2 or - 1000^3. Note: no unit suffix is appended) + 1000^3. Note: no unit suffix is appended | kib, mib, gib : format : All tag types diff --git a/tag.c b/tag.c index e95b1c7..438af64 100644 --- a/tag.c +++ b/tag.c @@ -510,6 +510,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) FMT_HEX, FMT_OCT, FMT_PERCENT, + FMT_BYTE, FMT_KBYTE, FMT_MBYTE, FMT_GBYTE, @@ -541,6 +542,8 @@ tags_expand_template(const char *template, const struct tag_set *tags) format = FMT_OCT; else if (strcmp(tag_args[i], "%") == 0) format = FMT_PERCENT; + else if (strcmp(tag_args[i], "b") == 0) + format = FMT_BYTE; else if (strcmp(tag_args[i], "kb") == 0) format = FMT_KBYTE; else if (strcmp(tag_args[i], "mb") == 0) @@ -634,19 +637,29 @@ tags_expand_template(const char *template, const struct tag_set *tags) break; } + case FMT_BYTE: case FMT_KBYTE: case FMT_MBYTE: case FMT_GBYTE: case FMT_KIBYTE: case FMT_MIBYTE: case FMT_GIBYTE: { - const long divider = format == FMT_KBYTE ? 1000 - : format == FMT_MBYTE ? 1000 * 1000 - : format == FMT_GBYTE ? 1000 * 1000 * 1000 - : format == FMT_KIBYTE ? 1024 - : format == FMT_MIBYTE ? 1024 * 1024 - : format == FMT_GIBYTE ? 1024 * 1024 * 1024 - : 1; + const long divider = + format == FMT_BYTE + ? 8 + : format == FMT_KBYTE + ? 1000 + : format == FMT_MBYTE + ? 1000 * 1000 + : format == FMT_GBYTE + ? 1000 * 1000 * 1000 + : format == FMT_KIBYTE + ? 1024 + : format == FMT_MIBYTE + ? 1024 * 1024 + : format == FMT_GIBYTE + ? 1024 * 1024 * 1024 + : 1; char str[24]; if (tag->type(tag) == TAG_TYPE_FLOAT) { @@ -684,19 +697,29 @@ tags_expand_template(const char *template, const struct tag_set *tags) fmt = zero_pad ? "%0*lu" : "%*lu"; break; + case FMT_BYTE: case FMT_KBYTE: case FMT_MBYTE: case FMT_GBYTE: case FMT_KIBYTE: case FMT_MIBYTE: case FMT_GIBYTE: { - const long divider = format == FMT_KBYTE ? 1024 - : format == FMT_MBYTE ? 1024 * 1024 - : format == FMT_GBYTE ? 1024 * 1024 * 1024 - : format == FMT_KIBYTE ? 1000 - : format == FMT_MIBYTE ? 1000 * 1000 - : format == FMT_GIBYTE ? 1000 * 1000 * 1000 - : 1; + const long divider = + format == FMT_BYTE + ? 8 + : format == FMT_KBYTE + ? 1024 + : format == FMT_MBYTE + ? 1024 * 1024 + : format == FMT_GBYTE + ? 1024 * 1024 * 1024 + : format == FMT_KIBYTE + ? 1000 + : format == FMT_MIBYTE + ? 1000 * 1000 + : format == FMT_GIBYTE + ? 1000 * 1000 * 1000 + : 1; value /= divider; fmt = zero_pad ? "%0*lu" : "%*lu"; break; From 1b2dee55efa246d1a020fff4345988ded02123f0 Mon Sep 17 00:00:00 2001 From: fraktal Date: Wed, 4 Sep 2024 15:33:25 +0200 Subject: [PATCH 072/112] fix bar Y position in case of multi-monitor setups with mixed resolutions --- bar/xcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar/xcb.c b/bar/xcb.c index 2552fe6..f3167a5 100644 --- a/bar/xcb.c +++ b/bar/xcb.c @@ -101,7 +101,7 @@ setup(struct bar *_bar) backend->x = mon->x; backend->y = mon->y; bar->width = mon->width; - backend->y += bar->location == BAR_TOP ? 0 : screen->height_in_pixels - bar->height_with_border; + backend->y += bar->location == BAR_TOP ? 0 : mon->height - bar->height_with_border; found_monitor = true; From 2d651d1c0e5b74ac3db643fc0aabffe561387a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 5 Sep 2024 08:16:25 +0200 Subject: [PATCH 073/112] changelog: bar position in multi-monitor setups, with location=bottom --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33e12b1..962c268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ * i3/sway: crash when output is turned off an on ([#300][300]). * mpd: yambar never attempting to reconnect after MPD closed the connection (for example, when MPD is restarted). +* Bar positioning on multi-monitor setups, when `location=bottom`. [377]: https://codeberg.org/dnkl/yambar/issues/377 [300]: https://codeberg.org/dnkl/yambar/issues/300 From 9498d7e445cd444d2840bf89a3e20dd71fc45045 Mon Sep 17 00:00:00 2001 From: Zhong Jianxin Date: Sun, 1 Sep 2024 21:16:49 +0800 Subject: [PATCH 074/112] tag: combine FMT_*BYTE into one FMT_DIVIDE --- tag.c | 100 +++++++++++++++++++--------------------------------------- 1 file changed, 32 insertions(+), 68 deletions(-) diff --git a/tag.c b/tag.c index 438af64..ce4e0e8 100644 --- a/tag.c +++ b/tag.c @@ -510,13 +510,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) FMT_HEX, FMT_OCT, FMT_PERCENT, - FMT_BYTE, - FMT_KBYTE, - FMT_MBYTE, - FMT_GBYTE, - FMT_KIBYTE, - FMT_MIBYTE, - FMT_GIBYTE, + FMT_DIVIDE, } format = FMT_DEFAULT; @@ -530,6 +524,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) int digits = 0; int decimals = 2; + long divider = 1; bool zero_pad = false; char *point = NULL; @@ -542,20 +537,34 @@ tags_expand_template(const char *template, const struct tag_set *tags) format = FMT_OCT; else if (strcmp(tag_args[i], "%") == 0) format = FMT_PERCENT; - else if (strcmp(tag_args[i], "b") == 0) - format = FMT_BYTE; - else if (strcmp(tag_args[i], "kb") == 0) - format = FMT_KBYTE; - else if (strcmp(tag_args[i], "mb") == 0) - format = FMT_MBYTE; - else if (strcmp(tag_args[i], "gb") == 0) - format = FMT_GBYTE; - else if (strcmp(tag_args[i], "kib") == 0) - format = FMT_KIBYTE; - else if (strcmp(tag_args[i], "mib") == 0) - format = FMT_MIBYTE; - else if (strcmp(tag_args[i], "gib") == 0) - format = FMT_GIBYTE; + else if (strcmp(tag_args[i], "b") == 0) { + format = FMT_DIVIDE; + divider = 8; + } + else if (strcmp(tag_args[i], "kb") == 0) { + format = FMT_DIVIDE; + divider = 1000; + } + else if (strcmp(tag_args[i], "mb") == 0) { + format = FMT_DIVIDE; + divider = 1000 * 1000; + } + else if (strcmp(tag_args[i], "gb") == 0) { + format = FMT_DIVIDE; + divider = 1000 * 1000 * 1000; + } + else if (strcmp(tag_args[i], "kib") == 0) { + format = FMT_DIVIDE; + divider = 1024; + } + else if (strcmp(tag_args[i], "mib") == 0) { + format = FMT_DIVIDE; + divider = 1024 * 1024; + } + else if (strcmp(tag_args[i], "gib") == 0) { + format = FMT_DIVIDE; + divider = 1024 * 1024 * 1024; + } else if (strcmp(tag_args[i], "min") == 0) kind = VALUE_MIN; else if (strcmp(tag_args[i], "max") == 0) @@ -637,30 +646,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) break; } - case FMT_BYTE: - case FMT_KBYTE: - case FMT_MBYTE: - case FMT_GBYTE: - case FMT_KIBYTE: - case FMT_MIBYTE: - case FMT_GIBYTE: { - const long divider = - format == FMT_BYTE - ? 8 - : format == FMT_KBYTE - ? 1000 - : format == FMT_MBYTE - ? 1000 * 1000 - : format == FMT_GBYTE - ? 1000 * 1000 * 1000 - : format == FMT_KIBYTE - ? 1024 - : format == FMT_MIBYTE - ? 1024 * 1024 - : format == FMT_GIBYTE - ? 1024 * 1024 * 1024 - : 1; - + case FMT_DIVIDE: { char str[24]; if (tag->type(tag) == TAG_TYPE_FLOAT) { const char *fmt = zero_pad ? "%0*.*f" : "%*.*f"; @@ -697,29 +683,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) fmt = zero_pad ? "%0*lu" : "%*lu"; break; - case FMT_BYTE: - case FMT_KBYTE: - case FMT_MBYTE: - case FMT_GBYTE: - case FMT_KIBYTE: - case FMT_MIBYTE: - case FMT_GIBYTE: { - const long divider = - format == FMT_BYTE - ? 8 - : format == FMT_KBYTE - ? 1024 - : format == FMT_MBYTE - ? 1024 * 1024 - : format == FMT_GBYTE - ? 1024 * 1024 * 1024 - : format == FMT_KIBYTE - ? 1000 - : format == FMT_MIBYTE - ? 1000 * 1000 - : format == FMT_GIBYTE - ? 1000 * 1000 * 1000 - : 1; + case FMT_DIVIDE: { value /= divider; fmt = zero_pad ? "%0*lu" : "%*lu"; break; From 311c481bfe0b22516859584bf79fb95716927e99 Mon Sep 17 00:00:00 2001 From: Zhong Jianxin Date: Sun, 1 Sep 2024 21:21:26 +0800 Subject: [PATCH 075/112] tag: add '/N' formatter --- doc/yambar-tags.5.scd | 4 ++++ tag.c | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/doc/yambar-tags.5.scd b/doc/yambar-tags.5.scd index adda208..f58678c 100644 --- a/doc/yambar-tags.5.scd +++ b/doc/yambar-tags.5.scd @@ -86,6 +86,10 @@ be used. : format : Range tags : Renders a range tag's value as a percentage value +| /N +: format +: All tag types +: Renders a tag's value (in decimal) divided by N | b : format : All tag types diff --git a/tag.c b/tag.c index ce4e0e8..48155b5 100644 --- a/tag.c +++ b/tag.c @@ -430,12 +430,12 @@ sbuf_append(struct sbuf *s1, const char *s2) // stores the number in "*value" on success static bool -is_number(const char *str, int *value) +is_number(const char *str, long *value) { errno = 0; char *end; - int v = strtol(str, &end, 10); + long v = strtol(str, &end, 10); if (errno != 0 || *end != '\0') return false; @@ -522,8 +522,8 @@ tags_expand_template(const char *template, const struct tag_set *tags) } kind = VALUE_VALUE; - int digits = 0; - int decimals = 2; + long digits = 0; + long decimals = 2; long divider = 1; bool zero_pad = false; char *point = NULL; @@ -537,6 +537,14 @@ tags_expand_template(const char *template, const struct tag_set *tags) format = FMT_OCT; else if (strcmp(tag_args[i], "%") == 0) format = FMT_PERCENT; + else if (*tag_args[i] == '/') { + format = FMT_DIVIDE; + const char *divider_str = tag_args[i] + 1; + if (!is_number(divider_str, ÷r) || divider == 0) { + divider = 1; + LOG_WARN("tag `%s`: invalid divider %s, reset to 1", tag_name, divider_str); + } + } else if (strcmp(tag_args[i], "b") == 0) { format = FMT_DIVIDE; divider = 8; From c80bae7604b18f54ee25e4073e9a95b081da1541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 5 Sep 2024 08:20:59 +0200 Subject: [PATCH 076/112] changelog: /N tag formatter --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 962c268..1bbcae1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ * network: `type` and `kind` tags ([#380][380]). * tags: `b` tag formatter; divides the tag's decimal value with `8` ([#392][392]). +* tags: `/` tag formatter: divides the tag's decimal value with `N` + ([#392][392]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 From 060586dbbeb9134ee0a8810d611fc08310da490a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 5 Sep 2024 08:23:47 +0200 Subject: [PATCH 077/112] tag: remove the :b formatter Superseded by /N. Removing since a) it's no longer needed, and b) its name is not consistent with the other kb/mb/gb formatters. --- CHANGELOG.md | 2 -- doc/yambar-tags.5.scd | 5 ----- tag.c | 4 ---- 3 files changed, 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bbcae1..0e2e456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,8 +20,6 @@ environment variable. * network: `type` tag ([#380][380]). * network: `type` and `kind` tags ([#380][380]). -* tags: `b` tag formatter; divides the tag's decimal value with `8` - ([#392][392]). * tags: `/` tag formatter: divides the tag's decimal value with `N` ([#392][392]). diff --git a/doc/yambar-tags.5.scd b/doc/yambar-tags.5.scd index f58678c..b6b8b56 100644 --- a/doc/yambar-tags.5.scd +++ b/doc/yambar-tags.5.scd @@ -90,11 +90,6 @@ be used. : format : All tag types : Renders a tag's value (in decimal) divided by N -| b -: format -: All tag types -: Renders a tag's value (in decimal) divided by 8. Note: no unit - suffix is appended | kb, mb, gb : format : All tag types diff --git a/tag.c b/tag.c index 48155b5..d6609af 100644 --- a/tag.c +++ b/tag.c @@ -545,10 +545,6 @@ tags_expand_template(const char *template, const struct tag_set *tags) LOG_WARN("tag `%s`: invalid divider %s, reset to 1", tag_name, divider_str); } } - else if (strcmp(tag_args[i], "b") == 0) { - format = FMT_DIVIDE; - divider = 8; - } else if (strcmp(tag_args[i], "kb") == 0) { format = FMT_DIVIDE; divider = 1000; From b81e41c3c4567c78fe45c8b380c271ab111fcd89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 5 Sep 2024 11:56:10 +0200 Subject: [PATCH 078/112] module/i3: add 'output' tag This allows bars to render workspaces differently, depending on which output the workspace is on: - map: default: ... conditions: output == DP-1: ... --- modules/i3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/i3.c b/modules/i3.c index 5cb6e01..b1d1ca8 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -876,6 +876,7 @@ content(struct module *mod) struct tag_set tags = { .tags = (struct tag *[]){ tag_new_string(mod, "name", name), + tag_new_string(mod, "output", ws->output), tag_new_bool(mod, "visible", ws->visible), tag_new_bool(mod, "focused", ws->focused), tag_new_bool(mod, "urgent", ws->urgent), @@ -887,7 +888,7 @@ content(struct module *mod) tag_new_string(mod, "mode", m->mode), }, - .count = 9, + .count = 10, }; if (ws->focused) { From c3f7fe013daba11ba32880687e4a7102e402b096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 7 Sep 2024 08:35:39 +0200 Subject: [PATCH 079/112] doc: i3/sway: add 'output' to tag list --- doc/yambar-modules-i3.5.scd | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/yambar-modules-i3.5.scd b/doc/yambar-modules-i3.5.scd index 296a2da..2014a3c 100644 --- a/doc/yambar-modules-i3.5.scd +++ b/doc/yambar-modules-i3.5.scd @@ -26,6 +26,9 @@ with the _application_ and _title_ tags to replace the X11-only | name : string : The workspace name +| output +: string +: The output (monitor) the workspace is on | visible : bool : True if the workspace is currently visible (on any output) From 0f47cbb889716dcd0824b5501cab6f5f1cc85eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 7 Sep 2024 08:35:58 +0200 Subject: [PATCH 080/112] changelog: i3/sway: output tag --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e2e456..763873f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ * network: `type` and `kind` tags ([#380][380]). * tags: `/` tag formatter: divides the tag's decimal value with `N` ([#392][392]). +* i3/sway: `output` tag, reflecting the output (monitor) a workspace + is on. [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 From 4826a52306ffc9881269d6ecf12c0f5ede123a11 Mon Sep 17 00:00:00 2001 From: bagnaram Date: Fri, 26 Jul 2024 14:40:10 -0600 Subject: [PATCH 081/112] string like operation --- CHANGELOG.md | 3 ++ doc/yambar-particles.5.scd | 20 ++++++++++++++ particles/map.c | 56 ++++++++++++++++++++++++++++++++++++++ particles/map.h | 1 + particles/map.l | 1 + particles/map.y | 14 +++++----- 6 files changed, 88 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 763873f..7b65b3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,10 +24,13 @@ ([#392][392]). * i3/sway: `output` tag, reflecting the output (monitor) a workspace is on. +* Added "string like" `~~` operator to Map particle. Allows + glob-style matching on strings using `*` and `?` characters. ([#400][400]) [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 [392]: https://codeberg.org/dnkl/yambar/issues/392 +[400]: https://codeberg.org/dnkl/yambar/pulls/400 ### Changed diff --git a/doc/yambar-particles.5.scd b/doc/yambar-particles.5.scd index d9b0e56..c86a93b 100644 --- a/doc/yambar-particles.5.scd +++ b/doc/yambar-particles.5.scd @@ -265,6 +265,26 @@ To match for empty strings, use ' "" ': == "" ``` +String glob matching + +To perform string matching using globbing with "\*" & "?" characters: +\* Match any zero or more characters. +? Match exactly any one character. + +``` + ~~ "hello*" +``` + +Will match any string starting with "hello", including "hello", +"hello1", "hello123", etc. + +``` + ~~ "hello?" +``` + +Will match any string starting with "hello" followed by any single +character, including "hello1", "hello-", but not "hello". + Furthermore, you may use the boolean operators: [- && diff --git a/particles/map.c b/particles/map.c index 51fc744..348e966 100644 --- a/particles/map.c +++ b/particles/map.c @@ -13,6 +13,59 @@ #include "map.h" +// String globbing match. +// Note: Uses "non-greedy" implementation for "*" wildcard matching +static bool +string_like(const char* name, const char* pattern) +{ + LOG_DBG("pattern:%s name:%s", pattern, name); + int px = 0, nx = 0; + int nextpx = 0, nextnx = 0; + while(px < strlen(pattern) || nx < strlen(name)) + { + if(px < strlen(pattern)) + { + char c = pattern[px]; + switch (c) { + case '?': { + // single character + px++; + nx++; + continue; + } + case '*': { + // zero or more glob + nextpx=px; + nextnx=nx+1; + px++; + continue; + } + default: { + // normal character + if (nx < strlen(name) && name[nx] == c) + { + px++; + nx++; + continue; + } + } + } + + } + // mismatch + if (0 < nextnx && nextnx <= strlen(name)) { + px = nextpx; + nx = nextnx; + continue; + } + return false; + + } + LOG_DBG("map: name %s matched all the pattern %s", name, pattern); + // Matched all of pattern to all of name. Success. + return true; +} + static bool int_condition(const long tag_value, const long cond_value, enum map_op op) { @@ -75,6 +128,8 @@ str_condition(const char *tag_value, const char *cond_value, enum map_op op) return strcmp(tag_value, cond_value) >= 0; case MAP_OP_GT: return strcmp(tag_value, cond_value) > 0; + case MAP_OP_LIKE: + return string_like(tag_value, cond_value) != 0; case MAP_OP_SELF: LOG_WARN("using String tag as bool"); default: @@ -166,6 +221,7 @@ free_map_condition(struct map_condition *c) case MAP_OP_LE: case MAP_OP_LT: case MAP_OP_GE: + case MAP_OP_LIKE: case MAP_OP_GT: free(c->value); /* FALLTHROUGH */ diff --git a/particles/map.h b/particles/map.h index 23670a5..1256744 100644 --- a/particles/map.h +++ b/particles/map.h @@ -9,6 +9,7 @@ enum map_op { MAP_OP_GT, MAP_OP_SELF, MAP_OP_NOT, + MAP_OP_LIKE, MAP_OP_AND, MAP_OP_OR, diff --git a/particles/map.l b/particles/map.l index d34f086..034353c 100644 --- a/particles/map.l +++ b/particles/map.l @@ -69,6 +69,7 @@ void yyerror(const char *s); \< yylval.op = MAP_OP_LT; return CMP_OP; >= yylval.op = MAP_OP_GE; return CMP_OP; > yylval.op = MAP_OP_GT; return CMP_OP; +~~ yylval.op = MAP_OP_LIKE; return CMP_OP; && yylval.op = MAP_OP_AND; return BOOL_OP; \|\| yylval.op = MAP_OP_OR; return BOOL_OP; ~ return NOT; diff --git a/particles/map.y b/particles/map.y index ee426da..8f3f46b 100644 --- a/particles/map.y +++ b/particles/map.y @@ -35,27 +35,27 @@ result: condition { MAP_CONDITION_PARSE_RESULT = $1; }; condition: WORD { $$ = malloc(sizeof(struct map_condition)); - $$->tag = $1; + $$->tag = $1; $$->op = MAP_OP_SELF; } | WORD CMP_OP WORD { $$ = malloc(sizeof(struct map_condition)); - $$->tag = $1; + $$->tag = $1; $$->op = $2; - $$->value = $3; + $$->value = $3; } | WORD CMP_OP STRING { $$ = malloc(sizeof(struct map_condition)); - $$->tag = $1; + $$->tag = $1; $$->op = $2; - $$->value = $3; + $$->value = $3; } | L_PAR condition R_PAR { $$ = $2; } | - NOT condition { + NOT condition { $$ = malloc(sizeof(struct map_condition)); $$->cond1 = $2; $$->op = MAP_OP_NOT; @@ -79,7 +79,7 @@ static char const* token_to_str(yysymbol_kind_t tkn) { switch (tkn) { - case YYSYMBOL_CMP_OP: return "==, !=, <=, <, >=, >"; + case YYSYMBOL_CMP_OP: return "==, !=, <=, <, >=, >, ~~"; case YYSYMBOL_BOOL_OP: return "||, &&"; case YYSYMBOL_L_PAR: return "("; case YYSYMBOL_R_PAR: return ")"; From 37ecc251a43ad14b49948c5eb7d119980ad82eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 2 Oct 2024 08:10:30 +0200 Subject: [PATCH 082/112] changelog: line-wrap --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b65b3b..09db85b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,8 +24,8 @@ ([#392][392]). * i3/sway: `output` tag, reflecting the output (monitor) a workspace is on. -* Added "string like" `~~` operator to Map particle. Allows - glob-style matching on strings using `*` and `?` characters. ([#400][400]) +* Added "string like" `~~` operator to Map particle. Allows glob-style + matching on strings using `*` and `?` characters ([#400][400]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 From 20d48a753b4faf1c9cad92359caad234296f34a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 2 Oct 2024 08:10:53 +0200 Subject: [PATCH 083/112] particle/map: code style --- particles/map.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/particles/map.c b/particles/map.c index 348e966..c5510ff 100644 --- a/particles/map.c +++ b/particles/map.c @@ -21,10 +21,9 @@ string_like(const char* name, const char* pattern) LOG_DBG("pattern:%s name:%s", pattern, name); int px = 0, nx = 0; int nextpx = 0, nextnx = 0; - while(px < strlen(pattern) || nx < strlen(name)) - { - if(px < strlen(pattern)) - { + + while (px < strlen(pattern) || nx < strlen(name)) { + if (px < strlen(pattern)) { char c = pattern[px]; switch (c) { case '?': { @@ -52,18 +51,21 @@ string_like(const char* name, const char* pattern) } } + // mismatch - if (0 < nextnx && nextnx <= strlen(name)) { - px = nextpx; - nx = nextnx; - continue; - } + if (0 < nextnx && nextnx <= strlen(name)) { + px = nextpx; + nx = nextnx; + continue; + } + return false; } + LOG_DBG("map: name %s matched all the pattern %s", name, pattern); // Matched all of pattern to all of name. Success. - return true; + return true; } static bool From e1b6a78f227eec7abf5b6d5dc59d5d913cb8e68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 2 Oct 2024 08:11:02 +0200 Subject: [PATCH 084/112] doc: particles: remove trailing spaces --- doc/yambar-particles.5.scd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/yambar-particles.5.scd b/doc/yambar-particles.5.scd index c86a93b..70a5375 100644 --- a/doc/yambar-particles.5.scd +++ b/doc/yambar-particles.5.scd @@ -268,21 +268,21 @@ To match for empty strings, use ' "" ': String glob matching To perform string matching using globbing with "\*" & "?" characters: -\* Match any zero or more characters. -? Match exactly any one character. +\* Match any zero or more characters. ? Match exactly any one +character. ``` ~~ "hello*" ``` -Will match any string starting with "hello", including "hello", +Will match any string starting with "hello", including "hello", "hello1", "hello123", etc. ``` ~~ "hello?" ``` -Will match any string starting with "hello" followed by any single +Will match any string starting with "hello" followed by any single character, including "hello1", "hello-", but not "hello". Furthermore, you may use the boolean operators: From 650d1f13f9f718dbbec33f4ebe6494aefe276ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20St=C3=A6rk?= Date: Tue, 8 Oct 2024 15:42:03 +0200 Subject: [PATCH 085/112] docs: fix typo in example --- doc/yambar-particles.5.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/yambar-particles.5.scd b/doc/yambar-particles.5.scd index 70a5375..231b419 100644 --- a/doc/yambar-particles.5.scd +++ b/doc/yambar-particles.5.scd @@ -476,7 +476,7 @@ itself when needed. ``` content: - progres-bar: + progress-bar: tag: tag_name length: 20 start: {string: {text: ├}} From a367895dc63f822ab4063449009bc6755adbeec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 23 Oct 2024 09:36:59 +0200 Subject: [PATCH 086/112] Open sockets, files etc with FD_CLOEXEC --- main.c | 2 +- modules/backlight.c | 8 ++++---- modules/battery.c | 36 ++++++++++++++++++------------------ modules/cpu.c | 2 +- modules/disk-io.c | 2 +- modules/dwl.c | 2 +- modules/i3.c | 2 +- modules/mem.c | 2 +- modules/network.c | 2 +- modules/pulse.c | 2 +- modules/removables.c | 2 +- modules/xwindow.c | 2 +- 12 files changed, 32 insertions(+), 32 deletions(-) diff --git a/main.c b/main.c index a9c6932..c355843 100644 --- a/main.c +++ b/main.c @@ -87,7 +87,7 @@ get_config_path(void) static struct bar * load_bar(const char *config_path, enum bar_backend backend) { - FILE *conf_file = fopen(config_path, "r"); + FILE *conf_file = fopen(config_path, "re"); if (conf_file == NULL) { LOG_ERRNO("%s: failed to open", config_path); return NULL; diff --git a/modules/backlight.c b/modules/backlight.c index 0fa1787..1495c5c 100644 --- a/modules/backlight.c +++ b/modules/backlight.c @@ -112,13 +112,13 @@ readint_from_fd(int fd) static int initialize(struct private *m) { - int backlight_fd = open("/sys/class/backlight", O_RDONLY); + int backlight_fd = open("/sys/class/backlight", O_RDONLY | O_CLOEXEC); if (backlight_fd == -1) { LOG_ERRNO("/sys/class/backlight"); return -1; } - int base_dir_fd = openat(backlight_fd, m->device, O_RDONLY); + int base_dir_fd = openat(backlight_fd, m->device, O_RDONLY | O_CLOEXEC); close(backlight_fd); if (base_dir_fd == -1) { @@ -126,7 +126,7 @@ initialize(struct private *m) return -1; } - int max_fd = openat(base_dir_fd, "max_brightness", O_RDONLY); + int max_fd = openat(base_dir_fd, "max_brightness", O_RDONLY | O_CLOEXEC); if (max_fd == -1) { LOG_ERRNO("/sys/class/backlight/%s/max_brightness", m->device); close(base_dir_fd); @@ -136,7 +136,7 @@ initialize(struct private *m) m->max_brightness = readint_from_fd(max_fd); close(max_fd); - int current_fd = openat(base_dir_fd, "brightness", O_RDONLY); + int current_fd = openat(base_dir_fd, "brightness", O_RDONLY | O_CLOEXEC); close(base_dir_fd); if (current_fd == -1) { diff --git a/modules/battery.c b/modules/battery.c index c3507d7..34b98c8 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -259,13 +259,13 @@ initialize(struct private *m) { char line_buf[512]; - int pw_fd = open("/sys/class/power_supply", O_RDONLY); + int pw_fd = open("/sys/class/power_supply", O_RDONLY | O_CLOEXEC); if (pw_fd < 0) { LOG_ERRNO("/sys/class/power_supply"); return false; } - int base_dir_fd = openat(pw_fd, m->battery, O_RDONLY); + int base_dir_fd = openat(pw_fd, m->battery, O_RDONLY | O_CLOEXEC); close(pw_fd); if (base_dir_fd < 0) { @@ -274,7 +274,7 @@ initialize(struct private *m) } { - int fd = openat(base_dir_fd, "manufacturer", O_RDONLY); + int fd = openat(base_dir_fd, "manufacturer", O_RDONLY | O_CLOEXEC); if (fd == -1) { LOG_WARN("/sys/class/power_supply/%s/manufacturer: %s", m->battery, strerror(errno)); m->manufacturer = NULL; @@ -285,7 +285,7 @@ initialize(struct private *m) } { - int fd = openat(base_dir_fd, "model_name", O_RDONLY); + int fd = openat(base_dir_fd, "model_name", O_RDONLY | O_CLOEXEC); if (fd == -1) { LOG_WARN("/sys/class/power_supply/%s/model_name: %s", m->battery, strerror(errno)); m->model = NULL; @@ -298,7 +298,7 @@ initialize(struct private *m) if (faccessat(base_dir_fd, "energy_full_design", O_RDONLY, 0) == 0 && faccessat(base_dir_fd, "energy_full", O_RDONLY, 0) == 0) { { - int fd = openat(base_dir_fd, "energy_full_design", O_RDONLY); + int fd = openat(base_dir_fd, "energy_full_design", O_RDONLY | O_CLOEXEC); if (fd == -1) { LOG_ERRNO("/sys/class/power_supply/%s/energy_full_design", m->battery); goto err; @@ -309,7 +309,7 @@ initialize(struct private *m) } { - int fd = openat(base_dir_fd, "energy_full", O_RDONLY); + int fd = openat(base_dir_fd, "energy_full", O_RDONLY | O_CLOEXEC); if (fd == -1) { LOG_ERRNO("/sys/class/power_supply/%s/energy_full", m->battery); goto err; @@ -325,7 +325,7 @@ initialize(struct private *m) if (faccessat(base_dir_fd, "charge_full_design", O_RDONLY, 0) == 0 && faccessat(base_dir_fd, "charge_full", O_RDONLY, 0) == 0) { { - int fd = openat(base_dir_fd, "charge_full_design", O_RDONLY); + int fd = openat(base_dir_fd, "charge_full_design", O_RDONLY | O_CLOEXEC); if (fd == -1) { LOG_ERRNO("/sys/class/power_supply/%s/charge_full_design", m->battery); goto err; @@ -336,7 +336,7 @@ initialize(struct private *m) } { - int fd = openat(base_dir_fd, "charge_full", O_RDONLY); + int fd = openat(base_dir_fd, "charge_full", O_RDONLY | O_CLOEXEC); if (fd == -1) { LOG_ERRNO("/sys/class/power_supply/%s/charge_full", m->battery); goto err; @@ -362,13 +362,13 @@ update_status(struct module *mod) { struct private *m = mod->private; - int pw_fd = open("/sys/class/power_supply", O_RDONLY); + int pw_fd = open("/sys/class/power_supply", O_RDONLY | O_CLOEXEC); if (pw_fd < 0) { LOG_ERRNO("/sys/class/power_supply"); return false; } - int base_dir_fd = openat(pw_fd, m->battery, O_RDONLY); + int base_dir_fd = openat(pw_fd, m->battery, O_RDONLY | O_CLOEXEC); close(pw_fd); if (base_dir_fd < 0) { @@ -376,14 +376,14 @@ update_status(struct module *mod) return false; } - int status_fd = openat(base_dir_fd, "status", O_RDONLY); + int status_fd = openat(base_dir_fd, "status", O_RDONLY | O_CLOEXEC); if (status_fd < 0) { LOG_ERRNO("/sys/class/power_supply/%s/status", m->battery); close(base_dir_fd); return false; } - int capacity_fd = openat(base_dir_fd, "capacity", O_RDONLY); + int capacity_fd = openat(base_dir_fd, "capacity", O_RDONLY | O_CLOEXEC); if (capacity_fd < 0) { LOG_ERRNO("/sys/class/power_supply/%s/capacity", m->battery); close(status_fd); @@ -391,12 +391,12 @@ update_status(struct module *mod) return false; } - int energy_fd = openat(base_dir_fd, "energy_now", O_RDONLY); - int power_fd = openat(base_dir_fd, "power_now", O_RDONLY); - int charge_fd = openat(base_dir_fd, "charge_now", O_RDONLY); - int current_fd = openat(base_dir_fd, "current_now", O_RDONLY); - int time_to_empty_fd = openat(base_dir_fd, "time_to_empty_now", O_RDONLY); - int time_to_full_fd = openat(base_dir_fd, "time_to_full_now", O_RDONLY); + int energy_fd = openat(base_dir_fd, "energy_now", O_RDONLY | O_CLOEXEC); + int power_fd = openat(base_dir_fd, "power_now", O_RDONLY | O_CLOEXEC); + int charge_fd = openat(base_dir_fd, "charge_now", O_RDONLY | O_CLOEXEC); + int current_fd = openat(base_dir_fd, "current_now", O_RDONLY | O_CLOEXEC); + int time_to_empty_fd = openat(base_dir_fd, "time_to_empty_now", O_RDONLY | O_CLOEXEC); + int time_to_full_fd = openat(base_dir_fd, "time_to_full_now", O_RDONLY | O_CLOEXEC); long capacity = readint_from_fd(capacity_fd); long energy = energy_fd >= 0 ? readint_from_fd(energy_fd) : -1; diff --git a/modules/cpu.c b/modules/cpu.c index 833c188..118361e 100644 --- a/modules/cpu.c +++ b/modules/cpu.c @@ -124,7 +124,7 @@ refresh_cpu_stats(struct cpu_stats *cpu_stats, size_t core_count) size_t len = 0; ssize_t read; - fp = fopen("/proc/stat", "r"); + fp = fopen("/proc/stat", "re"); if (NULL == fp) { LOG_ERRNO("unable to open /proc/stat"); return; diff --git a/modules/disk-io.c b/modules/disk-io.c index 015715f..c33cbef 100644 --- a/modules/disk-io.c +++ b/modules/disk-io.c @@ -105,7 +105,7 @@ refresh_device_stats(struct private *m) size_t len = 0; ssize_t read; - fp = fopen("/proc/diskstats", "r"); + fp = fopen("/proc/diskstats", "re"); if (NULL == fp) { LOG_ERRNO("unable to open /proc/diskstats"); return; diff --git a/modules/dwl.c b/modules/dwl.c index a0d5797..3b1bdcc 100644 --- a/modules/dwl.c +++ b/modules/dwl.c @@ -330,7 +330,7 @@ run_init(int *inotify_fd, int *inotify_wd, FILE **file, char *dwl_info_filename) return 1; } - *file = fopen(dwl_info_filename, "r"); + *file = fopen(dwl_info_filename, "re"); if (*file == NULL) { inotify_rm_watch(*inotify_fd, *inotify_wd); close(*inotify_fd); diff --git a/modules/i3.c b/modules/i3.c index b1d1ca8..47f6d99 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -664,7 +664,7 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m char path[64]; snprintf(path, sizeof(path), "/proc/%u/comm", ws->window.pid); - int fd = open(path, O_RDONLY); + int fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) { /* Application may simply have terminated */ free(ws->window.application); diff --git a/modules/mem.c b/modules/mem.c index dc9bcf8..de4e133 100644 --- a/modules/mem.c +++ b/modules/mem.c @@ -54,7 +54,7 @@ get_mem_stats(uint64_t *mem_free, uint64_t *mem_total) size_t len = 0; ssize_t read = 0; - fp = fopen("/proc/meminfo", "r"); + fp = fopen("/proc/meminfo", "re"); if (NULL == fp) { LOG_ERRNO("unable to open /proc/meminfo"); return false; diff --git a/modules/network.c b/modules/network.c index 1b2ceba..46a3148 100644 --- a/modules/network.c +++ b/modules/network.c @@ -1576,7 +1576,7 @@ out: static struct module * network_new(struct particle *label, int poll_interval, int left_spacing, int right_spacing) { - int urandom_fd = open("/dev/urandom", O_RDONLY); + int urandom_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); if (urandom_fd < 0) { LOG_ERRNO("failed to open /dev/urandom"); return NULL; diff --git a/modules/pulse.c b/modules/pulse.c index e605dea..f6c7f69 100644 --- a/modules/pulse.c +++ b/modules/pulse.c @@ -438,7 +438,7 @@ run(struct module *mod) } // Create refresh timer. - priv->refresh_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + priv->refresh_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); if (priv->refresh_timer_fd < 0) { LOG_ERRNO("failed to create timerfd"); pa_mainloop_free(priv->mainloop); diff --git a/modules/removables.c b/modules/removables.c index e4ef98e..a4fb4ad 100644 --- a/modules/removables.c +++ b/modules/removables.c @@ -162,7 +162,7 @@ static void find_mount_points(const char *dev_path, mount_point_list_t *mount_points) { int fd = open("/proc/self/mountinfo", O_RDONLY | O_CLOEXEC); - FILE *f = fd >= 0 ? fdopen(fd, "r") : NULL; + FILE *f = fd >= 0 ? fdopen(fd, "re") : NULL; if (fd < 0 || f == NULL) { LOG_ERRNO("failed to open /proc/self/mountinfo"); diff --git a/modules/xwindow.c b/modules/xwindow.c index ffae527..c730128 100644 --- a/modules/xwindow.c +++ b/modules/xwindow.c @@ -130,7 +130,7 @@ update_application(struct module *mod) char path[1024]; snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); - int fd = open(path, O_RDONLY); + int fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) return; From 3e0083c9f21a276840e3487a0a6a85c71e185b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 23 Oct 2024 09:40:06 +0200 Subject: [PATCH 087/112] module/removables: no need to open+fdopen, just do fopen() --- modules/removables.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/removables.c b/modules/removables.c index a4fb4ad..df4ade4 100644 --- a/modules/removables.c +++ b/modules/removables.c @@ -161,13 +161,10 @@ content(struct module *mod) static void find_mount_points(const char *dev_path, mount_point_list_t *mount_points) { - int fd = open("/proc/self/mountinfo", O_RDONLY | O_CLOEXEC); - FILE *f = fd >= 0 ? fdopen(fd, "re") : NULL; + FILE *f = fopen("/proc/self/mountinfo", "re"); - if (fd < 0 || f == NULL) { + if (f == NULL) { LOG_ERRNO("failed to open /proc/self/mountinfo"); - if (fd >= 0) - close(fd); return; } From b15714b38a1ed58196046d4365c45e85f552a8ce Mon Sep 17 00:00:00 2001 From: Alexey Yerin Date: Sat, 23 Nov 2024 20:10:14 +0300 Subject: [PATCH 088/112] pipewire: Improve handling of node switching When switching to a node that has a missing property, yambar didn't reset its internal state to the default value, causing outdated information to be displayed. --- CHANGELOG.md | 2 ++ modules/pipewire.c | 55 ++++++++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09db85b..3192cec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,9 +50,11 @@ * mpd: yambar never attempting to reconnect after MPD closed the connection (for example, when MPD is restarted). * Bar positioning on multi-monitor setups, when `location=bottom`. +* pipewire: Improve handling of node switching ([#424][424]). [377]: https://codeberg.org/dnkl/yambar/issues/377 [300]: https://codeberg.org/dnkl/yambar/issues/300 +[424]: https://codeberg.org/dnkl/yambar/pulls/424 ### Security diff --git a/modules/pipewire.c b/modules/pipewire.c index e614a0a..98b96d8 100644 --- a/modules/pipewire.c +++ b/modules/pipewire.c @@ -45,6 +45,16 @@ struct output_informations { }; static struct output_informations const output_informations_null; +static void +output_informations_destroy(struct output_informations *output_informations) +{ + free(output_informations->name); + free(output_informations->description); + free(output_informations->icon); + free(output_informations->form_factor); + free(output_informations->bus); +} + struct data; struct private { @@ -213,18 +223,23 @@ node_find_route(struct data *data, bool is_sink) static void node_unhook_binded_node(struct data *data, bool is_sink) { + struct private *private = data->module->private; + struct node **target_node = NULL; struct spa_hook *target_listener = NULL; void **target_proxy = NULL; + struct output_informations *output_informations = NULL; if (is_sink) { target_node = &data->binded_sink; target_listener = &data->node_sink_listener; target_proxy = &data->node_sink; + output_informations = &private->sink_informations; } else { target_node = &data->binded_source; target_listener = &data->node_source_listener; target_proxy = &data->node_source; + output_informations = &private->source_informations; } if (*target_node == NULL) @@ -235,6 +250,9 @@ node_unhook_binded_node(struct data *data, bool is_sink) *target_node = NULL; *target_proxy = NULL; + + output_informations_destroy(output_informations); + *output_informations = output_informations_null; } static void @@ -398,18 +416,18 @@ node_events_info(void *userdata, struct pw_node_info const *info) struct spa_dict_item const *item = NULL; item = spa_dict_lookup_item(info->props, "node.name"); - if (item != NULL) - X_FREE_SET(output_informations->name, X_STRDUP(item->value)); + X_FREE_SET(output_informations->name, item != NULL ? X_STRDUP(item->value) : NULL); item = spa_dict_lookup_item(info->props, "node.description"); - if (item != NULL) - X_FREE_SET(output_informations->description, X_STRDUP(item->value)); + X_FREE_SET(output_informations->description, item != NULL ? X_STRDUP(item->value) : NULL); item = spa_dict_lookup_item(info->props, "device.id"); if (item != NULL) { uint32_t value = 0; spa_atou32(item->value, &value, 10); output_informations->device_id = value; + } else { + output_informations->device_id = 0; } item = spa_dict_lookup_item(info->props, "card.profile.device"); @@ -417,30 +435,29 @@ node_events_info(void *userdata, struct pw_node_info const *info) uint32_t value = 0; spa_atou32(item->value, &value, 10); output_informations->card_profile_device_id = value; + } else { + output_informations->card_profile_device_id = 0; } /* Device's information has an more important priority than node's information */ /* icon_name */ struct route *route = node_find_route(data, node_data->is_sink); if (route != NULL && route->icon_name != NULL) - output_informations->icon = X_STRDUP(route->icon_name); + X_FREE_SET(output_informations->icon, X_STRDUP(route->icon_name)); else { item = spa_dict_lookup_item(info->props, "device.icon-name"); - if (item != NULL) - X_FREE_SET(output_informations->icon, X_STRDUP(item->value)); + X_FREE_SET(output_informations->icon, item != NULL ? X_STRDUP(item->value) : NULL); } /* form_factor */ if (route != NULL && route->form_factor != NULL) - output_informations->form_factor = X_STRDUP(route->form_factor); + X_FREE_SET(output_informations->form_factor, X_STRDUP(route->form_factor)); else { item = spa_dict_lookup_item(info->props, "device.form-factor"); - if (item != NULL) - X_FREE_SET(output_informations->form_factor, X_STRDUP(item->value)); + X_FREE_SET(output_informations->form_factor, item != NULL ? X_STRDUP(item->value) : NULL); } item = spa_dict_lookup_item(info->props, "device.bus"); - if (item != NULL) - X_FREE_SET(output_informations->bus, X_STRDUP(item->value)); + X_FREE_SET(output_informations->bus, item != NULL ? X_STRDUP(item->value) : NULL); data->module->bar->refresh(data->module->bar); } @@ -827,18 +844,8 @@ destroy(struct module *module) pipewire_deinit(private->data); private->label->destroy(private->label); - /* sink */ - free(private->sink_informations.name); - free(private->sink_informations.description); - free(private->sink_informations.icon); - free(private->sink_informations.form_factor); - free(private->sink_informations.bus); - /* source */ - free(private->source_informations.name); - free(private->source_informations.description); - free(private->source_informations.icon); - free(private->source_informations.form_factor); - free(private->source_informations.bus); + output_informations_destroy(&private->sink_informations); + output_informations_destroy(&private->source_informations); free(private); module_default_destroy(module); From 57711f0dbe84f9c9b7f5e019813d0a9f52698d8d Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 24 Dec 2024 23:52:13 +0100 Subject: [PATCH 089/112] mpd: support the `single` flag This flag indicates that `mpd` will automatically stop after the current song is played. --- CHANGELOG.md | 2 ++ doc/yambar-modules-mpd.5.scd | 3 +++ modules/mpd.c | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3192cec..d16b477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,11 +26,13 @@ is on. * Added "string like" `~~` operator to Map particle. Allows glob-style matching on strings using `*` and `?` characters ([#400][400]). +* Added "single" mode flag to the `mpd` module ([#428][428]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 [392]: https://codeberg.org/dnkl/yambar/issues/392 [400]: https://codeberg.org/dnkl/yambar/pulls/400 +[428]: https://codeberg.org/dnkl/yambar/pulls/428 ### Changed diff --git a/doc/yambar-modules-mpd.5.scd b/doc/yambar-modules-mpd.5.scd index aff6227..d89407a 100644 --- a/doc/yambar-modules-mpd.5.scd +++ b/doc/yambar-modules-mpd.5.scd @@ -20,6 +20,9 @@ mpd - This module provides MPD status such as currently playing artist/album/son | consume : bool : True if the *consume* flag is set +| single +: bool +: True if the *single* flag is set | volume : range : Volume of MPD in percentage diff --git a/modules/mpd.c b/modules/mpd.c index 63da818..e70e41f 100644 --- a/modules/mpd.c +++ b/modules/mpd.c @@ -39,6 +39,7 @@ struct private bool repeat; bool random; bool consume; + bool single; int volume; char *album; char *artist; @@ -176,6 +177,7 @@ content(struct module *mod) tag_new_bool(mod, "repeat", m->repeat), tag_new_bool(mod, "random", m->random), tag_new_bool(mod, "consume", m->consume), + tag_new_bool(mod, "single", m->single), tag_new_int_range(mod, "volume", m->volume, 0, 100), tag_new_string(mod, "album", m->album), tag_new_string(mod, "artist", m->artist), @@ -187,7 +189,7 @@ content(struct module *mod) tag_new_int_realtime( mod, "elapsed", elapsed, 0, m->duration, realtime), }, - .count = 13, + .count = 14, }; mtx_unlock(&mod->lock); @@ -336,6 +338,7 @@ update_status(struct module *mod) m->repeat = mpd_status_get_repeat(status); m->random = mpd_status_get_random(status); m->consume = mpd_status_get_consume(status); + m->single = mpd_status_get_single_state(status) == MPD_SINGLE_ONESHOT; m->volume = mpd_status_get_volume(status); m->duration = mpd_status_get_total_time(status) * 1000; m->elapsed.value = mpd_status_get_elapsed_ms(status); From 61d082c802c46438be0c1b165367536290328c1c Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 24 Dec 2024 23:48:34 +0100 Subject: [PATCH 090/112] typos: fix some typos --- bar/xcb.c | 2 +- doc/yambar-decorations.5.scd | 2 +- doc/yambar-modules-disk-io.5.scd | 4 ++-- doc/yambar-modules-pipewire.5.scd | 4 ++-- doc/yambar-modules-script.5.scd | 2 +- doc/yambar-particles.5.scd | 2 +- doc/yambar.1.scd | 2 +- modules/pipewire.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bar/xcb.c b/bar/xcb.c index f3167a5..ae52bf3 100644 --- a/bar/xcb.c +++ b/bar/xcb.c @@ -369,7 +369,7 @@ refresh(const struct bar *_bar) /* Send an event to handle refresh from main thread */ - /* Note: docs say that all X11 events are 32 bytes, reglardless of + /* Note: docs say that all X11 events are 32 bytes, regardless of * the size of the event structure */ xcb_expose_event_t *evt = calloc(32, 1); diff --git a/doc/yambar-decorations.5.scd b/doc/yambar-decorations.5.scd index 9dd21b8..3d7c379 100644 --- a/doc/yambar-decorations.5.scd +++ b/doc/yambar-decorations.5.scd @@ -137,7 +137,7 @@ content: # STACK -This particles combines multiple decorations. +This particle combines multiple decorations. ## CONFIGURATION diff --git a/doc/yambar-modules-disk-io.5.scd b/doc/yambar-modules-disk-io.5.scd index 5203316..3f51e79 100644 --- a/doc/yambar-modules-disk-io.5.scd +++ b/doc/yambar-modules-disk-io.5.scd @@ -17,8 +17,8 @@ currently present in the machine. for the machine | is_disk : boolean -: whether or not the device is a disk (e.g. sda, sdb) or a partition - (e.g. sda1, sda2, ...). "Total" is advertised as a disk. +: whether or not the device is a disk (e.g., sda, sdb) or a partition + (e.g., sda1, sda2, ...). "Total" is advertised as a disk. | read_speed : int : bytes read, in bytes/s diff --git a/doc/yambar-modules-pipewire.5.scd b/doc/yambar-modules-pipewire.5.scd index be94489..ba79aaf 100644 --- a/doc/yambar-modules-pipewire.5.scd +++ b/doc/yambar-modules-pipewire.5.scd @@ -19,10 +19,10 @@ pipewire - Monitors pipewire for volume, mute/unmute, device change : Current device description | form_factor : string -: Current device form factor (headset, speaker, mic, etc) +: Current device form factor (headset, speaker, mic, etc.) | bus : string -: Current device bus (bluetooth, alsa, etc) +: Current device bus (bluetooth, alsa, etc.) | icon : string : Current device icon name diff --git a/doc/yambar-modules-script.5.scd b/doc/yambar-modules-script.5.scd index d27a006..48722cf 100644 --- a/doc/yambar-modules-script.5.scd +++ b/doc/yambar-modules-script.5.scd @@ -16,7 +16,7 @@ configurable amount of time. In continuous mode, the script is executed once. It will typically run in a loop, sending an updated tag set whenever it needs, or wants to. The last tag set is used (displayed) by yambar until a new tag set -is received. This mode is intended to be used by scripts that depends +is received. This mode is intended to be used by scripts that depend on non-polling methods to update their state. Tag sets, or _transactions_, are separated by an empty line diff --git a/doc/yambar-particles.5.scd b/doc/yambar-particles.5.scd index 231b419..325ef89 100644 --- a/doc/yambar-particles.5.scd +++ b/doc/yambar-particles.5.scd @@ -155,7 +155,7 @@ content: This particle is a list (or sequence, if you like) of other particles. It can be used to render e.g. _string_ particles with -different font and/or color formatting. Or ay other particle +different font and/or color formatting. Or any other particle combinations. But note that this means you *cannot* set any attributes on the _list_ diff --git a/doc/yambar.1.scd b/doc/yambar.1.scd index 549b980..2aaa46f 100644 --- a/doc/yambar.1.scd +++ b/doc/yambar.1.scd @@ -25,7 +25,7 @@ yambar - modular status panel for X11 and Wayland *-p*,*--print-pid*=_FILE_|_FD_ Print PID to this file, or FD, when successfully started. The file (or FD) is closed immediately after writing the PID. When a _FILE_ - as been specified, the file is unlinked exit. + as been specified, the file is unlinked upon exiting. *-d*,*--log-level*={*info*,*warning*,*error*,*none*} Log level, used both for log output on stderr as well as diff --git a/modules/pipewire.c b/modules/pipewire.c index 98b96d8..a2fdcae 100644 --- a/modules/pipewire.c +++ b/modules/pipewire.c @@ -368,7 +368,7 @@ device_events_param(void *userdata, int seq, uint32_t id, uint32_t index, uint32 if (binded_node == NULL) return; - /* Node's device is the the same as route's device */ + /* Node's device is the same as route's device */ if (output_informations->device_id != route->device->id) return; From d746d12f6a36a93f8a2205ea03ccb4e4e06876af Mon Sep 17 00:00:00 2001 From: vova Date: Tue, 3 Sep 2024 21:18:05 +0200 Subject: [PATCH 091/112] add niri-workspaces and niri-language modules --- CHANGELOG.md | 2 + doc/meson.build | 6 + doc/yambar-modules-niri-language.5.scd | 34 ++ doc/yambar-modules-niri-workspaces.5.scd | 60 ++++ doc/yambar-modules.5.scd | 4 + meson.build | 2 + meson_options.txt | 4 + modules/meson.build | 14 + modules/niri-common.c | 377 +++++++++++++++++++++++ modules/niri-common.h | 45 +++ modules/niri-language.c | 160 ++++++++++ modules/niri-workspaces.c | 163 ++++++++++ plugin.c | 12 + 13 files changed, 883 insertions(+) create mode 100644 doc/yambar-modules-niri-language.5.scd create mode 100644 doc/yambar-modules-niri-workspaces.5.scd create mode 100644 modules/niri-common.c create mode 100644 modules/niri-common.h create mode 100644 modules/niri-language.c create mode 100644 modules/niri-workspaces.c diff --git a/CHANGELOG.md b/CHANGELOG.md index d16b477..aec47c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,12 +27,14 @@ * Added "string like" `~~` operator to Map particle. Allows glob-style matching on strings using `*` and `?` characters ([#400][400]). * Added "single" mode flag to the `mpd` module ([#428][428]). +* niri: add a new module for niri-workspaces and niri-language ([#405][405]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 [392]: https://codeberg.org/dnkl/yambar/issues/392 [400]: https://codeberg.org/dnkl/yambar/pulls/400 [428]: https://codeberg.org/dnkl/yambar/pulls/428 +[405]: https://codeberg.org/dnkl/yambar/issues/405 ### Changed diff --git a/doc/meson.build b/doc/meson.build index e5728ab..90a83ec 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -44,6 +44,12 @@ endif if plugin_network_enabled plugin_pages += ['yambar-modules-network.5.scd'] endif +if plugin_niri_language_enabled + plugin_pages += ['yambar-modules-niri-language.5.scd'] +endif +if plugin_niri_workspaces_enabled + plugin_pages += ['yambar-modules-niri-workspaces.5.scd'] +endif if plugin_pipewire_enabled plugin_pages += ['yambar-modules-pipewire.5.scd'] endif diff --git a/doc/yambar-modules-niri-language.5.scd b/doc/yambar-modules-niri-language.5.scd new file mode 100644 index 0000000..befa41e --- /dev/null +++ b/doc/yambar-modules-niri-language.5.scd @@ -0,0 +1,34 @@ +yambar-modules-niri-language(5) + +# NAME +niri-language - This module provides information about niri's currently +selected language. + +# TAGS + +[[ *Name* +:[ *Type* +:< *Description* +| language +: string +: The currently selected language. + +# CONFIGURATION + +No additional attributes supported, only the generic ones (see +*GENERIC CONFIGURATION* in *yambar-modules*(5)) + +# EXAMPLES + +``` +bar: + left: + - niri-language: + content: + string: {text: "{language}"} +``` + +# SEE ALSO + +*yambar-modules*(5), *yambar-particles*(5), *yambar-tags*(5), *yambar-decorations*(5) + diff --git a/doc/yambar-modules-niri-workspaces.5.scd b/doc/yambar-modules-niri-workspaces.5.scd new file mode 100644 index 0000000..812bade --- /dev/null +++ b/doc/yambar-modules-niri-workspaces.5.scd @@ -0,0 +1,60 @@ +yambar-modules-niri-workspaces(5) + +# NAME +niri-workspaces - This module provides information about niri workspaces. + +# DESCRIPTION + +This module provides a map of each workspace present in niri. + +Each workspace has its _id_, _name_, and its status (_focused_, +_active_, _empty_). The workspaces are sorted by their ids. + +This module will *only* track the monitor where yambar was launched. +If you have a multi monitor setup, please launch yambar on each +individual monitor to track its workspaces. + +# TAGS + +[[ *Name* +:[ *Type* +:< *Description* +| id +: int +: The workspace id. +| name +: string +: The name of the workspace. +| active +: bool +: True if the workspace is currently visible on the current output. +| focused +: bool +: True if the workspace is currently focused. +| empty +: bool +: True if the workspace contains no window. + +# CONFIGURATION + +No additional attributes supported, only the generic ones (see +*GENERIC CONFIGURATION* in *yambar-modules*(5)) + +# EXAMPLES + +``` +bar: + left: + - niri-workspaces: + content: + map: + default: {string: {text: "| {id}"}} + conditions: + active: {string: {text: "-> {id}"}} + ~empty: {string: {text: "@ {id}"}} +``` + +# SEE ALSO + +*yambar-modules*(5), *yambar-particles*(5), *yambar-tags*(5), *yambar-decorations*(5) + diff --git a/doc/yambar-modules.5.scd b/doc/yambar-modules.5.scd index 765d06f..1ec4871 100644 --- a/doc/yambar-modules.5.scd +++ b/doc/yambar-modules.5.scd @@ -174,6 +174,10 @@ Available modules have their own pages: *yambar-modules-sway*(5) +*yambar-modules-niri-language*(5) + +*yambar-modules-niri-workspaces*(5) + *yambar-modules-xkb*(5) *yambar-modules-xwindow*(5) diff --git a/meson.build b/meson.build index d9b1364..81af577 100644 --- a/meson.build +++ b/meson.build @@ -189,6 +189,8 @@ summary( 'River': plugin_river_enabled, 'Script': plugin_script_enabled, 'Sway XKB keyboard': plugin_sway_xkb_enabled, + 'Niri language': plugin_niri_language_enabled, + 'Niri workspaces': plugin_niri_workspaces_enabled, 'XKB keyboard (for X11)': plugin_xkb_enabled, 'XWindow (window tracking for X11)': plugin_xwindow_enabled, }, diff --git a/meson_options.txt b/meson_options.txt index a9aac05..9fd0dd5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -44,6 +44,10 @@ option('plugin-script', type: 'feature', value: 'auto', description: 'Script support') option('plugin-sway-xkb', type: 'feature', value: 'auto', description: 'keyboard support for Sway') +option('plugin-niri-language', type: 'feature', value: 'auto', + description: 'language support for Niri') +option('plugin-niri-workspaces', type: 'feature', value: 'auto', + description: 'workspaces support for Niri') option('plugin-xkb', type: 'feature', value: 'auto', description: 'keyboard support for X11') option('plugin-xwindow', type: 'feature', value: 'auto', diff --git a/modules/meson.build b/modules/meson.build index e2ed56e..b54e9d7 100644 --- a/modules/meson.build +++ b/modules/meson.build @@ -45,6 +45,12 @@ plugin_script_enabled = get_option('plugin-script').allowed() json_sway_xkb = dependency('json-c', required: get_option('plugin-sway-xkb')) plugin_sway_xkb_enabled = json_sway_xkb.found() +json_niri_language = dependency('json-c', required: get_option('plugin-niri-language')) +plugin_niri_language_enabled = json_niri_language.found() + +json_niri_workspaces = dependency('json-c', required: get_option('plugin-niri-workspaces')) +plugin_niri_workspaces_enabled = json_niri_workspaces.found() + xcb_xkb = dependency('xcb-xkb', required: get_option('plugin-xkb')) plugin_xkb_enabled = backend_x11 and xcb_xkb.found() @@ -121,6 +127,14 @@ if plugin_sway_xkb_enabled mod_data += {'sway-xkb': [['i3-common.c', 'i3-common.h'], [dynlist, json_sway_xkb]]} endif +if plugin_niri_language_enabled + mod_data += {'niri-language': [['niri-common.c', 'niri-common.h'], [dynlist, json_niri_language]]} +endif + +if plugin_niri_workspaces_enabled + mod_data += {'niri-workspaces': [['niri-common.c', 'niri-common.h'], [dynlist, json_niri_workspaces]]} +endif + if plugin_xkb_enabled mod_data += {'xkb': [[], [xcb_stuff, xcb_xkb]]} endif diff --git a/modules/niri-common.c b/modules/niri-common.c new file mode 100644 index 0000000..ac53921 --- /dev/null +++ b/modules/niri-common.c @@ -0,0 +1,377 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../log.h" +#include "niri-common.h" + +#define LOG_MODULE "niri:common" +#define LOG_ENABLE_DBG 0 + +static struct niri_socket instance = { + .fd = -1, + .abort_fd = -1, +}; + +static void +workspace_free(struct niri_workspace *workspace) +{ + free(workspace->name); + free(workspace); +} + +static void +parser(char *response) +{ + enum json_tokener_error error = json_tokener_success; + struct json_object *json = json_tokener_parse_verbose(response, &error); + if (error != json_tokener_success) { + LOG_WARN("failed to parse niri socket's response"); + return; + } + + enum niri_event events = 0; + struct json_object_iterator it = json_object_iter_begin(json); + struct json_object_iterator end = json_object_iter_end(json); + while (!json_object_iter_equal(&it, &end)) { + char const *key = json_object_iter_peek_name(&it); + + // "WorkspacesChanged": { + // "workspaces": [ + // { + // "id": 3, + // "idx": 1, + // "name": null, + // "output": "DP-4", + // "is_active": true, + // "is_focused": true, + // "active_window_id": 24 + // }, + // ... + // ] + // } + if (strcmp(key, "WorkspacesChanged") == 0) { + mtx_lock(&instance.mtx); + tll_foreach(instance.workspaces, it) { tll_remove_and_free(instance.workspaces, it, workspace_free); } + mtx_unlock(&instance.mtx); + + json_object *obj = json_object_iter_peek_value(&it); + json_object *workspaces = json_object_object_get(obj, "workspaces"); + + size_t length = json_object_array_length(workspaces); + for (size_t i = 0; i < length; ++i) { + json_object *ws_obj = json_object_array_get_idx(workspaces, i); + + // only add workspaces on the current yambar's monitor + struct json_object *output = json_object_object_get(ws_obj, "output"); + if (strcmp(instance.monitor, json_object_get_string(output)) != 0) + continue; + + struct niri_workspace *ws = calloc(1, sizeof(*ws)); + ws->idx = json_object_get_int(json_object_object_get(ws_obj, "idx")); + ws->id = json_object_get_int(json_object_object_get(ws_obj, "id")); + ws->active = json_object_get_boolean(json_object_object_get(ws_obj, "is_active")); + ws->focused = json_object_get_boolean(json_object_object_get(ws_obj, "is_focused")); + ws->empty = json_object_get_int(json_object_object_get(ws_obj, "active_window_id")) == 0; + + char const *name = json_object_get_string(json_object_object_get(ws_obj, "name")); + if (name) + ws->name = strdup(name); + + mtx_lock(&instance.mtx); + bool inserted = false; + tll_foreach(instance.workspaces, it) + { + if (it->item->idx > ws->idx) { + tll_insert_before(instance.workspaces, it, ws); + inserted = true; + break; + } + } + if (!inserted) + tll_push_back(instance.workspaces, ws); + mtx_unlock(&instance.mtx); + + events |= workspaces_changed; + } + } + + // "WorkspaceActivated": { + // "id": 7, + // "focused":true + // } + else if (strcmp(key, "WorkspaceActivated") == 0) { + json_object *obj = json_object_iter_peek_value(&it); + int id = json_object_get_int(json_object_object_get(obj, "id")); + + mtx_lock(&instance.mtx); + tll_foreach(instance.workspaces, it) + { + bool b = it->item->id == id; + it->item->focused = b; + it->item->active = b; + } + mtx_unlock(&instance.mtx); + + events |= workspace_activated; + } + + // "WorkspaceActiveWindowChanged": { + // "workspace_id": 3, + // "active_window_id": 8 + // } + else if (strcmp(key, "WorkspaceActiveWindowChanged") == 0) { + json_object *obj = json_object_iter_peek_value(&it); + int id = json_object_get_int(json_object_object_get(obj, "id")); + bool empty = json_object_get_int(json_object_object_get(obj, "active_window_id")) == 0; + + mtx_lock(&instance.mtx); + tll_foreach(instance.workspaces, it) + { + if (it->item->id == id) { + it->item->empty = empty; + break; + } + } + mtx_unlock(&instance.mtx); + + events |= workspace_active_window_changed; + } + + // + // "KeyboardLayoutsChanged": { + // "keyboard_layouts": { + // "names": [ + // "English (US)", + // "Russian" + // ], + // "current_idx": 0 + // } + // } + else if (strcmp(key, "KeyboardLayoutsChanged") == 0) { + tll_foreach(instance.keyboard_layouts, it) { tll_remove_and_free(instance.keyboard_layouts, it, free); } + + json_object *obj = json_object_iter_peek_value(&it); + json_object *kb_layouts = json_object_object_get(obj, "keyboard_layouts"); + + instance.keyboard_layout_index = json_object_get_int(json_object_object_get(kb_layouts, "current_idx")); + + json_object *names = json_object_object_get(kb_layouts, "names"); + size_t names_length = json_object_array_length(names); + for (size_t i = 0; i < names_length; ++i) { + char const *name = json_object_get_string(json_object_array_get_idx(names, i)); + tll_push_back(instance.keyboard_layouts, strdup(name)); + } + + events |= keyboard_layouts_changed; + } + + // "KeyboardLayoutSwitched": { + // "idx": 1 + // } + else if (strcmp(key, "KeyboardLayoutSwitched") == 0) { + json_object *obj = json_object_iter_peek_value(&it); + instance.keyboard_layout_index = json_object_get_int(json_object_object_get(obj, "idx")); + + events |= keyboard_layouts_switched; + } + + json_object_iter_next(&it); + } + + json_object_put(json); + + mtx_lock(&instance.mtx); + tll_foreach(instance.subscribers, it) + { + if (it->item->events & events) + if (write(it->item->fd, &(uint64_t){1}, sizeof(uint64_t)) == -1) + LOG_ERRNO("failed to write"); + } + mtx_unlock(&instance.mtx); +} + +static int +run(void *userdata) +{ + static char msg[] = "\"EventStream\"\n"; + static char expected[] = "{\"Ok\":\"Handled\"}"; + + if (write(instance.fd, msg, sizeof(msg) / sizeof(msg[0])) == -1) { + LOG_ERRNO("failed to sent message to niri socket"); + return thrd_error; + } + + static char buffer[8192]; + if (read(instance.fd, buffer, sizeof(buffer) / sizeof(buffer[0]) - 1) == -1) { + LOG_ERRNO("failed to read response of niri socket"); + return thrd_error; + } + + char *saveptr; + char *response = strtok_r(buffer, "\n", &saveptr); + if (response == NULL || strcmp(expected, response) != 0) { + // unexpected first response, something went wrong + LOG_ERR("unexpected response of niri socket"); + return thrd_error; + } + + while ((response = strtok_r(NULL, "\n", &saveptr)) != NULL) + parser(response); + + while (true) { + struct pollfd fds[] = { + (struct pollfd){.fd = instance.abort_fd, .events = POLLIN}, + (struct pollfd){.fd = instance.fd, .events = POLLIN}, + }; + + if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) == -1) { + if (errno == EINTR) + continue; + + LOG_ERRNO("failed to poll"); + break; + } + + if (fds[0].revents & POLLIN) + break; + + static char buffer[8192]; + ssize_t length = read(fds[1].fd, buffer, sizeof(buffer) / sizeof(buffer[0])); + + if (length == 0) + break; + + if (length == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + + LOG_ERRNO("unable to read niri socket"); + break; + } + + buffer[length] = '\0'; + saveptr = NULL; + response = strtok_r(buffer, "\n", &saveptr); + do { + parser(response); + } while ((response = strtok_r(NULL, "\n", &saveptr)) != NULL); + } + + return thrd_success; +} + +struct niri_socket * +niri_socket_open(char const *monitor) +{ + if (instance.fd >= 0) + return &instance; + + char const *path = getenv("NIRI_SOCKET"); + if (path == NULL) { + LOG_ERR("NIRI_SOCKET is empty. Is niri running?"); + return NULL; + } + + if ((instance.fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) { + LOG_ERRNO("failed to create socket"); + goto error; + } + + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; + strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); + + if (connect(instance.fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + LOG_ERRNO("failed to connect to niri socket"); + goto error; + } + + if ((instance.abort_fd = eventfd(0, EFD_CLOEXEC)) == -1) { + LOG_ERRNO("failed to create abort_fd"); + goto error; + } + + if (mtx_init(&instance.mtx, mtx_plain) != thrd_success) { + LOG_ERR("failed to initialize mutex"); + goto error; + } + + if (thrd_create(&instance.thrd, run, NULL) != thrd_success) { + LOG_ERR("failed to create thread"); + mtx_destroy(&instance.mtx); + goto error; + } + + instance.monitor = monitor; + + return &instance; + +error: + if (instance.fd >= 0) + close(instance.fd); + if (instance.abort_fd >= 0) + close(instance.abort_fd); + instance.fd = -1; + instance.abort_fd = -1; + instance.monitor = NULL; + + return NULL; +} + +static void +socket_close(void) +{ + if (write(instance.abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) + LOG_ERRNO("failed to write to abort_fd"); + + thrd_join(instance.thrd, NULL); + + close(instance.abort_fd); + close(instance.fd); + instance.abort_fd = -1; + instance.fd = -1; + + mtx_destroy(&instance.mtx); + + tll_free_and_free(instance.subscribers, free); + tll_free_and_free(instance.workspaces, workspace_free); + tll_free_and_free(instance.keyboard_layouts, free); +} + +void +niri_socket_close(void) +{ + static once_flag flag = ONCE_FLAG_INIT; + call_once(&flag, socket_close); +} + +int +niri_socket_subscribe(enum niri_event events) +{ + int fd = eventfd(0, EFD_CLOEXEC); + if (fd == -1) { + LOG_ERRNO("failed to create eventfd"); + return -1; + } + + struct niri_subscriber *subscriber = calloc(1, sizeof(*subscriber)); + subscriber->events = events; + subscriber->fd = fd; + + mtx_lock(&instance.mtx); + tll_push_back(instance.subscribers, subscriber); + mtx_unlock(&instance.mtx); + + return subscriber->fd; +} diff --git a/modules/niri-common.h b/modules/niri-common.h new file mode 100644 index 0000000..18afe38 --- /dev/null +++ b/modules/niri-common.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +enum niri_event { + workspaces_changed = (1 << 0), + workspace_activated = (1 << 1), + workspace_active_window_changed = (1 << 2), + keyboard_layouts_changed = (1 << 3), + keyboard_layouts_switched = (1 << 4), +}; + +struct niri_subscriber { + int events; + int fd; +}; + +struct niri_workspace { + int id; + int idx; + char *name; + bool active; + bool focused; + bool empty; +}; + +struct niri_socket { + char const *monitor; + int abort_fd; + int fd; + + tll(struct niri_subscriber *) subscribers; + tll(struct niri_workspace *) workspaces; + tll(char *) keyboard_layouts; + size_t keyboard_layout_index; + + thrd_t thrd; + mtx_t mtx; +}; + +struct niri_socket *niri_socket_open(char const *monitor); +void niri_socket_close(void); +int niri_socket_subscribe(enum niri_event events); diff --git a/modules/niri-language.c b/modules/niri-language.c new file mode 100644 index 0000000..f8138ee --- /dev/null +++ b/modules/niri-language.c @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include + +#define LOG_MODULE "niri-language" +#define LOG_ENABLE_DBG 0 +#include "niri-common.h" + +#include "../log.h" +#include "../particles/dynlist.h" +#include "../plugin.h" + +struct private +{ + struct particle *label; + struct niri_socket *niri; +}; + +static void +destroy(struct module *module) +{ + struct private *private = module->private; + private->label->destroy(private->label); + + free(private); + + module_default_destroy(module); +} + +static const char * +description(const struct module *module) +{ + return "niri-lang"; +} + +static struct exposable * +content(struct module *module) +{ + const struct private *private = module->private; + + if (private->niri == NULL) + return dynlist_exposable_new(&((struct exposable *){0}), 0, 0, 0); + + mtx_lock(&module->lock); + mtx_lock(&private->niri->mtx); + + char *name = "???"; + size_t i = 0; + tll_foreach(private->niri->keyboard_layouts, it) + { + if (i++ == private->niri->keyboard_layout_index) + name = it->item; + } + + struct tag_set tags = { + .tags = (struct tag *[]){tag_new_string(module, "language", name)}, + .count = 1, + }; + + struct exposable *exposable = private->label->instantiate(private->label, &tags); + tag_set_destroy(&tags); + mtx_unlock(&private->niri->mtx); + mtx_unlock(&module->lock); + return exposable; +} + +static int +run(struct module *module) +{ + struct private *private = module->private; + + /* Ugly, but I didn't find better way for waiting + * the monitor's name to be set */ + char const *monitor; + do { + monitor = module->bar->output_name(module->bar); + usleep(50); + } while (monitor == NULL); + + private->niri = niri_socket_open(monitor); + if (private->niri == NULL) + return 1; + + int fd = niri_socket_subscribe(keyboard_layouts_changed | keyboard_layouts_switched); + if (fd == -1) { + niri_socket_close(); + return 1; + } + + module->bar->refresh(module->bar); + + while (true) { + struct pollfd fds[] = { + (struct pollfd){.fd = module->abort_fd, .events = POLLIN}, + (struct pollfd){.fd = fd, .events = POLLIN}, + }; + + if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) == -1) { + if (errno == EINTR) + continue; + + LOG_ERRNO("failed to poll"); + break; + } + + if (fds[0].revents & POLLIN) + break; + + if (read(fds[1].fd, &(uint64_t){0}, sizeof(uint64_t)) == -1) + LOG_ERRNO("failed to read from eventfd"); + + module->bar->refresh(module->bar); + } + + niri_socket_close(); + return 0; +} + +static struct module * +niri_language_new(struct particle *label) +{ + struct private *private = calloc(1, sizeof(struct private)); + private->label = label; + + struct module *module = module_common_new(); + module->private = private; + module->run = &run; + module->destroy = &destroy; + module->content = &content; + module->description = &description; + + return module; +} + +static struct module * +from_conf(struct yml_node const *node, struct conf_inherit inherited) +{ + struct yml_node const *content = yml_get_value(node, "content"); + return niri_language_new(conf_to_particle(content, inherited)); +} + +static bool +verify_conf(keychain_t *chain, const struct yml_node *node) +{ + static struct attr_info const attrs[] = { + MODULE_COMMON_ATTRS, + }; + return conf_verify_dict(chain, node, attrs); +} + +const struct module_iface module_niri_language_iface = { + .verify_conf = &verify_conf, + .from_conf = &from_conf, +}; + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) +extern const struct module_iface iface __attribute__((weak, alias("module_niri_language_iface"))); +#endif diff --git a/modules/niri-workspaces.c b/modules/niri-workspaces.c new file mode 100644 index 0000000..bca0150 --- /dev/null +++ b/modules/niri-workspaces.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include + +#define LOG_MODULE "niri-workspaces" +#define LOG_ENABLE_DBG 0 +#include "niri-common.h" + +#include "../log.h" +#include "../particles/dynlist.h" +#include "../plugin.h" + +struct private +{ + struct particle *label; + struct niri_socket *niri; +}; + +static void +destroy(struct module *module) +{ + struct private *private = module->private; + private->label->destroy(private->label); + + free(private); + + module_default_destroy(module); +} + +static const char * +description(const struct module *module) +{ + return "niri-ws"; +} + +static struct exposable * +content(struct module *module) +{ + struct private const *private = module->private; + + if (private->niri == NULL) + return dynlist_exposable_new(&((struct exposable *){0}), 0, 0, 0); + + mtx_lock(&module->lock); + mtx_lock(&private->niri->mtx); + + size_t i = 0; + struct exposable *exposable[tll_length(private->niri->workspaces)]; + tll_foreach(private->niri->workspaces, it) + { + struct tag_set tags = { + .tags = (struct tag*[]){ + tag_new_int(module, "id", it->item->idx), + tag_new_string(module, "name", it->item->name), + tag_new_bool(module, "active", it->item->active), + tag_new_bool(module, "focused", it->item->focused), + tag_new_bool(module, "empty", it->item->empty), + }, + .count = 5, + }; + + exposable[i++] = private->label->instantiate(private->label, &tags); + tag_set_destroy(&tags); + } + + mtx_unlock(&private->niri->mtx); + mtx_unlock(&module->lock); + return dynlist_exposable_new(exposable, i, 0, 0); +} + +static int +run(struct module *module) +{ + struct private *private = module->private; + + /* Ugly, but I didn't find better way for waiting + * the monitor's name to be set */ + char const *monitor; + do { + monitor = module->bar->output_name(module->bar); + usleep(50); + } while (monitor == NULL); + + private->niri = niri_socket_open(monitor); + if (private->niri == NULL) + return 1; + + int fd = niri_socket_subscribe(workspaces_changed | workspace_activated | workspace_active_window_changed); + if (fd == -1) { + niri_socket_close(); + return 1; + } + + module->bar->refresh(module->bar); + + while (true) { + struct pollfd fds[] = { + (struct pollfd){.fd = module->abort_fd, .events = POLLIN}, + (struct pollfd){.fd = fd, .events = POLLIN}, + }; + + if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) == -1) { + if (errno == EINTR) + continue; + + LOG_ERRNO("failed to poll"); + break; + } + + if (fds[0].revents & POLLIN) + break; + + if (read(fds[1].fd, &(uint64_t){0}, sizeof(uint64_t)) == -1) + LOG_ERRNO("failed to read from eventfd"); + + module->bar->refresh(module->bar); + } + + niri_socket_close(); + return 0; +} + +static struct module * +niri_workspaces_new(struct particle *label) +{ + struct private *private = calloc(1, sizeof(struct private)); + private->label = label; + + struct module *module = module_common_new(); + module->private = private; + module->run = &run; + module->destroy = &destroy; + module->content = &content; + module->description = &description; + + return module; +} + +static struct module * +from_conf(struct yml_node const *node, struct conf_inherit inherited) +{ + struct yml_node const *content = yml_get_value(node, "content"); + return niri_workspaces_new(conf_to_particle(content, inherited)); +} + +static bool +verify_conf(keychain_t *chain, const struct yml_node *node) +{ + static struct attr_info const attrs[] = { + MODULE_COMMON_ATTRS, + }; + return conf_verify_dict(chain, node, attrs); +} + +const struct module_iface module_niri_workspaces_iface = { + .verify_conf = &verify_conf, + .from_conf = &from_conf, +}; + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) +extern const struct module_iface iface __attribute__((weak, alias("module_niri_workspaces_iface"))); +#endif diff --git a/plugin.c b/plugin.c index 8e75389..b1e268b 100644 --- a/plugin.c +++ b/plugin.c @@ -84,6 +84,12 @@ EXTERN_MODULE(script); #if defined(HAVE_PLUGIN_sway_xkb) EXTERN_MODULE(sway_xkb); #endif +#if defined(HAVE_PLUGIN_niri_language) +EXTERN_MODULE(niri_language); +#endif +#if defined(HAVE_PLUGIN_niri_workspaces) +EXTERN_MODULE(niri_workspaces); +#endif #if defined(HAVE_PLUGIN_xkb) EXTERN_MODULE(xkb); #endif @@ -214,6 +220,12 @@ static void __attribute__((constructor)) init(void) #if defined(HAVE_PLUGIN_sway_xkb) REGISTER_CORE_MODULE(sway-xkb, sway_xkb); #endif +#if defined(HAVE_PLUGIN_niri_language) + REGISTER_CORE_MODULE(niri-language, niri_language); +#endif +#if defined(HAVE_PLUGIN_niri_workspaces) + REGISTER_CORE_MODULE(niri-workspaces, niri_workspaces); +#endif #if defined(HAVE_PLUGIN_xkb) REGISTER_CORE_MODULE(xkb, xkb); #endif From e1f7c0292fadfcd369cf26da82f4c3504cc7f628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 1 Jan 2025 13:52:52 +0100 Subject: [PATCH 092/112] changelog: fix ref for #405 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aec47c4..74181de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ [392]: https://codeberg.org/dnkl/yambar/issues/392 [400]: https://codeberg.org/dnkl/yambar/pulls/400 [428]: https://codeberg.org/dnkl/yambar/pulls/428 -[405]: https://codeberg.org/dnkl/yambar/issues/405 +[405]: https://codeberg.org/dnkl/yambar/pulls/405 ### Changed From fc24ea225d0cb66c1e6949cecd584c21ad1af9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 1 Jan 2025 13:57:32 +0100 Subject: [PATCH 093/112] changelog: fix ref (again) for #405 - the issue number is #404 --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74181de..802c82b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,14 +27,15 @@ * Added "string like" `~~` operator to Map particle. Allows glob-style matching on strings using `*` and `?` characters ([#400][400]). * Added "single" mode flag to the `mpd` module ([#428][428]). -* niri: add a new module for niri-workspaces and niri-language ([#405][405]). +* niri: add a new module for niri-workspaces and niri-language + ([#404][404]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 [392]: https://codeberg.org/dnkl/yambar/issues/392 [400]: https://codeberg.org/dnkl/yambar/pulls/400 [428]: https://codeberg.org/dnkl/yambar/pulls/428 -[405]: https://codeberg.org/dnkl/yambar/pulls/405 +[404]: https://codeberg.org/dnkl/yambar/issues/404 ### Changed From 21f374d2eb6d7db915bda4ca3551169454b19531 Mon Sep 17 00:00:00 2001 From: Ralph Torres Date: Mon, 24 Feb 2025 04:59:37 +0000 Subject: [PATCH 094/112] module/pipewire: add spacing config --- doc/yambar-modules-pipewire.5.scd | 12 ++++++++++++ modules/pipewire.c | 22 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/doc/yambar-modules-pipewire.5.scd b/doc/yambar-modules-pipewire.5.scd index ba79aaf..8010449 100644 --- a/doc/yambar-modules-pipewire.5.scd +++ b/doc/yambar-modules-pipewire.5.scd @@ -43,6 +43,18 @@ pipewire - Monitors pipewire for volume, mute/unmute, device change :[ *Type* :[ *Req* :< *Description* +| left-spacing +: int +: no +: Space, in pixels, in the left side of each rendered volume +| right-spacing +: int +: no +: Space, in pixels, on the right side of each rendered volume +| spacing +: int +: no +: Short-hand for setting both _left-spacing_ and _right-spacing_ | content : particle : yes diff --git a/modules/pipewire.c b/modules/pipewire.c index a2fdcae..1ff3642 100644 --- a/modules/pipewire.c +++ b/modules/pipewire.c @@ -60,6 +60,8 @@ struct private { struct particle *label; struct data *data; + int left_spacing; + int right_spacing; /* pipewire related */ struct output_informations sink_informations; @@ -918,7 +920,7 @@ content(struct module *module) mtx_unlock(&module->lock); - return dynlist_exposable_new(exposables, exposables_length, 0, 0); + return dynlist_exposable_new(exposables, exposables_length, private->left_spacing, private->right_spacing); } static int @@ -965,11 +967,13 @@ run(struct module *module) } static struct module * -pipewire_new(struct particle *label) +pipewire_new(struct particle *label, int left_spacing, int right_spacing) { struct private *private = calloc(1, sizeof(struct private)); assert(private != NULL); private->label = label; + private->left_spacing = left_spacing; + private->right_spacing = right_spacing; struct module *module = module_common_new(); module->private = private; @@ -987,13 +991,25 @@ static struct module * from_conf(struct yml_node const *node, struct conf_inherit inherited) { struct yml_node const *content = yml_get_value(node, "content"); - return pipewire_new(conf_to_particle(content, inherited)); + struct yml_node const *spacing = yml_get_value(node, "spacing"); + struct yml_node const *left_spacing = yml_get_value(node, "left-spacing"); + struct yml_node const *right_spacing = yml_get_value(node, "right-spacing"); + + int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; + int right = spacing != NULL ? yml_value_as_int(spacing) + : right_spacing != NULL ? yml_value_as_int(right_spacing) + : 0; + + return pipewire_new(conf_to_particle(content, inherited), left, right); } static bool verify_conf(keychain_t *keychain, struct yml_node const *node) { static struct attr_info const attrs[] = { + {"spacing", false, &conf_verify_unsigned}, + {"left-spacing", false, &conf_verify_unsigned}, + {"right-spacing", false, &conf_verify_unsigned}, MODULE_COMMON_ATTRS, }; return conf_verify_dict(keychain, node, attrs); From 2eb1cda73337544bb0ff5782e3d43edf39371b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 5 Mar 2025 08:19:29 +0100 Subject: [PATCH 095/112] changelog: pipewire: spacing attributes --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 802c82b..20f637a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ * Added "single" mode flag to the `mpd` module ([#428][428]). * niri: add a new module for niri-workspaces and niri-language ([#404][404]). +* pipewire: added `spacing`, `left-spacing` and `right-spacing` + attributes. [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 From a242d3d56975189136a98a6feec8fde6728430e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 5 Mar 2025 08:21:03 +0100 Subject: [PATCH 096/112] ci: sr.ht: skip codespell (this is done in woodpecker) --- .builds/alpine-x64.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.builds/alpine-x64.yml b/.builds/alpine-x64.yml index e4ad80c..1703a3d 100644 --- a/.builds/alpine-x64.yml +++ b/.builds/alpine-x64.yml @@ -37,10 +37,6 @@ sources: # to: tasks: - - codespell: | - pip install codespell - cd yambar - ~/.local/bin/codespell README.md CHANGELOG.md *.c *.h doc/*.scd - fcft: | cd yambar/subprojects git clone https://codeberg.org/dnkl/fcft.git From b486088f77b6f4813a89e38afde77573d1a804e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 5 Mar 2025 08:21:54 +0100 Subject: [PATCH 097/112] examples: codespell: re-using -> reusing --- examples/configurations/laptop.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/configurations/laptop.conf b/examples/configurations/laptop.conf index e57ebb3..1bdd16c 100644 --- a/examples/configurations/laptop.conf +++ b/examples/configurations/laptop.conf @@ -4,7 +4,7 @@ # For X11/i3, you'll want to replace calls to swaymsg with i3-msg, and # the sway-xkb module with the xkb module. -# fonts we'll be re-using here and there +# fonts we'll be reusing here and there awesome: &awesome Font Awesome 6 Free:style=solid:pixelsize=14 awesome_brands: &awesome_brands Font Awesome 6 Brands:pixelsize=16 From 5a515eae99116be895634f9f0a5e9498ae7bce35 Mon Sep 17 00:00:00 2001 From: Nicholas Sudsgaard Date: Tue, 4 Mar 2025 13:42:11 +0900 Subject: [PATCH 098/112] bar/wayland: Add unused attribute to count This variable is only used in LOG_DBG which expands to nothing by default. Adding the unused attribute prevents the compiler from throwing an error (-Wunused-but-set-variable) when building. --- bar/wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar/wayland.c b/bar/wayland.c index 3d8e4e0..86ab252 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -1223,7 +1223,7 @@ loop(struct bar *_bar, void (*expose)(const struct bar *bar), bool do_expose = false; /* Coalesce “refresh” commands */ - size_t count = 0; + __attribute__((unused)) size_t count = 0; while (true) { uint8_t command; ssize_t r = read(backend->pipe_fds[0], &command, sizeof(command)); From b5450c3918d8a0c2c9ab6384de32933e7b5a4534 Mon Sep 17 00:00:00 2001 From: Nicholas Sudsgaard Date: Tue, 4 Mar 2025 14:46:08 +0900 Subject: [PATCH 099/112] modules/i3: Add unused attribute to focused This variable is only used in assert() which expands to nothing in release builds. Adding the unused attribute prevents the compiler from throwing an error (-Wunused-but-set-variable) when building. --- modules/i3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/i3.c b/modules/i3.c index 47f6d99..cbdafaf 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -594,7 +594,7 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m mtx_lock(&mod->lock); struct workspace *ws = NULL; - size_t focused = 0; + __attribute__((unused)) size_t focused = 0; tll_foreach(m->workspaces, it) { if (it->item.focused) { From c27de56beab0a4e6239894599138c931e4a8d4a6 Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Fri, 5 Jul 2024 23:22:20 +0200 Subject: [PATCH 100/112] Added 'MPRIS' module This commit adds the ability to display status information for MPRIS compatible music players. Closes #53 --- CHANGELOG.md | 2 + doc/meson.build | 3 + doc/yambar-modules-mpris.5.scd | 95 +++ meson.build | 10 +- meson_options.txt | 2 + modules/dbus.h | 13 + modules/meson.build | 7 + modules/mpris.c | 1129 ++++++++++++++++++++++++++++++++ plugin.c | 6 + 9 files changed, 1266 insertions(+), 1 deletion(-) create mode 100644 doc/yambar-modules-mpris.5.scd create mode 100644 modules/dbus.h create mode 100644 modules/mpris.c diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f637a..0e0e772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ ([#404][404]). * pipewire: added `spacing`, `left-spacing` and `right-spacing` attributes. +* mpris: new module ([#53][53]). [96]: https://codeberg.org/dnkl/yambar/issues/96 [380]: https://codeberg.org/dnkl/yambar/issues/380 @@ -38,6 +39,7 @@ [400]: https://codeberg.org/dnkl/yambar/pulls/400 [428]: https://codeberg.org/dnkl/yambar/pulls/428 [404]: https://codeberg.org/dnkl/yambar/issues/404 +[53]: https://codeberg.org/dnkl/yambar/issues/53 ### Changed diff --git a/doc/meson.build b/doc/meson.build index 90a83ec..e801bf1 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -34,6 +34,9 @@ endif if plugin_mpd_enabled plugin_pages += ['yambar-modules-mpd.5.scd'] endif +if plugin_mpris_enabled + plugin_pages += ['yambar-modules-mpris.5.scd'] +endif if plugin_i3_enabled plugin_pages += ['yambar-modules-i3.5.scd'] plugin_pages += ['yambar-modules-sway.5.scd'] diff --git a/doc/yambar-modules-mpris.5.scd b/doc/yambar-modules-mpris.5.scd new file mode 100644 index 0000000..a52caba --- /dev/null +++ b/doc/yambar-modules-mpris.5.scd @@ -0,0 +1,95 @@ +yambar-modules-mpris(5) + +# NAME +mpris - This module provides MPRIS status such as currently playing artist/album/song + +# TAGS + +[[ *Name* +:[ *Type* +:< *Description* +| state +: string +: One of *offline*, *stopped*, *paused* or *playing* +| shuffle +: bool +: True if the *shuffle* flag is set +| repeat +: string +: One of *none*, *track* or *paylist* +| volume +: range +: Volume in percentage +| album +: string +: Currently playing album +| artist +: string +: Artist of currently playing song +| title +: string +: Title of currently playing song +| file +: string +: Filename or URL of currently playing song +| pos +: string +: *%M:%S*-formatted string describing the song's current position + (also see _elapsed_) +| end +: string +: *%M:%S*-formatted string describing the song's total length (also + see _duration_) +| elapsed +: realtime +: Position in currently playing song, in milliseconds. Can be used + with a _progress-bar_ particle. + +# CONFIGURATION + +[[ *Name* +:[ *Type* +:[ *Req* +:< *Description* +| identities +: list of string +: yes +: A list of MPRIS client identities + +# EXAMPLES + +``` +bar: + center: + - mpris: + identities: + - "spotify" + - "firefox" + content: + map: + conditions: + state != offline && state != stopped: + - string: {text: "{artist}", max: 30 } + - string: {text: "-" } + - string: {text: "{title}", max: 30 } +``` + +# NOTE + +The 'identity' refers a part of your clients DBus bus name. +You can obtain a list of available bus names using: + +``` +Systemd: > busctl --user --list +Playerctl: > playerctl --list-all +Libdbus: > dbus-send --session --print-reply --type=method_call --dest='org.freedesktop.DBus' /org org.freedesktop.DBus.ListNames ... | grep 'org.mpris.MediaPlayer2' +``` + +The identity refers to the part after 'org.mpris.MediaPlayer2'. +For example, firefox may use the bus name +'org.mpris.MediaPlayer2.firefox.instance_1_7' and its identity would be +'firefox' + +# SEE ALSO + +*yambar-modules*(5), *yambar-particles*(5), *yambar-tags*(5), *yambar-decorations*(5) diff --git a/meson.build b/meson.build index 81af577..1a6d211 100644 --- a/meson.build +++ b/meson.build @@ -4,13 +4,15 @@ project('yambar', 'c', meson_version: '>=0.59.0', default_options: ['c_std=c18', 'warning_level=1', - 'werror=true', 'b_ndebug=if-release']) is_debug_build = get_option('buildtype').startswith('debug') plugs_as_libs = get_option('core-plugins-as-shared-libraries') cc = meson.get_compiler('c') +cc_flags = [ + '-Werror=all' + ] if cc.has_function('memfd_create', args: ['-D_GNU_SOURCE=200809L'], @@ -75,7 +77,12 @@ backend_wayland = wayland_client.found() and wayland_cursor.found() tllist = dependency('tllist', version: '>=1.0.1', fallback: 'tllist') fcft = dependency('fcft', version: ['>=3.0.0', '<4.0.0'], fallback: 'fcft') +# DBus dependency. Used by 'modules/mpris' +sdbus_library = dependency('libsystemd', 'libelogind', 'basu', required: get_option('plugin-mpris')) +sdbus = declare_dependency(compile_args: ['-DHAVE_' + sdbus_library.name().to_upper()], dependencies:[sdbus_library]) + add_project_arguments( + cc_flags + ['-D_GNU_SOURCE'] + (is_debug_build ? ['-D_DEBUG'] : []) + (backend_x11 ? ['-DENABLE_X11'] : []) + @@ -180,6 +187,7 @@ summary( 'Foreign toplevel (window tracking for Wayland)': plugin_foreign_toplevel_enabled, 'Memory monitoring': plugin_mem_enabled, 'Music Player Daemon (MPD)': plugin_mpd_enabled, + 'Media Player Remote Interface Specificaion (MPRIS)': plugin_mpris_enabled, 'i3+Sway': plugin_i3_enabled, 'Label': plugin_label_enabled, 'Network monitoring': plugin_network_enabled, diff --git a/meson_options.txt b/meson_options.txt index 9fd0dd5..23a8e11 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -26,6 +26,8 @@ option('plugin-mem', type: 'feature', value: 'auto', description: 'Memory monitoring support') option('plugin-mpd', type: 'feature', value: 'auto', description: 'Music Player Daemon (MPD) support') +option('plugin-mpris', type: 'feature', value: 'enabled', + description: 'Media Player Remote Interface Specificaion (MPRIS) support') option('plugin-i3', type: 'feature', value: 'auto', description: 'i3+Sway support') option('plugin-label', type: 'feature', value: 'auto', diff --git a/modules/dbus.h b/modules/dbus.h new file mode 100644 index 0000000..6517cef --- /dev/null +++ b/modules/dbus.h @@ -0,0 +1,13 @@ +#pragma once + +// This header provides an generic interface for different versions of +// systemd-sdbus. + +#if defined(HAVE_LIBSYSTEMD) +#include +#elif defined(HAVE_LIBELOGIND) +#include +#elif defined(HAVE_BASU) +#include +#endif + diff --git a/modules/meson.build b/modules/meson.build index b54e9d7..0e65812 100644 --- a/modules/meson.build +++ b/modules/meson.build @@ -22,6 +22,9 @@ plugin_mem_enabled = get_option('plugin-mem').allowed() mpd = dependency('libmpdclient', required: get_option('plugin-mpd')) plugin_mpd_enabled = mpd.found() +mpris = sdbus +plugin_mpris_enabled = sdbus.found() + json_i3 = dependency('json-c', required: get_option('plugin-i3')) plugin_i3_enabled = json_i3.found() @@ -95,6 +98,10 @@ if plugin_mpd_enabled mod_data += {'mpd': [[], [mpd]]} endif +if plugin_mpris_enabled + mod_data += {'mpris': [[], [mpris]]} +endif + if plugin_i3_enabled mod_data += {'i3': [['i3-common.c', 'i3-common.h'], [dynlist, json_i3]]} endif diff --git a/modules/mpris.c b/modules/mpris.c new file mode 100644 index 0000000..4cf99ef --- /dev/null +++ b/modules/mpris.c @@ -0,0 +1,1129 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "dbus.h" + +#define LOG_MODULE "mpris" +#define LOG_ENABLE_DBG 1 +#include "../bar/bar.h" +#include "../config-verify.h" +#include "../config.h" +#include "../log.h" +#include "../plugin.h" + +#define QUERY_TIMEOUT 100 + +#define PATH "/org/mpris/MediaPlayer2" +#define BUS_NAME "org.mpris.MediaPlayer2" +#define SERVICE "org.mpris.MediaPlayer2" +#define INTERFACE_ROOT "org.mpris.MediaPlayer2" +#define INTERFACE_PLAYER INTERFACE_ROOT ".Player" + +#define DBUS_PATH "/org/freedesktop/DBus" +#define DBUS_BUS_NAME "org.freedesktop.DBus" +#define DBUS_SERVICE "org.freedesktop.DBus" +#define DBUS_INTERFACE_MONITORING "org.freedesktop.DBus.Monitoring" +#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" + +enum status { + STATUS_OFFLINE, + STATUS_PLAYING, + STATUS_PAUSED, + STATUS_STOPPED, + STATUS_ERROR, +}; + +typedef tll(char *) string_array; + +struct metadata { + uint64_t length_us; + char *trackid; + string_array artists; + char *album; + char *title; +}; + +struct property { + struct metadata metadata; + char *playback_status; + char *loop_status; + uint64_t position_us; + double rate; + double volume; + bool shuffle; +}; + +struct client { + bool has_seeked_support; + enum status status; + const char *bus_name; + const char *bus_unique_name; + + struct property property; + + /* The unix timestamp of the last position change (ie. + * seeking, pausing) */ + struct timespec seeked_when; +}; + +struct context { + sd_bus *monitor_connection; + sd_bus_message *update_message; + + /* FIXME: There is no nice way to pass the desired identities to + * the event handler for validation. */ + char **identities_ref; + size_t identities_count; + + tll(struct client *) clients; + struct client *current_client; + + bool has_update; +}; + +struct private +{ + thrd_t refresh_thread_id; + int refresh_abort_fd; + + size_t identities_count; + const char **identities; + struct particle *label; + + struct context context; +}; + +#if 0 +static void +debug_print_argument_type(sd_bus_message *message) +{ + char type; + const char *content; + sd_bus_message_peek_type(message, &type, &content); + LOG_DBG("peek_message_type: %c -> %s", type, content); +} +#endif + +#if defined(LOG_ENABLE_DBG) +#define dump_type(message) \ + { \ + char type; \ + const char *content; \ + sd_bus_message_peek_type(message, &type, &content); \ + LOG_DBG("argument layout: %c -> %s", type, content); \ + } +#endif + +static void +metadata_clear(struct metadata *metadata) +{ + tll_free_and_free(metadata->artists, free); + + if (metadata->album != NULL) { + free(metadata->album); + } + + if (metadata->title != NULL) { + free(metadata->title); + } + + if (metadata->trackid != NULL) { + free(metadata->trackid); + } +} + +static void +property_clear(struct property *property) +{ + metadata_clear(&property->metadata); + memset(property, 0, sizeof(*property)); +} + +static void +client_free(struct client *client) +{ + property_clear(&client->property); + + free((void *)client->bus_name); + free((void *)client->bus_unique_name); + free(client); +} + +static void +clients_free_by_unique_name(struct context *context, const char *unique_name) +{ + tll_foreach(context->clients, it) + { + struct client *client = it->item; + if (strcmp(client->bus_unique_name, unique_name) == 0) { + LOG_DBG("client_remove: Removing client %s", client->bus_name); + client_free(client); + tll_remove(context->clients, it); + } + } +} + +static void +client_free_all(struct context *context) +{ + tll_free_and_free(context->clients, client_free); +} + +static void +client_add(struct context *context, const char *name, const char *unique_name) +{ + struct client *client = malloc(sizeof(*client)); + (*client) = (struct client){ + .bus_name = strdup(name), + .bus_unique_name = strdup(unique_name), + }; + + tll_push_back(context->clients, client); + LOG_DBG("client_add: name='%s' unique_name='%s'", name, unique_name); +} + +static struct client * +client_lookup_by_unique_name(struct context *context, const char *unique_name) +{ + tll_foreach(context->clients, it) + { + struct client *client = it->item; + if (strcmp(client->bus_unique_name, unique_name) == 0) { + LOG_DBG("client_lookup: name: %s", client->bus_name); + return client; + } + } + + return NULL; +} + +static void +client_change_unique_name(struct client *client, const char *new_name) +{ + if (client->bus_unique_name != NULL) { + free((void *)client->bus_unique_name); + } + + client->bus_unique_name = strdup(new_name); +} + +static bool +verify_bus_name(char **idents, const size_t ident_count, const char *name) +{ + for (size_t i = 0; i < ident_count; i++) { + const char *ident = idents[i]; + + if (strlen(name) < strlen(BUS_NAME ".") + strlen(ident)) { + continue; + } + + const char *cmp = name + strlen(BUS_NAME "."); + if (strncmp(cmp, ident, strlen(ident)) != 0) { + continue; + } + + return true; + } + + return false; +} + +static bool +read_string_array(sd_bus_message *message, string_array *list) +{ + int status = 0; + + /* message argument layout: 'vas' */ + /* enter variant */ + status = sd_bus_message_enter_container(message, SD_BUS_TYPE_VARIANT, "as"); + if (status <= 0) { + LOG_DBG("unexpected layout: errno=%d (%s)", status, strerror(-status)); + return false; + } + + /* enter array */ + status = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "s"); + assert(status >= 0); + + const char *string; + while ((status = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &string)) > 0) { + if (strlen(string) > 0) { + tll_push_back(*list, strdup(string)); + } + } + + if (status < 0) { + LOG_ERR("metadata: unexpected layout: errno=%d (%s)", status, strerror(-status)); + return false; + } + + /* close array */ + sd_bus_message_exit_container(message); + /* close variant */ + sd_bus_message_exit_container(message); + + return true; +} + +static bool +metadata_parse_property(const char *property_name, sd_bus_message *message, struct metadata *buffer) +{ + int status = 0; + const char *string = NULL; + + char argument_type = 0; + const char *argument_layout = NULL; + sd_bus_message_peek_type(message, &argument_type, &argument_layout); + assert(argument_type == SD_BUS_TYPE_VARIANT); + assert(argument_layout != NULL && strlen(argument_layout) > 0); + + if (strcmp(property_name, "mpris:trackid") == 0) { + if (argument_layout[0] != SD_BUS_TYPE_STRING && argument_layout[0] != SD_BUS_TYPE_OBJECT_PATH) + goto unexpected_type; + + status = sd_bus_message_read(message, "v", argument_layout, &string); + if (status > 0) + buffer->trackid = strdup(string); + + /* FIXME: "strcmp matches both 'album' as well as 'albumArtist'" */ + } else if (strcmp(property_name, "xesam:album") == 0) { + status = sd_bus_message_read(message, "v", argument_layout, &string); + if (status > 0 && strlen(string) > 0) + buffer->album = strdup(string); + + } else if (strcmp(property_name, "xesam:artist") == 0) { + status = read_string_array(message, &buffer->artists); + + } else if (strcmp(property_name, "xesam:title") == 0) { + status = sd_bus_message_read(message, "v", "s", &string); + if(status > 0) + buffer->title = strdup(string); + + } else if (strcmp(property_name, "mpris:length") == 0) { + /* MPRIS requires 'mpris:length' to be an i64 (the wording is a bit ambiguous), however some client + * use a u64 instead. */ + if (argument_layout[0] != SD_BUS_TYPE_INT64 && argument_layout[0] != SD_BUS_TYPE_UINT64) + goto unexpected_type; + + status = sd_bus_message_read(message, "v", argument_layout, &buffer->length_us); + + } else { + LOG_DBG("metadata: ignoring property: %s", property_name); + sd_bus_message_skip(message, NULL); + return true; + } + + if (status < 0) { + LOG_ERR("metadata: failed to read property: arg_type='%c' arg_layout='%s' errno=%d (%s)", argument_type, + argument_layout, status, strerror(-status)); + return false; + } + + return true; +unexpected_type: + LOG_ERR("metadata: unexpected type for '%s'", property_name); + return false; +} + +static bool +metadata_parse_array(struct metadata *metadata, sd_bus_message *message) +{ + int status = sd_bus_message_enter_container(message, SD_BUS_TYPE_VARIANT, "a{sv}"); + if (status <= 0) { + LOG_DBG("unexpected layout: errno=%d (%s)", status, strerror(-status)); + return false; + } + status = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "{sv}"); + assert(status >= 0); + + while ((status = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { + const char *property_name = NULL; + status = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &property_name); + if (status <= 0) { + LOG_DBG("unexpected layout: errno=%d (%s)", status, strerror(-status)); + return false; + } + + status = metadata_parse_property(property_name, message, metadata); + if (status == 0) { + return false; + } + + status = sd_bus_message_exit_container(message); + assert(status >= 0); + } + + /* close array */ + sd_bus_message_exit_container(message); + /* close variant */ + sd_bus_message_exit_container(message); + + return status >= 0; +} + +static bool +property_parse(struct property *prop, const char *property_name, sd_bus_message *message) +{ + /* This function is called in two different ways: + * 1. update_status(): The property is passed directly + * 2. update_status_from_message(): The property is passed wrapped + * inside a variant and has to be unpacked */ + const char *argument_layout = NULL; + char argument_type = 0; + int status = sd_bus_message_peek_type(message, &argument_type, &argument_layout); + + assert(status > 0); + assert(argument_type == SD_BUS_TYPE_VARIANT); + assert(argument_layout != NULL && strlen(argument_layout) > 0); + + const char *string; + if (strcmp(property_name, "PlaybackStatus") == 0) { + status = sd_bus_message_read(message, "v", "s", &string); + if (status) + prop->playback_status = strdup(string); + + } else if (strcmp(property_name, "LoopStatus") == 0) { + status = sd_bus_message_read(message, "v", "s", &string); + if (status) + prop->loop_status = strdup(string); + + } else if (strcmp(property_name, "Position") == 0) { + /* MPRIS requires 'Position' to be a i64, however some client + * use a u64 instead. */ + if (argument_layout[0] != SD_BUS_TYPE_INT64 && argument_layout[0] != SD_BUS_TYPE_UINT64) { + LOG_ERR("property: unexpected type for '%s'", property_name); + return false; + } + status = sd_bus_message_read(message, "v", argument_layout[0], &prop->position_us); + + } else if (strcmp(property_name, "Shuffle") == 0) { + status = sd_bus_message_read(message, "v", "b", &prop->shuffle); + + } else if (strcmp(property_name, "Metadata") == 0) { + metadata_clear(&prop->metadata); + status = metadata_parse_array(&prop->metadata, message); + + } else { + LOG_DBG("property: ignoring property: %s", property_name); + sd_bus_message_skip(message, NULL); + return true; + } + + return status > 0; +} + +/* ------------- */ + +static void +format_usec_timestamp(unsigned usec, char *s, size_t sz) +{ + uint32_t secs = usec / 1000 / 1000; + uint32_t hours = secs / (60 * 60); + uint32_t minutes = secs % (60 * 60) / 60; + secs %= 60; + + if (hours > 0) + snprintf(s, sz, "%02u:%02u:%02u", hours, minutes, secs); + else + snprintf(s, sz, "%02u:%02u", minutes, secs); +} + +static void +destroy(struct module *mod) +{ + struct private *m = mod->private; + struct context *context = &m->context; + + client_free_all(context); + + sd_bus_close(context->monitor_connection); + + module_default_destroy(mod); + m->label->destroy(m->label); + free(m); +} + +static void +context_event_handle_name_owner_changed(sd_bus_message *message, struct context *context) +{ + /* NameOwnerChanged (STRING name, STRING old_owner, STRING new_owner) */ + /* This signal indicates that the owner of a name has changed, ie. + * it was acquired, lost or changed */ + + const char *bus_name = NULL, *old_owner = NULL, *new_owner = NULL; + int status = sd_bus_message_read(message, "sss", &bus_name, &old_owner, &new_owner); + assert(status > 0); + +#if 1 + LOG_DBG("event_handler: 'NameOwnerChanged': bus_name: '%s' old_owner: '%s' new_ower: '%s'", bus_name, old_owner, + new_owner); +#endif + + if (strlen(new_owner) == 0 && strlen(old_owner) > 0) { + /* Target bus has been lost */ + struct client *client = client_lookup_by_unique_name(context, old_owner); + + if (client == NULL) + return; + + LOG_DBG("event_handler: 'NameOwnerChanged': Target bus disappeared: %s", client->bus_name); + clients_free_by_unique_name(context, client->bus_unique_name); + + if (context->current_client == client) + context->current_client = NULL; + + return; + } else if (strlen(old_owner) == 0 && strlen(new_owner) > 0) { + /* New unique name registered. Not used */ + return; + } + + /* Name changed */ + assert(new_owner != NULL && strlen(new_owner) > 0); + assert(old_owner != NULL && strlen(old_owner) > 0); + + struct client *client = client_lookup_by_unique_name(context, old_owner); + LOG_DBG("'NameOwnerChanged': Name changed from '%s' to '%s' for client '%s'", old_owner, new_owner, + client->bus_name); + client_change_unique_name(client, new_owner); +} + +static void +context_event_handle_name_acquired(sd_bus_message *message, struct context *context) +{ + /* Spy on applications that requested an "MPRIS style" bus name */ + + /* NameAcquired (STRING name) */ + /* " This signal is sent to a specific application when it gains ownership of a name. " */ + const char *name = NULL; + int status = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &name); + assert(status > 0); + + /*LOG_DBG("event_handler: 'NameAcquired': name: '%s'", name);*/ + + if (strncmp(name, BUS_NAME, strlen(BUS_NAME)) != 0) { + return; + } + + if (verify_bus_name(context->identities_ref, context->identities_count, name)) { + const char *unique_name = sd_bus_message_get_destination(message); + LOG_DBG("'NameAcquired': Acquired new client: %s unique: %s", name, unique_name); + client_add(context, name, unique_name); + } +} + +static int +context_event_handler(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) +{ + struct context *context = userdata; + + const char *member = sd_bus_message_get_member(message); + const char *sender = sd_bus_message_get_sender(message); + const char *path_name = sd_bus_message_get_path(message); + +#if 0 + const char *destination = sd_bus_message_get_destination(message); + const char *self = sd_bus_message_get_sender(message); + LOG_DBG("member: '%s' self: '%s' dest: '%s' sender: '%s'", member, self, + destination, sender); +#endif + + if (tll_length(context->clients) == 0 && strcmp(member, "NameAcquired") != 0) { + return 1; + } + + /* TODO: Allow multiple clients to connect */ + if (strcmp(path_name, DBUS_PATH) == 0 && strcmp(member, "NameAcquired") == 0) { + context_event_handle_name_acquired(message, context); + } + + if (strcmp(path_name, DBUS_PATH) == 0 && strcmp(member, "NameOwnerChanged") == 0) { + context_event_handle_name_owner_changed(message, context); + return 1; + } + + /* Copy the 'PropertiesChanged/Seeked' message, so it can be parsed + * later on */ + if (strcmp(path_name, PATH) == 0 && (strcmp(member, "PropertiesChanged") == 0 || strcmp(member, "Seeked") == 0)) { + struct client *client = client_lookup_by_unique_name(context, sender); + if (client == NULL) + return 1; + + LOG_DBG("event_handler: '%s': name: '%s' unique_name: '%s'", member, client->bus_name, client->bus_unique_name); + + context->has_update = true; + context->current_client = client; + context->update_message = sd_bus_message_ref(message); + + assert(context->update_message != NULL); + } + + return 1; +} + +static bool +context_process_events(struct context *context, uint32_t timeout_ms) +{ + int status = -1; + + status = sd_bus_wait(context->monitor_connection, timeout_ms); + if (status < 0) { + if (status == -ENOTCONN) + LOG_DBG("Disconnect signal has been processed"); + else + LOG_ERR("Failed to query monitor connection: errno=%d", status); + + return false; + } + + /* 'sd_bus_process' processes one 'action' per call. + * This includes: connection, authentication, message processing */ + status = sd_bus_process(context->monitor_connection, NULL); + + if (status < 0) { + if (status == -ENOTCONN) + LOG_DBG("Disconnect signal has been processed"); + else + LOG_ERR("Failed to query monitor connection: errno=%d", status); + + return false; + } + + return true; +} + +static bool +context_new(struct private *m, struct context *context) +{ + int status = true; + sd_bus *connection; + if ((status = sd_bus_default_user(&connection)) < 0) { + LOG_ERR("Failed to connect to the desktop bus. errno: %d", status); + return -1; + } + + /* Turn this connection into a monitor */ + sd_bus_message *message; + status = sd_bus_message_new_method_call(connection, &message, DBUS_SERVICE, DBUS_PATH, DBUS_INTERFACE_MONITORING, + "BecomeMonitor"); + + const char *matching_rules[] = { + /* Listen for... */ + /* ... new MPRIS clients */ + "type='signal',interface='org.freedesktop.DBus',member='NameAcquired',path='/org/freedesktop/" + "DBus',arg0namespace='org.mpris.MediaPlayer2'", + /* ... name changes */ + "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'," + "path='/org/freedesktop/DBus'", + /* ... property changes */ + "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged', " + "path='/org/mpris/MediaPlayer2'", + /* ... changes in playback position */ + "type='signal',interface='org.mpris.MediaPlayer2.Player',member='Seeked', " + "path='/org/mpris/MediaPlayer2'", + }; + + /* TODO: Error handling */ + /* "BecomeMonitor" ('asu'): (Rules: String[], Flags: UINT32) */ + /* https://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-become-monitor */ + status = sd_bus_message_open_container(message, SD_BUS_TYPE_ARRAY, "s"); + for (uint32_t i = 0; i < sizeof(matching_rules) / sizeof(matching_rules[0]); i++) { + status = sd_bus_message_append(message, "s", matching_rules[i]); + } + status = sd_bus_message_close_container(message); + status = sd_bus_message_append_basic(message, SD_BUS_TYPE_UINT32, &(uint32_t){0}); + + sd_bus_message *reply = NULL; + sd_bus_error error = {}; + status = sd_bus_call(NULL, message, QUERY_TIMEOUT, &error, &reply); + + if (status < 0 && sd_bus_error_is_set(&error)) { + LOG_ERR("context_new: got error response with error: %s: %s (%d)", error.name, error.message, + sd_bus_error_get_errno(&error)); + return false; + } + + sd_bus_message_unref(message); + sd_bus_message_unref(reply); + + (*context) = (struct context){ + .monitor_connection = connection, + .identities_ref = (char **)m->identities, + .identities_count = m->identities_count, + .clients = tll_init(), + }; + + sd_bus_add_filter(connection, NULL, context_event_handler, context); + + return status >= 0; +} + +static uint64_t +timespec_diff_us(const struct timespec *a, const struct timespec *b) +{ + uint64_t nsecs_a = a->tv_sec * 1000000000 + a->tv_nsec; + uint64_t nsecs_b = b->tv_sec * 1000000000 + b->tv_nsec; + + assert(nsecs_a >= nsecs_b); + uint64_t nsec_diff = nsecs_a - nsecs_b; + return nsec_diff / 1000; +} + +static bool +update_status_from_message(struct module *mod, sd_bus_message *message) +{ + struct private *m = mod->private; + mtx_lock(&mod->lock); + + struct client *client = m->context.current_client; + int status = 1; + + /* Player.Seeked (UINT64 position)*/ + if (strcmp(sd_bus_message_get_member(message), "Seeked") == 0) { + client->has_seeked_support = true; + + status = sd_bus_message_read_basic(message, SD_BUS_TYPE_INT64, &client->property.position_us); + if (status <= 0) + return status; + + clock_gettime(CLOCK_MONOTONIC, &client->seeked_when); + return true; + } + + /* Properties.PropertiesChanged (STRING interface_name, + * ARRAY of DICT_ENTRY changed_properties, + * ARRAY invalidated_properties); */ + assert(strcmp(sd_bus_message_get_member(message), "PropertiesChanged") == 0); + assert(strcmp(sd_bus_message_get_signature(message, 1), "sa{sv}as") == 0); + + /* argument: 'interface_name' layout: 's' */ + const char *interface_name = NULL; + sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &interface_name); + + if (strcmp(interface_name, INTERFACE_PLAYER) != 0) { + LOG_DBG("Ignoring interface: %s", interface_name); + mtx_unlock(&mod->lock); + return true; + } + + /* argument: 'changed_properties' layout: 'a{sv}' */ + + /* Make sure we reset the position on metadata change unless the + * update contains its own position value */ + bool should_reset_position = true; + bool has_entries = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "{sv}"); + + while ((has_entries = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { + const char *property_name = NULL; + int status = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &property_name); + assert(status > 0); + + if (!property_parse(&client->property, property_name, message)) { + return false; + } + + status = sd_bus_message_exit_container(message); + assert(status >= 0); + + if (strcmp(property_name, "PlaybackStatus") == 0) { + if (strcmp(client->property.playback_status, "Stopped") == 0) { + client->status = STATUS_STOPPED; + + } else if (strcmp(client->property.playback_status, "Playing") == 0) { + clock_gettime(CLOCK_MONOTONIC, &client->seeked_when); + client->status = STATUS_PLAYING; + + } else if (strcmp(client->property.playback_status, "Paused") == 0) { + /* Update our position to include the elapsed time */ + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + client->status = STATUS_PAUSED; + client->property.position_us += timespec_diff_us(&now, &client->seeked_when); + } + } + + /* Make sure to reset the position upon metadata/song changes */ + if (should_reset_position && strcmp(property_name, "Metadata") == 0) { + client->property.position_us = 0; + + if (client->property.playback_status == NULL) { + client->property.playback_status = "Paused"; + client->status = STATUS_PAUSED; + } + } + + if (strcmp(property_name, "Position") == 0) { + should_reset_position = false; + } + } + + status = sd_bus_message_exit_container(message); + assert(status > 0); + + mtx_unlock(&mod->lock); + return true; +} + +static struct exposable * +content_empty(struct module *mod) +{ + struct private *m = mod->private; + + struct tag_set tags = { + .tags = (struct tag *[]){ + tag_new_bool(mod, "has-seeked-support", "false"), + tag_new_string(mod, "state", "offline"), + tag_new_bool(mod, "shuffle", "false"), + tag_new_string(mod, "loop", "None"), + tag_new_int_range(mod, "volume", 0, 0, 100), + tag_new_string(mod, "album", ""), + tag_new_string(mod, "artist", ""), + tag_new_string(mod, "title", ""), + tag_new_string(mod, "pos", ""), + tag_new_string(mod, "end", ""), + tag_new_int_realtime( + mod, "elapsed", 0, 0, 0, TAG_REALTIME_NONE), + }, + .count = 10, + }; + + mtx_unlock(&mod->lock); + + struct exposable *exposable = m->label->instantiate(m->label, &tags); + + tag_set_destroy(&tags); + return exposable; +} + +static struct exposable * +content(struct module *mod) +{ + const struct private *m = mod->private; + const struct client *client = m->context.current_client; + + if (client == NULL) { + return content_empty(mod); + } + + const struct metadata *metadata = &client->property.metadata; + const struct property *property = &client->property; + + /* Calculate the current playback position */ + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + uint64_t elapsed_us = client->property.position_us; + uint64_t length_us = metadata->length_us; + + if (client->has_seeked_support && client->status == STATUS_PLAYING) { + elapsed_us += timespec_diff_us(&now, &client->seeked_when); + if (elapsed_us > length_us) { + LOG_DBG("dynamic update of elapsed overflowed: " + "elapsed=%" PRIu64 ", duration=%" PRIu64, + elapsed_us, length_us); + elapsed_us = length_us; + } + } + + /* Some clients can report misleading or incomplete updates to the + * playback position, potentially causing the position to exceed + * the length */ + if (elapsed_us > length_us) + elapsed_us = length_us = 0; + + char tag_pos_value[16] = {0}, tag_end_value[16] = {0}; + if (length_us > 0) { + format_usec_timestamp(elapsed_us, tag_pos_value, sizeof(tag_pos_value)); + format_usec_timestamp(length_us, tag_end_value, sizeof(tag_end_value)); + } + + char *tag_state_value = NULL; + switch (client->status) { + case STATUS_ERROR: + tag_state_value = "error"; + break; + case STATUS_OFFLINE: + tag_state_value = "offline"; + break; + case STATUS_PLAYING: + tag_state_value = "playing"; + break; + case STATUS_PAUSED: + tag_state_value = "paused"; + break; + case STATUS_STOPPED: + tag_state_value = "stopped"; + break; + } + + const char *tag_loop_value = (property->loop_status == NULL) ? "" : property->loop_status; + const char *tag_album_value = (metadata->album == NULL) ? "" : metadata->album; + const char *tag_artists_value = (tll_length(metadata->artists) <= 0) ? "" : tll_front(metadata->artists); + const char *tag_title_value = (metadata->title == NULL) ? "" : metadata->title; + const uint32_t tag_volume_value = (property->volume >= 0.995) ? 100 : 100 * property->volume; + const bool tag_shuffle_value = property->shuffle; + const enum tag_realtime_unit realtime_unit + = (client->has_seeked_support && client->status == STATUS_PLAYING) ? TAG_REALTIME_MSECS : TAG_REALTIME_NONE; + + struct tag_set tags = { + .tags = (struct tag *[]){ + tag_new_bool(mod, "has_seeked_support", client->has_seeked_support), + tag_new_bool(mod, "shuffle", tag_shuffle_value), + tag_new_int_range(mod, "volume", tag_volume_value, 0, 100), + tag_new_string(mod, "album", tag_album_value), + tag_new_string(mod, "artist", tag_artists_value), + tag_new_string(mod, "end", tag_end_value), + tag_new_string(mod, "loop", tag_loop_value), + tag_new_string(mod, "pos", tag_pos_value), + tag_new_string(mod, "state", tag_state_value), + tag_new_string(mod, "title", tag_title_value), + tag_new_int_realtime( + mod, "elapsed", elapsed_us, 0, length_us, realtime_unit), + }, + .count = 11, + }; + + mtx_unlock(&mod->lock); + + struct exposable *exposable = m->label->instantiate(m->label, &tags); + + tag_set_destroy(&tags); + return exposable; +} + +struct refresh_context { + struct module *mod; + int abort_fd; + long milli_seconds; +}; + +static int +refresh_in_thread(void *arg) +{ + struct refresh_context *ctx = arg; + struct module *mod = ctx->mod; + + /* Extract data from context so that we can free it */ + int abort_fd = ctx->abort_fd; + long milli_seconds = ctx->milli_seconds; + free(ctx); + + /*LOG_DBG("going to sleep for %ldms", milli_seconds);*/ + + /* Wait for timeout, or abort signal */ + struct pollfd fds[] = {{.fd = abort_fd, .events = POLLIN}}; + int r = poll(fds, 1, milli_seconds); + + if (r < 0) { + LOG_ERRNO("failed to poll() in refresh thread"); + return 1; + } + + /* Aborted? */ + if (r == 1) { + assert(fds[0].revents & POLLIN); + /*LOG_DBG("refresh thread aborted");*/ + return 0; + } + + LOG_DBG("timed refresh"); + mod->bar->refresh(mod->bar); + + return 0; +} + +static bool +refresh_in(struct module *mod, long milli_seconds) +{ + struct private *m = mod->private; + + /* Abort currently running refresh thread */ + if (m->refresh_thread_id != 0) { + /*LOG_DBG("aborting current refresh thread");*/ + + /* Signal abort to thread */ + assert(m->refresh_abort_fd != -1); + if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) { + LOG_ERRNO("failed to signal abort to refresher thread"); + return false; + } + + /* Wait for it to finish */ + int res; + thrd_join(m->refresh_thread_id, &res); + + /* Close and cleanup */ + close(m->refresh_abort_fd); + m->refresh_abort_fd = -1; + m->refresh_thread_id = 0; + } + + /* Create a new eventfd, to be able to signal abort to the thread */ + int abort_fd = eventfd(0, EFD_CLOEXEC); + if (abort_fd == -1) { + LOG_ERRNO("failed to create eventfd"); + return false; + } + + /* Thread context */ + struct refresh_context *ctx = malloc(sizeof(*ctx)); + ctx->mod = mod; + ctx->abort_fd = m->refresh_abort_fd = abort_fd; + ctx->milli_seconds = milli_seconds; + + /* Create thread */ + int r = thrd_create(&m->refresh_thread_id, &refresh_in_thread, ctx); + + if (r != thrd_success) { + LOG_ERR("failed to create refresh thread"); + close(m->refresh_abort_fd); + m->refresh_abort_fd = -1; + m->refresh_thread_id = 0; + free(ctx); + } + + /* Detach - we don't want to have to thrd_join() it */ + // thrd_detach(tid); + return r == 0; +} + +static int +run(struct module *mod) +{ + const struct bar *bar = mod->bar; + struct private *m = mod->private; + + if (!context_new(m, &m->context)) { + LOG_ERR("Failed to setup context"); + return -1; + } + + struct context *context = &m->context; + + int ret = 0; + bool aborted = false; + while (ret == 0 && !aborted) { + const uint32_t timeout_ms = 50; + struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}}; + + /* Check for abort event */ + if (poll(fds, 1, timeout_ms) < 0) { + if (errno == EINTR) + continue; + + LOG_ERRNO("failed to poll"); + break; + } + + if (fds[0].revents & POLLIN) { + aborted = true; + break; + } + + if (!context_process_events(context, QUERY_TIMEOUT)) { + aborted = true; + break; + } + + /* Process dynamic updates, received through the contexts + * monitor connection. The 'upate_message' attribute is set + * inside the contexts event callback, if there are any + * updates to be processed. */ + if (context->has_update) { + assert(context->current_client != NULL); + assert(context->update_message != NULL); + + context->has_update = false; + aborted = !update_status_from_message(mod, context->update_message); + context->update_message = sd_bus_message_unref(context->update_message); + } + + bar->refresh(bar); + } + + LOG_DBG("exiting"); + + return ret; +} + +static const char * +description(const struct module *mod) +{ + return "mpris"; +} + +static struct module * +mpris_new(const char **ident, size_t ident_count, struct particle *label) +{ + struct private *priv = calloc(1, sizeof(*priv)); + priv->label = label; + priv->identities = malloc(sizeof(*ident) * ident_count); + priv->identities_count = ident_count; + + for (size_t i = 0; i < ident_count; i++) { + priv->identities[i] = strdup(ident[i]); + } + + struct module *mod = module_common_new(); + mod->private = priv; + mod->run = &run; + mod->destroy = &destroy; + mod->content = &content; + mod->description = &description; + mod->refresh_in = &refresh_in; + return mod; +} + +static struct module * +from_conf(const struct yml_node *node, struct conf_inherit inherited) +{ + const struct yml_node *ident_list = yml_get_value(node, "identities"); + const struct yml_node *c = yml_get_value(node, "content"); + + const size_t ident_count = yml_list_length(ident_list); + const char *ident[ident_count]; + size_t i = 0; + for (struct yml_list_iter iter = yml_list_iter(ident_list); iter.node != NULL; yml_list_next(&iter), i++) { + ident[i] = yml_value_as_string(iter.node); + } + + return mpris_new(ident, ident_count, conf_to_particle(c, inherited)); +} + +static bool +conf_verify_indentities(keychain_t *chain, const struct yml_node *node) +{ + return conf_verify_list(chain, node, &conf_verify_string); +} + +static bool +verify_conf(keychain_t *chain, const struct yml_node *node) +{ + static const struct attr_info attrs[] = { + {"identities", true, &conf_verify_indentities}, + MODULE_COMMON_ATTRS, + }; + + return conf_verify_dict(chain, node, attrs); +} + +const struct module_iface module_mpris_iface = { + .verify_conf = &verify_conf, + .from_conf = &from_conf, +}; + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) +extern const struct module_iface iface __attribute__((weak, alias("module_mpris_iface"))); +#endif diff --git a/plugin.c b/plugin.c index b1e268b..2ed0a4f 100644 --- a/plugin.c +++ b/plugin.c @@ -57,6 +57,9 @@ EXTERN_MODULE(mem); #if defined(HAVE_PLUGIN_mpd) EXTERN_MODULE(mpd); #endif +#if defined(HAVE_PLUGIN_mpris) +EXTERN_MODULE(mpris); +#endif #if defined(HAVE_PLUGIN_i3) EXTERN_MODULE(i3); #endif @@ -193,6 +196,9 @@ static void __attribute__((constructor)) init(void) #if defined(HAVE_PLUGIN_mpd) REGISTER_CORE_MODULE(mpd, mpd); #endif +#if defined(HAVE_PLUGIN_mpris) + REGISTER_CORE_MODULE(mpris, mpris); +#endif #if defined(HAVE_PLUGIN_i3) REGISTER_CORE_MODULE(i3, i3); #endif From e68ed8d8434e016041be944416def5c8d6e2d0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 5 Mar 2025 08:41:04 +0100 Subject: [PATCH 101/112] module: mpris: mark debug-only variables with attribute unused Fixes release builds --- modules/mpris.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/mpris.c b/modules/mpris.c index 4cf99ef..538256d 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -463,7 +463,8 @@ context_event_handle_name_owner_changed(sd_bus_message *message, struct context * it was acquired, lost or changed */ const char *bus_name = NULL, *old_owner = NULL, *new_owner = NULL; - int status = sd_bus_message_read(message, "sss", &bus_name, &old_owner, &new_owner); + int status __attribute__((unused)) + = sd_bus_message_read(message, "sss", &bus_name, &old_owner, &new_owner); assert(status > 0); #if 1 @@ -508,7 +509,8 @@ context_event_handle_name_acquired(sd_bus_message *message, struct context *cont /* NameAcquired (STRING name) */ /* " This signal is sent to a specific application when it gains ownership of a name. " */ const char *name = NULL; - int status = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &name); + int status __attribute__((unused)) + = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &name); assert(status > 0); /*LOG_DBG("event_handler: 'NameAcquired': name: '%s'", name);*/ @@ -727,7 +729,8 @@ update_status_from_message(struct module *mod, sd_bus_message *message) while ((has_entries = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { const char *property_name = NULL; - int status = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &property_name); + int status __attribute__((unused)) + = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &property_name); assert(status > 0); if (!property_parse(&client->property, property_name, message)) { From e423776000982ad5646dfae6f753226f743c36e3 Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Sun, 9 Mar 2025 22:28:59 +0100 Subject: [PATCH 102/112] module_mpris: Added 'query-timeout' option This enables us to configure the communication timeout with the dbus daemon. --- doc/yambar-modules-mpris.5.scd | 18 ++++++++++++------ modules/mpris.c | 23 ++++++++++++++++------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/doc/yambar-modules-mpris.5.scd b/doc/yambar-modules-mpris.5.scd index a52caba..510dc8f 100644 --- a/doc/yambar-modules-mpris.5.scd +++ b/doc/yambar-modules-mpris.5.scd @@ -55,6 +55,11 @@ mpris - This module provides MPRIS status such as currently playing artist/album : list of string : yes : A list of MPRIS client identities +| query_timeout +: int +: no +: Dbus/MPRIS client connection timeout in ms. Try setting/incrementing + this value if the module reports a timeout error. Defaults to 500. # EXAMPLES @@ -77,18 +82,19 @@ bar: # NOTE The 'identity' refers a part of your clients DBus bus name. -You can obtain a list of available bus names using: +You can obtain a list of active client names using: ``` Systemd: > busctl --user --list Playerctl: > playerctl --list-all -Libdbus: > dbus-send --session --print-reply --type=method_call --dest='org.freedesktop.DBus' /org org.freedesktop.DBus.ListNames ... | grep 'org.mpris.MediaPlayer2' +Libdbus: > dbus-send --session --print-reply --type=method_call \ + --dest='org.freedesktop.DBus' /org org.freedesktop.DBus.ListNames ``` -The identity refers to the part after 'org.mpris.MediaPlayer2'. -For example, firefox may use the bus name -'org.mpris.MediaPlayer2.firefox.instance_1_7' and its identity would be -'firefox' +MPRIS client bus names start with 'org.mpris.MediaPlayer2.'. +For example, firefox may use the bus name: +'org.mpris.MediaPlayer2.firefox.instance_1_7' which +gives us the identity 'firefox' # SEE ALSO diff --git a/modules/mpris.c b/modules/mpris.c index 538256d..c610176 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -14,16 +14,17 @@ #include #include "dbus.h" +#include "yml.h" #define LOG_MODULE "mpris" -#define LOG_ENABLE_DBG 1 +#define LOG_ENABLE_DBG 0 #include "../bar/bar.h" #include "../config-verify.h" #include "../config.h" #include "../log.h" #include "../plugin.h" -#define QUERY_TIMEOUT 100 +#define DEFAULT_QUERY_TIMEOUT 500 #define PATH "/org/mpris/MediaPlayer2" #define BUS_NAME "org.mpris.MediaPlayer2" @@ -99,6 +100,7 @@ struct private int refresh_abort_fd; size_t identities_count; + size_t timeout_ms; const char **identities; struct particle *label; @@ -649,10 +651,10 @@ context_new(struct private *m, struct context *context) sd_bus_message *reply = NULL; sd_bus_error error = {}; - status = sd_bus_call(NULL, message, QUERY_TIMEOUT, &error, &reply); + status = sd_bus_call(NULL, message, m->timeout_ms, &error, &reply); if (status < 0 && sd_bus_error_is_set(&error)) { - LOG_ERR("context_new: got error response with error: %s: %s (%d)", error.name, error.message, + LOG_ERR("context_new: got error response: %s: %s (%d)", error.name, error.message, sd_bus_error_get_errno(&error)); return false; } @@ -1035,7 +1037,7 @@ run(struct module *mod) break; } - if (!context_process_events(context, QUERY_TIMEOUT)) { + if (!context_process_events(context, m->timeout_ms)) { aborted = true; break; } @@ -1068,10 +1070,11 @@ description(const struct module *mod) } static struct module * -mpris_new(const char **ident, size_t ident_count, struct particle *label) +mpris_new(const char **ident, size_t ident_count, size_t timeout, struct particle *label) { struct private *priv = calloc(1, sizeof(*priv)); priv->label = label; + priv->timeout_ms = timeout; priv->identities = malloc(sizeof(*ident) * ident_count); priv->identities_count = ident_count; @@ -1093,8 +1096,13 @@ static struct module * from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *ident_list = yml_get_value(node, "identities"); + const struct yml_node *query_timeout = yml_get_value(node, "query_timeout"); const struct yml_node *c = yml_get_value(node, "content"); + size_t timeout_ms = DEFAULT_QUERY_TIMEOUT * 1000; + if(query_timeout != NULL) + timeout_ms = yml_value_as_int(query_timeout) * 1000; + const size_t ident_count = yml_list_length(ident_list); const char *ident[ident_count]; size_t i = 0; @@ -1102,7 +1110,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) ident[i] = yml_value_as_string(iter.node); } - return mpris_new(ident, ident_count, conf_to_particle(c, inherited)); + return mpris_new(ident, ident_count, timeout_ms, conf_to_particle(c, inherited)); } static bool @@ -1116,6 +1124,7 @@ verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"identities", true, &conf_verify_indentities}, + {"query_timeout", false, &conf_verify_unsigned}, MODULE_COMMON_ATTRS, }; From dcf936fd9b04cb77c9125dd5be5856872ec3b405 Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Mon, 10 Mar 2025 00:32:14 +0100 Subject: [PATCH 103/112] module_mpris: Fixed 'use after free' --- modules/mpris.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/mpris.c b/modules/mpris.c index c610176..b29e883 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -135,14 +135,17 @@ metadata_clear(struct metadata *metadata) if (metadata->album != NULL) { free(metadata->album); + metadata->album = NULL; } if (metadata->title != NULL) { free(metadata->title); + metadata->title = NULL; } if (metadata->trackid != NULL) { free(metadata->trackid); + metadata->trackid = NULL; } } @@ -296,7 +299,7 @@ metadata_parse_property(const char *property_name, sd_bus_message *message, stru goto unexpected_type; status = sd_bus_message_read(message, "v", argument_layout, &string); - if (status > 0) + if (status > 0 && strlen(string) > 0) buffer->trackid = strdup(string); /* FIXME: "strcmp matches both 'album' as well as 'albumArtist'" */ @@ -310,7 +313,7 @@ metadata_parse_property(const char *property_name, sd_bus_message *message, stru } else if (strcmp(property_name, "xesam:title") == 0) { status = sd_bus_message_read(message, "v", "s", &string); - if(status > 0) + if(status > 0 && strlen(string) > 0) buffer->title = strdup(string); } else if (strcmp(property_name, "mpris:length") == 0) { @@ -393,12 +396,12 @@ property_parse(struct property *prop, const char *property_name, sd_bus_message const char *string; if (strcmp(property_name, "PlaybackStatus") == 0) { status = sd_bus_message_read(message, "v", "s", &string); - if (status) + if (status && strlen(string) > 0) prop->playback_status = strdup(string); } else if (strcmp(property_name, "LoopStatus") == 0) { status = sd_bus_message_read(message, "v", "s", &string); - if (status) + if (status && strlen(string) > 0) prop->loop_status = strdup(string); } else if (strcmp(property_name, "Position") == 0) { From 7e76d53c0a4ffe51c873a3aaf3f2faea845c0045 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 9 Mar 2025 21:43:47 +0100 Subject: [PATCH 104/112] modules/mpris: fix dependency search Move dependency discovery to be with other module dependency searches. Also only define the `sdbus` dependency if the module is enabled. The `mpris` module was always being compiled because the `sdbus` dependency always existed. Instead, check for the external dependency's status and create the `sdbus` bridge dependency only when necessary. --- meson.build | 4 ---- modules/meson.build | 8 +++++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 1a6d211..e1f695a 100644 --- a/meson.build +++ b/meson.build @@ -77,10 +77,6 @@ backend_wayland = wayland_client.found() and wayland_cursor.found() tllist = dependency('tllist', version: '>=1.0.1', fallback: 'tllist') fcft = dependency('fcft', version: ['>=3.0.0', '<4.0.0'], fallback: 'fcft') -# DBus dependency. Used by 'modules/mpris' -sdbus_library = dependency('libsystemd', 'libelogind', 'basu', required: get_option('plugin-mpris')) -sdbus = declare_dependency(compile_args: ['-DHAVE_' + sdbus_library.name().to_upper()], dependencies:[sdbus_library]) - add_project_arguments( cc_flags + ['-D_GNU_SOURCE'] + diff --git a/modules/meson.build b/modules/meson.build index 0e65812..f6d53d8 100644 --- a/modules/meson.build +++ b/modules/meson.build @@ -22,8 +22,9 @@ plugin_mem_enabled = get_option('plugin-mem').allowed() mpd = dependency('libmpdclient', required: get_option('plugin-mpd')) plugin_mpd_enabled = mpd.found() -mpris = sdbus -plugin_mpris_enabled = sdbus.found() +# DBus dependency. Used by 'mpris' +sdbus_library = dependency('libsystemd', 'libelogind', 'basu', required: get_option('plugin-mpris')) +plugin_mpris_enabled = sdbus_library.found() json_i3 = dependency('json-c', required: get_option('plugin-i3')) plugin_i3_enabled = json_i3.found() @@ -99,7 +100,8 @@ if plugin_mpd_enabled endif if plugin_mpris_enabled - mod_data += {'mpris': [[], [mpris]]} + sdbus = declare_dependency(compile_args: ['-DHAVE_' + sdbus_library.name().to_upper()], dependencies:[sdbus_library]) + mod_data += {'mpris': [[], [sdbus]]} endif if plugin_i3_enabled From 56467d0ba3eeddb3f57f817d720e70c5ac8b4afc Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 9 Mar 2025 21:45:20 +0100 Subject: [PATCH 105/112] meson: require 0.60.0 This introduces dependencies with multiple names which is used for the `sdbus_library` dependency of the `mpris` module. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index e1f695a..67d3096 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project('yambar', 'c', version: '1.11.0', license: 'MIT', - meson_version: '>=0.59.0', + meson_version: '>=0.60.0', default_options: ['c_std=c18', 'warning_level=1', 'b_ndebug=if-release']) From 0bcde5c453e7765deec020321e08484b0781b980 Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Mon, 10 Mar 2025 01:36:26 +0100 Subject: [PATCH 106/112] module_mpris: Fixed memory leak The identity list now uses tlllist and is deallocated properly --- modules/mpris.c | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/modules/mpris.c b/modules/mpris.c index b29e883..74d2e95 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -83,11 +83,6 @@ struct context { sd_bus *monitor_connection; sd_bus_message *update_message; - /* FIXME: There is no nice way to pass the desired identities to - * the event handler for validation. */ - char **identities_ref; - size_t identities_count; - tll(struct client *) clients; struct client *current_client; @@ -99,14 +94,14 @@ struct private thrd_t refresh_thread_id; int refresh_abort_fd; - size_t identities_count; size_t timeout_ms; - const char **identities; struct particle *label; struct context context; }; +static tll(const char*) identity_list; + #if 0 static void debug_print_argument_type(sd_bus_message *message) @@ -225,10 +220,10 @@ client_change_unique_name(struct client *client, const char *new_name) } static bool -verify_bus_name(char **idents, const size_t ident_count, const char *name) +verify_bus_name(const char *name) { - for (size_t i = 0; i < ident_count; i++) { - const char *ident = idents[i]; + tll_foreach(identity_list, it) { + const char *ident = it->item; if (strlen(name) < strlen(BUS_NAME ".") + strlen(ident)) { continue; @@ -455,9 +450,13 @@ destroy(struct module *mod) sd_bus_close(context->monitor_connection); - module_default_destroy(mod); + tll_foreach(identity_list, it) { + free((char*)it->item); + } m->label->destroy(m->label); free(m); + + module_default_destroy(mod); } static void @@ -524,7 +523,7 @@ context_event_handle_name_acquired(sd_bus_message *message, struct context *cont return; } - if (verify_bus_name(context->identities_ref, context->identities_count, name)) { + if (verify_bus_name(name)) { const char *unique_name = sd_bus_message_get_destination(message); LOG_DBG("'NameAcquired': Acquired new client: %s unique: %s", name, unique_name); client_add(context, name, unique_name); @@ -667,8 +666,6 @@ context_new(struct private *m, struct context *context) (*context) = (struct context){ .monitor_connection = connection, - .identities_ref = (char **)m->identities, - .identities_count = m->identities_count, .clients = tll_init(), }; @@ -1061,8 +1058,8 @@ run(struct module *mod) bar->refresh(bar); } - LOG_DBG("exiting"); + LOG_DBG("exiting"); return ret; } @@ -1073,17 +1070,11 @@ description(const struct module *mod) } static struct module * -mpris_new(const char **ident, size_t ident_count, size_t timeout, struct particle *label) +mpris_new(size_t timeout, struct particle *label) { struct private *priv = calloc(1, sizeof(*priv)); priv->label = label; priv->timeout_ms = timeout; - priv->identities = malloc(sizeof(*ident) * ident_count); - priv->identities_count = ident_count; - - for (size_t i = 0; i < ident_count; i++) { - priv->identities[i] = strdup(ident[i]); - } struct module *mod = module_common_new(); mod->private = priv; @@ -1106,14 +1097,14 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) if(query_timeout != NULL) timeout_ms = yml_value_as_int(query_timeout) * 1000; - const size_t ident_count = yml_list_length(ident_list); - const char *ident[ident_count]; + // FIXME: This is a redundant copy size_t i = 0; for (struct yml_list_iter iter = yml_list_iter(ident_list); iter.node != NULL; yml_list_next(&iter), i++) { - ident[i] = yml_value_as_string(iter.node); + const char *string = strdup(yml_value_as_string(iter.node)); + tll_push_back(identity_list, string); } - return mpris_new(ident, ident_count, timeout_ms, conf_to_particle(c, inherited)); + return mpris_new(timeout_ms, conf_to_particle(c, inherited)); } static bool From 87c74d54b792468ffe6b0348f214548a48204fd0 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sat, 8 Feb 2025 20:17:13 +0100 Subject: [PATCH 107/112] meson: guard the `full-conf-good` test by the plugins it expects --- test/meson.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/meson.build b/test/meson.build index e8c7138..a3635a2 100644 --- a/test/meson.build +++ b/test/meson.build @@ -7,4 +7,9 @@ test('no-config', yambar, args: ['-C', '-c', 'xyz'], should_fail: true) test('config-isnt-file', yambar, args: ['-C', '-c', '.'], should_fail: true) test('config-no-bar', yambar, args: ['-C', '-c', join_paths(pwd, 'no-bar.yml')], should_fail: true) -test('full-conf-good', yambar, args: ['-C', '-c', join_paths(pwd, 'full-conf-good.yml')]) +if plugin_alsa_enabled and plugin_backlight_enabled and \ + plugin_battery_enabled and plugin_clock_enabled and \ + plugin_i3_enabled and plugin_mpd_enabled and plugin_network_enabled \ + and plugin_removables_enabled + test('full-conf-good', yambar, args: ['-C', '-c', join_paths(pwd, 'full-conf-good.yml')]) +endif From 6a97b364a01b0bd4af54fa0c0e434acfc2ef704f Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Mon, 10 Mar 2025 11:13:17 +0100 Subject: [PATCH 108/112] module_mpris: Fixed inconsistent string validation checks This addresses changes requested by @mathstuf --- modules/mpris.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/mpris.c b/modules/mpris.c index 74d2e95..31b8fd2 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -24,8 +24,9 @@ #include "../log.h" #include "../plugin.h" -#define DEFAULT_QUERY_TIMEOUT 500 +#define is_empty_string(str) ((str) == NULL || (str)[0] == '\0') +#define DEFAULT_QUERY_TIMEOUT 500 #define PATH "/org/mpris/MediaPlayer2" #define BUS_NAME "org.mpris.MediaPlayer2" #define SERVICE "org.mpris.MediaPlayer2" @@ -259,7 +260,7 @@ read_string_array(sd_bus_message *message, string_array *list) const char *string; while ((status = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &string)) > 0) { - if (strlen(string) > 0) { + if (!is_empty_string(string)) { tll_push_back(*list, strdup(string)); } } @@ -287,20 +288,20 @@ metadata_parse_property(const char *property_name, sd_bus_message *message, stru const char *argument_layout = NULL; sd_bus_message_peek_type(message, &argument_type, &argument_layout); assert(argument_type == SD_BUS_TYPE_VARIANT); - assert(argument_layout != NULL && strlen(argument_layout) > 0); + assert(!is_empty_string(argument_layout)); if (strcmp(property_name, "mpris:trackid") == 0) { if (argument_layout[0] != SD_BUS_TYPE_STRING && argument_layout[0] != SD_BUS_TYPE_OBJECT_PATH) goto unexpected_type; status = sd_bus_message_read(message, "v", argument_layout, &string); - if (status > 0 && strlen(string) > 0) + if (status > 0 && !is_empty_string(string)) buffer->trackid = strdup(string); /* FIXME: "strcmp matches both 'album' as well as 'albumArtist'" */ } else if (strcmp(property_name, "xesam:album") == 0) { status = sd_bus_message_read(message, "v", argument_layout, &string); - if (status > 0 && strlen(string) > 0) + if (status > 0 && !is_empty_string(string)) buffer->album = strdup(string); } else if (strcmp(property_name, "xesam:artist") == 0) { @@ -308,7 +309,7 @@ metadata_parse_property(const char *property_name, sd_bus_message *message, stru } else if (strcmp(property_name, "xesam:title") == 0) { status = sd_bus_message_read(message, "v", "s", &string); - if(status > 0 && strlen(string) > 0) + if(status > 0 && !is_empty_string(string)) buffer->title = strdup(string); } else if (strcmp(property_name, "mpris:length") == 0) { @@ -386,17 +387,17 @@ property_parse(struct property *prop, const char *property_name, sd_bus_message assert(status > 0); assert(argument_type == SD_BUS_TYPE_VARIANT); - assert(argument_layout != NULL && strlen(argument_layout) > 0); + assert(!is_empty_string(argument_layout)); const char *string; if (strcmp(property_name, "PlaybackStatus") == 0) { status = sd_bus_message_read(message, "v", "s", &string); - if (status && strlen(string) > 0) + if (status && !is_empty_string(string)) prop->playback_status = strdup(string); } else if (strcmp(property_name, "LoopStatus") == 0) { status = sd_bus_message_read(message, "v", "s", &string); - if (status && strlen(string) > 0) + if (status && !is_empty_string(string)) prop->loop_status = strdup(string); } else if (strcmp(property_name, "Position") == 0) { @@ -476,7 +477,7 @@ context_event_handle_name_owner_changed(sd_bus_message *message, struct context new_owner); #endif - if (strlen(new_owner) == 0 && strlen(old_owner) > 0) { + if (is_empty_string(new_owner) && !is_empty_string(old_owner)) { /* Target bus has been lost */ struct client *client = client_lookup_by_unique_name(context, old_owner); @@ -490,14 +491,14 @@ context_event_handle_name_owner_changed(sd_bus_message *message, struct context context->current_client = NULL; return; - } else if (strlen(old_owner) == 0 && strlen(new_owner) > 0) { + } else if (is_empty_string(old_owner) && !is_empty_string(new_owner)) { /* New unique name registered. Not used */ return; } /* Name changed */ - assert(new_owner != NULL && strlen(new_owner) > 0); - assert(old_owner != NULL && strlen(old_owner) > 0); + assert(!is_empty_string(new_owner)); + assert(!is_empty_string(old_owner)); struct client *client = client_lookup_by_unique_name(context, old_owner); LOG_DBG("'NameOwnerChanged': Name changed from '%s' to '%s' for client '%s'", old_owner, new_owner, From dcbb0f88ae9c3f4a9b429c0c69e183551c365559 Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Mon, 10 Mar 2025 11:34:29 +0100 Subject: [PATCH 109/112] module_mpris: Cleanup Fixed inconsistent variable naming/debug logging --- modules/mpris.c | 78 ++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 47 deletions(-) diff --git a/modules/mpris.c b/modules/mpris.c index 31b8fd2..79f1980 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -13,9 +13,6 @@ #include -#include "dbus.h" -#include "yml.h" - #define LOG_MODULE "mpris" #define LOG_ENABLE_DBG 0 #include "../bar/bar.h" @@ -24,14 +21,17 @@ #include "../log.h" #include "../plugin.h" +#include "dbus.h" +#include "yml.h" + #define is_empty_string(str) ((str) == NULL || (str)[0] == '\0') -#define DEFAULT_QUERY_TIMEOUT 500 -#define PATH "/org/mpris/MediaPlayer2" -#define BUS_NAME "org.mpris.MediaPlayer2" -#define SERVICE "org.mpris.MediaPlayer2" -#define INTERFACE_ROOT "org.mpris.MediaPlayer2" -#define INTERFACE_PLAYER INTERFACE_ROOT ".Player" +#define DEFAULT_QUERY_TIMEOUT_MS (500 * 1000) + +#define MPRIS_PATH "/org/mpris/MediaPlayer2" +#define MPRIS_BUS_NAME "org.mpris.MediaPlayer2" +#define MPRIS_SERVICE "org.mpris.MediaPlayer2" +#define MPRIS_INTERFACE_PLAYER "org.mpris.MediaPlayer2.Player" #define DBUS_PATH "/org/freedesktop/DBus" #define DBUS_BUS_NAME "org.freedesktop.DBus" @@ -101,29 +101,19 @@ struct private struct context context; }; -static tll(const char*) identity_list; +static tll(const char *) identity_list; -#if 0 -static void +#if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG +static void __attribute__((unused)) debug_print_argument_type(sd_bus_message *message) { char type; const char *content; sd_bus_message_peek_type(message, &type, &content); - LOG_DBG("peek_message_type: %c -> %s", type, content); + LOG_DBG("argument type: %c -> %s", type, content); } #endif -#if defined(LOG_ENABLE_DBG) -#define dump_type(message) \ - { \ - char type; \ - const char *content; \ - sd_bus_message_peek_type(message, &type, &content); \ - LOG_DBG("argument layout: %c -> %s", type, content); \ - } -#endif - static void metadata_clear(struct metadata *metadata) { @@ -223,14 +213,15 @@ client_change_unique_name(struct client *client, const char *new_name) static bool verify_bus_name(const char *name) { - tll_foreach(identity_list, it) { + tll_foreach(identity_list, it) + { const char *ident = it->item; - if (strlen(name) < strlen(BUS_NAME ".") + strlen(ident)) { + if (strlen(name) < strlen(MPRIS_BUS_NAME ".") + strlen(ident)) { continue; } - const char *cmp = name + strlen(BUS_NAME "."); + const char *cmp = name + strlen(MPRIS_BUS_NAME "."); if (strncmp(cmp, ident, strlen(ident)) != 0) { continue; } @@ -309,7 +300,7 @@ metadata_parse_property(const char *property_name, sd_bus_message *message, stru } else if (strcmp(property_name, "xesam:title") == 0) { status = sd_bus_message_read(message, "v", "s", &string); - if(status > 0 && !is_empty_string(string)) + if (status > 0 && !is_empty_string(string)) buffer->title = strdup(string); } else if (strcmp(property_name, "mpris:length") == 0) { @@ -451,9 +442,7 @@ destroy(struct module *mod) sd_bus_close(context->monitor_connection); - tll_foreach(identity_list, it) { - free((char*)it->item); - } + tll_foreach(identity_list, it) { free((char *)it->item); } m->label->destroy(m->label); free(m); @@ -468,14 +457,11 @@ context_event_handle_name_owner_changed(sd_bus_message *message, struct context * it was acquired, lost or changed */ const char *bus_name = NULL, *old_owner = NULL, *new_owner = NULL; - int status __attribute__((unused)) - = sd_bus_message_read(message, "sss", &bus_name, &old_owner, &new_owner); + int status __attribute__((unused)) = sd_bus_message_read(message, "sss", &bus_name, &old_owner, &new_owner); assert(status > 0); -#if 1 LOG_DBG("event_handler: 'NameOwnerChanged': bus_name: '%s' old_owner: '%s' new_ower: '%s'", bus_name, old_owner, new_owner); -#endif if (is_empty_string(new_owner) && !is_empty_string(old_owner)) { /* Target bus has been lost */ @@ -514,13 +500,12 @@ context_event_handle_name_acquired(sd_bus_message *message, struct context *cont /* NameAcquired (STRING name) */ /* " This signal is sent to a specific application when it gains ownership of a name. " */ const char *name = NULL; - int status __attribute__((unused)) - = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &name); + int status __attribute__((unused)) = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &name); assert(status > 0); - /*LOG_DBG("event_handler: 'NameAcquired': name: '%s'", name);*/ + LOG_DBG("event_handler: 'NameAcquired': name: '%s'", name); - if (strncmp(name, BUS_NAME, strlen(BUS_NAME)) != 0) { + if (strncmp(name, MPRIS_BUS_NAME, strlen(MPRIS_BUS_NAME)) != 0) { return; } @@ -563,7 +548,8 @@ context_event_handler(sd_bus_message *message, void *userdata, sd_bus_error *ret /* Copy the 'PropertiesChanged/Seeked' message, so it can be parsed * later on */ - if (strcmp(path_name, PATH) == 0 && (strcmp(member, "PropertiesChanged") == 0 || strcmp(member, "Seeked") == 0)) { + if (strcmp(path_name, MPRIS_PATH) == 0 + && (strcmp(member, "PropertiesChanged") == 0 || strcmp(member, "Seeked") == 0)) { struct client *client = client_lookup_by_unique_name(context, sender); if (client == NULL) return 1; @@ -717,7 +703,7 @@ update_status_from_message(struct module *mod, sd_bus_message *message) const char *interface_name = NULL; sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &interface_name); - if (strcmp(interface_name, INTERFACE_PLAYER) != 0) { + if (strcmp(interface_name, MPRIS_INTERFACE_PLAYER) != 0) { LOG_DBG("Ignoring interface: %s", interface_name); mtx_unlock(&mod->lock); return true; @@ -732,8 +718,7 @@ update_status_from_message(struct module *mod, sd_bus_message *message) while ((has_entries = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { const char *property_name = NULL; - int status __attribute__((unused)) - = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &property_name); + int status __attribute__((unused)) = sd_bus_message_read_basic(message, SD_BUS_TYPE_STRING, &property_name); assert(status > 0); if (!property_parse(&client->property, property_name, message)) { @@ -1059,7 +1044,6 @@ run(struct module *mod) bar->refresh(bar); } - LOG_DBG("exiting"); return ret; } @@ -1071,11 +1055,11 @@ description(const struct module *mod) } static struct module * -mpris_new(size_t timeout, struct particle *label) +mpris_new(size_t timeout_ms, struct particle *label) { struct private *priv = calloc(1, sizeof(*priv)); priv->label = label; - priv->timeout_ms = timeout; + priv->timeout_ms = timeout_ms; struct module *mod = module_common_new(); mod->private = priv; @@ -1094,8 +1078,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *query_timeout = yml_get_value(node, "query_timeout"); const struct yml_node *c = yml_get_value(node, "content"); - size_t timeout_ms = DEFAULT_QUERY_TIMEOUT * 1000; - if(query_timeout != NULL) + size_t timeout_ms = DEFAULT_QUERY_TIMEOUT_MS; + if (query_timeout != NULL) timeout_ms = yml_value_as_int(query_timeout) * 1000; // FIXME: This is a redundant copy From dfa0970b75297cf2047d6cf45af98cf093c07e6a Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Mon, 10 Mar 2025 12:03:17 +0100 Subject: [PATCH 110/112] module_mpris: Fixed multi threading issues regarding 'identity_list' This addresses changes requested by @dnkl --- modules/mpris.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/modules/mpris.c b/modules/mpris.c index 79f1980..6a03e8c 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -86,6 +86,7 @@ struct context { tll(struct client *) clients; struct client *current_client; + const string_array *identity_list_ref; bool has_update; }; @@ -96,13 +97,12 @@ struct private int refresh_abort_fd; size_t timeout_ms; + string_array identity_list; struct particle *label; struct context context; }; -static tll(const char *) identity_list; - #if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG static void __attribute__((unused)) debug_print_argument_type(sd_bus_message *message) @@ -166,12 +166,6 @@ clients_free_by_unique_name(struct context *context, const char *unique_name) } } -static void -client_free_all(struct context *context) -{ - tll_free_and_free(context->clients, client_free); -} - static void client_add(struct context *context, const char *name, const char *unique_name) { @@ -211,9 +205,9 @@ client_change_unique_name(struct client *client, const char *new_name) } static bool -verify_bus_name(const char *name) +verify_bus_name(const string_array *identity_list, const char *name) { - tll_foreach(identity_list, it) + tll_foreach(*identity_list, it) { const char *ident = it->item; @@ -438,11 +432,10 @@ destroy(struct module *mod) struct private *m = mod->private; struct context *context = &m->context; - client_free_all(context); - + tll_free_and_free(context->clients, client_free); sd_bus_close(context->monitor_connection); - tll_foreach(identity_list, it) { free((char *)it->item); } + tll_free_and_free(m->identity_list, free); m->label->destroy(m->label); free(m); @@ -509,7 +502,7 @@ context_event_handle_name_acquired(sd_bus_message *message, struct context *cont return; } - if (verify_bus_name(name)) { + if (verify_bus_name(context->identity_list_ref, name)) { const char *unique_name = sd_bus_message_get_destination(message); LOG_DBG("'NameAcquired': Acquired new client: %s unique: %s", name, unique_name); client_add(context, name, unique_name); @@ -652,6 +645,7 @@ context_new(struct private *m, struct context *context) sd_bus_message_unref(reply); (*context) = (struct context){ + .identity_list_ref = &m->identity_list, .monitor_connection = connection, .clients = tll_init(), }; @@ -1055,12 +1049,18 @@ description(const struct module *mod) } static struct module * -mpris_new(size_t timeout_ms, struct particle *label) +mpris_new(const struct yml_node *ident_list, size_t timeout_ms, struct particle *label) { struct private *priv = calloc(1, sizeof(*priv)); priv->label = label; priv->timeout_ms = timeout_ms; + size_t i = 0; + for (struct yml_list_iter iter = yml_list_iter(ident_list); iter.node != NULL; yml_list_next(&iter), i++) { + char *string = strdup(yml_value_as_string(iter.node)); + tll_push_back(priv->identity_list, string); + } + struct module *mod = module_common_new(); mod->private = priv; mod->run = &run; @@ -1082,14 +1082,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) if (query_timeout != NULL) timeout_ms = yml_value_as_int(query_timeout) * 1000; - // FIXME: This is a redundant copy - size_t i = 0; - for (struct yml_list_iter iter = yml_list_iter(ident_list); iter.node != NULL; yml_list_next(&iter), i++) { - const char *string = strdup(yml_value_as_string(iter.node)); - tll_push_back(identity_list, string); - } - return mpris_new(timeout_ms, conf_to_particle(c, inherited)); + return mpris_new(ident_list, timeout_ms, conf_to_particle(c, inherited)); } static bool From ca0f565237656dd5bf3af8b5e2d429357545b614 Mon Sep 17 00:00:00 2001 From: haruInDisguise Date: Tue, 18 Mar 2025 12:05:02 +0100 Subject: [PATCH 111/112] module_mpris: Refactoring + Fixed mutex usage - Addressed inconsistens variable naming and removed redundant code. - Mutex locks are now used correctly. - The context struct now references the modules config, making config access less awkward --- modules/mpris.c | 60 +++++++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/modules/mpris.c b/modules/mpris.c index 6a03e8c..5ddf6e0 100644 --- a/modules/mpris.c +++ b/modules/mpris.c @@ -81,12 +81,13 @@ struct client { }; struct context { + const struct private *mpd_config; + sd_bus *monitor_connection; sd_bus_message *update_message; tll(struct client *) clients; struct client *current_client; - const string_array *identity_list_ref; bool has_update; }; @@ -98,9 +99,8 @@ struct private size_t timeout_ms; string_array identity_list; - struct particle *label; - struct context context; + struct particle *label; }; #if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG @@ -135,31 +135,23 @@ metadata_clear(struct metadata *metadata) } } -static void -property_clear(struct property *property) -{ - metadata_clear(&property->metadata); - memset(property, 0, sizeof(*property)); -} - static void client_free(struct client *client) { - property_clear(&client->property); - free((void *)client->bus_name); free((void *)client->bus_unique_name); free(client); } static void -clients_free_by_unique_name(struct context *context, const char *unique_name) +client_free_by_unique_name(struct context *context, const char *unique_name) { tll_foreach(context->clients, it) { struct client *client = it->item; if (strcmp(client->bus_unique_name, unique_name) == 0) { LOG_DBG("client_remove: Removing client %s", client->bus_name); + client_free(client); tll_remove(context->clients, it); } @@ -430,10 +422,9 @@ static void destroy(struct module *mod) { struct private *m = mod->private; - struct context *context = &m->context; - tll_free_and_free(context->clients, client_free); - sd_bus_close(context->monitor_connection); + tll_free_and_free(m->context.clients, client_free); + sd_bus_close(m->context.monitor_connection); tll_free_and_free(m->identity_list, free); m->label->destroy(m->label); @@ -464,7 +455,7 @@ context_event_handle_name_owner_changed(sd_bus_message *message, struct context return; LOG_DBG("event_handler: 'NameOwnerChanged': Target bus disappeared: %s", client->bus_name); - clients_free_by_unique_name(context, client->bus_unique_name); + client_free_by_unique_name(context, client->bus_unique_name); if (context->current_client == client) context->current_client = NULL; @@ -502,7 +493,7 @@ context_event_handle_name_acquired(sd_bus_message *message, struct context *cont return; } - if (verify_bus_name(context->identity_list_ref, name)) { + if (verify_bus_name(&context->mpd_config->identity_list, name)) { const char *unique_name = sd_bus_message_get_destination(message); LOG_DBG("'NameAcquired': Acquired new client: %s unique: %s", name, unique_name); client_add(context, name, unique_name); @@ -591,15 +582,17 @@ context_process_events(struct context *context, uint32_t timeout_ms) } static bool -context_new(struct private *m, struct context *context) +context_setup(struct context *context) { int status = true; sd_bus *connection; if ((status = sd_bus_default_user(&connection)) < 0) { LOG_ERR("Failed to connect to the desktop bus. errno: %d", status); - return -1; + return false; } + context->monitor_connection = connection; + /* Turn this connection into a monitor */ sd_bus_message *message; status = sd_bus_message_new_method_call(connection, &message, DBUS_SERVICE, DBUS_PATH, DBUS_INTERFACE_MONITORING, @@ -633,23 +626,16 @@ context_new(struct private *m, struct context *context) sd_bus_message *reply = NULL; sd_bus_error error = {}; - status = sd_bus_call(NULL, message, m->timeout_ms, &error, &reply); + status = sd_bus_call(NULL, message, context->mpd_config->timeout_ms, &error, &reply); if (status < 0 && sd_bus_error_is_set(&error)) { - LOG_ERR("context_new: got error response: %s: %s (%d)", error.name, error.message, - sd_bus_error_get_errno(&error)); + LOG_ERR("context_setup: got error: %s: %s (%d)", error.name, error.message, sd_bus_error_get_errno(&error)); return false; } sd_bus_message_unref(message); sd_bus_message_unref(reply); - (*context) = (struct context){ - .identity_list_ref = &m->identity_list, - .monitor_connection = connection, - .clients = tll_init(), - }; - sd_bus_add_filter(connection, NULL, context_event_handler, context); return status >= 0; @@ -765,6 +751,7 @@ static struct exposable * content_empty(struct module *mod) { struct private *m = mod->private; + mtx_lock(&mod->lock); struct tag_set tags = { .tags = (struct tag *[]){ @@ -784,11 +771,10 @@ content_empty(struct module *mod) .count = 10, }; + struct exposable *exposable = m->label->instantiate(m->label, &tags); + tag_set_destroy(&tags); mtx_unlock(&mod->lock); - struct exposable *exposable = m->label->instantiate(m->label, &tags); - - tag_set_destroy(&tags); return exposable; } @@ -862,6 +848,7 @@ content(struct module *mod) const enum tag_realtime_unit realtime_unit = (client->has_seeked_support && client->status == STATUS_PLAYING) ? TAG_REALTIME_MSECS : TAG_REALTIME_NONE; + mtx_lock(&mod->lock); struct tag_set tags = { .tags = (struct tag *[]){ tag_new_bool(mod, "has_seeked_support", client->has_seeked_support), @@ -880,11 +867,10 @@ content(struct module *mod) .count = 11, }; + struct exposable *exposable = m->label->instantiate(m->label, &tags); + tag_set_destroy(&tags); mtx_unlock(&mod->lock); - struct exposable *exposable = m->label->instantiate(m->label, &tags); - - tag_set_destroy(&tags); return exposable; } @@ -990,7 +976,7 @@ run(struct module *mod) const struct bar *bar = mod->bar; struct private *m = mod->private; - if (!context_new(m, &m->context)) { + if (!context_setup(&m->context)) { LOG_ERR("Failed to setup context"); return -1; } @@ -1054,6 +1040,7 @@ mpris_new(const struct yml_node *ident_list, size_t timeout_ms, struct particle struct private *priv = calloc(1, sizeof(*priv)); priv->label = label; priv->timeout_ms = timeout_ms; + priv->context.mpd_config = priv; size_t i = 0; for (struct yml_list_iter iter = yml_list_iter(ident_list); iter.node != NULL; yml_list_next(&iter), i++) { @@ -1082,7 +1069,6 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) if (query_timeout != NULL) timeout_ms = yml_value_as_int(query_timeout) * 1000; - return mpris_new(ident_list, timeout_ms, conf_to_particle(c, inherited)); } From abeffbd9a9fd0b2133343e1149e65d4a795a43d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 5 May 2025 08:14:47 +0200 Subject: [PATCH 112/112] readme: goodbye! --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 48566dc..4e825b3 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,27 @@ # Yambar +**This project is not developed anymore, and this repository will be +archived in a near future**. + +I do not have neither the time nor the will to work on this +anymore. Mainly because I do not use a bar myself anymore. + +There are also technical difficulties, caused by the fact that yambar +was initially X11, and only later was Wayland support added. + +This means I have to maintain a backend (X11) I have not used myself +in many years, as well as trying to work around technical limitations +imposed by the way both X11 and Wayland is supported, As my own use of +a bar has dwindled, the will to refactor and improve the backends has +disappeared. + +Yambar has seen a lot of contributions, for which I am very +grateful. I hope that means someone is willing to pick up where I left +of, and continue working on yambar. If not, we at least had a good +run; the first commit was in late 2018, roughly 6½ years ago! + + [![Packaging status](https://repology.org/badge/vertical-allrepos/yambar.svg?columns=4)](https://repology.org/project/yambar/versions)