diff --git a/NEWS.md b/NEWS.md index 2e0a6109..ad71a1df 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 | |------------|---------------|-----------------|---------------| -| 2026-04-29 | [unreleased] | 0.20.0 | 27849 | +| 2026-05-25 | [0.20.0] | 0.20.1 | 28313 | | 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 | @@ -45,6 +45,7 @@ The format is based on [Keep a Changelog] | 2021-03-05 | [0.1.0] | 0.12.0 | 4627 | [unreleased]: NEWS.md#unreleased +[0.20.0]: NEWS.md#0200---2026-05-25 [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 @@ -79,6 +80,109 @@ The format is based on [Keep a Changelog] [0.2.0]: NEWS.md#020---2021-04-15 [0.1.0]: NEWS.md#010---2021-03-05 +## unreleased + +[unreleased-commits] + +## 0.20.0 - 2026-05-25 + +[0.20.0-commits] + +This is the first release using wlroots-0.20 and therefore has an increased risk +of teething issues. Many thanks to @Consolatis for leading the effort to port +across [#2956]. + +In terms of new features, the most noteworthy ones include: (i) the frequently +requested show-desktop action; (ii) initial toplevel capture support to +screenshot specific windows; (iii) menu accelerators/shortcuts; and (iv) HDR10 +support when running with the Vulkan renderer option. + +The eagle-eyed amongst you will have noticed the sudden jump from labwc `0.9.7` +to `0.20.0`. The reason for this is to align the minor number to that of the +wlroots version against which the compositor is linked. + +The 0.9.x series has turned into a maintenance branch named v0.9 with bug fixes +only, for anyone preferring to build with wlroots-0.19. + +Note to maintainers: + +- libinput >=1.26 is required in support of tablet tool pressure range + configuration. +- wlroots >=0.20.1 is required to avoid some bugs that we do not want labwc to + ship with. For details, see: + https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5325 + +### Added + +- Partially support toplevel-capture. Note that the following are not yet + implemented: (i) XWayland child windows; (ii) XWayland unmanaged windows + (e.g. popups); (iii) xdg child window positioning; (iv) xdg subsurfaces; + and (v) xdg popup positioning. [#2968] @Consolatis +- Add command line option -t|--title to set the labwc window title when running + nested [#3577] @mdsib +- Add support for HDR10 output @kode54 @Consolatis [#3424] +- Include wlroots version in --version string @Consolatis [#3567] [#3581] +- Implement menu accelerators (one-letter mnemonics to quickly select/exec + items from the current menu) @ch3rn1ka [#3505] +- Add Next/PreviousWindowImmediate actions @elviosak @johanmalm [#3547] +- Add labnag options `--details-border-color` and `--details-margin` + @st0rm-shad0w [#3527] +- Add config option `` to defer raise-on-focus by a + small amount when `raiseOnFocus` is enabled @joske [#3513] +- Install `labwc-session.target` systemd user unit when the systemd dependency + is available @joske [#3534] +- Add `onbutton` to config option ``. Also add + associated option ``. @diniamo [#3540] +- Add `overrideInhibition` option to `` [#3507] @drougas +- Add action `ToggleShowDesktop` to hide/unhide windows, and default keybind + `Super-d` to trigger this action [#3500] [#3595] @johanmalm +- Add `` config option so that privileged protocols can be + restricted [#3493] @xi +- Add action `DebugToggleKeyStateIndicator` to show a key-state on-screen + display (OSD) for debugging. [#3499] @johanmalm @tokyo4j +- Add support for `color-management-v1` and `color-representation-manager-v1` + protocols [#3469] @ManuLinares +- Add configuration option `` + to enable tablet tool pressure range libinput settings [#2916] @jp7677 +- Add `wl_fixes` interface [#2956] @kode54 + +### Fixed + +- Enable labnag long option --exclusive-zone [#3576] @st0rm-shad0w +- Position chromium popup correctly when a window is maximized on a multi- + output setup @elviosak [#3547] +- Run session activation environment update synchronously to avoid a race + condition with the autostart script [#3543] @joske +- Allow interactive resize on fully maximized windows so that a resize + initiated by modifier plus right-mouse-button-drag is not ignored [#3525] + @bjorn +- Gracefully handle missing XWayland packages, so that a labwc compositor which + has been built with XWayland support (which is optional) can be run even if + XWayland is not installed. [#3401] @quite +- Rework how XWayland window initial geometry is set to ensure that the natural + geometry does not exceed the usable output area when handling initial + maximize/fullscreen requests. [#3439] @jlindgren90. +- For XWayland windows, sync always-on-top state back to X.Org Server. This + makes `wmctrl -b toggle,above` work. [#3446] @jlindgren90 +- Fix missing title and icon with XWayland client override-redirect toggle. + There are no known issues with clients, so this is purely for preventative + purposes. [#3450] @jlindgren90 +- Update titlebar title when set to empty and fix an associated issue causing + the title to be misplaced outside of the titlebar when the window is resized. + [#3443] @tokyo4j +- When running nested, exit compositor when last output is destroyed because + in this situation, each output corresponds to a window in the parent + compositor and, unlike DRM outputs, these cannot be reconnected after being + destroyed. [#3440] @marler8997 +- Allow policy-based placement to apply when an initially-maximized/fullscreen + view is restored to floating geometry. [#3387] [#3502] @jlindgren90 + +### Changed + +- Change the default keybinds for XF86Audio{LowerVolume,RaiseVolume,Mute} to use + pactl instead of amixer [#3484] @danielrrrr +- Drop cosmic-workspace protocol [#3031] @tokyo4j + ## Notes on wlroots-0.19 There are some regression warnings worth noting for the switch to wlroots 0.19: @@ -113,72 +217,6 @@ 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 - -[unreleased-commits] - -The codebase has been ported to wlroots 0.20 [#2956] @Consolatis - -Note to maintainers: -- libinput >=1.26 is required in support of tablet tool pressure range - configuration. - -### Added - -- Add labnag options `--details-border-color` and `--details-margin` - @st0rm-shad0w [#3527] -- Add config option `` to defer raise-on-focus by a - small amount when `raiseOnFocus` is enabled @joske [#3513] -- Install `labwc-session.target` systemd user unit when the systemd dependency - is available @joske [#3534] -- Add `onbutton` to config option ``. Also add - associated option ``. @diniamo [#3540] -- Add `overrideInhibition` option to `` [#3507] @drougas -- Add action `ToggleShowDesktop` to hide/unhide windows [#3500] @johanmalm -- Add `` config option so that privileged protocols can be - restricted [#3493] @xi -- Add action `DebugToggleKeyStateIndicator` to show a key-state on-screen - display (OSD) for debugging. [#3499] @johanmalm @tokyo4j -- Add support for `color-management-v1` and `color-representation-manager-v1` - protocols [#3469] @ManuLinares -- Add configuration option `` - to enable tablet tool pressure range libinput settings [#2916] @jp7677 -- Add `wl_fixes` interface [#2956] @kode54 - -### Fixed - -- Run session activation environment update synchronously to avoid a race - condition with the autostart script [#3543] @joske -- Allow interactive resize on fully maximized windows so that a resize - initiated by modifier plus right-mouse-button-drag is not ignored [#3525] - @bjorn -- Gracefully handle missing XWayland packages, so that a labwc compositor which - has been built with XWayland support (which is optional) can be run even if - XWayland is not installed. [#3401] @quite -- Rework how XWayland window initial geometry is set to ensure that the natural - geometry does not exceed the usable output area when handling initial - maximize/fullscreen requests. [#3439] @jlindgren90. -- For XWayland windows, sync always-on-top state back to X.Org Server. This - makes `wmctrl -b toggle,above` work. [#3446] @jlindgren90 -- Fix missing title and icon with XWayland client override-redirect toggle. - There are no known issues with clients, so this is purely for preventative - purposes. [#3450] @jlindgren90 -- Update titlebar title when set to empty and fix an associated issue causing - the title to be misplaced outside of the titlebar when the window is resized. - [#3443] @tokyo4j -- When running nested, exit compositor when last output is destroyed because - in this situation, each output corresponds to a window in the parent - compositor and, unlike DRM outputs, these cannot be reconnected after being - destroyed. [#3440] @marler8997 -- Allow policy-based placement to apply when an initially-maximized/fullscreen - view is restored to floating geometry. [#3387] [#3502] @jlindgren90 - -### Changed - -- Change the default keybinds for XF86Audio{LowerVolume,RaiseVolume,Mute} to use - pactl instead of amixer [#3484] @danielrrrr -- Drop cosmic-workspace protocol [#3031] @tokyo4j - ## 0.9.7 - 2026-04-17 [0.9.7-commits] @@ -2732,7 +2770,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 +[unreleased-commits]: https://github.com/labwc/labwc/compare/0.20.0...HEAD +[0.20.0-commits]: https://github.com/labwc/labwc/compare/0.9.5..0.20.0 [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 @@ -3272,6 +3311,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3410]: https://github.com/labwc/labwc/pull/3410 [#3411]: https://github.com/labwc/labwc/pull/3411 [#3412]: https://github.com/labwc/labwc/pull/3412 +[#3424]: https://github.com/labwc/labwc/pull/3424 [#3425]: https://github.com/labwc/labwc/pull/3425 [#3426]: https://github.com/labwc/labwc/pull/3426 [#3428]: https://github.com/labwc/labwc/pull/3428 @@ -3292,6 +3332,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3499]: https://github.com/labwc/labwc/pull/3499 [#3500]: https://github.com/labwc/labwc/pull/3500 [#3502]: https://github.com/labwc/labwc/pull/3502 +[#3505]: https://github.com/labwc/labwc/pull/3505 [#3507]: https://github.com/labwc/labwc/pull/3507 [#3511]: https://github.com/labwc/labwc/pull/3511 [#3513]: https://github.com/labwc/labwc/pull/3513 @@ -3300,3 +3341,6 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3534]: https://github.com/labwc/labwc/pull/3534 [#3540]: https://github.com/labwc/labwc/pull/3540 [#3543]: https://github.com/labwc/labwc/pull/3543 +[#3547]: https://github.com/labwc/labwc/pull/3547 +[#3567]: https://github.com/labwc/labwc/pull/3567 +[#3595]: https://github.com/labwc/labwc/pull/3595 diff --git a/README.md b/README.md index 9cc81e88..80796af7 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ If you have not created an rc.xml config file, default bindings will be: | `super`-`return` | lab-sensible-terminal | `alt`-`F4` | close window | `super`-`a` | toggle maximize +| `super`-`d` | toggle show-desktop | `super`-`mouse-left` | move window | `super`-`mouse-right` | resize window | `super`-`arrow` | resize window to fill half the output diff --git a/clients/labnag.c b/clients/labnag.c index 8d47ee29..60a5abb3 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -1592,6 +1592,7 @@ nag_parse_options(int argc, char **argv, struct nag *nag, {"message", required_argument, NULL, 'm'}, {"output", required_argument, NULL, 'o'}, {"timeout", required_argument, NULL, 't'}, + {"exclusive-zone", no_argument, NULL, 'x'}, {"version", no_argument, NULL, 'v'}, {"background-color", required_argument, NULL, TO_COLOR_BACKGROUND}, diff --git a/docs/autostart b/docs/autostart index 17fcc270..18adb23b 100644 --- a/docs/autostart +++ b/docs/autostart @@ -12,7 +12,7 @@ swaybg -c '#113344' >/dev/null 2>&1 & # Configure output directives such as mode, position, scale and transform. -# Use wlr-randr to get your output names +# Use wlr-randr to get your output names. # Example ~/.config/kanshi/config below: # profile { # output HDMI-A-1 position 1366,0 diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index 47ee1801..2677e348 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -16,7 +16,7 @@ Actions are used in menus and keyboard/mouse bindings. SIGTERM signal. ** - Execute command. Note that in the interest of backward compatibility, + Execute command. Note that in the interest of backward compatibility, labwc supports as an alternative to even though openbox documentation states that it is deprecated. Note: Tilde (~) is expanded in the command before passing to execvp(). @@ -139,22 +139,21 @@ Actions are used in menus and keyboard/mouse bindings. and OSD, useful for binding to keys without modifiers. *workspace* [all|current] - This determines whether to cycle through windows on all workspaces or the - current workspace. Default is "current". + This determines whether to cycle through windows on all workspaces or + the current workspace. Default is "current". *output* [all|focused|cursor] - This determines whether to cycle through windows on all outputs, the focused - output, or the output under the cursor. Default is "all". + This determines whether to cycle through windows on all outputs, the + focused output, or the output under the cursor. Default is "all". *identifier* [all|current] - This determines whether to cycle through all windows or only windows of the - same application as the currently focused window. Default is "all". + This determines whether to cycle through all windows or only windows of + the same application as the currently focused window. Default is "all". ** Re-load configuration and theme files. -** - +** Show a menu. ``` @@ -300,7 +299,7 @@ Actions are used in menus and keyboard/mouse bindings. (if one exists). *wrap* [yes|no] When using the direction attribute, wrap around from - right-to-left or top-to-bottom, and vice versa. Default no. + right-to-left or top-to-bottom, and vice versa. Default is no. ** Resizes active window size to width and height of the output when the @@ -314,10 +313,10 @@ Actions are used in menus and keyboard/mouse bindings. workspace or its index (starting at 1) as configured in rc.xml. *wrap* [yes|no] Wrap around from last desktop to first, and vice - versa. Default yes. + versa. Default is yes. *toggle* [yes|no] Toggle to “last” if already on the workspace that - would be the actual destination. Default no. + would be the actual destination. Default is no. ** Send active window to workspace. @@ -325,10 +324,11 @@ Actions are used in menus and keyboard/mouse bindings. *to* The workspace to send the window to. Supported values are the same as for GoToDesktop. - *follow* [yes|no] Also switch to the specified workspace. Default yes. + *follow* [yes|no] Also switch to the specified workspace. + Default is yes. *wrap* [yes|no] Wrap around from last desktop to first, and vice - versa. Default yes. + versa. Default is yes. ** Add virtual output (headless backend). @@ -346,11 +346,11 @@ Actions are used in menus and keyboard/mouse bindings. ``` - - + + - + ``` @@ -371,7 +371,7 @@ Actions are used in menus and keyboard/mouse bindings. *output_name* The name of virtual output. If not supplied, will remove the last virtual output added. -** +** Reposition the window according to the desired placement policy. *policy* [automatic|cursor|center|cascade] Use the specified policy, @@ -430,11 +430,11 @@ Actions are used in menus and keyboard/mouse bindings. used. ** - Minimize all windows in the current workspace so that the desktop becomes - visible. On calling the action again the hidden windows are unminimized, - provided that - since the initial `ShowDesktop` - (a) no windows have been - unminimized; (b) workspaces have not been switched; and (c) no new - applications have been started. + Minimize all windows in the current workspace so that the desktop + becomes visible. On calling the action again the hidden windows are + unminimized, provided that - since the initial `ShowDesktop` - (a) no + windows have been unminimized; (b) workspaces have not been switched; + and (c) no new applications have been started. **++ ** @@ -449,8 +449,8 @@ Actions are used in menus and keyboard/mouse bindings. binding. ** - Toggle visibility of key-state on-screen display (OSD). Note: This is for - debugging purposes only. + Toggle visibility of key-state on-screen display (OSD). Note: This is + for debugging purposes only. # CONDITIONAL ACTIONS @@ -464,10 +464,10 @@ Actions that execute other actions. Used in keyboard/mouse bindings. ``` - - - - + + + + ``` @@ -549,9 +549,9 @@ Actions that execute other actions. Used in keyboard/mouse bindings. ``` - + - + diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 831a732f..39f1f9d4 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -25,7 +25,7 @@ The XDG Base Directory Specification does not specify whether or not programs should (a) allow the first-identified configuration file to supersede any others, or (b) define rules for merging the information from more than one file. -By default, labwc uses option (a), reading only the first file identified. With +By default, labwc uses option (a), reading only the first file identified. With the --merge-config option, the search order is reversed, but every configuration file encountered is processed in turn. Thus, user-specific files will augment system-wide configurations, with conflicts favoring the user-specific @@ -550,7 +550,8 @@ extending outward from the snapped edge. ** and **, and 50 for **. ** [yes|no] - Show an overlay when snapping a window to an output edge. Default is yes. + Show an overlay when snapping a window to an output edge. + Default is yes. **++ ** @@ -619,7 +620,7 @@ extending outward from the snapped edge. A setting of 0 disables the OSD. Default is 1000 ms. ** - Set the prefix to use when using "number" above. Default is "Workspace" + Set the prefix to use when using "number" above. Default is "Workspace". ## THEME @@ -773,7 +774,7 @@ generate gesture events, like swipe and pinch. There are some related settings (e.g. *threeFingerDrag* and *twoFingerScroll*) in the ** section. In the Wayland Compositor domain, events associated with touchscreens are -sometimes simply referred to as *touch* events. Touchscreens can be configured +sometimes simply referred to as *touch* events. Touchscreens can be configured in both the ** and ** sections. Note that touchscreen gestures are not interpreted by libinput, nor labwc. Any touch point is passed to the client (application) for any interpretation of gestures. @@ -848,9 +849,10 @@ overrideInhibition="">* Make this keybind work even if the screen is locked. Default is no. *overrideInhibition* [yes|no] - Make this keybind work even if the view inhibits keybinds. Default is no. + Make this keybind work even if the view inhibits keybinds. This can be used to prevent W-Tab and similar keybinds from being delivered to Virtual Machines, VNC clients or nested compositors. + Default is no. *onRelease* [yes|no] When yes, fires the keybind action when the key or key @@ -864,7 +866,7 @@ overrideInhibition="">* ``` - + ``` @@ -885,6 +887,7 @@ overrideInhibition="">* W-Return - lab-sensible-terminal A-F4 - close window W-a - toggle maximize + W-d - toggle show-desktop W- - resize window to fill half or quarter of the output A-Space - show window menu ``` @@ -924,7 +927,7 @@ input-devices by the Wayland protocol. - Shade: A button that, by default, toggles window shading. - AllDesktops: A button that, by default, toggles omnipresence of a window. - - Close: A button that, by default, closses a window. + - Close: A button that, by default, closes a window. - Border: The window's border including Top...BRCorner below. - Top: The top edge of the window's border. - Bottom: The bottom edge of the window's border. @@ -998,10 +1001,10 @@ input-devices by the Wayland protocol. ``` - + - - + + ``` @@ -1009,7 +1012,7 @@ input-devices by the Wayland protocol. ** Load default mousebinds. This is an addition to the openbox specification and provides a way to keep config files simpler whilst - allowing user specific binds. Note that if no rc.xml is found, or if no + allowing user specific binds. Note that if no rc.xml is found, or if no entries exist, the same default mousebinds will be loaded even if the element is not provided. @@ -1021,7 +1024,7 @@ Note: To rotate touch events with output rotation, use the libinput *calibrationMatrix* setting. ``` - + ``` ** @@ -1284,7 +1287,8 @@ Note: To rotate touch events with output rotation, use the libinput The default method depends on the touchpad hardware. ** [none|twofinger|edge|onbutton] - Configure the method by which physical movements are mapped to scroll events. + Configure the method by which physical movements are mapped to scroll + events. The scroll methods available are: - *twofinger* - Scroll by two fingers being placed on the surface of the @@ -1299,7 +1303,8 @@ Note: To rotate touch events with output rotation, use the libinput ** [button] Set the button used for the *onbutton* scroll method. - *button* is the decimal form of a value from `linux/input-event-codes.h`. + *button* is the decimal form of a value + from `linux/input-event-codes.h`. ** [yes|no|disabledOnExternalMouse] Optionally enable or disable sending any device events. @@ -1348,7 +1353,7 @@ defined as shown below. - + @@ -1545,7 +1550,7 @@ This is the full list of interfaces that can be controlled with this mechanism: *XCURSOR_PATH* Specify a colon-separated list of paths to look for mouse cursors in. - Default + Default is ~/.local/share/icons: ~/.icons: /usr/share/icons: @@ -1556,7 +1561,7 @@ This is the full list of interfaces that can be controlled with this mechanism: *XCURSOR_SIZE* Specify an alternative mouse cursor size in pixels. Requires - XCURSOR_THEME to be set also. Default 24. + XCURSOR_THEME to be set also. Default is 24. *XCURSOR_THEME* Specify a mouse cursor theme within XCURSOR_PATH. diff --git a/docs/labwc-menu.5.scd b/docs/labwc-menu.5.scd index df04ccf9..e2c40d84 100644 --- a/docs/labwc-menu.5.scd +++ b/docs/labwc-menu.5.scd @@ -12,7 +12,7 @@ Static menus are built based on the menu.xml file located at # SYNTAX The menu file must be entirely enclosed within and - tags. Inside these tags, menus are specified as follows: + tags. Inside these tags, menus are specified as follows: ``` @@ -111,7 +111,7 @@ Pipe menus are menus generated dynamically based on output of scripts or binaries. They are so-called because the output of the executable is piped to the labwc menu. -For any ** entry in menu.xml, the +For any ** entry in menu.xml, the COMMAND will be executed the first time the item is selected (for example by cursor or keyboard input). The XML output of the command will be parsed and shown as a submenu. The content of pipemenus is cached until the whole menu @@ -124,7 +124,7 @@ menus, for example: ``` - + ``` @@ -144,7 +144,7 @@ obmenu-generator with the menu generator of your choice): ``` - + ``` diff --git a/docs/labwc-theme.5.scd b/docs/labwc-theme.5.scd index 5f99cae7..dce48bdf 100644 --- a/docs/labwc-theme.5.scd +++ b/docs/labwc-theme.5.scd @@ -135,7 +135,7 @@ window.*.title.bg.colorTo.splitTo: #557485 *window.active.title.bg* Texture for the focused window's titlebar. See texture section above. - Default is *Solid* + Default is *Solid*. *window.active.title.bg.color* Background color for the focused window's titlebar. See texture section @@ -144,7 +144,7 @@ window.*.title.bg.colorTo.splitTo: #557485 *window.inactive.title.bg* Texture for non-focused windows' titlebars. See texture section above. - Default is *Solid* + Default is *Solid*. *window.inactive.title.bg.color* Background color for non-focused windows' titlebars. See texture section @@ -470,7 +470,7 @@ all are supported. Width of magnifier window border in pixels. Default is 1. *magnifier.border.color* - Color of the magnfier window border. Default is #ff0000 (red). + Color of the magnifier window border. Default is #ff0000 (red). # BUTTONS diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd index 31f28c19..56dfe775 100644 --- a/docs/labwc.1.scd +++ b/docs/labwc.1.scd @@ -66,10 +66,18 @@ the `--exit` and `--reconfigure` options use. Manager, or the Window Manager can be launched independently first. On Wayland, the Compositor is both Display Server and Window Manager, so the described session management mechanisms do not work because the - Compositor needs to be running before the session can function. As some + Compositor needs to be running before the session can function. As some session clients support both X11 and Wayland, this command line option avoids re-writes and fragmentation. +*-t, --title* + Set the window title for labwc to use when it is running in a window + (i.e. nested in a compositor). is a format string to be used as + the window title, replacing `%o` with the name of the output + region. This is useful when simulating multiple screens, such as with + running labwc with the environment variable `WLR_WL_OUTPUTS=2`. In this + case, `%o` will be unique per simulated screen. + *-v, --version* Show the version number and quit diff --git a/docs/menu.xml b/docs/menu.xml index 4b4d5dda..3344161a 100644 --- a/docs/menu.xml +++ b/docs/menu.xml @@ -23,7 +23,7 @@ Any menu with the id "workspaces" will be hidden if there is only a single workspace available. --> - + diff --git a/include/config/default-bindings.h b/include/config/default-bindings.h index a49f60f4..d1a96562 100644 --- a/include/config/default-bindings.h +++ b/include/config/default-bindings.h @@ -28,6 +28,9 @@ static struct key_combos { }, { .binding = "W-a", .action = "ToggleMaximize", + }, { + .binding = "W-d", + .action = "ToggleShowDesktop", }, { .binding = "W-Left", .action = "SnapToEdge", @@ -141,14 +144,14 @@ static struct key_combos { * * * - * - * - * + * + * + * * * * * - * + * * * * diff --git a/include/labwc.h b/include/labwc.h index edde2771..87a42198 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -194,6 +194,13 @@ struct server { struct wlr_xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager; struct wl_listener xdg_toplevel_icon_set_icon; + struct { + struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 *manager; + struct { + struct wl_listener new_request; + } on; + } toplevel_capture; + /* front to back order */ struct wl_list views; uint64_t next_view_creation_id; @@ -315,6 +322,8 @@ struct server { struct sfdo *sfdo; pid_t primary_client_pid; + + char *title_fmt; }; /* defined in main.c */ diff --git a/include/scaled-buffer/scaled-buffer.h b/include/scaled-buffer/scaled-buffer.h index c2af6054..017e29fb 100644 --- a/include/scaled-buffer/scaled-buffer.h +++ b/include/scaled-buffer/scaled-buffer.h @@ -130,7 +130,7 @@ void scaled_buffer_request_update(struct scaled_buffer *self, /** * scaled_buffer_invalidate_sharing - clear the list of entire cached - * scaled_buffers used to share visually dupliated buffers. This should + * scaled_buffers used to share visually duplicated buffers. This should * be called on Reconfigure to force updates of newly created * scaled_buffers rather than reusing ones created before Reconfigure. */ diff --git a/include/view.h b/include/view.h index a179338e..46943ab2 100644 --- a/include/view.h +++ b/include/view.h @@ -177,6 +177,12 @@ struct view { char *title; char *app_id; /* WM_CLASS for xwayland windows */ + struct { + struct wlr_scene *scene; + struct wlr_ext_image_capture_source_v1 *source; + struct wl_listener on_capture_source_destroy; + } capture; + bool mapped; bool been_mapped; uint64_t creation_id; @@ -319,6 +325,7 @@ struct xdg_toplevel_view { /* Events unique to xdg-toplevel views */ struct wl_listener set_app_id; struct wl_listener request_show_window_menu; + struct wl_listener set_parent; struct wl_listener new_popup; }; diff --git a/meson.build b/meson.build index 7e345ba6..8684732f 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'labwc', 'c', - version: '0.9.5', + version: '0.20.0', license: 'GPL-2.0-only', meson_version: '>=0.59.0', default_options: [ @@ -53,7 +53,7 @@ add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c') wlroots = dependency( 'wlroots-0.20', default_options: ['default_library=static', 'examples=false'], - version: ['>=0.20.0', '<0.21.0'], + version: ['>=0.20.1', '<0.21.0'], ) wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true' diff --git a/po/de.po b/po/de.po index 5841f3f6..d83ef64a 100644 --- a/po/de.po +++ b/po/de.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: labwc\n" "Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n" "POT-Creation-Date: 2024-09-19 21:09+1000\n" -"PO-Revision-Date: 2025-08-15 20:01+0000\n" -"Last-Translator: Ettore Atalan \n" +"PO-Revision-Date: 2026-05-18 18:28+0000\n" +"Last-Translator: Demian \n" "Language-Team: German \n" "Language: de\n" @@ -21,7 +21,7 @@ msgstr "" #: src/menu/menu.c:1016 msgid "Go there..." -msgstr "Dorthin gehen..." +msgstr "Dorthin wechseln ..." #: src/menu/menu.c:1034 msgid "Terminal" @@ -61,11 +61,11 @@ msgstr "Immer im Vordergrund" #: src/menu/menu.c:1071 msgid "Move Left" -msgstr "nach links" +msgstr "Nach links" #: src/menu/menu.c:1078 msgid "Move Right" -msgstr "nach rechts" +msgstr "Nach rechts" #: src/menu/menu.c:1083 msgid "Always on Visible Workspace" diff --git a/src/action.c b/src/action.c index 8691df60..0f88e8a2 100644 --- a/src/action.c +++ b/src/action.c @@ -146,7 +146,7 @@ struct action_arg_list { * Will expand to: * * enum action_type { - * ACTION_TYPE_INVALID, + * ACTION_TYPE_INVALID = 0, * ACTION_TYPE_NONE, * ACTION_TYPE_CLOSE, * ACTION_TYPE_KILL, @@ -1313,7 +1313,7 @@ run_action(struct view *view, struct action *action, /* * To support only setting one of width/height - * in + * in * we fall back to current dimension when unset. */ struct wlr_box box = { diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 2c5f436e..1d9afff4 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -614,9 +614,9 @@ fill_mousebind(xmlNode *node, const char *context) /* * Example of what we are parsing: * - * - * - * + * + * + * * */ diff --git a/src/foreign-toplevel/ext-foreign.c b/src/foreign-toplevel/ext-foreign.c index 78774433..1dfa1d96 100644 --- a/src/foreign-toplevel/ext-foreign.c +++ b/src/foreign-toplevel/ext-foreign.c @@ -75,6 +75,9 @@ ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, return; } + /* In support for ext-toplevel-capture */ + ext_toplevel->handle->data = view; + /* Client side requests */ ext_toplevel->on.handle_destroy.notify = handle_handle_destroy; wl_signal_add(&ext_toplevel->handle->events.destroy, &ext_toplevel->on.handle_destroy); diff --git a/src/img/img-xbm.c b/src/img/img-xbm.c index 91269f64..3771444a 100644 --- a/src/img/img-xbm.c +++ b/src/img/img-xbm.c @@ -226,7 +226,7 @@ out: /* * Openbox built-in icons are not bigger than 8x8, so have only written this - * function to cope wit that max size + * function to cope with that max size */ #define LABWC_BUILTIN_ICON_MAX_SIZE (8) diff --git a/src/main.c b/src/main.c index 53f85623..081bd62a 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include "common/font.h" #include "common/macros.h" #include "common/spawn.h" +#include "common/string-helpers.h" #include "config/rcxml.h" #include "config/session.h" #include "labwc.h" @@ -37,6 +38,7 @@ static const struct option long_options[] = { {"reconfigure", no_argument, NULL, 'r'}, {"startup", required_argument, NULL, 's'}, {"session", required_argument, NULL, 'S'}, + {"title", required_argument, NULL, 't'}, {"version", no_argument, NULL, 'v'}, {"verbose", no_argument, NULL, 'V'}, {0, 0, 0, 0} @@ -53,6 +55,7 @@ static const char labwc_usage[] = " -r, --reconfigure Reload the compositor configuration\n" " -s, --startup Run command on startup\n" " -S, --session Run command on startup and terminate on exit\n" +" -t, --title Specify title to use when running in a window\n" " -v, --version Show version number and quit\n" " -V, --verbose Enable more verbose logging\n"; @@ -67,7 +70,7 @@ static void print_version(void) { #define FEATURE_ENABLED(feature) (HAVE_##feature ? "+" : "-") - printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo) running on wlroots %d.%d.%d\n", + printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo) wlroots-%d.%d.%d\n", LABWC_VERSION, FEATURE_ENABLED(XWAYLAND), FEATURE_ENABLED(NLS), @@ -178,7 +181,7 @@ main(int argc, char *argv[]) int c; while (1) { int index = 0; - c = getopt_long(argc, argv, "c:C:dehmrs:S:vV", long_options, &index); + c = getopt_long(argc, argv, "c:C:dehmrs:S:t:vV", long_options, &index); if (c == -1) { break; } @@ -207,6 +210,9 @@ main(int argc, char *argv[]) case 'S': primary_client = optarg; break; + case 't': + server.title_fmt = optarg; + break; case 'v': print_version(); exit(0); @@ -265,6 +271,10 @@ main(int argc, char *argv[]) increase_nofile_limit(); + if (string_null_or_empty(server.title_fmt)) { + server.title_fmt = "labwc - %o"; + } + server_init(); server_start(); diff --git a/src/menu/menu.c b/src/menu/menu.c index 2505317d..c0e93c59 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -172,7 +172,7 @@ item_parse_accelerator(struct menuitem *item, const char *text) accel_ptr = underscore + 1; break; } else { - /* Ignore empty accelertor */ + /* Ignore empty accelerator */ break; } } @@ -627,7 +627,7 @@ fill_menu(struct menu *parent, xmlNode *n) * * * - * + * * */ } else { diff --git a/src/output.c b/src/output.c index 29a2d5a0..2eab8ec3 100644 --- a/src/output.c +++ b/src/output.c @@ -10,6 +10,7 @@ #include "output.h" #include #include +#include #include #include #include @@ -26,6 +27,7 @@ #include "common/macros.h" #include "common/mem.h" #include "common/scene-helpers.h" +#include "common/string-helpers.h" #include "config/rcxml.h" #include "labwc.h" #include "layers.h" @@ -605,9 +607,10 @@ handle_new_output(struct wl_listener *listener, void *data) } if (wlr_output_is_wl(wlr_output)) { - char title[64]; - snprintf(title, sizeof(title), "%s - %s", "labwc", wlr_output->name); - wlr_wl_output_set_title(wlr_output, title); + GString *title = g_string_new(server.title_fmt); + g_string_replace(title, "%o", wlr_output->name, 0); + wlr_wl_output_set_title(wlr_output, title->str); + g_string_free(title, TRUE); wlr_wl_output_set_app_id(wlr_output, "labwc"); } diff --git a/src/server.c b/src/server.c index 5a39dabe..79e2eb8f 100644 --- a/src/server.c +++ b/src/server.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #define _POSIX_C_SOURCE 200809L #include "config.h" +#include #include #include #include @@ -414,6 +415,39 @@ handle_renderer_lost(struct wl_listener *listener, void *data) wlr_renderer_destroy(old_renderer); } +static void +handle_toplevel_capture_source_destroy(struct wl_listener *listener, void *data) +{ + struct view *view = wl_container_of(listener, view, capture.on_capture_source_destroy); + assert(view->capture.source); + view->capture.source = NULL; + wl_list_remove(&listener->link); + wl_list_init(&listener->link); +} + +static void +handle_toplevel_capture_request(struct wl_listener *listener, void *data) +{ + struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request *request = data; + struct view *view = request->toplevel_handle->data; + assert(view); + wlr_log(WLR_INFO, "Capturing toplevel %s", view->app_id); + + if (!view->capture.source) { + view->capture.source = wlr_ext_image_capture_source_v1_create_with_scene_node( + &view->capture.scene->tree.node, server.wl_event_loop, + server.allocator, server.renderer); + assert(view->capture.source); + + view->capture.on_capture_source_destroy.notify = + handle_toplevel_capture_source_destroy; + wl_signal_add(&view->capture.source->events.destroy, + &view->capture.on_capture_source_destroy); + } + wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request_accept( + request, view->capture.source); +} + void server_init(void) { @@ -693,6 +727,19 @@ server_init(void) wlr_screencopy_manager_v1_create(server.wl_display); wlr_ext_image_copy_capture_manager_v1_create(server.wl_display, 1); wlr_ext_output_image_capture_source_manager_v1_create(server.wl_display, 1); + + server.toplevel_capture.manager = + wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create( + server.wl_display, 1); + if (server.toplevel_capture.manager) { + server.toplevel_capture.on.new_request.notify = handle_toplevel_capture_request; + wl_signal_add(&server.toplevel_capture.manager->events.new_request, + &server.toplevel_capture.on.new_request); + } else { + /* Allow safe removal on shutdown */ + wl_list_init(&server.toplevel_capture.on.new_request.link); + } + wlr_data_control_manager_v1_create(server.wl_display); wlr_ext_data_control_manager_v1_create(server.wl_display, LAB_EXT_DATA_CONTROL_VERSION); @@ -828,6 +875,8 @@ server_finish(void) server.drm_lease_request.notify = NULL; } + wl_list_remove(&server.toplevel_capture.on.new_request.link); + wlr_backend_destroy(server.backend); wlr_allocator_destroy(server.allocator); diff --git a/src/theme.c b/src/theme.c index 93ac1c5e..71e577ce 100644 --- a/src/theme.c +++ b/src/theme.c @@ -788,7 +788,7 @@ entry(struct theme *theme, const char *key, const char *value) value, "window.button.spacing"); } - /* botton hover overlay */ + /* button hover overlay */ if (match_glob(key, "window.button.hover.bg.color")) { parse_color(value, theme->window_button_hover_bg_color); } diff --git a/src/view.c b/src/view.c index bcbd366e..21005f20 100644 --- a/src/view.c +++ b/src/view.c @@ -2482,6 +2482,10 @@ view_init(struct view *view) view->title = xstrdup(""); view->app_id = xstrdup(""); + + view->capture.scene = wlr_scene_create(); + view->capture.scene->restack_xwayland_surfaces = false; + wl_list_init(&view->capture.on_capture_source_destroy.link); } void @@ -2503,6 +2507,9 @@ view_destroy(struct view *view) wl_list_remove(&view->request_fullscreen.link); wl_list_remove(&view->set_title.link); wl_list_remove(&view->destroy.link); + wl_list_remove(&view->capture.on_capture_source_destroy.link); + + wlr_scene_node_destroy(&view->capture.scene->tree.node); if (view->foreign_toplevel) { foreign_toplevel_destroy(view->foreign_toplevel); diff --git a/src/window-rules.c b/src/window-rules.c index f43b92f4..4118ae32 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -69,8 +69,8 @@ window_rules_get_property(struct view *view, const char *property) * for foot's "serverDecoration" property to be "default". * * - * - * + * + * * */ struct window_rule *rule; diff --git a/src/xdg-popup.c b/src/xdg-popup.c index 8e6870af..7ca9ab01 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -169,4 +169,6 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup) node_descriptor_create(wlr_popup->base->surface->data, LAB_NODE_XDG_POPUP, view, /*data*/ NULL); + + wlr_scene_xdg_surface_create(&view->capture.scene->tree, wlr_popup->base); } diff --git a/src/xdg.c b/src/xdg.c index 211a340d..03035d63 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -30,6 +30,8 @@ #define LAB_XDG_SHELL_VERSION 6 #define CONFIGURE_TIMEOUT_MS 100 +static struct view *xdg_toplevel_view_get_root(struct view *view); + static struct xdg_toplevel_view * xdg_toplevel_view_from_view(struct view *view) { @@ -462,6 +464,7 @@ handle_destroy(struct wl_listener *listener, void *data) /* Remove xdg-shell view specific listeners */ wl_list_remove(&xdg_toplevel_view->set_app_id.link); wl_list_remove(&xdg_toplevel_view->request_show_window_menu.link); + wl_list_remove(&xdg_toplevel_view->set_parent.link); wl_list_remove(&xdg_toplevel_view->new_popup.link); wl_list_remove(&view->commit.link); @@ -565,6 +568,23 @@ handle_request_show_window_menu(struct wl_listener *listener, void *data) menu_open_root(menu, cursor->x, cursor->y); } +static void +handle_set_parent(struct wl_listener *listener, void *data) +{ + struct xdg_toplevel_view *xdg_toplevel_view = wl_container_of( + listener, xdg_toplevel_view, set_parent); + struct view *view = &xdg_toplevel_view->base; + struct view *view_root = xdg_toplevel_view_get_root(view); + if (view_root == view) { + return; + } + struct wlr_scene_node *node, *tmp; + wl_list_for_each_safe(node, tmp, &view->capture.scene->tree.children, link) { + wlr_log(WLR_DEBUG, "moving capture scene node to view_root"); + wlr_scene_node_reparent(node, &view_root->capture.scene->tree); + } +} + static void handle_set_title(struct wl_listener *listener, void *data) { @@ -1046,6 +1066,9 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) mappable_connect(&view->mappable, xdg_surface->surface, handle_map, handle_unmap); + struct view *root_view = xdg_toplevel_view_get_root(view); + wlr_scene_xdg_surface_create(&root_view->capture.scene->tree, xdg_surface); + struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel; CONNECT_SIGNAL(toplevel, view, destroy); CONNECT_SIGNAL(toplevel, view, request_move); @@ -1059,6 +1082,7 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) /* Events specific to XDG toplevel views */ CONNECT_SIGNAL(toplevel, xdg_toplevel_view, set_app_id); CONNECT_SIGNAL(toplevel, xdg_toplevel_view, request_show_window_menu); + CONNECT_SIGNAL(toplevel, xdg_toplevel_view, set_parent); CONNECT_SIGNAL(xdg_surface, xdg_toplevel_view, new_popup); wl_list_insert(&server.views, &view->link); diff --git a/src/xwayland.c b/src/xwayland.c index 967364c5..5838d412 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -783,6 +783,7 @@ handle_map(struct wl_listener *listener, void *data) view->content_tree = wlr_scene_subsurface_tree_create( view->scene_tree, view->surface); die_if_null(view->content_tree); + wlr_scene_subsurface_tree_create(&view->capture.scene->tree, view->surface); } wlr_scene_node_set_enabled(&view->content_tree->node, !view->shaded);