From 1043a9becc9858c229cce6130bee29942d8202ac Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 29 Sep 2025 16:03:36 +0900 Subject: [PATCH 01/12] 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 02/12] 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 03/12] 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 04/12] 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 05/12] 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 06/12] 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 07/12] 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 08/12] 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 09/12] 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 10/12] 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 11/12] 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 12/12] 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) {