From f2639226c7431bc11472ca19a4994e722d33ad22 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Tue, 9 Sep 2025 21:21:04 +0100 Subject: [PATCH 01/55] labwc-config(5): add example for autoEnableOutputs ...with inspiration from example in #3059 by @jlindgren90 --- docs/labwc-config.5.scd | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 95600d3b..a854d886 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -228,6 +228,23 @@ this is for compatibility with Openbox. unless an external tool such as `wlr-randr` or `kanshi` is used to manage outputs. + The reason for the existance of this option is that after losing signal + from the PC (e.g. by `wlopm -off`), some monitors do an input detection + that makes it appear (from the PC side) to disconnect and reconnect a + few seconds later, causing the monitor to turn back on again (as labwc + auto-enables newly connected outputs by default). + + An example usage pattern to avoid the above behavior looks as follows: + - Set ** to *no* + - Run kanshi (e.g. from autostart) and rely on it to enable new outputs + - Have swayidle kill and restart kanshi when entering powersave as + follows: + + ``` + swayidle -w timeout 600 \\ + 'pkill kanshi ; wlopm --off \*' resume 'kanshi & wlopm --on \*' + ``` + ** [yes|no] Try to re-use the existing output mode (resolution / refresh rate). This may prevent unnecessary screenblank delays when starting labwc From e17ec0203c3ea837829e8a50b62714430823c789 Mon Sep 17 00:00:00 2001 From: "thatonecoder (formerly Coccocoa's Helper)" <157546848+Coccocoahelper@users.noreply.github.com> Date: Thu, 11 Sep 2025 08:47:31 +0100 Subject: [PATCH 02/55] CONTRIBUTING.md: fix some typos, lots of Oxford commas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The primary change is “Github”/“github” ⇾ “GitHub”, but there are plenty of others. --- CONTRIBUTING.md | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c1025234..1a2251ad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,14 +23,14 @@ # How to Contribute -1. Report bugs as github issues. We use a template prompting you to provide +1. Report bugs as GitHub issues. We use a template prompting you to provide some sensible information such as what happened, what you expected to happen - and steps to reproduce. If applicable try with default configuration. If - you are able to, try to do some debugging (guidelines below). + and steps to reproduce. If applicable try with default configuration. If + you are able to, try debugging (guidelines below). -2. Submit patches as github pull-requests. If you wish to introduces significant +2. Submit patches as GitHub pull requests. If you wish to introduce significant changes or new features, consult the [scope document], discuss on IRC or via - a github issue first. + a GitHub issue first. # Debugging @@ -251,14 +251,14 @@ We try to keep the use of GLib pretty minimal for the following reasons: - The use of GLib has been known to make AddressSanitiser diagnose false positives and negatives. - Log messages coming from GLib functions look inconsistent. -- The use of GLib functions, naming-conventions and iterators in a code base +- The use of GLib functions, naming-conventions and iterators in a codebase that is predominantly ANSI C creates a clash which makes readability and maintainability harder. - Mixing gmalloc()/malloc() and respective free()s can create problems with memory pools [^1] -Having said that, with our use of cairo and pango we depend on glib-2.0 anyway -so linking with it and making use of some of its helper functions comes for free +Having said that, with our use of cairo and pango we depend on glib-2.0 anyway, +so linking with it and making use of some of its helper functions comes for free, and can keep the code simpler. For example, if we were going to carry out extensive string manipulation, @@ -291,7 +291,7 @@ match(const gchar *pattern, const gchar *string) ### The Use of GNU Extensions -We avoid [GNU C extensions] because we want to fit into the eco-system +We avoid [GNU C extensions] because we want to fit into the ecosystem (wayland and wlroots) we live in. We do use `__typeof__` which strictly speaking is a GNU C extension (`typeof`) @@ -300,18 +300,18 @@ but through the use of `__` is supported by gcc and clang without defining in the [`wl_container_of()`] macro which is needed in `wl_list*` and it does provide pretty big benefits in terms of type safety. -We compile with `-std=c11` because that's what 'wlroots' uses and we do not +We compile with `-std=c11` because that's what 'wlroots' uses, and we do not want to increase the entry-level for OSs without good reason (and currently we can't think of one). ### Naming Conventions -There are three types of coordinate systems: surface, output and layout - for +There are three types of coordinate systems: surface, output, and layout — for which the variables (sx, sy), (ox, oy) and (lx, ly) are used respectively in line with wlroots. With the introduction of the scene-graph API, some wlroots functions also use -node coordinates (nx, ny) but we prefer (sx, sy) where possible. +node coordinates (nx, ny), but we prefer (sx, sy) where possible. We do not worry about namespace issues too much and we try to not make the code a pain to use just to uniquify names. If we were writing a library we would @@ -361,11 +361,11 @@ In new files, please order `#include` lines as follows: compiles cleanly on its own, without implicit dependencies on other headers being included first. -- Then list any "system" headers (those not part of labwc) in alphebetical +- Then list any "system" headers (those not part of labwc) in alphabetical order, using angle brackets. This includes 3rd-party library headers such as ``, as well as wlroots headers. -- Then list any other labwc headers in alphetical order, using quotation +- Then list any other labwc headers in alphabetical order, using quotation marks and relative to the `include/` folder. Subfolders below `include/`, such as `common/`, should be specified even when including one header from another in the same folder (for example, `#include "common/buf.h"` @@ -388,11 +388,11 @@ This first line should: - In most cases be prefixed with "area: " where area refers to a filename or identifier for the general area of the code being modified. - Not capitalize the first word following the "area: " prefix, unless - it's a name, acronym or similar. + it's a name, acronym, or similar. - Skip the full stop And please wrap the commit message at max 74 characters, otherwise `git log` -and similar look so weird. URLs and other references are exempt. +and similar look very weird. URLs and other references are exempt. # Unit Tests @@ -404,9 +404,9 @@ In the bigger scheme of validating that the compositor meets users' needs, unit tests do not contribute a great deal. However, they have a role to play in providing some verification that stand-alone functions behave as expected. -On this project, writing unit-tests is not compulsory nor do we measure +On this project, writing unit-tests is not compulsory, nor do we measure coverage. The inclusion of the t/ directory does not signify a move towards -test-driven development. We intend to use unit tests sparingly and only when +test-driven development. We intend to use unit tests sparingly, and only when devs find them useful. ## Usage @@ -432,17 +432,17 @@ and use the web interface. Adding new languages should work, otherwise the administrators can be contacted. Suggestions for improving existing translations can be added without account. -### Github Pull Request +### GitHub Pull Request Translators can add their `MY_LOCALE.po` files to the `po` directory -based on `po/labwc.pot` and issue a pull request. To do this they can +based on `po/labwc.pot`, and issue a pull request. To do this they can generate their `MY_LOCALE.po` file in a few steps: 1. Edit the `po/LINGUAS` file to add their locale code in English alphabetical order to the field of locale codes. 2. Copy the `po/labwc.pot` to `po/MY_LOCALE.po` 3. Edit the newly generated `MY_LOCALE.po` file with some of their -contact and locale details in the header of the file then add the +contact and locale details in the header of the file. Then, add the translation strings under each English string. [See this tutorial for further guidance](https://www.labri.fr/perso/fleury/posts/programming/a-quick-gettext-tutorial.html) @@ -483,13 +483,13 @@ follow the steps to be taken: 2. Update `NEWS.md` with the release details and run `git commit -m 'NEWS.md: update notes for X.Y.Z'` Note: If new dependencies are needed, make this clear. -3. In `meson.build` update the version and (if required) the wlroots +3. In `meson.build`, update the version, and (if required) the wlroots dependency version. Then run `git commit -m 'build: bump version to X.Y.Z'` 4. Run `git tag -a X.Y.Z`. The first line of the commit message should be "labwc X.Y.Z" and the body should be the `NEWS.md` additions removing hash characters (#) from the headings as these will otherwise be ignored by git. -5. On github, create a 'Release' as some distros use this as a trigger. Set it +5. On GitHub, create a 'Release' as some distros use this as a trigger. Set it as 'latest release'. [scope document]: https://github.com/labwc/labwc-scope#readme @@ -510,4 +510,3 @@ follow the steps to be taken: different memory pools (and new/delete call constructors and destructors)." See: https://docs.gtk.org/glib/memory.html - From bca0ec07ac162ba7bed3d7aa66ed005bbd380063 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 8 Sep 2025 22:35:23 -0400 Subject: [PATCH 03/55] rcxml: use fixed arrays for rc.title_buttons_* These are just lists of enum lab_node_type, with a bounded size and no middle-insertions/removals, so linked lists are overkill. Also, the use of wl_list_for_each[_reverse] just to access the first or last entry in the list (corner button) was weird. --- include/config/rcxml.h | 16 +++++++++------- src/config/rcxml.c | 33 ++++++++++----------------------- src/ssd/ssd-titlebar.c | 19 ++++++++++--------- src/theme.c | 27 +++++++++------------------ 4 files changed, 38 insertions(+), 57 deletions(-) diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 33c49376..89e215c0 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -14,6 +14,9 @@ #define BUTTON_MAP_MAX 16 +/* max of one button of each type (no repeats) */ +#define TITLE_BUTTONS_MAX ((LAB_NODE_BUTTON_LAST + 1) - LAB_NODE_BUTTON_FIRST) + enum adaptive_sync_mode { LAB_ADAPTIVE_SYNC_DISABLED, LAB_ADAPTIVE_SYNC_ENABLED, @@ -48,11 +51,6 @@ struct button_map_entry { uint32_t to; }; -struct title_button { - enum lab_node_type type; - struct wl_list link; -}; - struct usable_area_override { struct border margin; char *output; @@ -88,8 +86,12 @@ struct rcxml { char *theme_name; char *icon_theme_name; char *fallback_app_icon_name; - struct wl_list title_buttons_left; - struct wl_list title_buttons_right; + + enum lab_node_type title_buttons_left[TITLE_BUTTONS_MAX]; + int nr_title_buttons_left; + enum lab_node_type title_buttons_right[TITLE_BUTTONS_MAX]; + int nr_title_buttons_right; + int corner_radius; bool show_title; bool title_layout_loaded; diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 35195345..74733441 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -116,7 +116,8 @@ parse_window_type(const char *type) * desk D All-desktops toggle (aka omnipresent) */ static void -fill_section(const char *content, struct wl_list *list, uint32_t *found_buttons) +fill_section(const char *content, enum lab_node_type *buttons, int *count, + uint32_t *found_buttons /* bitmask */) { gchar **identifiers = g_strsplit(content, ",", -1); for (size_t i = 0; identifiers[i]; ++i) { @@ -162,9 +163,8 @@ fill_section(const char *content, struct wl_list *list, uint32_t *found_buttons) *found_buttons |= (1 << type); - struct title_button *item = znew(*item); - item->type = type; - wl_list_append(list, &item->link); + assert(*count < TITLE_BUTTONS_MAX); + buttons[(*count)++] = type; } g_strfreev(identifiers); } @@ -172,15 +172,8 @@ fill_section(const char *content, struct wl_list *list, uint32_t *found_buttons) static void clear_title_layout(void) { - struct title_button *button, *button_tmp; - wl_list_for_each_safe(button, button_tmp, &rc.title_buttons_left, link) { - wl_list_remove(&button->link); - zfree(button); - } - wl_list_for_each_safe(button, button_tmp, &rc.title_buttons_right, link) { - wl_list_remove(&button->link); - zfree(button); - } + rc.nr_title_buttons_left = 0; + rc.nr_title_buttons_right = 0; rc.title_layout_loaded = false; } @@ -189,11 +182,6 @@ fill_title_layout(char *content) { clear_title_layout(); - struct wl_list *sections[] = { - &rc.title_buttons_left, - &rc.title_buttons_right, - }; - gchar **parts = g_strsplit(content, ":", -1); if (g_strv_length(parts) != 2) { @@ -202,9 +190,10 @@ fill_title_layout(char *content) } uint32_t found_buttons = 0; - for (size_t i = 0; parts[i]; ++i) { - fill_section(parts[i], sections[i], &found_buttons); - } + fill_section(parts[0], rc.title_buttons_left, + &rc.nr_title_buttons_left, &found_buttons); + fill_section(parts[1], rc.title_buttons_right, + &rc.nr_title_buttons_right, &found_buttons); rc.title_layout_loaded = true; err: @@ -1362,8 +1351,6 @@ rcxml_init(void) static bool has_run; if (!has_run) { - wl_list_init(&rc.title_buttons_left); - wl_list_init(&rc.title_buttons_right); wl_list_init(&rc.usable_area_overrides); wl_list_init(&rc.keybinds); wl_list_init(&rc.mousebinds); diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 595a203d..13f5e7df 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -81,7 +81,6 @@ ssd_titlebar_create(struct ssd *ssd) LAB_NODE_TITLE, view, /*data*/ NULL); /* Buttons */ - struct title_button *b; int x = theme->window_titlebar_padding_width; /* Center vertically within titlebar */ @@ -90,20 +89,22 @@ ssd_titlebar_create(struct ssd *ssd) wl_list_init(&subtree->buttons_left); wl_list_init(&subtree->buttons_right); - wl_list_for_each(b, &rc.title_buttons_left, link) { + for (int b = 0; b < rc.nr_title_buttons_left; b++) { + enum lab_node_type type = rc.title_buttons_left[b]; struct lab_img **imgs = - theme->window[active].button_imgs[b->type]; - attach_ssd_button(&subtree->buttons_left, b->type, parent, + theme->window[active].button_imgs[type]; + attach_ssd_button(&subtree->buttons_left, type, parent, imgs, x, y, view); x += theme->window_button_width + theme->window_button_spacing; } x = width - theme->window_titlebar_padding_width + theme->window_button_spacing; - wl_list_for_each_reverse(b, &rc.title_buttons_right, link) { + for (int b = rc.nr_title_buttons_right - 1; b >= 0; b--) { x -= theme->window_button_width + theme->window_button_spacing; + enum lab_node_type type = rc.title_buttons_right[b]; struct lab_img **imgs = - theme->window[active].button_imgs[b->type]; - attach_ssd_button(&subtree->buttons_right, b->type, parent, + theme->window[active].button_imgs[type]; + attach_ssd_button(&subtree->buttons_right, type, parent, imgs, x, y, view); } } @@ -223,8 +224,8 @@ update_visible_buttons(struct ssd *ssd) int width = MAX(view->current.width - 2 * theme->window_titlebar_padding_width, 0); int button_width = theme->window_button_width; int button_spacing = theme->window_button_spacing; - int button_count_left = wl_list_length(&rc.title_buttons_left); - int button_count_right = wl_list_length(&rc.title_buttons_right); + int button_count_left = rc.nr_title_buttons_left; + int button_count_right = rc.nr_title_buttons_right; /* Make sure infinite loop never occurs */ assert(button_width > 0); diff --git a/src/theme.c b/src/theme.c index f0b48158..d5279367 100644 --- a/src/theme.c +++ b/src/theme.c @@ -231,25 +231,16 @@ load_button(struct theme *theme, struct button *b, int active) struct lab_img **rounded_img = &button_imgs[b->type][b->state_set | LAB_BS_ROUNDED]; - struct title_button *leftmost_button; - wl_list_for_each(leftmost_button, - &rc.title_buttons_left, link) { - if (leftmost_button->type == b->type) { - *rounded_img = lab_img_copy(*img); - lab_img_add_modifier(*rounded_img, - round_left_corner_button); - } - break; + if (rc.nr_title_buttons_left > 0 + && b->type == rc.title_buttons_left[0]) { + *rounded_img = lab_img_copy(*img); + lab_img_add_modifier(*rounded_img, round_left_corner_button); } - struct title_button *rightmost_button; - wl_list_for_each_reverse(rightmost_button, - &rc.title_buttons_right, link) { - if (rightmost_button->type == b->type) { - *rounded_img = lab_img_copy(*img); - lab_img_add_modifier(*rounded_img, - round_right_corner_button); - } - break; + if (rc.nr_title_buttons_right > 0 + && b->type == rc.title_buttons_right + [rc.nr_title_buttons_right - 1]) { + *rounded_img = lab_img_copy(*img); + lab_img_add_modifier(*rounded_img, round_right_corner_button); } } From 0ce10f6afa5093dd92e0b0e317f136ca4b177fff Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 6 Sep 2025 23:31:00 -0400 Subject: [PATCH 04/55] interactive: add braces around case containing declaration --- src/interactive.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/interactive.c b/src/interactive.c index f66a66b3..f9c7f771 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -101,7 +101,7 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) cursor_shape = LAB_CURSOR_GRAB; break; - case LAB_INPUT_STATE_RESIZE: + case LAB_INPUT_STATE_RESIZE: { if (view->shaded || view->fullscreen || view->maximized == VIEW_AXIS_BOTH) { /* @@ -133,6 +133,7 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) view_set_untiled(view); cursor_shape = cursor_get_from_edge(edges); break; + } default: /* Should not be reached */ return; From 072d45d4b2e1ee3773084320e674a460c9356fb9 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 6 Sep 2025 23:31:38 -0400 Subject: [PATCH 05/55] osd-thumbnail: put designated initializers in order --- src/osd/osd-thumbnail.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/osd/osd-thumbnail.c b/src/osd/osd-thumbnail.c index 0345582a..24505a31 100644 --- a/src/osd/osd-thumbnail.c +++ b/src/osd/osd-thumbnail.c @@ -130,12 +130,12 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view, /* background for selected item */ struct lab_scene_rect_options opts = { + .border_colors = (float *[1]) { switcher_theme->item_active_border_color }, + .nr_borders = 1, + .border_width = switcher_theme->item_active_border_width, + .bg_color = switcher_theme->item_active_bg_color, .width = switcher_theme->item_width, .height = switcher_theme->item_height, - .bg_color = switcher_theme->item_active_bg_color, - .nr_borders = 1, - .border_colors = (float *[1]) { switcher_theme->item_active_border_color }, - .border_width = switcher_theme->item_active_border_width, }; item->active_bg = lab_scene_rect_create(item->tree, &opts); @@ -241,12 +241,12 @@ osd_thumbnail_create(struct output *output, struct wl_array *views) /* background */ struct lab_scene_rect_options bg_opts = { - .width = nr_cols * switcher_theme->item_width + 2 * padding, - .height = nr_rows * switcher_theme->item_height + 2 * padding, - .bg_color = theme->osd_bg_color, + .border_colors = (float *[1]) { theme->osd_border_color }, .nr_borders = 1, .border_width = theme->osd_border_width, - .border_colors = (float *[1]) { theme->osd_border_color }, + .bg_color = theme->osd_bg_color, + .width = nr_cols * switcher_theme->item_width + 2 * padding, + .height = nr_rows * switcher_theme->item_height + 2 * padding, }; struct lab_scene_rect *bg = lab_scene_rect_create(output->osd_scene.tree, &bg_opts); From 5ce20b2b958df6638752f0579eba06b5a95449fd Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 8 Sep 2025 20:10:42 -0400 Subject: [PATCH 06/55] rcxml: use const char* for string literals --- src/config/rcxml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 74733441..aeeecc20 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -178,7 +178,7 @@ clear_title_layout(void) } static void -fill_title_layout(char *content) +fill_title_layout(const char *content) { clear_title_layout(); From d54051d9c12eeb713251781e9f5273b39565879d Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 8 Sep 2025 20:34:27 -0400 Subject: [PATCH 07/55] clang-format: tweak to match existing code a little better "clang-format -i src/view.c" before: 1 file changed, 204 insertions(+), 169 deletions(-) "clang-format -i src/view.c" after: 1 file changed, 181 insertions(+), 146 deletions(-) --- .clang-format | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.clang-format b/.clang-format index a8e09433..b3b6af52 100644 --- a/.clang-format +++ b/.clang-format @@ -12,14 +12,21 @@ UseTab: Always IndentWidth: 8 ContinuationIndentWidth: 8 AlignAfterOpenBracket: DontAlign +AlignOperands: false AlwaysBreakAfterDefinitionReturnType: true BreakBeforeBinaryOperators: NonAssignment BreakBeforeBraces: Linux IndentCaseLabels: false +PenaltyBreakOpenParenthesis: 100 +PenaltyReturnTypeOnItsOwnLine: 500 SpaceBeforeParens: ControlStatementsExceptControlMacros ForEachMacros: ['for_each_view', + 'for_each_view_reverse', 'wl_array_for_each', 'wl_list_for_each', 'wl_list_for_each_reverse', 'wl_list_for_each_reverse_safe', 'wl_list_for_each_safe'] +IncludeCategories: + - Regex: '<.*>' + - Regex: '.*' From f09ace51bfb85b82cba8e434c69c6466aabd3f90 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 15 Sep 2025 03:31:56 +0900 Subject: [PATCH 08/55] view: fix Before this commit, branch was always executed with monitor="current", monitor="left" or monitor="right" queries. For example: --- src/view.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/view.c b/src/view.c index ef871313..97616cbc 100644 --- a/src/view.c +++ b/src/view.c @@ -215,20 +215,25 @@ view_matches_query(struct view *view, struct view_query *query) if (query->monitor) { struct output *current = output_nearest_to_cursor(view->server); - - if (!strcasecmp(query->monitor, "current") && current != view->output) { - return false; - } - if (!strcasecmp(query->monitor, "left") && - output_get_adjacent(current, LAB_EDGE_LEFT, false) != view->output) { - return false; - } - if (!strcasecmp(query->monitor, "right") && - output_get_adjacent(current, LAB_EDGE_RIGHT, false) != view->output) { - return false; - } - if (output_from_name(view->server, query->monitor) != view->output) { - return false; + if (!strcasecmp(query->monitor, "current")) { + if (current != view->output) { + return false; + } + } else if (!strcasecmp(query->monitor, "left")) { + if (output_get_adjacent(current, LAB_EDGE_LEFT, false) + != view->output) { + return false; + } + } else if (!strcasecmp(query->monitor, "right")) { + if (output_get_adjacent(current, LAB_EDGE_RIGHT, false) + != view->output) { + return false; + } + } else { + if (output_from_name(view->server, query->monitor) + != view->output) { + return false; + } } } From 268ef857db51699d284422c9fac46711c70999a8 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 15 Sep 2025 19:31:05 +0100 Subject: [PATCH 09/55] NEWS.md: interim update --- NEWS.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 8cfac48f..4216dad6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| -| 2025-08-25 | [unreleased] | 0.19.0 | | +| 2025-09-15 | [unreleased] | 0.19.0 | 28686 | | 2025-08-02 | [0.9.1] | 0.19.0 | 28605 | | 2025-07-11 | [0.9.0] | 0.19.0 | 28586 | | 2025-05-02 | [0.8.4] | 0.18.2 | 27679 | @@ -110,6 +110,12 @@ There are some regression warnings worth noting for the switch to wlroots 0.19: ### Added +- Support `Border` context for mousebinds as an alias for `Top`...`BRCorner` to + make configuration easier. @tokyo4j [#3047] +- Add window-switcher mode with thumbnails. This can be enabled with: + ``. @tokyo4j [#2981] +- Add `toggle` option to `GoToDesktop` action. This has the effect of going back + to the last desktop if already on the target. @RainerKuemmerle [#3024] - Add `` to allow hiding titlebar when window is maximized. @CosmicFusion @tokyo4j [#3015] - Use client-send-to-menu as 'Workspace' submenu in built-in client-menu @@ -141,6 +147,10 @@ There are some regression warnings worth noting for the switch to wlroots 0.19: ### Fixed +- Restore initially-maximized window position after unplug/plug @tokyo4j [#3042] +- Fix large client-side icon not being loaded when the rendered icon size is + larger than icon sizes from the client. @tokyo4j [#3033] +- Improve debug logging for configuring input devices @jlindgren90 [#3028] - Fix false positives when matching desktop entries @datMaffin [#3004] - Prevent accidental downcasting of scale in scaled-icon-buffer to avoid blurry icons on non-integer scales and a cairo assert when using a output scale < 1. @@ -152,6 +162,16 @@ There are some regression warnings worth noting for the switch to wlroots 0.19: ### Changed +- `Focus` and `Raise` on window border press because it is probably what most + people expect and it makes the behavior consistent with that of Openbox. + @johanmalm [#3039] [#3049] +- On interactive resize, only un-maximize the axis/axes that are being resized. + @jlindgren90 [#3043] +- Change theme setting `osd.window-switcher.*` to + `osd.window-switcher.style-classic.*`. Backward compatibility is preserved. + @tokyo4j [#2981] +- In client-list menu, add brackets around the titles of any minimised windows + @davidphilipbarr [#3002] - Respect client-initiated window resize of non-maximized axis, for example remember the width of vertically-maximized window resizing itself horizontally. @jlindgren90 [#3020] @@ -2763,10 +2783,20 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#2971]: https://github.com/labwc/labwc/pull/2971 [#2972]: https://github.com/labwc/labwc/pull/2972 [#2976]: https://github.com/labwc/labwc/pull/2976 +[#2981]: https://github.com/labwc/labwc/pull/2981 [#2994]: https://github.com/labwc/labwc/pull/2994 [#2995]: https://github.com/labwc/labwc/pull/2995 [#2998]: https://github.com/labwc/labwc/pull/2998 +[#3002]: https://github.com/labwc/labwc/pull/3002 [#3004]: https://github.com/labwc/labwc/pull/3004 [#3011]: https://github.com/labwc/labwc/pull/3011 [#3015]: https://github.com/labwc/labwc/pull/3015 [#3020]: https://github.com/labwc/labwc/pull/3020 +[#3024]: https://github.com/labwc/labwc/pull/3024 +[#3028]: https://github.com/labwc/labwc/pull/3028 +[#3033]: https://github.com/labwc/labwc/pull/3033 +[#3039]: https://github.com/labwc/labwc/pull/3039 +[#3042]: https://github.com/labwc/labwc/pull/3042 +[#3043]: https://github.com/labwc/labwc/pull/3043 +[#3047]: https://github.com/labwc/labwc/pull/3047 +[#3049]: https://github.com/labwc/labwc/pull/3049 From c6503e299feaf267b800c96251f3c1895a51d292 Mon Sep 17 00:00:00 2001 From: cunlem <87859114+cunlem@users.noreply.github.com> Date: Tue, 16 Sep 2025 18:48:20 +0000 Subject: [PATCH 10/55] Update labwc-actions.5.scd --- docs/labwc-actions.5.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index aa273111..4879873d 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -479,7 +479,7 @@ Actions that execute other actions. Used in keyboard/mouse bindings. The "left" , "right", "left-occupied" and "right-occupied" directions will not wrap. - *tiled* [up|right|down|left|top-left|top-right|down-left|down-right|center|any] + *tiled* [up|right|down|left|up-left|up-right|down-left|down-right|center|any] Whether the client is tiled (snapped) along the the indicated screen edge. From 387e62d87b51a387d1e07ab6d1118fd586cfb9c5 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 17 Sep 2025 21:12:08 +0100 Subject: [PATCH 11/55] README.md: remove yambar reference as discontinued --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 26ce81ca..7f21b2b5 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ Suggested apps to use with Labwc: - Screen shooter: [grim] - Screen recorder: [wf-recorder] - Background image: [swaybg] -- Panel: [waybar], [yambar], [lavalauncher], [sfwbar], [xfce4-panel] +- Panel: [waybar], [lavalauncher], [sfwbar], [xfce4-panel] - Launchers: [bemenu], [fuzzel], [wofi] - Output managers: [wlopm], [kanshi], [wlr-randr] - Screen locker: [swaylock] @@ -292,7 +292,6 @@ The default window bar menu can be translated on the [weblate platform](https:// [wf-recorder]: https://github.com/ammen99/wf-recorder [swaybg]: https://github.com/swaywm/swaybg [waybar]: https://github.com/Alexays/Waybar -[yambar]: https://codeberg.org/dnkl/yambar [lavalauncher]: https://sr.ht/~leon_plickat/LavaLauncher [sfwbar]: https://github.com/LBCrion/sfwbar [xfce4-panel]: https://gitlab.xfce.org/xfce/xfce4-panel From 0db3b9309bce5eca478781c3b5af3324e5db990b Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 18 Sep 2025 21:39:30 +0100 Subject: [PATCH 12/55] libsfdo.wrap: update revision to v0.1.4 --- subprojects/libsfdo.wrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/libsfdo.wrap b/subprojects/libsfdo.wrap index 22df1d6a..d05264db 100644 --- a/subprojects/libsfdo.wrap +++ b/subprojects/libsfdo.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/vyivel/libsfdo.git -revision = v0.1.3 +revision = v0.1.4 [provide] dependency_names = libsfdo-basedir, libsfdo-desktop, libsfdo-icon From af6a0df2311fa8b38c532285b3868a649f7998f5 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 15 Sep 2025 03:54:40 +0900 Subject: [PATCH 13/55] view: remove an obsolete code in view_snap_to_edge() We no longer need to call view_apply_tiled_geometry() there, since we now clear view->tiled when dragging a tiled window since 9f51384. --- src/view.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/view.c b/src/view.c index 97616cbc..13b36a54 100644 --- a/src/view.c +++ b/src/view.c @@ -2145,17 +2145,7 @@ view_snap_to_edge(struct view *view, enum lab_edge edge, if (across_outputs && view->tiled == edge && view->maximized == VIEW_AXIS_NONE) { /* We are already tiled for this edge; try to switch outputs */ output = output_get_adjacent(view->output, edge, /* wrap */ false); - if (!output) { - /* - * No more output to move to - * - * We re-apply the tiled geometry without changing any - * state because the window might have been moved away - * (and thus got untiled) and then snapped back to the - * original edge. - */ - view_apply_tiled_geometry(view); return; } From 2ac48116e14491abec2326e70190a32192df6764 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Fri, 5 Sep 2025 12:14:52 +0900 Subject: [PATCH 14/55] action: allow SnapToEdge to combine two cardinal directions This patch adds `combine` argument to (Toggle)SnapToEdge actions. This allows to snap a window to e.g. up-left by running two actions: - `` - `` Then running `` snaps it to left again. This behavior is almost the same as KWin, except that snapping a up-right-tiled window to right doesn't move it to the right-adjacent output, but makes it right-tiled first. --- docs/labwc-actions.5.scd | 17 +++++++++----- include/view.h | 2 +- src/action.c | 22 +++++++++++------- src/interactive.c | 5 ++--- src/view.c | 48 ++++++++++++++++++++++++++++++++-------- 5 files changed, 68 insertions(+), 26 deletions(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index 4879873d..4a76a374 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -92,11 +92,18 @@ Actions are used in menus and keyboard/mouse bindings. Move window relative to its current position. Positive value of x moves it right, negative left. Positive value of y moves it down, negative up. -**++ -** - Resize window to fill half the output in the given direction. Supports - directions "left", "up", "right", "down", "up-left", "up-right", "down-left", - "down-right" and "center". +**++ +** + Resize window to fill half or quarter the output in the given direction. + + *direction* [up|down|left|right|up-left|up-right|down-left|down-right|center] + Direction in which to snap the window. + + *combine* [yes|no] + Allows to snap a window to an output corner by combining two + directions. For example, snapping a window to *right* and then + to *up* places it in the *up-right* quarter of the output. + Default is no. ToggleSnapToEdge additionally toggles the active window between tiled to the given direction and its untiled position. diff --git a/include/view.h b/include/view.h index 5ff70984..efdcf3fd 100644 --- a/include/view.h +++ b/include/view.h @@ -548,7 +548,7 @@ void view_move_to_edge(struct view *view, enum lab_edge direction, bool snap_to_ void view_grow_to_edge(struct view *view, enum lab_edge direction); void view_shrink_to_edge(struct view *view, enum lab_edge direction); void view_snap_to_edge(struct view *view, enum lab_edge direction, - bool across_outputs, bool store_natural_geometry); + bool across_outputs, bool combine, bool store_natural_geometry); void view_snap_to_region(struct view *view, struct region *region, bool store_natural_geometry); void view_move_to_output(struct view *view, struct output *output); diff --git a/src/action.c b/src/action.c index 60c57b33..ab9d3e18 100644 --- a/src/action.c +++ b/src/action.c @@ -337,11 +337,6 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char } break; case ACTION_TYPE_MOVE_TO_EDGE: - if (!strcasecmp(argument, "snapWindows")) { - action_arg_add_bool(action, argument, parse_bool(content, true)); - goto cleanup; - } - /* Falls through */ case ACTION_TYPE_TOGGLE_SNAP_TO_EDGE: case ACTION_TYPE_SNAP_TO_EDGE: case ACTION_TYPE_GROW_TO_EDGE: @@ -358,6 +353,17 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char } goto cleanup; } + if (action->type == ACTION_TYPE_MOVE_TO_EDGE + && !strcasecmp(argument, "snapWindows")) { + action_arg_add_bool(action, argument, parse_bool(content, true)); + goto cleanup; + } + if ((action->type == ACTION_TYPE_SNAP_TO_EDGE + || action->type == ACTION_TYPE_TOGGLE_SNAP_TO_EDGE) + && !strcasecmp(argument, "combine")) { + action_arg_add_bool(action, argument, parse_bool(content, false)); + goto cleanup; + } break; case ACTION_TYPE_SHOW_MENU: if (!strcmp(argument, "menu")) { @@ -1031,9 +1037,9 @@ run_action(struct view *view, struct server *server, struct action *action, view_apply_natural_geometry(view); break; } - view_snap_to_edge(view, edge, - /*across_outputs*/ true, - /*store_natural_geometry*/ true); + bool combine = action_get_bool(action, "combine", false); + view_snap_to_edge(view, edge, /*across_outputs*/ true, + combine, /*store_natural_geometry*/ true); } break; case ACTION_TYPE_GROW_TO_EDGE: diff --git a/src/interactive.c b/src/interactive.c index f9c7f771..8ca258c1 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -260,9 +260,8 @@ snap_to_edge(struct view *view) view_maximize(view, VIEW_AXIS_BOTH, /*store_natural_geometry*/ false); } else { - view_snap_to_edge(view, edge, - /*across_outputs*/ false, - /*store_natural_geometry*/ false); + view_snap_to_edge(view, edge, /*across_outputs*/ false, + /*combine*/ false, /*store_natural_geometry*/ false); } return true; diff --git a/src/view.c b/src/view.c index 13b36a54..e402b626 100644 --- a/src/view.c +++ b/src/view.c @@ -2126,7 +2126,7 @@ view_placement_parse(const char *policy) void view_snap_to_edge(struct view *view, enum lab_edge edge, - bool across_outputs, bool store_natural_geometry) + bool across_outputs, bool combine, bool store_natural_geometry) { assert(view); @@ -2142,15 +2142,45 @@ view_snap_to_edge(struct view *view, enum lab_edge edge, view_set_shade(view, false); - if (across_outputs && view->tiled == edge && view->maximized == VIEW_AXIS_NONE) { - /* We are already tiled for this edge; try to switch outputs */ - output = output_get_adjacent(view->output, edge, /* wrap */ false); - if (!output) { - return; - } + if (lab_edge_is_cardinal(edge) && view->maximized == VIEW_AXIS_NONE) { + enum lab_edge invert_edge = lab_edge_invert(edge); + /* Represents axis of snapping direction */ + enum lab_edge parallel_mask = edge | invert_edge; + /* + * The vector view->tiled is split to components + * parallel/orthogonal to snapping direction. For example, + * view->tiled=TOP_LEFT is split to parallel_tiled=TOP and + * orthogonal_tiled=LEFT when edge=TOP or edge=BOTTOM. + */ + enum lab_edge parallel_tiled = view->tiled & parallel_mask; + enum lab_edge orthogonal_tiled = view->tiled & ~parallel_mask; - /* When switching outputs, jump to the opposite edge */ - edge = lab_edge_invert(edge); + if (across_outputs && view->tiled == edge) { + /* + * E.g. when window is tiled to up and being snapped + * to up again, move it to the output above and tile + * it to down. + */ + output = output_get_adjacent(view->output, edge, + /* wrap */ false); + if (!output) { + return; + } + edge = invert_edge; + } else if (combine && parallel_tiled == invert_edge + && orthogonal_tiled != LAB_EDGE_NONE) { + /* + * E.g. when window is tiled to downleft/downright and + * being snapped to up, tile it to left/right. + */ + edge = view->tiled & ~parallel_mask; + } else if (combine && parallel_tiled == LAB_EDGE_NONE) { + /* + * E.g. when window is tiled to left/right and being + * snapped to up, tile it to upleft/upright. + */ + edge = view->tiled | edge; + } } if (view->maximized != VIEW_AXIS_NONE) { From 24f39e3a41b50cca3f0c26bada9295a3b39ded9e Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Wed, 17 Sep 2025 16:25:32 +0900 Subject: [PATCH 15/55] default-bindings.h: set combine="yes" for SnapToEdge keybinds --- docs/labwc-config.5.scd | 2 +- docs/rc.xml.all | 8 ++++---- include/config/default-bindings.h | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index a854d886..7ddf2d5b 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -727,7 +727,7 @@ extending outward from the snapped edge. W-Return - lab-sensible-terminal A-F4 - close window W-a - toggle maximize - W- - resize window to fill half the output + W- - resize window to fill half or quarter of the output A-Space - show window menu ``` diff --git a/docs/rc.xml.all b/docs/rc.xml.all index a96993ab..12d0c761 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -271,16 +271,16 @@ - + - + - + - + diff --git a/include/config/default-bindings.h b/include/config/default-bindings.h index 08caeade..9d42d237 100644 --- a/include/config/default-bindings.h +++ b/include/config/default-bindings.h @@ -35,6 +35,10 @@ static struct key_combos { .name = "direction", .value = "left", }, + .attributes[1] = { + .name = "combine", + .value = "yes", + }, }, { .binding = "W-Right", .action = "SnapToEdge", @@ -42,6 +46,10 @@ static struct key_combos { .name = "direction", .value = "right", }, + .attributes[1] = { + .name = "combine", + .value = "yes", + }, }, { .binding = "W-Up", .action = "SnapToEdge", @@ -49,6 +57,10 @@ static struct key_combos { .name = "direction", .value = "up", }, + .attributes[1] = { + .name = "combine", + .value = "yes", + }, }, { .binding = "W-Down", .action = "SnapToEdge", @@ -56,6 +68,10 @@ static struct key_combos { .name = "direction", .value = "down", }, + .attributes[1] = { + .name = "combine", + .value = "yes", + }, }, { .binding = "A-Space", .action = "ShowMenu", From 141f932efa5b4b8c6068ca1e72512a9b542edcbb Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 19 Sep 2025 20:50:03 +0100 Subject: [PATCH 16/55] README.md: remove high-level scope summary ...as it is very old and not relevant anymore. --- README.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/README.md b/README.md index 7f21b2b5..1e8d3759 100644 --- a/README.md +++ b/README.md @@ -101,21 +101,8 @@ spend our effort. A lot of emphasis is put on code simplicity when considering features. -The main development effort is focused on producing a solid foundation for a -stacking compositor rather than adding configuration and theming options. - See [scope] for full details on implemented features. -High-level summary of items that Labwc supports: - -- [x] Config files (rc.xml, autostart, shutdown, environment, menu.xml) -- [x] Theme files and xbm/png/svg icons -- [x] Basic desktop and client menus -- [x] HiDPI -- [x] wlroots protocols such as `output-management`, `layer-shell` and - `foreign-toplevel` -- [x] Optionally xwayland - ### 1.5 Videos | video link | date | duration From ebce406b11c94f5eb3c79f54f0128bfd17901a18 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Sun, 21 Sep 2025 20:40:49 +0900 Subject: [PATCH 17/55] font: remove 4px padding on the right Added `menu.items.padding.x` padding between item text and arrow instead. Replaced `if (!string)` with `if (string_null_or_empty(string))` in `font_extents()` just as a minor optimization. --- src/common/font.c | 6 +----- src/menu/menu.c | 8 +++++--- src/ssd/resize-indicator.c | 3 --- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/common/font.c b/src/common/font.c index 81784ea8..b307729c 100644 --- a/src/common/font.c +++ b/src/common/font.c @@ -22,7 +22,7 @@ static PangoRectangle font_extents(struct font *font, const char *string) { PangoRectangle rect = { 0 }; - if (!string) { + if (string_null_or_empty(string)) { return rect; } cairo_surface_t *surface; @@ -43,10 +43,6 @@ font_extents(struct font *font, const char *string) pango_layout_get_extents(layout, NULL, &rect); pango_extents_to_pixels(&rect, NULL); - /* we put a 2 px edge on each side - because Openbox does it :) */ - /* TODO: remove the 4 pixel addition and always do the padding by the caller */ - rect.width += 4; - cairo_destroy(c); cairo_surface_destroy(surface); pango_font_description_free(desc); diff --git a/src/menu/menu.c b/src/menu/menu.c index e7a7b90c..455035ec 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -135,6 +135,7 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho assert(menu); assert(text); + struct theme *theme = menu->server->theme; struct menuitem *menuitem = znew(*menuitem); menuitem->parent = menu; menuitem->selectable = true; @@ -151,7 +152,8 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho menuitem->native_width = font_width(&rc.font_menuitem, text); if (menuitem->arrow) { - menuitem->native_width += font_width(&rc.font_menuitem, menuitem->arrow); + menuitem->native_width += font_width(&rc.font_menuitem, menuitem->arrow) + + theme->menu_items_padding_x; } wl_list_append(&menu->menuitems, &menuitem->link); @@ -177,7 +179,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, int bg_width = menu->size.width - 2 * theme->menu_border_width; int arrow_width = item->arrow ? - font_width(&rc.font_menuitem, item->arrow) : 0; + font_width(&rc.font_menuitem, item->arrow) + theme->menu_items_padding_x : 0; int label_max_width = bg_width - 2 * theme->menu_items_padding_x - arrow_width - icon_width; @@ -227,7 +229,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, scaled_font_buffer_update(arrow_buffer, item->arrow, -1, &rc.font_menuitem, text_color, bg_color); /* Vertically center and right-align arrow */ - x += label_max_width; + x += label_max_width + theme->menu_items_padding_x; y = (theme->menu_item_height - label_buffer->height) / 2; wlr_scene_node_set_position(&arrow_buffer->scene_buffer->node, x, y); diff --git a/src/ssd/resize-indicator.c b/src/ssd/resize-indicator.c index 6c22e656..3a635edc 100644 --- a/src/ssd/resize-indicator.c +++ b/src/ssd/resize-indicator.c @@ -193,9 +193,6 @@ resize_indicator_update(struct view *view) /* Let the indicator change width as required by the content */ int width = font_width(&rc.font_osd, text); - /* font_extents() adds 4 pixels to the calculated width */ - width -= 4; - resize_indicator_set_size(indicator, width); /* Center the indicator in the window */ From 7028e65154058afac01f77226e351332b1b669ec Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Tue, 23 Sep 2025 19:27:45 +0100 Subject: [PATCH 18/55] labnag: fix segfault caused by providing --timeout as long option --- clients/labnag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/labnag.c b/clients/labnag.c index 20fb1dbe..bea25dd1 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -1370,7 +1370,7 @@ nag_parse_options(int argc, char **argv, struct nag *nag, {"detailed-button", required_argument, NULL, 'L'}, {"message", required_argument, NULL, 'm'}, {"output", required_argument, NULL, 'o'}, - {"timeout", no_argument, NULL, 't'}, + {"timeout", required_argument, NULL, 't'}, {"version", no_argument, NULL, 'v'}, {"background", required_argument, NULL, TO_COLOR_BACKGROUND}, From 57655866365c4422c8f3352960c0ccc088d27bce Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 22 Sep 2025 18:32:42 +0100 Subject: [PATCH 19/55] config: add `` ...to enable configuration of the action prompt command. Also set some better defaults for labnag. The new default command is: labnag \ --message '%m' \ --button-dismiss '%n' \ --button-dismiss '%y' \ --background '%b' \ --text '%t' \ --border '%t' \ --border-bottom '%t' \ --button-background '%b' \ --button-text '%t' \ --border-bottom-size 1 \ --button-border-size 3 \ --timeout 0 ...where the conversion specifiers are defined as follows: %m: the `` message option %n: _("No") %y: _("Yes") %b: osd.bg.color %t: osd.label.text.color This config options also enables the use of a different dialog client, for example like this: zenity --question --text="%m" --- docs/rc.xml.all | 4 ++ include/action-prompt-command.h | 12 ++++ include/action.h | 2 + include/common/buf.h | 11 ++++ include/config/rcxml.h | 2 + src/action-prompt-command.c | 108 ++++++++++++++++++++++++++++++++ src/action.c | 14 +++-- src/common/buf.c | 24 +++++++ src/config/rcxml.c | 21 +++++++ src/meson.build | 1 + 10 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 include/action-prompt-command.h create mode 100644 src/action-prompt-command.c diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 12d0c761..ed80fdf0 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -19,6 +19,10 @@ no no yes + diff --git a/include/action-prompt-command.h b/include/action-prompt-command.h new file mode 100644 index 00000000..219896b9 --- /dev/null +++ b/include/action-prompt-command.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_ACTION_PROMPT_COMMAND_H +#define LABWC_ACTION_PROMPT_COMMAND_H + +struct buf; +struct action; +struct theme; + +void action_prompt_command(struct buf *buf, const char *format, + struct action *action, struct theme *theme); + +#endif /* LABWC_ACTION_PROMPT_COMMAND_H */ diff --git a/include/action.h b/include/action.h index cb88d0d5..31ecfb6e 100644 --- a/include/action.h +++ b/include/action.h @@ -23,6 +23,8 @@ struct action { struct action *action_create(const char *action_name); +const char *action_get_str(struct action *action, const char *key, + const char *default_value); bool action_is_valid(struct action *action); bool action_is_show_menu(struct action *action); diff --git a/include/common/buf.h b/include/common/buf.h index a75c1144..857b6c48 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -50,6 +50,17 @@ void buf_expand_shell_variables(struct buf *s); */ void buf_add_fmt(struct buf *s, const char *fmt, ...); +/** + * buf_add_hex_color - add rgb color as hex string to C string buffer + * @s: buffer + * @color: rgb color to be added + * + * For example: + * - With the input 'red' (defined as red[4] = { 1.0f, 0.0f, 0.0f, 1.0f}) the + * string "#ff0000ff" will be written to the buffer. + */ +void buf_add_hex_color(struct buf *s, float color[4]); + /** * buf_add - add data to C string buffer * @s: buffer diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 89e215c0..e3b7bf06 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -74,6 +74,8 @@ struct rcxml { enum lab_placement_policy placement_policy; bool xwayland_persistence; bool primary_selection; + char *prompt_command; + int placement_cascade_offset_x; int placement_cascade_offset_y; diff --git a/src/action-prompt-command.c b/src/action-prompt-command.c new file mode 100644 index 00000000..65bd0b49 --- /dev/null +++ b/src/action-prompt-command.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define _POSIX_C_SOURCE 200809L +#include "action-prompt-command.h" +#include +#include +#include "action.h" +#include "common/buf.h" +#include "labwc.h" /* for gettext */ +#include "theme.h" + +enum { + LAB_PROMPT_NONE = 0, + LAB_PROMPT_MESSAGE, + LAB_PROMPT_NO, + LAB_PROMPT_YES, + LAB_PROMPT_BG_COL, + LAB_PROMPT_TEXT_COL, + + LAB_PROMPT_COUNT +}; + +typedef void field_conversion_type(struct buf *buf, struct action *action, + struct theme *theme); + +struct field_converter { + const char fmt_char; + field_conversion_type *fn; +}; + +/* %m */ +static void +set_message(struct buf *buf, struct action *action, struct theme *theme) +{ + buf_add(buf, action_get_str(action, "message.prompt", "Choose wisely")); +} + +/* %n */ +static void +set_no(struct buf *buf, struct action *action, struct theme *theme) +{ + buf_add(buf, _("No")); +} + +/* %y */ +static void +set_yes(struct buf *buf, struct action *action, struct theme *theme) +{ + buf_add(buf, _("Yes")); +} + +/* %b */ +static void +set_bg_col(struct buf *buf, struct action *action, struct theme *theme) +{ + buf_add_hex_color(buf, theme->osd_bg_color); +} + +/* %t */ +static void +set_text_col(struct buf *buf, struct action *action, struct theme *theme) +{ + buf_add_hex_color(buf, theme->osd_label_text_color); +} + +static const struct field_converter field_converter[LAB_PROMPT_COUNT] = { + [LAB_PROMPT_MESSAGE] = { 'm', set_message }, + [LAB_PROMPT_NO] = { 'n', set_no }, + [LAB_PROMPT_YES] = { 'y', set_yes }, + [LAB_PROMPT_BG_COL] = { 'b', set_bg_col }, + [LAB_PROMPT_TEXT_COL] = { 't', set_text_col }, +}; + +void +action_prompt_command(struct buf *buf, const char *format, + struct action *action, struct theme *theme) +{ + if (!format) { + wlr_log(WLR_ERROR, "missing format"); + return; + } + + for (const char *p = format; *p; p++) { + /* + * If we're not on a conversion specifier (like %m) then just + * keep adding it to the buffer + */ + if (*p != '%') { + buf_add_char(buf, *p); + continue; + } + + /* Process the %* conversion specifier */ + ++p; + + bool found = false; + for (unsigned char i = 0; i < LAB_PROMPT_COUNT; i++) { + if (*p == field_converter[i].fmt_char) { + field_converter[i].fn(buf, action, theme); + found = true; + break; + } + } + if (!found) { + wlr_log(WLR_ERROR, + "invalid prompt command conversion specifier '%c'", *p); + } + } +} diff --git a/src/action.c b/src/action.c index ab9d3e18..62ab2b2d 100644 --- a/src/action.c +++ b/src/action.c @@ -10,6 +10,7 @@ #include #include #include "action-prompt-codes.h" +#include "action-prompt-command.h" #include "common/buf.h" #include "common/macros.h" #include "common/list.h" @@ -281,7 +282,7 @@ action_get_arg(struct action *action, const char *key, enum action_arg_type type return NULL; } -static const char * +const char * action_get_str(struct action *action, const char *key, const char *default_value) { struct action_arg_str *arg = action_get_arg(action, key, LAB_ACTION_ARG_STR); @@ -833,12 +834,13 @@ handle_view_destroy(struct wl_listener *listener, void *data) static void action_prompt_create(struct view *view, struct server *server, struct action *action) { - char *command = strdup_printf("labnag -m \"%s\" -Z \"%s\" -Z \"%s\"", - action_get_str(action, "message.prompt", "Choose wisely"), - _("No"), _("Yes")); + struct buf command = BUF_INIT; + action_prompt_command(&command, rc.prompt_command, action, rc.theme); + + wlr_log(WLR_INFO, "prompt command: '%s'", command.data); int pipe_fd; - pid_t prompt_pid = spawn_piped(command, &pipe_fd); + pid_t prompt_pid = spawn_piped(command.data, &pipe_fd); if (prompt_pid < 0) { wlr_log(WLR_ERROR, "Failed to create action prompt"); goto cleanup; @@ -862,7 +864,7 @@ action_prompt_create(struct view *view, struct server *server, struct action *ac wl_list_insert(&prompts, &prompt->link); cleanup: - free(command); + buf_reset(&command); } bool diff --git a/src/common/buf.c b/src/common/buf.c index c98fc97f..bd8e82d0 100644 --- a/src/common/buf.c +++ b/src/common/buf.c @@ -128,6 +128,30 @@ buf_add_fmt(struct buf *s, const char *fmt, ...) s->data[s->len] = 0; } +void +buf_add_hex_color(struct buf *s, float color[4]) +{ + /* + * In theme.c parse_hexstr() colors are pre-multiplied (by alpha) as + * expected by wlr_scene(). We therefore need to reverse that here. + * + * For details, see https://github.com/labwc/labwc/pull/1685 + */ + float alpha = color[3]; + + /* Avoid division by zero */ + if (alpha == 0.0f) { + buf_add(s, "#00000000"); + return; + } + + buf_add_fmt(s, "#%02x%02x%02x%02x", + (int)(color[0] / alpha * 255), + (int)(color[1] / alpha * 255), + (int)(color[2] / alpha * 255), + (int)(alpha * 255)); +} + void buf_add(struct buf *s, const char *data) { diff --git a/src/config/rcxml.c b/src/config/rcxml.c index aeeecc20..162f3f1d 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1102,6 +1102,10 @@ entry(xmlNode *node, char *nodename, char *content) set_bool(content, &rc.xwayland_persistence); } else if (!strcasecmp(nodename, "primarySelection.core")) { set_bool(content, &rc.primary_selection); + + } else if (!strcasecmp(nodename, "promptCommand.core")) { + xstrdup_replace(rc.prompt_command, content); + } else if (!strcmp(nodename, "policy.placement")) { enum lab_placement_policy policy = view_placement_parse(content); if (policy != LAB_PLACE_INVALID) { @@ -1624,6 +1628,22 @@ post_processing(void) load_default_mouse_bindings(); } + if (!rc.prompt_command) { + rc.prompt_command = + xstrdup("labnag " + "--message '%m' " + "--button-dismiss '%n' " + "--button-dismiss '%y' " + "--background '%b' " + "--text '%t' " + "--border '%t' " + "--border-bottom '%t' " + "--button-background '%b' " + "--button-text '%t' " + "--border-bottom-size 1 " + "--button-border-size 3 " + "--timeout 0"); + } if (!rc.fallback_app_icon_name) { rc.fallback_app_icon_name = xstrdup("labwc"); } @@ -1886,6 +1906,7 @@ rcxml_finish(void) zfree(rc.font_menuheader.name); zfree(rc.font_menuitem.name); zfree(rc.font_osd.name); + zfree(rc.prompt_command); zfree(rc.theme_name); zfree(rc.icon_theme_name); zfree(rc.fallback_app_icon_name); diff --git a/src/meson.build b/src/meson.build index 330b5daf..dc760f0c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,6 @@ labwc_sources = files( 'action.c', + 'action-prompt-command.c', 'buffer.c', 'debug.c', 'desktop.c', From 5fdebedcd99d03a38c50f650a3d016c0850811d7 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Tue, 23 Sep 2025 19:26:52 +0100 Subject: [PATCH 20/55] labwc-config(5): document --- docs/labwc-config.5.scd | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 7ddf2d5b..52cd9638 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -179,6 +179,7 @@ this is for compatibility with Openbox. no no yes + [see details below] ``` @@ -265,6 +266,53 @@ this is for compatibility with Openbox. up/down) in Chromium and electron based clients without inadvertantly pasting the primary clipboard. Default is yes. +** + Set command to be invoked for an action prompt (**) + + The following conversion specifiers are supported: + - *%m*: the ** message option + - *%n*: "No" (in local language if translation is available) + - *%y*: "Yes" (in local language if translation is available) + - *%b*: osd.bg.color + - *%t*: osd.label.text.color + + The default prompt command is: + + ``` + labnag \\ + --message '%m' \\ + --button-dismiss '%n' \\ + --button-dismiss '%y' \\ + --background '%b' \\ + --text '%t' \\ + --border '%t' \\ + --border-bottom '%t' \\ + --button-background '%b' \\ + --button-text '%t' \\ + --border-bottom-size 1 \\ + --button-border-size 3 \\ + --timeout 0 + ``` + + Example 1: The prompt can be configured to use a different dialog client + + ``` + + zenity --question --text="%m" + + ``` + + Example 2: A more complex zenity command could be used: + + ``` + zenity \\ + --question \\ + --title="" \\ + --text="%m" \\ + --ok-label="%y" \\ + --cancel-label="%n" + ``` + ## PLACEMENT ``` From 7a5b7aa37881690e26a01aada6ffcf668d0df52f Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 24 Sep 2025 20:16:37 +0100 Subject: [PATCH 21/55] rcxml.h: minor tweaks to order of variables --- include/config/rcxml.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/config/rcxml.h b/include/config/rcxml.h index e3b7bf06..b1c28d12 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -71,11 +71,12 @@ struct rcxml { enum tearing_mode allow_tearing; bool auto_enable_outputs; bool reuse_output_mode; - enum lab_placement_policy placement_policy; bool xwayland_persistence; bool primary_selection; char *prompt_command; + /* placement */ + enum lab_placement_policy placement_policy; int placement_cascade_offset_x; int placement_cascade_offset_y; From 6bbdc3c6dc3ba5bfd3702454325723b975845d2b Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 25 Sep 2025 19:24:52 +0100 Subject: [PATCH 22/55] Remove unused function menu_call_actions() --- include/menu/menu.h | 12 ------------ src/menu/menu.c | 9 --------- 2 files changed, 21 deletions(-) diff --git a/include/menu/menu.h b/include/menu/menu.h index a4d236d6..f65ff9a3 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -100,18 +100,6 @@ void menu_open_root(struct menu *menu, int x, int y); */ void menu_process_cursor_motion(struct wlr_scene_node *node); -/** - * menu_call_actions - call actions associated with a menu node - * - * If menuitem connected to @node does not just open a submenu: - * - associated actions will be called - * - server->menu_current will be closed - * - server->menu_current will be set to NULL - * - * Returns true if actions have actually been executed - */ -bool menu_call_actions(struct wlr_scene_node *node); - /** * menu_close_root- close root menu * diff --git a/src/menu/menu.c b/src/menu/menu.c index 455035ec..fca755b2 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -1544,15 +1544,6 @@ menu_process_cursor_motion(struct wlr_scene_node *node) menu_process_item_selection(item); } -bool -menu_call_actions(struct wlr_scene_node *node) -{ - assert(node && node->data); - struct menuitem *item = node_menuitem_from_node(node); - - return menu_execute_item(item); -} - void menu_close_root(struct server *server) { From 0bf2678f9dc2b3ca55881c1dcf3a60b36182988d Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 25 Sep 2025 19:25:51 +0100 Subject: [PATCH 23/55] Remove unused function scaled_font_buffer_set_max_width() --- include/scaled-buffer/scaled-font-buffer.h | 8 -------- src/scaled-buffer/scaled-font-buffer.c | 14 -------------- 2 files changed, 22 deletions(-) diff --git a/include/scaled-buffer/scaled-font-buffer.h b/include/scaled-buffer/scaled-font-buffer.h index 6953f9da..a5e95087 100644 --- a/include/scaled-buffer/scaled-font-buffer.h +++ b/include/scaled-buffer/scaled-font-buffer.h @@ -73,12 +73,4 @@ void scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text int max_width, struct font *font, const float *color, const float *bg_color); -/** - * Update the max width of an existing auto scaling font buffer - * and force a new render. - * - * No steps are taken to detect if its actually required to render a new buffer. - */ -void scaled_font_buffer_set_max_width(struct scaled_font_buffer *self, int max_width); - #endif /* LABWC_SCALED_FONT_BUFFER_H */ diff --git a/src/scaled-buffer/scaled-font-buffer.c b/src/scaled-buffer/scaled-font-buffer.c index 61fd5db3..bb93fc67 100644 --- a/src/scaled-buffer/scaled-font-buffer.c +++ b/src/scaled-buffer/scaled-font-buffer.c @@ -139,17 +139,3 @@ scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text, scaled_buffer_request_update(self->scaled_buffer, self->width, self->height); } - -void -scaled_font_buffer_set_max_width(struct scaled_font_buffer *self, int max_width) -{ - self->max_width = max_width; - - int computed_height; - font_get_buffer_size(self->max_width, self->text, &self->font, - &self->width, &computed_height); - self->height = (self->fixed_height > 0) ? - self->fixed_height : computed_height; - scaled_buffer_request_update(self->scaled_buffer, - self->width, self->height); -} From 139a5f0383b9e10d93d6d25c85c5abe7b4670877 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 25 Sep 2025 19:27:01 +0100 Subject: [PATCH 24/55] Remove unused function output_max_scale() --- include/output.h | 7 ------- src/output.c | 14 -------------- 2 files changed, 21 deletions(-) diff --git a/include/output.h b/include/output.h index 413b43c5..ceccaf9f 100644 --- a/include/output.h +++ b/include/output.h @@ -70,11 +70,4 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data); void output_enable_adaptive_sync(struct output *output, bool enabled); -/** - * output_max_scale() - get maximum scale factor of all usable outputs. - * Used when loading/rendering resources (e.g. icons) that may be - * displayed on any output. - */ -float output_max_scale(struct server *server); - #endif // LABWC_OUTPUT_H diff --git a/src/output.c b/src/output.c index 22e9fc4e..8345c653 100644 --- a/src/output.c +++ b/src/output.c @@ -1142,17 +1142,3 @@ output_enable_adaptive_sync(struct output *output, bool enabled) enabled ? "en" : "dis", output->wlr_output->name); } } - -float -output_max_scale(struct server *server) -{ - /* Never return less than 1, in case outputs are disabled */ - float scale = 1; - struct output *output; - wl_list_for_each(output, &server->outputs, link) { - if (output_is_usable(output)) { - scale = MAX(scale, output->wlr_output->scale); - } - } - return scale; -} From 34e52a40c740de0fb150e31871ce80e464e319ef Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 25 Sep 2025 19:33:55 +0100 Subject: [PATCH 25/55] Remove unused function node_layer_popup_from_node() --- include/node.h | 7 ------- src/node.c | 9 --------- 2 files changed, 16 deletions(-) diff --git a/include/node.h b/include/node.h index d6d177f0..bfad1373 100644 --- a/include/node.h +++ b/include/node.h @@ -45,13 +45,6 @@ struct view *node_view_from_node(struct wlr_scene_node *wlr_scene_node); struct lab_layer_surface *node_layer_surface_from_node( struct wlr_scene_node *wlr_scene_node); -/** - * node_layer_popup_from_node - return lab_layer_popup struct from node - * @wlr_scene_node: wlr_scene_node from which to return data - */ -struct lab_layer_popup *node_layer_popup_from_node( - struct wlr_scene_node *wlr_scene_node); - /** * node_menuitem_from_node - return menuitem struct from node * @wlr_scene_node: wlr_scene_node from which to return data diff --git a/src/node.c b/src/node.c index 025789e8..ce4fb040 100644 --- a/src/node.c +++ b/src/node.c @@ -50,15 +50,6 @@ node_layer_surface_from_node(struct wlr_scene_node *wlr_scene_node) return (struct lab_layer_surface *)node_descriptor->data; } -struct lab_layer_popup * -node_layer_popup_from_node(struct wlr_scene_node *wlr_scene_node) -{ - assert(wlr_scene_node->data); - struct node_descriptor *node_descriptor = wlr_scene_node->data; - assert(node_descriptor->type == LAB_NODE_LAYER_POPUP); - return (struct lab_layer_popup *)node_descriptor->data; -} - struct menuitem * node_menuitem_from_node(struct wlr_scene_node *wlr_scene_node) { From ee87b4fc30914eca576e70c3fd6afa0a0ac77972 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 25 Sep 2025 19:35:22 +0100 Subject: [PATCH 26/55] Remove unused function trim_last_field() --- include/common/string-helpers.h | 9 --------- src/common/string-helpers.c | 9 --------- 2 files changed, 18 deletions(-) diff --git a/include/common/string-helpers.h b/include/common/string-helpers.h index 0509d33c..35c994b2 100644 --- a/include/common/string-helpers.h +++ b/include/common/string-helpers.h @@ -15,15 +15,6 @@ bool string_null_or_empty(const char *s); */ bool str_space_only(const char *s); -/** - * trim_last_field() - Trim last field of string splitting on provided delim - * @buf: string to trim - * @delim: delimitator - * - * Example: With delim='_' and buf="foo_bar_baz" the return value is "foo_bar" - */ -void trim_last_field(char *buf, char delim); - /** * string_strip - strip white space left and right * Note: this function does a left skip, so the returning pointer cannot be diff --git a/src/common/string-helpers.c b/src/common/string-helpers.c index a0d73034..13fe6f68 100644 --- a/src/common/string-helpers.c +++ b/src/common/string-helpers.c @@ -20,15 +20,6 @@ string_null_or_empty(const char *s) return !s || !*s; } -void -trim_last_field(char *buf, char delim) -{ - char *p = strrchr(buf, delim); - if (p) { - *p = '\0'; - } -} - static void rtrim(char *s) { From bdc8e1c546f76be969b6da9ee9f5054c1f2566eb Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 25 Sep 2025 19:36:37 +0100 Subject: [PATCH 27/55] Remove unused function lab_xml_get_node() --- include/common/xml.h | 1 - src/common/xml.c | 6 ------ 2 files changed, 7 deletions(-) diff --git a/include/common/xml.h b/include/common/xml.h index 8b49d0e4..16c319ec 100644 --- a/include/common/xml.h +++ b/include/common/xml.h @@ -30,7 +30,6 @@ void lab_xml_expand_dotted_attributes(xmlNode *root); /* Returns true if the node only contains a string or is empty */ bool lab_xml_node_is_leaf(xmlNode *node); -bool lab_xml_get_node(xmlNode *node, const char *key, xmlNode **dst_node); bool lab_xml_get_string(xmlNode *node, const char *key, char *s, size_t len); bool lab_xml_get_int(xmlNode *node, const char *key, int *i); bool lab_xml_get_bool(xmlNode *node, const char *key, bool *b); diff --git a/src/common/xml.c b/src/common/xml.c index 4868d7ed..7e089267 100644 --- a/src/common/xml.c +++ b/src/common/xml.c @@ -164,12 +164,6 @@ get_node(xmlNode *node, const char *key, xmlNode **dst_node, bool leaf_only) return false; } -bool -lab_xml_get_node(xmlNode *node, const char *key, xmlNode **dst_node) -{ - return get_node(node, key, dst_node, /* leaf_only */ false); -} - bool lab_xml_get_string(xmlNode *node, const char *key, char *s, size_t len) { From 1692c47fa08038640ef0a6442182320e68540149 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 25 Sep 2025 19:38:13 +0100 Subject: [PATCH 28/55] Remove unused function key_state_nr_pressed_keys() --- include/input/key-state.h | 1 - src/input/key-state.c | 6 ------ 2 files changed, 7 deletions(-) diff --git a/include/input/key-state.h b/include/input/key-state.h index c53a4b10..d9971b74 100644 --- a/include/input/key-state.h +++ b/include/input/key-state.h @@ -24,6 +24,5 @@ void key_state_store_pressed_key_as_bound(uint32_t keycode); bool key_state_corresponding_press_event_was_bound(uint32_t keycode); void key_state_bound_key_remove(uint32_t keycode); int key_state_nr_bound_keys(void); -int key_state_nr_pressed_keys(void); #endif /* LABWC_KEY_STATE_H */ diff --git a/src/input/key-state.c b/src/input/key-state.c index def6b72c..492f7b0f 100644 --- a/src/input/key-state.c +++ b/src/input/key-state.c @@ -84,9 +84,3 @@ key_state_nr_bound_keys(void) { return bound.size; } - -int -key_state_nr_pressed_keys(void) -{ - return pressed.size; -} From 26bd02d45730ccfa99bccb786a9a07e0aa32fd04 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 24 Sep 2025 20:25:27 +0100 Subject: [PATCH 29/55] Add translate.h for HAVE_NLS includes/defines ...to shrink labwc.h footprint --- include/labwc.h | 7 ------- include/translate.h | 14 ++++++++++++++ src/action-prompt-command.c | 2 +- src/config/rcxml.c | 1 + src/desktop-entry.c | 1 + src/main.c | 1 + src/menu/menu.c | 1 + 7 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 include/translate.h diff --git a/include/labwc.h b/include/labwc.h index 72dbe687..c75b1e39 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -7,13 +7,6 @@ #include "common/set.h" #include "input/cursor.h" #include "overlay.h" -#if HAVE_NLS -#include -#include -#define _ gettext -#else -#define _(s) (s) -#endif #define XCURSOR_DEFAULT "left_ptr" #define XCURSOR_SIZE 24 diff --git a/include/translate.h b/include/translate.h new file mode 100644 index 00000000..f7fc51e2 --- /dev/null +++ b/include/translate.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_TRANSLATE_H +#define LABWC_TRANSLATE_H +#include "config.h" + +#if HAVE_NLS +#include +#include +#define _ gettext +#else +#define _(s) (s) +#endif + +#endif /* LABWC_TRANSLATE_H */ diff --git a/src/action-prompt-command.c b/src/action-prompt-command.c index 65bd0b49..faad41c9 100644 --- a/src/action-prompt-command.c +++ b/src/action-prompt-command.c @@ -5,8 +5,8 @@ #include #include "action.h" #include "common/buf.h" -#include "labwc.h" /* for gettext */ #include "theme.h" +#include "translate.h" enum { LAB_PROMPT_NONE = 0, diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 162f3f1d..89293c43 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -33,6 +33,7 @@ #include "osd.h" #include "regions.h" #include "ssd.h" +#include "translate.h" #include "view.h" #include "window-rules.h" #include "workspaces.h" diff --git a/src/desktop-entry.c b/src/desktop-entry.c index 60cff28e..7aefa77e 100644 --- a/src/desktop-entry.c +++ b/src/desktop-entry.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include "desktop-entry.h" +#include #include #include #include diff --git a/src/main.c b/src/main.c index 068829dc..755a0a0c 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include "config/session.h" #include "labwc.h" #include "theme.h" +#include "translate.h" #include "menu/menu.h" struct rcxml rc = { 0 }; diff --git a/src/menu/menu.c b/src/menu/menu.c index fca755b2..0e23e850 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -29,6 +29,7 @@ #include "scaled-buffer/scaled-font-buffer.h" #include "scaled-buffer/scaled-icon-buffer.h" #include "theme.h" +#include "translate.h" #include "view.h" #include "workspaces.h" From c9030dcc5b321abb2afb3a38d00b795081c8fe4d Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 17:52:13 +0100 Subject: [PATCH 30/55] CI: fix broken FreeBSD CI by setting -Dlibsfdo:b_ndebug=false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...because with with meson setup build -Dbuildtype=release -Db_ndebug=true \ --werror --force-fallback-for=libsfdo we get the following warning: In file included from ../subprojects/libsfdo/common/dirs.c:5: ../subprojects/libsfdo/include/common/membuild.h: In function ‘sfdo_membuild_validate’: ../subprojects/libsfdo/include/common/membuild.h:29:65: error: unused parameter ‘membuild’ [-Werror=unused-parameter] 29 | static inline void sfdo_membuild_validate(struct sfdo_membuild *membuild) { ...because `sfdo_membuild_validate()` contains nothing but an `assert()` and that therefore results in an `unused-parameter` warning with `NDEBUG`. https://gitlab.freedesktop.org/vyivel/libsfdo/-/blob/main/include/common/membuild.h?ref_type=heads#L30 --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b0ff3053..2b76b4d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -168,6 +168,7 @@ jobs: meson setup build-gcc-release -Dxwayland=enabled \ -Dbuildtype=release -Db_ndebug=true --werror meson configure build-gcc-release -Dwlroots:b_ndebug=false || true + meson configure build-gcc-release -Dlibsfdo:b_ndebug=false || true meson compile -C build-gcc-release ' | $TARGET @@ -190,6 +191,7 @@ jobs: meson setup build-clang-release -Dxwayland=enabled \ -Dbuildtype=release -Db_ndebug=true --werror meson configure build-clang-release -Dwlroots:b_ndebug=false || true + meson configure build-clang-release -Dlibsfdo:b_ndebug=false || true meson compile -C build-clang-release ' | $TARGET From 94c980c6be2195281e7bde30f58e0be40cfd2fe5 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 20:42:31 +0100 Subject: [PATCH 31/55] action: fix UAF when using prompt during reconfigure Reported-by: @jlindgren90 Fixes #3106 --- include/action.h | 1 + src/action.c | 9 +++++++++ src/server.c | 3 +++ 3 files changed, 13 insertions(+) diff --git a/include/action.h b/include/action.h index 31ecfb6e..7692e383 100644 --- a/include/action.h +++ b/include/action.h @@ -50,6 +50,7 @@ bool actions_contain_toggle_keybinds(struct wl_list *action_list); void actions_run(struct view *activator, struct server *server, struct wl_list *actions, struct cursor_context *ctx); +void action_prompts_destroy(void); bool action_check_prompt_result(pid_t pid, int exit_code); void action_free(struct action *action); diff --git a/src/action.c b/src/action.c index 62ab2b2d..9a5623ff 100644 --- a/src/action.c +++ b/src/action.c @@ -867,6 +867,15 @@ cleanup: buf_reset(&command); } +void +action_prompts_destroy(void) +{ + struct action_prompt *prompt, *tmp; + wl_list_for_each_safe(prompt, tmp, &prompts, link) { + action_prompt_destroy(prompt); + } +} + bool action_check_prompt_result(pid_t pid, int exit_code) { diff --git a/src/server.c b/src/server.c index 56f091b9..c39649b8 100644 --- a/src/server.c +++ b/src/server.c @@ -78,6 +78,9 @@ static void reload_config_and_theme(struct server *server) { + /* Avoid UAF when dialog client is used during reconfigure */ + action_prompts_destroy(); + scaled_buffer_invalidate_sharing(); rcxml_finish(); rcxml_read(rc.config_file); From 1043a9becc9858c229cce6130bee29942d8202ac Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 29 Sep 2025 16:03:36 +0900 Subject: [PATCH 32/55] test: fix build error in t/xml.c 38a1a9b broke `t/xml.c` due to `macros.h` requiring `wlr/version.h`. This commit fixes it by adding `wlroots` as a direct dependency of the test executables. --- t/meson.build | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/t/meson.build b/t/meson.build index 6aafc1e9..07d55a1f 100644 --- a/t/meson.build +++ b/t/meson.build @@ -1,3 +1,10 @@ +test_deps = [ + dep_cmocka, + glib, + xml2, + wlroots, +] + test_lib = static_library( 'test_lib', sources: files( @@ -8,12 +15,7 @@ test_lib = static_library( '../src/common/parse-bool.c', ), include_directories: [labwc_inc], - dependencies: [ - dep_cmocka, - glib, - xml2, - wlroots, - ], + dependencies: test_deps, ) tests = [ @@ -30,7 +32,7 @@ foreach t : tests sources: '@0@.c'.format(t), include_directories: [labwc_inc], link_with: [test_lib], - dependencies: [xml2], + dependencies: test_deps, ), is_parallel: false, ) From 7e27f78662045c7b1fdb3b357b1e5d5c78a3a486 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 29 Sep 2025 16:04:37 +0900 Subject: [PATCH 33/55] test/xml: use xmlBufferContent() xmlBuffer->content has been deprecated. --- t/xml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/xml.c b/t/xml.c index 003632a6..a7be6b87 100644 --- a/t/xml.c +++ b/t/xml.c @@ -111,7 +111,7 @@ test_lab_xml_expand_dotted_attributes(void **state) xmlBuffer *buf = xmlBufferCreate(); xmlNodeDump(buf, root->doc, root, 0, 0); - assert_string_equal(test_cases[i].after, (char *)buf->content); + assert_string_equal(test_cases[i].after, (char *)xmlBufferContent(buf)); xmlBufferFree(buf); xmlFreeDoc(doc); From 46bd1fef95eccf372ad5ea26105f8b1dfba1f1d9 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 29 Sep 2025 16:13:37 +0900 Subject: [PATCH 34/55] CI: add unit tests --- .github/workflows/build.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b76b4d2..0cf69f85 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,7 +82,7 @@ jobs: pacman -Syu --noconfirm pacman -S --noconfirm git meson clang wlroots0.19 libdrm libinput \ wayland-protocols cairo pango libxml2 xorg-xwayland librsvg \ - libdisplay-info gdb ttf-dejavu foot libsfdo + libdisplay-info gdb ttf-dejavu foot libsfdo cmocka - name: Install Debian Testing dependencies if: matrix.name == 'Debian' @@ -207,6 +207,18 @@ jobs: meson compile -C build-gcc-no-feature ' | $TARGET + # Unit tests, run on Arch only + - name: Build with gcc - unit test + if: matrix.name == 'Arch' + run: | + echo ' + cd "$GITHUB_WORKSPACE" + export CC=gcc + meson setup build-gcc-unit-test -Dtest=enabled --werror + meson compile -C build-gcc-unit-test + meson test -C build-gcc-unit-test --print-errorlogs + ' | $TARGET + # Runtime tests, these run on Arch and Void only (the later due to libmusl being used) - name: Build with gcc - runtime test if: matrix.name == 'Arch' From c5cd1f691d3390aa2b6091f882651b8f1aff47dd Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 29 Sep 2025 17:07:43 +0900 Subject: [PATCH 35/55] CI: use libwlroots-0.19-dev build-dep for Debian --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0cf69f85..e2876ac9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -92,7 +92,7 @@ jobs: apt-get upgrade -y apt-get install -y git gcc clang gdb xwayland apt-get build-dep -y labwc - apt-get build-dep -y libwlroots-0.18-dev + apt-get build-dep -y libwlroots-0.19-dev - name: Install FreeBSD dependencies if: matrix.name == 'FreeBSD' From 27f3097f8f882abc710e94bcb9a177319140d0b9 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 17:47:47 +0100 Subject: [PATCH 36/55] build: add 'sections' option to show unused functions --- meson.build | 10 ++++++++++ meson_options.txt | 1 + 2 files changed, 11 insertions(+) diff --git a/meson.build b/meson.build index 5f4cfe9b..0ac5cea1 100644 --- a/meson.build +++ b/meson.build @@ -134,6 +134,15 @@ if get_option('static_analyzer').enabled() add_project_arguments(['-fanalyzer'], language: 'c') endif +link_args = [] +if get_option('sections').enabled() + add_project_arguments(['-ffunction-sections'], language: 'c') + link_args += [ + '-Wl,--gc-sections', + '-Wl,--print-gc-sections', + ] +endif + msgfmt = find_program('msgfmt', required: get_option('nls')) if msgfmt.found() source_root = meson.current_source_dir() @@ -193,6 +202,7 @@ executable( include_directories: [labwc_inc], dependencies: labwc_deps, install: true, + link_args: link_args, ) install_data('data/labwc.desktop', install_dir: get_option('datadir') / 'wayland-sessions') diff --git a/meson_options.txt b/meson_options.txt index ec3fe85d..a3da65a8 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -5,3 +5,4 @@ option('icon', type: 'feature', value: 'enabled', description: 'Enable window ic option('nls', type: 'feature', value: 'auto', description: 'Enable native language support') option('static_analyzer', type: 'feature', value: 'disabled', description: 'Run gcc static analyzer') option('test', type: 'feature', value: 'disabled', description: 'Run tests') +option('sections', type: 'feature', value: 'disabled', description: 'Show unused functions') From 040e25f38e1865feb400cea6576b28d274e09ba8 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 17:46:20 +0100 Subject: [PATCH 37/55] Privatize private view_get_root() --- include/view.h | 1 - src/view.c | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/view.h b/include/view.h index efdcf3fd..45bf42d8 100644 --- a/include/view.h +++ b/include/view.h @@ -554,7 +554,6 @@ void view_move_to_output(struct view *view, struct output *output); void view_move_to_front(struct view *view); void view_move_to_back(struct view *view); -struct view *view_get_root(struct view *view); void view_append_children(struct view *view, struct wl_array *children); /** diff --git a/src/view.c b/src/view.c index e402b626..aa15ef92 100644 --- a/src/view.c +++ b/src/view.c @@ -240,6 +240,16 @@ view_matches_query(struct view *view, struct view_query *query) return true; } +static struct view * +view_get_root(struct view *view) +{ + assert(view); + if (view->impl->get_root) { + return view->impl->get_root(view); + } + return view; +} + static bool matches_criteria(struct view *view, enum lab_view_criteria criteria) { @@ -2327,16 +2337,6 @@ view_move_to_back(struct view *view) desktop_update_top_layer_visibility(view->server); } -struct view * -view_get_root(struct view *view) -{ - assert(view); - if (view->impl->get_root) { - return view->impl->get_root(view); - } - return view; -} - void view_append_children(struct view *view, struct wl_array *children) { From 286005e121c5409f72ea9c60ceb3f1aa12d61625 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 19:14:30 +0100 Subject: [PATCH 38/55] Privatize rcxml_parse_xml() --- include/config/rcxml.h | 1 - src/config/rcxml.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/config/rcxml.h b/include/config/rcxml.h index b1c28d12..e4fd184b 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -200,7 +200,6 @@ struct rcxml { extern struct rcxml rc; -void rcxml_parse_xml(struct buf *b); void rcxml_read(const char *filename); void rcxml_finish(void); diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 89293c43..9bf38941 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1323,8 +1323,7 @@ traverse(xmlNode *node) } } -/* Exposed in header file to allow unit tests to parse buffers */ -void +static void rcxml_parse_xml(struct buf *b) { int options = 0; From 950c634cea8251b4f4d6649281ee0481a3eece48 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 19:15:29 +0100 Subject: [PATCH 39/55] Privatize xwayland_surface_from_view() --- include/xwayland.h | 2 -- src/xwayland.c | 30 +++++++++++++++--------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/include/xwayland.h b/include/xwayland.h index b5bd2623..5fa20e11 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -65,8 +65,6 @@ void xwayland_unmanaged_create(struct server *server, void xwayland_view_create(struct server *server, struct wlr_xwayland_surface *xsurface, bool mapped); -struct wlr_xwayland_surface *xwayland_surface_from_view(struct view *view); - void xwayland_server_init(struct server *server, struct wlr_compositor *compositor); void xwayland_server_finish(struct server *server); diff --git a/src/xwayland.c b/src/xwayland.c index 0604dcaf..0ab92f0d 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -40,6 +40,21 @@ static xcb_atom_t atoms[ATOM_COUNT] = {0}; static void xwayland_view_unmap(struct view *view, bool client_request); +static struct xwayland_view * +xwayland_view_from_view(struct view *view) +{ + assert(view->type == LAB_XWAYLAND_VIEW); + return (struct xwayland_view *)view; +} + +static struct wlr_xwayland_surface * +xwayland_surface_from_view(struct view *view) +{ + struct xwayland_view *xwayland_view = xwayland_view_from_view(view); + assert(xwayland_view->xwayland_surface); + return xwayland_view->xwayland_surface; +} + static bool xwayland_view_contains_window_type(struct view *view, enum lab_window_type window_type) @@ -186,21 +201,6 @@ top_parent_of(struct view *view) return s; } -static struct xwayland_view * -xwayland_view_from_view(struct view *view) -{ - assert(view->type == LAB_XWAYLAND_VIEW); - return (struct xwayland_view *)view; -} - -struct wlr_xwayland_surface * -xwayland_surface_from_view(struct view *view) -{ - struct xwayland_view *xwayland_view = xwayland_view_from_view(view); - assert(xwayland_view->xwayland_surface); - return xwayland_view->xwayland_surface; -} - static void ensure_initial_geometry_and_output(struct view *view) { From 2ea0f6fff4d02891c0081d95f8d9ce28afcc775b Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 19:16:01 +0100 Subject: [PATCH 40/55] Privatize output_manager_init() --- include/output.h | 1 - src/output.c | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/output.h b/include/output.h index ceccaf9f..888f62c7 100644 --- a/include/output.h +++ b/include/output.h @@ -40,7 +40,6 @@ struct output { void output_init(struct server *server); void output_finish(struct server *server); -void output_manager_init(struct server *server); struct output *output_from_wlr_output(struct server *server, struct wlr_output *wlr_output); struct output *output_from_name(struct server *server, const char *name); diff --git a/src/output.c b/src/output.c index 8345c653..adee3f9d 100644 --- a/src/output.c +++ b/src/output.c @@ -551,6 +551,8 @@ handle_new_output(struct wl_listener *listener, void *data) do_output_layout_change(server); } +static void output_manager_init(struct server *server); + void output_init(struct server *server) { @@ -890,7 +892,7 @@ handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) wlr_output_schedule_frame(output->wlr_output); } -void +static void output_manager_init(struct server *server) { server->output_manager = wlr_output_manager_v1_create(server->wl_display); From eb41c6a3b02f064a8bee539de5fbf4a717200180 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 19:17:27 +0100 Subject: [PATCH 41/55] Privatize view_contains_window_type() --- include/view.h | 1 - src/view.c | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/view.h b/include/view.h index 45bf42d8..0970bb02 100644 --- a/include/view.h +++ b/include/view.h @@ -425,7 +425,6 @@ void view_array_append(struct server *server, struct wl_array *views, enum lab_view_criteria criteria); enum view_wants_focus view_wants_focus(struct view *view); -bool view_contains_window_type(struct view *view, enum lab_window_type window_type); /* If view is NULL, the size of SSD is not considered */ struct wlr_box view_get_edge_snap_box(struct view *view, struct output *output, diff --git a/src/view.c b/src/view.c index aa15ef92..29736b80 100644 --- a/src/view.c +++ b/src/view.c @@ -120,6 +120,16 @@ query_str_match(const char *condition, const char *value) return value && match_glob(condition, value); } +static bool +view_contains_window_type(struct view *view, enum lab_window_type window_type) +{ + assert(view); + if (view->impl->contains_window_type) { + return view->impl->contains_window_type(view, window_type); + } + return false; +} + bool view_matches_query(struct view *view, struct view_query *query) { @@ -403,16 +413,6 @@ view_wants_focus(struct view *view) return VIEW_WANTS_FOCUS_ALWAYS; } -bool -view_contains_window_type(struct view *view, enum lab_window_type window_type) -{ - assert(view); - if (view->impl->contains_window_type) { - return view->impl->contains_window_type(view, window_type); - } - return false; -} - bool view_is_focusable(struct view *view) { From 9ec49144ac65db8a56e678670e12e31b308df753 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 19:17:56 +0100 Subject: [PATCH 42/55] Privatize desktop_topmost_focusable_view() --- include/labwc.h | 1 - src/desktop.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index c75b1e39..5a3bbefa 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -359,7 +359,6 @@ void desktop_focus_view_or_surface(struct seat *seat, struct view *view, void desktop_arrange_all_views(struct server *server); void desktop_focus_output(struct output *output); -struct view *desktop_topmost_focusable_view(struct server *server); /** * Toggles the (output local) visibility of the layershell top layer diff --git a/src/desktop.c b/src/desktop.c index dc2aa1a2..bac6c065 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -132,7 +132,7 @@ desktop_focus_view_or_surface(struct seat *seat, struct view *view, } } -struct view * +static struct view * desktop_topmost_focusable_view(struct server *server) { struct view *view; From 60d536304bd72d818b40ac9ecb0a056c25fabaa8 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 26 Sep 2025 19:21:34 +0100 Subject: [PATCH 43/55] Privatize view_append_children() --- include/view.h | 1 - src/view.c | 18 +++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/view.h b/include/view.h index 0970bb02..ba662550 100644 --- a/include/view.h +++ b/include/view.h @@ -553,7 +553,6 @@ void view_move_to_output(struct view *view, struct output *output); void view_move_to_front(struct view *view); void view_move_to_back(struct view *view); -void view_append_children(struct view *view, struct wl_array *children); /** * view_get_modal_dialog() - returns any modal dialog found among this diff --git a/src/view.c b/src/view.c index 29736b80..792401cf 100644 --- a/src/view.c +++ b/src/view.c @@ -808,6 +808,15 @@ _minimize(struct view *view, bool minimized) } } +static void +view_append_children(struct view *view, struct wl_array *children) +{ + assert(view); + if (view->impl->append_children) { + view->impl->append_children(view, children); + } +} + static void minimize_sub_views(struct view *view, bool minimized) { @@ -2337,15 +2346,6 @@ view_move_to_back(struct view *view) desktop_update_top_layer_visibility(view->server); } -void -view_append_children(struct view *view, struct wl_array *children) -{ - assert(view); - if (view->impl->append_children) { - view->impl->append_children(view, children); - } -} - struct view * view_get_modal_dialog(struct view *view) { From c8581b3fed4d3685fe673a891af5a721bcedd1bf Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 29 Sep 2025 21:30:04 +0100 Subject: [PATCH 44/55] include/common/xml.h: fix declaration/definition arg name difference --- include/common/xml.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/common/xml.h b/include/common/xml.h index 16c319ec..e218226f 100644 --- a/include/common/xml.h +++ b/include/common/xml.h @@ -25,7 +25,7 @@ * * */ -void lab_xml_expand_dotted_attributes(xmlNode *root); +void lab_xml_expand_dotted_attributes(xmlNode *parent); /* Returns true if the node only contains a string or is empty */ bool lab_xml_node_is_leaf(xmlNode *node); From e558d0d619ef4e867475cf1ae86b73fb067b2ac6 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Wed, 1 Oct 2025 15:22:54 +0900 Subject: [PATCH 45/55] labnag: rename options for color --- clients/labnag.c | 64 +++++++++++++++++++++-------------------- docs/labnag.1.scd | 26 ++++++++--------- docs/labwc-config.5.scd | 12 ++++---- src/config/rcxml.c | 12 ++++---- 4 files changed, 58 insertions(+), 56 deletions(-) diff --git a/clients/labnag.c b/clients/labnag.c index bea25dd1..23e0be1f 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -45,7 +45,7 @@ struct conf { uint32_t details_background; uint32_t background; uint32_t text; - uint32_t border; + uint32_t button_border; uint32_t border_bottom; /* Sizing */ @@ -429,7 +429,7 @@ render_button(cairo_t *cairo, struct nag *nag, struct button *button, int *x) button->width = text_width + padding * 2; button->height = text_height + padding * 2; - cairo_set_source_u32(cairo, nag->conf->border); + cairo_set_source_u32(cairo, nag->conf->button_border); cairo_rectangle(cairo, button->x - border, button->y - border, button->width + border * 2, button->height + border * 2); cairo_fill(cairo); @@ -1255,7 +1255,7 @@ conf_init(struct conf *conf) conf->background = 0x323232FF; conf->text = 0xFFFFFFFF; conf->button_text = 0xFFFFFFFF; - conf->border = 0x222222FF; + conf->button_border = 0x222222FF; conf->border_bottom = 0x444444FF; conf->bar_border_thickness = 2; conf->message_padding = 8; @@ -1270,7 +1270,7 @@ conf_init(struct conf *conf) conf->background = 0x900000FF; conf->text = 0xFFFFFFFF; conf->button_text = 0xFFFFFFFF; - conf->border = 0xD92424FF; + conf->button_border = 0xD92424FF; conf->border_bottom = 0x470909FF; } @@ -1342,9 +1342,9 @@ nag_parse_options(int argc, char **argv, struct nag *nag, { enum type_options { TO_COLOR_BACKGROUND = 256, - TO_COLOR_BORDER, + TO_COLOR_BUTTON_BORDER, TO_COLOR_BORDER_BOTTOM, - TO_COLOR_BUTTON, + TO_COLOR_BUTTON_BG, TO_COLOR_DETAILS, TO_COLOR_TEXT, TO_COLOR_BUTTON_TEXT, @@ -1373,16 +1373,16 @@ nag_parse_options(int argc, char **argv, struct nag *nag, {"timeout", required_argument, NULL, 't'}, {"version", no_argument, NULL, 'v'}, - {"background", required_argument, NULL, TO_COLOR_BACKGROUND}, - {"border", required_argument, NULL, TO_COLOR_BORDER}, - {"border-bottom", required_argument, NULL, TO_COLOR_BORDER_BOTTOM}, - {"button-background", required_argument, NULL, TO_COLOR_BUTTON}, - {"text", required_argument, NULL, TO_COLOR_TEXT}, - {"button-text", required_argument, NULL, TO_COLOR_BUTTON_TEXT}, + {"background-color", required_argument, NULL, TO_COLOR_BACKGROUND}, + {"button-border-color", required_argument, NULL, TO_COLOR_BUTTON_BORDER}, + {"border-bottom-color", required_argument, NULL, TO_COLOR_BORDER_BOTTOM}, + {"button-background-color", required_argument, NULL, TO_COLOR_BUTTON_BG}, + {"text-color", required_argument, NULL, TO_COLOR_TEXT}, + {"button-text-color", required_argument, NULL, TO_COLOR_BUTTON_TEXT}, {"border-bottom-size", required_argument, NULL, TO_THICK_BAR_BORDER}, {"message-padding", required_argument, NULL, TO_PADDING_MESSAGE}, {"details-border-size", required_argument, NULL, TO_THICK_DET_BORDER}, - {"details-background", required_argument, NULL, TO_COLOR_DETAILS}, + {"details-background-color", required_argument, NULL, TO_COLOR_DETAILS}, {"button-border-size", required_argument, NULL, TO_THICK_BTN_BORDER}, {"button-gap", required_argument, NULL, TO_GAP_BTN}, {"button-dismiss-gap", required_argument, NULL, TO_GAP_BTN_DISMISS}, @@ -1413,21 +1413,23 @@ nag_parse_options(int argc, char **argv, struct nag *nag, " -v, --version Show the version number and quit.\n" "\n" "The following appearance options can also be given:\n" - " --background RRGGBB[AA] Background color.\n" - " --border RRGGBB[AA] Border color.\n" - " --border-bottom RRGGBB[AA] Bottom border color.\n" - " --button-background RRGGBB[AA] Button background color.\n" - " --text RRGGBB[AA] Text color.\n" - " --button-text RRGGBB[AA] Button text color.\n" - " --border-bottom-size size Thickness of the bar border.\n" - " --message-padding padding Padding for the message.\n" - " --details-border-size size Thickness for the details border.\n" - " --details-background RRGGBB[AA] Details background color.\n" - " --button-border-size size Thickness for the button border.\n" - " --button-gap gap Size of the gap between buttons\n" - " --button-dismiss-gap gap Size of the gap for dismiss button.\n" - " --button-margin-right margin Margin from dismiss button to edge.\n" - " --button-padding padding Padding for the button text.\n"; + " --background-color RRGGBB[AA] Background color.\n" + " --button-border-color RRGGBB[AA] Button border color.\n" + " --border-bottom-color RRGGBB[AA] Bottom border color.\n" + " --button-background-color RRGGBB[AA]\n" + " Button background color.\n" + " --text-color RRGGBB[AA] Text color.\n" + " --button-text-color RRGGBB[AA] Button text color.\n" + " --border-bottom-size size Thickness of the bar border.\n" + " --message-padding padding Padding for the message.\n" + " --details-border-size size Thickness for the details border.\n" + " --details-background-color RRGGBB[AA]\n" + " Details background color.\n" + " --button-border-size size Thickness for the button border.\n" + " --button-gap gap Size of the gap between buttons\n" + " --button-dismiss-gap gap Size of the gap for dismiss button.\n" + " --button-margin-right margin Margin from dismiss button to edge.\n" + " --button-padding padding Padding for the button text.\n"; optind = 1; while (1) { @@ -1522,8 +1524,8 @@ nag_parse_options(int argc, char **argv, struct nag *nag, fprintf(stderr, "Invalid background color: %s\n", optarg); } break; - case TO_COLOR_BORDER: /* Border color */ - if (!parse_color(optarg, &conf->border)) { + case TO_COLOR_BUTTON_BORDER: /* Border color */ + if (!parse_color(optarg, &conf->button_border)) { fprintf(stderr, "Invalid border color: %s\n", optarg); } break; @@ -1532,7 +1534,7 @@ nag_parse_options(int argc, char **argv, struct nag *nag, fprintf(stderr, "Invalid border bottom color: %s\n", optarg); } break; - case TO_COLOR_BUTTON: /* Button background color */ + case TO_COLOR_BUTTON_BG: /* Button background color */ if (!parse_color(optarg, &conf->button_background)) { fprintf(stderr, "Invalid button background color: %s\n", optarg); } diff --git a/docs/labnag.1.scd b/docs/labnag.1.scd index 8ff5fe18..c8aa4d09 100644 --- a/docs/labnag.1.scd +++ b/docs/labnag.1.scd @@ -62,22 +62,22 @@ _labnag_ [options...] # APPEARANCE OPTIONS -*--background* +*--background-color* Set the color of the background. -*--border* - Set the color of the border. +*--button-border-color* + Set the color of the button border. -*--border-bottom* +*--border-bottom-color* Set the color of the bottom border. -*--button-background* +*--button-background-color* Set the color for the background for buttons. -*--text* +*--text-color* Set the text color. -*--button-text* +*--button-text-color* Set the button text color. *--border-bottom-size* @@ -86,7 +86,7 @@ _labnag_ [options...] *--message-padding* Set the padding for the message. -*--details-background* +*--details-background-color* Set the color for the background for details. *--details-border-size* @@ -126,11 +126,11 @@ labnag \\ -Z "Hibernate" "systemctl hibernate"\\ -Z " Suspend " "systemctl suspend"\\ -Z " Cancel "\\ - --background 00ffff\\ - --button-background 00ffff\\ - --border 00ccccaa\\ - --text 000000\\ - --button-text 000000\\ + --background-color 00ffff\\ + --button-background-color 00ffff\\ + --button-border-color 00ccccaa\\ + --text-color 000000\\ + --button-text-color 000000\\ --button-gap 8\\ --button-margin-right 0\\ --button-padding 5\\ diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 52cd9638..d389c4cf 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -283,12 +283,12 @@ this is for compatibility with Openbox. --message '%m' \\ --button-dismiss '%n' \\ --button-dismiss '%y' \\ - --background '%b' \\ - --text '%t' \\ - --border '%t' \\ - --border-bottom '%t' \\ - --button-background '%b' \\ - --button-text '%t' \\ + --background-color '%b' \\ + --text-color '%t' \\ + --button-border-color '%t' \\ + --border-bottom-color '%t' \\ + --button-background-color '%b' \\ + --button-text-color '%t' \\ --border-bottom-size 1 \\ --button-border-size 3 \\ --timeout 0 diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 9bf38941..1353b3c2 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1634,12 +1634,12 @@ post_processing(void) "--message '%m' " "--button-dismiss '%n' " "--button-dismiss '%y' " - "--background '%b' " - "--text '%t' " - "--border '%t' " - "--border-bottom '%t' " - "--button-background '%b' " - "--button-text '%t' " + "--background-color '%b' " + "--text-color '%t' " + "--button-border-color '%t' " + "--border-bottom-color '%t' " + "--button-background-color '%b' " + "--button-text-color '%t' " "--border-bottom-size 1 " "--button-border-size 3 " "--timeout 0"); From 389cef9c3b8a97e099c09ad62bea06299fb3020a Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 1 Oct 2025 20:47:33 +0100 Subject: [PATCH 46/55] include/common/box.h: fix declaration/definition arg name difference --- include/common/box.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/common/box.h b/include/common/box.h index 3d900a0e..45c0fc4d 100644 --- a/include/common/box.h +++ b/include/common/box.h @@ -18,7 +18,7 @@ void box_union(struct wlr_box *box_dest, struct wlr_box *box_a, * The returned x & y coordinates are the centered content position * relative to the top-left corner of the bounding box. */ -struct wlr_box box_fit_within(int width, int height, struct wlr_box *bounding_box); +struct wlr_box box_fit_within(int width, int height, struct wlr_box *bound); struct wlr_fbox box_to_fbox(struct wlr_box *box); From 4c1e66f6c8d9fd19684e0d5d899526f8c4c7525f Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 1 Oct 2025 20:48:15 +0100 Subject: [PATCH 47/55] include/common/buf.h: fix declaration/definition arg name difference --- include/common/buf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/common/buf.h b/include/common/buf.h index 857b6c48..24158630 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -71,9 +71,9 @@ void buf_add(struct buf *s, const char *data); /** * buf_add_char - add single char to C string buffer * @s: buffer - * @data: char to be added + * @ch: char to be added */ -void buf_add_char(struct buf *s, char data); +void buf_add_char(struct buf *s, char ch); /** * buf_clear - clear the buffer, internal allocations are preserved From 0d0d1075ccb6c714a0c829354558bad839510e6a Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 1 Oct 2025 20:48:45 +0100 Subject: [PATCH 48/55] include/common/scene-helpers: fix declaration/definition arg name difference --- include/common/scene-helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/common/scene-helpers.h b/include/common/scene-helpers.h index 021d3b16..453052fb 100644 --- a/include/common/scene-helpers.h +++ b/include/common/scene-helpers.h @@ -20,6 +20,6 @@ struct wlr_scene_node *lab_wlr_scene_get_prev_node(struct wlr_scene_node *node); /* A variant of wlr_scene_output_commit() that respects wlr_output->pending */ bool lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output, - struct wlr_output_state *output_state); + struct wlr_output_state *state); #endif /* LABWC_SCENE_HELPERS_H */ From bed0be8a88aa5c8a05618c97ab8385aa260ad591 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 1 Oct 2025 20:50:31 +0100 Subject: [PATCH 49/55] src/common/graphic-helpers.c: fix declaration/definition arg name difference --- src/common/graphic-helpers.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/common/graphic-helpers.c b/src/common/graphic-helpers.c index bc0adbc4..4371c9e5 100644 --- a/src/common/graphic-helpers.c +++ b/src/common/graphic-helpers.c @@ -27,34 +27,34 @@ draw_cairo_border(cairo_t *cairo, struct wlr_fbox fbox, double line_width) /* Sets the cairo color. Splits the single color channels */ void -set_cairo_color(cairo_t *cairo, const float *c) +set_cairo_color(cairo_t *cairo, const float *color) { /* * We are dealing with pre-multiplied colors * but cairo expects unmultiplied colors here */ - float alpha = c[3]; + float alpha = color[3]; if (alpha == 0.0f) { cairo_set_source_rgba(cairo, 0, 0, 0, 0); return; } - cairo_set_source_rgba(cairo, c[0] / alpha, c[1] / alpha, - c[2] / alpha, alpha); + cairo_set_source_rgba(cairo, color[0] / alpha, color[1] / alpha, + color[2] / alpha, alpha); } cairo_pattern_t * -color_to_pattern(const float *c) +color_to_pattern(const float *color) { - float alpha = c[3]; + float alpha = color[3]; if (alpha == 0.0f) { return cairo_pattern_create_rgba(0, 0, 0, 0); } - return cairo_pattern_create_rgba( - c[0] / alpha, c[1] / alpha, c[2] / alpha, alpha); + return cairo_pattern_create_rgba(color[0] / alpha, color[1] / alpha, + color[2] / alpha, alpha); } /* From 4cc00058e3bac1ae988064492d8adf849feff0a0 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 18:10:07 +0200 Subject: [PATCH 50/55] [revert later] CI: allow compiling wlroots as subproject --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e2876ac9..cb24dfe9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,6 +93,7 @@ jobs: apt-get install -y git gcc clang gdb xwayland apt-get build-dep -y labwc apt-get build-dep -y libwlroots-0.19-dev + apt-get build-dep -y libxkbcommon-dev - name: Install FreeBSD dependencies if: matrix.name == 'FreeBSD' @@ -119,7 +120,7 @@ jobs: xbps-install -y git meson gcc clang pkg-config scdoc \ cairo-devel glib-devel libpng-devel librsvg-devel libxml2-devel \ pango-devel wlroots0.19-devel gdb bash xorg-server-xwayland \ - dejavu-fonts-ttf libsfdo-devel foot + dejavu-fonts-ttf libsfdo-devel foot hwids # These builds are executed on all runners - name: Build with gcc From a0dacbf85d69d786d0eb1757263c162150201a66 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 16:59:41 +0200 Subject: [PATCH 51/55] chase wlroots: increase wlroots meson dep --- meson.build | 4 ++-- subprojects/wlroots.wrap | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index 0ac5cea1..4b016dce 100644 --- a/meson.build +++ b/meson.build @@ -51,9 +51,9 @@ endif add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c') wlroots = dependency( - 'wlroots-0.19', + 'wlroots-0.20', default_options: ['default_library=static', 'examples=false'], - version: ['>=0.19.0', '<0.20.0'], + version: ['>=0.20.0', '<0.21.0'], ) wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true' diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 25a947ed..c1d52098 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,7 +1,7 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 0.19 +revision = f04ef79f619983bfb4a7c9908bdae62e0d0d5ba7 [provide] -dependency_names = wlroots-0.19 -wlroots-0.19=wlroots +dependency_names = wlroots-0.20 +wlroots-0.20=wlroots From 13e838cd3421478195b116c8032fce71a4938bb1 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:03:38 +0200 Subject: [PATCH 52/55] chase wlroots: ime: rename to new_text_input (MR 5032) Ref: 536100488fc4c64528786801860f96cfa1a55765 (text-input-v3: Name new text input event correctly) --- src/input/ime.c | 2 +- subprojects/wlroots.wrap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/input/ime.c b/src/input/ime.c index 92d88ffe..ab24f927 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -583,7 +583,7 @@ input_method_relay_create(struct seat *seat) relay->popup_tree = wlr_scene_tree_create(&seat->server->scene->tree); relay->new_text_input.notify = handle_new_text_input; - wl_signal_add(&seat->server->text_input_manager->events.text_input, + wl_signal_add(&seat->server->text_input_manager->events.new_text_input, &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index c1d52098..9199c211 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = f04ef79f619983bfb4a7c9908bdae62e0d0d5ba7 +revision = 536100488fc4c64528786801860f96cfa1a55765 [provide] dependency_names = wlroots-0.20 From b7f46ac9ba92ef7e2a004441070814f273a2344b Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Wed, 13 Aug 2025 19:57:58 -0700 Subject: [PATCH 53/55] [wip] chase wlroots: Add wl_fixes interface (MR + subproject commit missing) Ref: 812675ba34ce612e9294e8a9814b1baf4b4775d4 (fixes: add implementation) --- src/server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/server.c b/src/server.c index c39649b8..e2c577bd 100644 --- a/src/server.c +++ b/src/server.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,7 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, "wl_data_device_manager", /* would be great if we could drop this one */ "wl_seat", "xdg_wm_base", + "wl_fixes", /* enhanced */ "wl_output", "wl_drm", @@ -434,6 +436,8 @@ server_init(struct server *server) server->wl_event_loop = wl_display_get_event_loop(server->wl_display); + wlr_fixes_create(server->wl_display, 1); + /* Catch signals */ server->sighup_source = wl_event_loop_add_signal( server->wl_event_loop, SIGHUP, handle_sighup, server); From 19b8ad35f9327e728b09f023a3f2b1a32d188345 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Tue, 9 Sep 2025 14:58:03 +0200 Subject: [PATCH 54/55] chase wlroots: ime: rename to new_input_method (MR 5107) Ref: 06aacb2a6fd237a5e1062d611909432bbcf5b566 (input-method: rename input_method event to new_input_method) --- src/input/ime.c | 2 +- subprojects/wlroots.wrap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/input/ime.c b/src/input/ime.c index ab24f927..bfb8816f 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -587,7 +587,7 @@ input_method_relay_create(struct seat *seat) &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; - wl_signal_add(&seat->server->input_method_manager->events.input_method, + wl_signal_add(&seat->server->input_method_manager->events.new_input_method, &relay->new_input_method); relay->focused_surface_destroy.notify = handle_focused_surface_destroy; diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 9199c211..253b83d7 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 536100488fc4c64528786801860f96cfa1a55765 +revision = 06aacb2a6fd237a5e1062d611909432bbcf5b566 [provide] dependency_names = wlroots-0.20 From d6dcda73d6d6a2f9ff2def34d4f363eaa5768b5b Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:37:22 +0200 Subject: [PATCH 55/55] [wip] chase wlroots: track master branch --- subprojects/wlroots.wrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 253b83d7..4352289b 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 06aacb2a6fd237a5e1062d611909432bbcf5b566 +revision = master [provide] dependency_names = wlroots-0.20