diff --git a/NEWS.md b/NEWS.md index 79a3c918..97e65de9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| +| 2026-04-17 | [0.9.7] | 0.19.2 | 29277 | +| 2026-03-15 | [0.9.6] | 0.19.2 | 29271 | | 2026-03-04 | [0.9.5] | 0.19.2 | 29251 | | 2026-02-27 | [0.9.4] | 0.19.2 | 29225 | | 2025-12-19 | [0.9.3] | 0.19.2 | 28968 | @@ -41,7 +43,8 @@ The format is based on [Keep a Changelog] | 2021-04-15 | [0.2.0] | 0.13.0 | 5011 | | 2021-03-05 | [0.1.0] | 0.12.0 | 4627 | -[unreleased]: NEWS.md#unreleased +[0.9.7]: NEWS.md#097---2026-04-17 +[0.9.6]: NEWS.md#096---2026-03-15 [0.9.5]: NEWS.md#095---2026-03-04 [0.9.4]: NEWS.md#094---2026-02-27 [0.9.3]: NEWS.md#093---2025-12-19 @@ -108,9 +111,64 @@ There are some regression warnings worth noting for the switch to wlroots 0.19: [wlroots-5098]:https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5098 [gtk-8792]: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8792 -## unreleased +## 0.9.7 - 2026-04-17 -[unreleased-commits] +[0.9.7-commits] + +This is a small bug fix release. + +``` + 0.9.6--------0.9.7 <--- v0.9 branch with bug-fixes only + / + / +0.9.4--------0.9.5-------- <-- master (built with wlroots-0.20) +``` + +## Fixed + +- Fix intermittent failed-to-get-texture issue with some clients (e.g. foot) + when using the window-switcher in the thumbnail mode. [#3511] @yuiiio +- Fix tablet tool tilt motion. [#3494] @jp7677 +- Handle window-switcher buffer allocation failure when in 'thumbnail' mode. + This is believed to be very unlikely to happen, but has been reported by one + user and is believed to be GPU driver related. [#3490] @Consolatis + +## 0.9.6 - 2026-03-15 + +[0.9.6-commits] + +This is an earlier-than-usual release containing bug fixes only. It has been +done on a separate branch (v0.9) to avoid the inclusion of refactoring and new +features. + +``` + 0.9.6 <--- bug-fixes only + / + / +0.9.4--------0.9.5-------- <-- master +``` + +### Fixed + +- Disable outputs where all modes fail [#3428] [#3429] @Consolatis @kode54 +- Fix regression in `0.9.4` that causes `NextWindow` action to segfault when + no outputs are connected. This fixes a window-switcher crash with some + Nvidia GPUs/drivers after suspend [#3425] [#3430] @Consolatis +- Fix typo to allow `xdg-dialog-v1` global [#3426] @xi + +### Changed + +- Disallow X11 window always-on-top requests by default to fix an issue whereby + Alt+Tab cannot be used to switch to other windows when using some XWayland + Wine games [#3441]. Add window-rule property `allowAlwaysOnTop` to optionally + allow this always-on-top requests. Add the snippet below to the `rc.xml` file + to restore the previous behaviour. [#3445] @Consolatis + +``` + + + +``` ## 0.9.5 - 2026-03-04 @@ -2607,7 +2665,8 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 ShowMenu [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/ -[unreleased-commits]: https://github.com/labwc/labwc/compare/0.9.5...HEAD +[0.9.7-commits]: https://github.com/labwc/labwc/compare/0.9.6...0.9.7 +[0.9.6-commits]: https://github.com/labwc/labwc/compare/0.9.5...0.9.6 [0.9.5-commits]: https://github.com/labwc/labwc/compare/0.9.4...0.9.5 [0.9.4-commits]: https://github.com/labwc/labwc/compare/0.9.3...0.9.4 [0.9.3-commits]: https://github.com/labwc/labwc/compare/0.9.2...0.9.3 @@ -3135,8 +3194,21 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3365]: https://github.com/labwc/labwc/pull/3365 [#3372]: https://github.com/labwc/labwc/pull/3372 [#3373]: https://github.com/labwc/labwc/pull/3373 +[#3387]: https://github.com/labwc/labwc/pull/3387 [#3400]: https://github.com/labwc/labwc/pull/3400 [#3406]: https://github.com/labwc/labwc/pull/3406 [#3410]: https://github.com/labwc/labwc/pull/3410 [#3411]: https://github.com/labwc/labwc/pull/3411 [#3412]: https://github.com/labwc/labwc/pull/3412 +[#3425]: https://github.com/labwc/labwc/pull/3425 +[#3426]: https://github.com/labwc/labwc/pull/3426 +[#3428]: https://github.com/labwc/labwc/pull/3428 +[#3429]: https://github.com/labwc/labwc/pull/3429 +[#3430]: https://github.com/labwc/labwc/pull/3430 +[#3440]: https://github.com/labwc/labwc/pull/3440 +[#3441]: https://github.com/labwc/labwc/pull/3441 +[#3443]: https://github.com/labwc/labwc/pull/3443 +[#3445]: https://github.com/labwc/labwc/pull/3445 +[#3490]: https://github.com/labwc/labwc/pull/3490 +[#3494]: https://github.com/labwc/labwc/pull/3494 +[#3511]: https://github.com/labwc/labwc/pull/3511 diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index e72354a3..03d5fc24 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -1354,6 +1354,13 @@ situation. *ignoreConfigureRequest* prevents a X11 window to position and size itself. +** [yes|no|default] + *allowAlwaysOnTop* allows a X11 window to control its always-on-top + state ('above' in X11 terms). + + Note: X11 window always-on-top requests are disallowed by default. + This window rule offers a means of allowing it. + ** [yes|no|default] *fixedPosition* disallows interactive move/resize and prevents re-positioning in response to changes in reserved output space, which @@ -1429,9 +1436,25 @@ situation. ## ENVIRONMENT VARIABLES -*XCURSOR_THEME* and *XCURSOR_SIZE* are supported to set cursor theme -and size respectively. The default size is 24. System cursor themes can -typically be found with a command such as: +*XCURSOR_PATH* + Specify a colon-separated list of paths to look for mouse cursors in. + Default + ~/.local/share/icons: + ~/.icons: + /usr/share/icons: + /usr/share/pixmaps: + ~/.cursors: + /usr/share/cursors/xorg-x11: + /usr/X11R6/lib/X11/icons: + +*XCURSOR_SIZE* + Specify an alternative mouse cursor size in pixels. Requires + XCURSOR_THEME to be set also. Default 24. + +*XCURSOR_THEME* + Specify a mouse cursor theme within XCURSOR_PATH. + +System cursor themes can typically be found with a command such as: ``` find /usr/share/icons/ -type d -name "cursors" diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd index 4840c0fa..2dab30a5 100644 --- a/docs/labwc.1.scd +++ b/docs/labwc.1.scd @@ -141,7 +141,7 @@ example: *LABWC_DEBUG_FOO=1 labwc*. *LABWC_DEBUG_KEY_STATE* Enable logging of press and release events for bound keys (generally - key-combinations like *Ctrl-Alt-t*) + key-combinations like *Ctrl-Alt-t*). # SEE ALSO diff --git a/include/window-rules.h b/include/window-rules.h index 1bee4c09..624f3b85 100644 --- a/include/window-rules.h +++ b/include/window-rules.h @@ -40,6 +40,7 @@ struct window_rule { enum property ignore_configure_request; enum property fixed_position; enum property icon_prefer_client; + enum property allow_always_on_top; struct wl_list link; /* struct rcxml.window_rules */ }; diff --git a/meson.build b/meson.build index ddb3d42b..63dd63c8 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'labwc', 'c', - version: '0.9.5', + version: '0.9.7', license: 'GPL-2.0-only', meson_version: '>=0.59.0', default_options: [ diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 95285776..45093781 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -300,6 +300,8 @@ fill_window_rule(xmlNode *node) set_property(content, &window_rule->ignore_configure_request); } else if (!strcasecmp(key, "fixedPosition")) { set_property(content, &window_rule->fixed_position); + } else if (!strcasecmp(key, "allowAlwaysOnTop")) { + set_property(content, &window_rule->allow_always_on_top); } } diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index cec5cac5..8d1c7612 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -346,8 +346,10 @@ init_cycle(struct server *server, struct cycle_filter filter) struct view *view; for_each_view(view, &server->views, criteria) { - if (!(cycle_outputs & view->output->id_bit)) { - continue; + if (filter.output != CYCLE_OUTPUT_ALL) { + if (!view->output || !(cycle_outputs & view->output->id_bit)) { + continue; + } } if (cycle_app_id && strcmp(view->app_id, cycle_app_id) != 0) { continue; diff --git a/src/cycle/osd-thumbnail.c b/src/cycle/osd-thumbnail.c index d5a0bf3e..464201bc 100644 --- a/src/cycle/osd-thumbnail.c +++ b/src/cycle/osd-thumbnail.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include "config/rcxml.h" @@ -45,8 +46,12 @@ render_node(struct server *server, struct wlr_render_pass *pass, if (!scene_buffer->buffer) { break; } - struct wlr_texture *texture = wlr_texture_from_buffer( - server->renderer, scene_buffer->buffer); + struct wlr_texture *texture = NULL; + struct wlr_client_buffer *client_buffer = + wlr_client_buffer_get(scene_buffer->buffer); + if (client_buffer) { + texture = client_buffer->texture; + } if (!texture) { break; } @@ -61,7 +66,6 @@ render_node(struct server *server, struct wlr_render_pass *pass, }, .transform = scene_buffer->transform, }); - wlr_texture_destroy(texture); break; } case WLR_SCENE_NODE_RECT: @@ -85,6 +89,10 @@ render_thumb(struct output *output, struct view *view) struct wlr_buffer *buffer = wlr_allocator_create_buffer(server->allocator, view->current.width, view->current.height, &output->wlr_output->swapchain->format); + if (!buffer) { + wlr_log(WLR_ERROR, "failed to allocate buffer for thumbnail"); + return NULL; + } struct wlr_render_pass *pass = wlr_renderer_begin_buffer_pass( server->renderer, buffer, NULL); render_node(server, pass, &view->content_tree->node, 0, 0); diff --git a/src/input/tablet.c b/src/input/tablet.c index 319c06b3..bc4426d6 100644 --- a/src/input/tablet.c +++ b/src/input/tablet.c @@ -402,8 +402,6 @@ handle_tablet_tool_axis(struct wl_listener *listener, void *data) */ tool->dx = 0; tool->dy = 0; - tool->tilt_x = 0; - tool->tilt_y = 0; if (ev->updated_axes & WLR_TABLET_TOOL_AXIS_X) { tool->x = ev->x; diff --git a/src/output.c b/src/output.c index f62dd87e..2e78ccaa 100644 --- a/src/output.c +++ b/src/output.c @@ -362,8 +362,10 @@ output_test_auto(struct wlr_output *wlr_output, struct wlr_output_state *state, } /* Reset mode if none worked (we may still try to commit) */ - wlr_output_state_set_mode(state, NULL); - return false; + wlr_log(WLR_DEBUG, "no working fixed mode found for output %s", wlr_output->name); + state->committed &= ~WLR_OUTPUT_STATE_MODE; + + return wlr_output_test_state(wlr_output, state); } static void @@ -378,10 +380,8 @@ configure_new_output(struct server *server, struct output *output) /* is_client_request */ false)) { wlr_log(WLR_INFO, "mode test failed for output %s", wlr_output->name); - /* - * Continue anyway. For some reason, the test fails when - * running nested, yet the following commit succeeds. - */ + wlr_output_state_set_enabled(&output->pending, false); + return; } if (rc.adaptive_sync == LAB_ADAPTIVE_SYNC_ENABLED) { diff --git a/src/server.c b/src/server.c index 93d95503..b8abc633 100644 --- a/src/server.c +++ b/src/server.c @@ -277,7 +277,7 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, "zxdg_importer_v1", "zxdg_importer_v2", "xdg_toplevel_icon_manager_v1", - "xdg_dialog_v1", + "xdg_wm_dialog_v1", /* plus */ "wp_alpha_modifier_v1", "wp_linux_drm_syncobj_manager_v1", diff --git a/src/view.c b/src/view.c index cb82ab22..ab9c67d5 100644 --- a/src/view.c +++ b/src/view.c @@ -1541,6 +1541,9 @@ void view_set_layer(struct view *view, enum view_layer layer) { assert(view); + if (view->layer == layer) { + return; + } view->layer = layer; wlr_scene_node_reparent(&view->scene_tree->node, view->workspace->view_trees[layer]); @@ -2499,9 +2502,6 @@ view_destroy(struct view *view) wl_list_remove(&view->set_title.link); wl_list_remove(&view->destroy.link); - zfree(view->title); - zfree(view->app_id); - if (view->foreign_toplevel) { foreign_toplevel_destroy(view->foreign_toplevel); view->foreign_toplevel = NULL; @@ -2556,6 +2556,9 @@ view_destroy(struct view *view) assert(wl_list_empty(&view->events.set_icon.listener_list)); assert(wl_list_empty(&view->events.destroy.listener_list)); + zfree(view->title); + zfree(view->app_id); + /* Remove view from server->views */ wl_list_remove(&view->link); free(view); diff --git a/src/window-rules.c b/src/window-rules.c index 0b8f1101..bfeacfe7 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -110,6 +110,10 @@ window_rules_get_property(struct view *view, const char *property) && !strcasecmp(property, "iconPreferClient")) { return rule->icon_prefer_client; } + if (rule->allow_always_on_top + && !strcasecmp(property, "allowAlwaysOnTop")) { + return rule->allow_always_on_top; + } } } return LAB_PROP_UNSPECIFIED; diff --git a/src/xwayland.c b/src/xwayland.c index 707ab390..fa3941d5 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -431,6 +431,11 @@ handle_request_above(struct wl_listener *listener, void *data) wl_container_of(listener, xwayland_view, request_above); struct view *view = &xwayland_view->base; + if (window_rules_get_property(view, "allowAlwaysOnTop") != LAB_PROP_TRUE) { + wlr_log(WLR_INFO, "X11 client side always on top request rejected"); + return; + } + view_set_layer(view, xwayland_view->xwayland_surface->above ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); } @@ -727,8 +732,11 @@ handle_map_request(struct wl_listener *listener, void *data) axis |= VIEW_AXIS_VERTICAL; } view_maximize(view, axis); - view_set_layer(view, xsurface->above - ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); + + if (window_rules_get_property(view, "allowAlwaysOnTop") == LAB_PROP_TRUE) { + view_set_layer(view, xsurface->above + ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); + } /* * We could also call set_initial_position() here, but it's not * really necessary until the view is actually mapped (and at