Merge branch 'master' into menu-accelerators

This commit is contained in:
Alex Chernika 2026-05-08 00:20:57 +02:00
commit 634a3464bd
No known key found for this signature in database
GPG key ID: 6029FAD8ABFB076A
12 changed files with 321 additions and 69 deletions

74
NEWS.md
View file

@ -264,9 +264,9 @@ Note to package maintainers: This release requires wayland version >=1.22.90
- Add theme option window.button.hover.bg.color [#3365] @johanmalm - Add theme option window.button.hover.bg.color [#3365] @johanmalm
- Implement scrollable window-switcher OSD [#3291] @tokyo4j - Implement scrollable window-switcher OSD [#3291] @tokyo4j
- Support the `NextWindow` options listed below [#3271] @tokyo4j - Support the `NextWindow` options listed below [#3271] @tokyo4j
- `<action name="NextWindow" workspace="current|all"/>` - `<action name="NextWindow" workspace="current|all" />`
- `<action name="NextWindow" output="all|focused|cursor"/>` - `<action name="NextWindow" output="all|focused|cursor" />`
- `<action name="NextWindow" identifier="all|current"/>` - `<action name="NextWindow" identifier="all|current" />`
- Add config option `*<desktops><initial>` for setting the active workspace on - Add config option `*<desktops><initial>` for setting the active workspace on
startup. [#3265] @5trixs0f startup. [#3265] @5trixs0f
@ -314,7 +314,7 @@ Note to package maintainers: This release requires wayland version >=1.22.90
and get keyboard focus so that they can be operated with the keyboard. and get keyboard focus so that they can be operated with the keyboard.
An example use-case is the xfce4-panel applications-menu being opened by An example use-case is the xfce4-panel applications-menu being opened by
the command xfce4-popup-applicationsmenu. [#3165] @johanmalm the command xfce4-popup-applicationsmenu. [#3165] @johanmalm
- On popup destory, return focus to whoever had it before the popop [#3165] - On popup destroy, return focus to whoever had it before the popop [#3165]
@johanmalm @tokyo4j @johanmalm @tokyo4j
- Unshade window if selected from client-list-combined-menu [#3345] @Amodio - Unshade window if selected from client-list-combined-menu [#3345] @Amodio
- Show non-dialog child windows in window-switcher [#3339] @tokyo4j - Show non-dialog child windows in window-switcher [#3339] @tokyo4j
@ -348,7 +348,7 @@ A big thank you to all involved in this release.
### Added ### Added
- Add `<windowSwitcher order="focus|age"/>` to optionally order windows by age - Add `<windowSwitcher order="focus|age" />` to optionally order windows by age
rather than most recent focus. @mbroemme [#3229] rather than most recent focus. @mbroemme [#3229]
- Replace `<snapping><range>` with `<snapping><range inner="" outer="">` to - Replace `<snapping><range>` with `<snapping><range inner="" outer="">` to
provide more granular control when configuring the size of snapping areas provide more granular control when configuring the size of snapping areas
@ -379,7 +379,7 @@ A big thank you to all involved in this release.
[#3134] [#3134]
- labnag: add --keyboard-focus option @tokyo4j [#3120] - labnag: add --keyboard-focus option @tokyo4j [#3120]
- Allow window switcher to temporarily unshade windows using config option - Allow window switcher to temporarily unshade windows using config option
`<windowSwitcher unshade="yes|no"/>` @Amodio @Consolatis [#3124] `<windowSwitcher unshade="yes|no" />` @Amodio @Consolatis [#3124]
- For the 'classic' style window-switcher, add the following theme options: - For the 'classic' style window-switcher, add the following theme options:
- `osd.window-switcher.style-classic.item.active.border.color` - `osd.window-switcher.style-classic.item.active.border.color`
- `osd.window-switcher.style-classic.item.active.bg.color` - `osd.window-switcher.style-classic.item.active.bg.color`
@ -409,7 +409,7 @@ A big thank you to all involved in this release.
client surface. Fixes a regression in 885919f. @tokyo4j [#3211] client surface. Fixes a regression in 885919f. @tokyo4j [#3211]
- Set all foreign-toplevel initial states correctly. This is not believed to fix - Set all foreign-toplevel initial states correctly. This is not believed to fix
any particular user-issue, but just feels safer. @jlindgren90 [#3217] any particular user-issue, but just feels safer. @jlindgren90 [#3217]
- Update layer-shell client top layer visiblity on unmap instead of destroy - Update layer-shell client top layer visibility on unmap instead of destroy
because it is possible for fullscreen xwayland windows to be unmapped without because it is possible for fullscreen xwayland windows to be unmapped without
being destroyed, and in this case the top layer visibility needs to be updated being destroyed, and in this case the top layer visibility needs to be updated
to unhide other layer-shell clients like panels. @jlindgren90 [#3199] to unhide other layer-shell clients like panels. @jlindgren90 [#3199]
@ -421,7 +421,7 @@ A big thank you to all involved in this release.
@elviosak [#3146] [#3168] @elviosak [#3146] [#3168]
- Work around client-side rounding issues at right/bottom pixel. This fixes an - Work around client-side rounding issues at right/bottom pixel. This fixes an
issue with some clients (notably Qt ones) where cursor coordinates in the issue with some clients (notably Qt ones) where cursor coordinates in the
rightmost or bottom fixel are incorrectly rounded up putting them outside the rightmost or bottom pixel are incorrectly rounded up putting them outside the
surface bounds. The issue has been particularly noticeable with layer-shell surface bounds. The issue has been particularly noticeable with layer-shell
clients like lxqt-panel. @jlindgren90 [#3157] [#2379] [#3099] clients like lxqt-panel. @jlindgren90 [#3157] [#2379] [#3099]
Note: This also avoids a similar server-side rounding issue with some Note: This also avoids a similar server-side rounding issue with some
@ -469,7 +469,7 @@ A big thank you to all involved in this release.
when a window is using fullscreen mode. @johanmalm [#3158] when a window is using fullscreen mode. @johanmalm [#3158]
- Call labnag with on-demand keyboard interactivity by default @tokyo4j [#3120] - Call labnag with on-demand keyboard interactivity by default @tokyo4j [#3120]
- Temporarily unshade windows when switching windows. Restore old behaviour with - Temporarily unshade windows when switching windows. Restore old behaviour with
`<windowSwitcher unshade="no"/>` @Amodio @Consolatis [#3124] `<windowSwitcher unshade="no" />` @Amodio @Consolatis [#3124]
- In the classic style window-switcher, the default color of the selected window - In the classic style window-switcher, the default color of the selected window
item has been changed to inherit the border color but with 15% opacity item has been changed to inherit the border color but with 15% opacity
@tokyo4j [#3118] @tokyo4j [#3118]
@ -488,7 +488,7 @@ A big thank you to all involved in this release.
`<windowSwitcher style="thumbnail">`. @tokyo4j [#2981] `<windowSwitcher style="thumbnail">`. @tokyo4j [#2981]
- Add `toggle` option to `GoToDesktop` action. This has the effect of going back - Add `toggle` option to `GoToDesktop` action. This has the effect of going back
to the last desktop if already on the target. @RainerKuemmerle [#3024] to the last desktop if already on the target. @RainerKuemmerle [#3024]
- Add `<theme maximizedDecoration="titlebar|none"/>` to allow hiding titlebar - Add `<theme maximizedDecoration="titlebar|none" />` to allow hiding titlebar
when window is maximized. @CosmicFusion @tokyo4j [#3015] when window is maximized. @CosmicFusion @tokyo4j [#3015]
- Use client-send-to-menu as 'Workspace' submenu in built-in client-menu - Use client-send-to-menu as 'Workspace' submenu in built-in client-menu
@johanmalm [#2995] @johanmalm [#2995]
@ -539,7 +539,7 @@ A big thank you to all involved in this release.
- Change default keybind `W-<arrow>` to combine cardinal directions to support - Change default keybind `W-<arrow>` to combine cardinal directions to support
resizing of windows to fill a quarter of an output. This only affects users resizing of windows to fill a quarter of an output. This only affects users
who do not use an `rc.xml` (thereby using default keybinds) or use the who do not use an `rc.xml` (thereby using default keybinds) or use the
`<keyboard><default/>` option. Previous behavior can be restored by setting `<keyboard><default />` option. Previous behavior can be restored by setting
`combine="no"` as shown below. [#3081] @tokyo4j `combine="no"` as shown below. [#3081] @tokyo4j
``` ```
@ -638,7 +638,7 @@ window.*.title.bg.colorTo.splitTo:
window rule to enable this. @Consolatis @tokyo4j [#2840] window rule to enable this. @Consolatis @tokyo4j [#2840]
- Add config option `<core><primarySelection>`. This enables autoscroll - Add config option `<core><primarySelection>`. This enables autoscroll
(middle-click to scroll up/down) in Chromium and electron based clients (middle-click to scroll up/down) in Chromium and electron based clients
without inadvertantly pasting the primary clipboard. @johanmalm [#2832] without inadvertently pasting the primary clipboard. @johanmalm [#2832]
- Bump `xdg_shell` version from 3 to 6 @tokyo4j [#2814] - Bump `xdg_shell` version from 3 to 6 @tokyo4j [#2814]
- Bump `wl_compositor` version from 5 to 6 @tokyo4j [#2812] - Bump `wl_compositor` version from 5 to 6 @tokyo4j [#2812]
- Support tablet tool mouse buttons @jp7677 [#2778] - Support tablet tool mouse buttons @jp7677 [#2778]
@ -715,7 +715,7 @@ window.*.title.bg.colorTo.splitTo:
agnostic on choice of launcher. agnostic on choice of launcher.
- `A-<arrow>` for `MoveToEdge` because `Alt-` keybinds should be for clients - `A-<arrow>` for `MoveToEdge` because `Alt-` keybinds should be for clients
to use and this one results in frequent user complaints because it prevents to use and this one results in frequent user complaints because it prevents
some common usage patterns like alt-left/right in web browers. some common usage patterns like alt-left/right in web browsers.
- Change default titlebar menu button from a dot to an arrow @johanmalm [#2844] - Change default titlebar menu button from a dot to an arrow @johanmalm [#2844]
- When `dragLock` is set to `yes`, the drag no longer expires after a short - When `dragLock` is set to `yes`, the drag no longer expires after a short
delay (known as `Sticky` mode) as recommended by libinput [#2803]. The timeout delay (known as `Sticky` mode) as recommended by libinput [#2803]. The timeout
@ -750,7 +750,7 @@ release.
- Localize desktop-entry application names used by the window switcher via - Localize desktop-entry application names used by the window switcher via
`desktop_entry_name` or the `%n` specifier @tokyo4j [#2653] `desktop_entry_name` or the `%n` specifier @tokyo4j [#2653]
- Add `HideCursor` action @jp7677 [#2633] - Add `HideCursor` action @jp7677 [#2633]
- Support application icons in window-switcher using `<field content="icon"/>` - Support application icons in window-switcher using `<field content="icon" />`
and use this by default. @tokyo4j [#2621] and use this by default. @tokyo4j [#2621]
- Support application icons in client-list-combined-menu @tokyo4j [#2617] - Support application icons in client-list-combined-menu @tokyo4j [#2617]
- Support the use of the keypad-enter key when using menu. @zeusgoose [#2610] - Support the use of the keypad-enter key when using menu. @zeusgoose [#2610]
@ -887,7 +887,7 @@ Notes to package maintainers:
closing a popup did not move the pointer focus to the main toplevel until the closing a popup did not move the pointer focus to the main toplevel until the
cursor was moved. [#2443] cursor was moved. [#2443]
- Improve algorithm for menu placement with xdg-positioner [#2408] - Improve algorithm for menu placement with xdg-positioner [#2408]
- Do not forward IME key-release without correspinding key-press to avoid stuck - Do not forward IME key-release without corresponding key-press to avoid stuck
keys [#2437] keys [#2437]
### Changed ### Changed
@ -949,7 +949,7 @@ Notes to package maintainers:
```xml ```xml
<windowRules> <windowRules>
<windowRule identifier="blender" wantAbsorbedModifierReleaseEvents="yes"/> <windowRule identifier="blender" wantAbsorbedModifierReleaseEvents="yes" />
</windowRules> </windowRules>
``` ```
@ -966,8 +966,8 @@ menu.border.color: #aaaaaa
```xml ```xml
<windowSwitcher> <windowSwitcher>
<fields> <fields>
<field content="custom" format="%n" width="25%"/> <field content="custom" format="%n" width="25%" />
<field content="title" width="75%"/> <field content="title" width="75%" />
</fields> </fields>
</windowSwitcher> </windowSwitcher>
``` ```
@ -1097,7 +1097,7 @@ Notes to package maintainers:
- Support the openbox style menus listed below. Written-by: @droc12345 - Support the openbox style menus listed below. Written-by: @droc12345
1. `client-list-combined-menu` shows windows across all workspaces. This can 1. `client-list-combined-menu` shows windows across all workspaces. This can
be used with a mouse/key bind using: be used with a mouse/key bind using:
`<action name="ShowMenu" menu="client-list-combined-menu"/>` [#2101] `<action name="ShowMenu" menu="client-list-combined-menu" />` [#2101]
2. `client-send-to` shows all workspaces that the current window can be sent 2. `client-send-to` shows all workspaces that the current window can be sent
to. This can additional be used within a client menu using: to. This can additional be used within a client menu using:
`<menu id="client-send-to-menu" label="Send to Workspace..." />` [#2152] `<menu id="client-send-to-menu" label="Send to Workspace..." />` [#2152]
@ -1256,14 +1256,14 @@ have been attributed with a 'Written-by' against each relevant log entry.
```xml ```xml
<placement> <placement>
<policy>cascade</policy> <policy>cascade</policy>
<cascadeOffset x="40" y="30"/> <cascadeOffset x="40" y="30" />
</placement> </placement>
``` ```
- Support relative tablet motion. Written-by: @jp7677 [#1962] - Support relative tablet motion. Written-by: @jp7677 [#1962]
```xml ```xml
<tabletTool motion="absolute|relative" relativeMotionSensitivity="1.0"/> <tabletTool motion="absolute|relative" relativeMotionSensitivity="1.0" />
``` ```
### Fixed ### Fixed
@ -1347,7 +1347,7 @@ joint effort by @spl237 and @Consolatis.
- Respect `menu.overlap.x` when using pipemenus. [#1940] - Respect `menu.overlap.x` when using pipemenus. [#1940]
- Do not try to restore windows to very small width/height on unmaximize. - Do not try to restore windows to very small width/height on unmaximize.
This fixes a bug with Thonny (Python IDE made with Tk). [#1938] This fixes a bug with Thonny (Python IDE made with Tk). [#1938]
- Conditially set squared server-side decoration (SSD) corners when a view is - Conditionally set squared server-side decoration (SSD) corners when a view is
tiled. Written-by: @jp7677 [#1926] tiled. Written-by: @jp7677 [#1926]
- Remember initial direction when starting window-cycling with `PreviousView`. - Remember initial direction when starting window-cycling with `PreviousView`.
Also make the toggling of direction when shift is pressed relative to the Also make the toggling of direction when shift is pressed relative to the
@ -1371,7 +1371,7 @@ joint effort by @spl237 and @Consolatis.
Chromium and Steam. [#1861] Chromium and Steam. [#1861]
- Session-lock: fix flashing & update cursor shape. [#1858] - Session-lock: fix flashing & update cursor shape. [#1858]
- Remove tearing-controller listeners on destroy. [#1853] - Remove tearing-controller listeners on destroy. [#1853]
- Handle invalid `ForEach` and `If` action cofigs. [#1838] - Handle invalid `ForEach` and `If` action configs. [#1838]
- Delay startup of applications until event loop is ready. This avoids race - Delay startup of applications until event loop is ready. This avoids race
conditions when using autostart scripts that trigger a labwc SIGHUP. [#1588] conditions when using autostart scripts that trigger a labwc SIGHUP. [#1588]
- With `SendToDesktop` action follow=no option, ensure the topmost window is - With `SendToDesktop` action follow=no option, ensure the topmost window is
@ -1388,7 +1388,7 @@ joint effort by @spl237 and @Consolatis.
- Remove subprojects/seatd.wrap as no longer needed - Remove subprojects/seatd.wrap as no longer needed
- Action `MoveToCursor` is deprecated in favour of: - Action `MoveToCursor` is deprecated in favour of:
`<action name="AutoPlace" policy="cursor"/>`. `<action name="AutoPlace" policy="cursor" />`.
## 0.7.2 - 2024-05-10 ## 0.7.2 - 2024-05-10
@ -1405,7 +1405,7 @@ contributions from others as noted in the log.
### Added ### Added
- Add `<menu><ignoreButtonReleasePeriod>` to prevent clicks with small movements - Add `<menu><ignoreButtonReleasePeriod>` to prevent clicks with small movements
from inadvertantly closing a menu or selecting a menu item. This is the from inadvertently closing a menu or selecting a menu item. This is the
equivalent of `<menu><hideDelay>` on Openbox. [#1760] equivalent of `<menu><hideDelay>` on Openbox. [#1760]
- Support drop-shadows (disabled by default) for windows using server-side - Support drop-shadows (disabled by default) for windows using server-side
decorations. Written-by: @cillian64 decorations. Written-by: @cillian64
@ -1433,7 +1433,7 @@ window.inactive.shadow.color: #00000040
```xml ```xml
<action name="ForEach"> <action name="ForEach">
<query identifier="foo"/> <query identifier="foo" />
<then> <then>
<!-- carry out some action on match --> <!-- carry out some action on match -->
</then> </then>
@ -1475,7 +1475,7 @@ osd.window-switcher.width: 75%
<snapping> <snapping>
<overlay> <overlay>
<enabled>yes|no</enabled> <enabled>yes|no</enabled>
<delay inner="500" outer="500"/> <delay inner="500" outer="500" />
</overlay> </overlay>
</snapping> </snapping>
``` ```
@ -1638,7 +1638,7 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff
```xml ```xml
<keybind key="A-Space"> <keybind key="A-Space">
<action name="ShowMenu" menu="client-menu" atCursor="No"/> <action name="ShowMenu" menu="client-menu" atCursor="No" />
</keybind> </keybind>
``` ```
@ -1646,7 +1646,7 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff
is already used by the action itself). [#1589] is already used by the action itself). [#1589]
```xml ```xml
<action name="MoveToOutput" output="HDMI-A-1"/> <action name="MoveToOutput" output="HDMI-A-1" />
``` ```
- Do not deactivate window when giving keyboard focus to a non-view - Do not deactivate window when giving keyboard focus to a non-view
@ -1711,8 +1711,8 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff
Written-by: @jp7677 Written-by: @jp7677
```xml ```xml
<touch mapToOutput=""/> <touch mapToOutput="" />
<touch deviceName="" mapToOutput=""/> <touch deviceName="" mapToOutput="" />
``` ```
- Add tablet support including: - Add tablet support including:
@ -1925,7 +1925,7 @@ relating to surface focus and keyboard issues, amongst others.
- Allow referencing the current workspace in actions, for example: - Allow referencing the current workspace in actions, for example:
```xml ```xml
<action name="SendToDesktop" to="current"/> <action name="SendToDesktop" to="current" />
``` ```
### Fixed ### Fixed
@ -2081,7 +2081,7 @@ relating to surface focus and keyboard issues, amongst others.
```xml ```xml
<windowSwitcher> <windowSwitcher>
<fields> <fields>
<field content="identifier" width="25%"/> <field content="identifier" width="25%" />
</fields> </fields>
</windowSwithcer> </windowSwithcer>
``` ```
@ -2148,9 +2148,9 @@ relating to surface focus and keyboard issues, amongst others.
```xml ```xml
<windowRules> <windowRules>
<windowRule identifier="some-application"> <windowRule identifier="some-application">
<action name="Maximize"/> <action name="Maximize" />
</windowRule> </windowRule>
<windowRule identifier="foo*" serverDecoration="yes|no"/> <windowRule identifier="foo*" serverDecoration="yes|no" />
</windowRules> </windowRules>
``` ```
@ -2235,7 +2235,7 @@ Unless otherwise stated all contributions are by the core-devs
```xml ```xml
<keyboard> <keyboard>
<default/> <default />
<keybind key="A-Left"><action name="None" /></keybind> <keybind key="A-Left"><action name="None" /></keybind>
<keybind key="A-Right"><action name="None" /></keybind> <keybind key="A-Right"><action name="None" /></keybind>
</keyboard> </keyboard>
@ -2499,7 +2499,7 @@ reported, tested and fixed issues. Particular mentions go to @bi4k8,
actions to be de-coupled from buttons. As a result, "Drag" and actions to be de-coupled from buttons. As a result, "Drag" and
"DoubleClick" actions previously defined against "TitleBar" should now "DoubleClick" actions previously defined against "TitleBar" should now
come under the "Title" context, for example: come under the "Title" context, for example:
`<mousebind button="Left" action="Drag"><action name="Move"/></mousebind>` `<mousebind button="Left" action="Drag"><action name="Move" /></mousebind>`
- Remove default alt-escape keybind for Exit because too many people have - Remove default alt-escape keybind for Exit because too many people have
exited the compositor by mistake trying to get out of alt-tab cycling exited the compositor by mistake trying to get out of alt-tab cycling
or similar. or similar.

View file

@ -175,6 +175,7 @@ this is for compatibility with Openbox.
<adaptiveSync>no</adaptiveSync> <adaptiveSync>no</adaptiveSync>
<allowTearing>no</allowTearing> <allowTearing>no</allowTearing>
<autoEnableOutputs>yes</autoEnableOutputs> <autoEnableOutputs>yes</autoEnableOutputs>
<hdr>no</hdr>
<reuseOutputMode>no</reuseOutputMode> <reuseOutputMode>no</reuseOutputMode>
<xwaylandPersistence>no</xwaylandPersistence> <xwaylandPersistence>no</xwaylandPersistence>
<primarySelection>yes</primarySelection> <primarySelection>yes</primarySelection>
@ -240,6 +241,11 @@ this is for compatibility with Openbox.
'pkill kanshi ; wlopm --off \*' resume 'kanshi & wlopm --on \*' 'pkill kanshi ; wlopm --off \*' resume 'kanshi & wlopm --on \*'
``` ```
*<core><hdr>* [yes|no]
Automatically enable HDR support on outputs when configuring them,
where supported by the particular output device and display. Default
is no.
*<core><reuseOutputMode>* [yes|no] *<core><reuseOutputMode>* [yes|no]
Try to re-use the existing output mode (resolution / refresh rate). Try to re-use the existing output mode (resolution / refresh rate).
This may prevent unnecessary screenblank delays when starting labwc This may prevent unnecessary screenblank delays when starting labwc

View file

@ -13,6 +13,7 @@
<adaptiveSync>no</adaptiveSync> <adaptiveSync>no</adaptiveSync>
<allowTearing>no</allowTearing> <allowTearing>no</allowTearing>
<autoEnableOutputs>yes</autoEnableOutputs> <autoEnableOutputs>yes</autoEnableOutputs>
<hdr>no</hdr>
<reuseOutputMode>no</reuseOutputMode> <reuseOutputMode>no</reuseOutputMode>
<xwaylandPersistence>no</xwaylandPersistence> <xwaylandPersistence>no</xwaylandPersistence>
<primarySelection>yes</primarySelection> <primarySelection>yes</primarySelection>

View file

@ -62,7 +62,11 @@
#define BOUNDED_INT(a) ((a) < INT_MAX && (a) > INT_MIN) #define BOUNDED_INT(a) ((a) < INT_MAX && (a) > INT_MIN)
#endif #endif
#define LAB_WLR_VERSION_AT_LEAST(major, minor, micro) \ #define _LAB_CALC_WLR_VERSION_NUM(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro))
(WLR_VERSION_NUM >= (((major) << 16) | ((minor) << 8) | (micro)))
#define LAB_WLR_VERSION_AT_LEAST(major, minor, micro) ( \
server.wlr_version >= _LAB_CALC_WLR_VERSION_NUM(major, minor, micro))
#define LAB_WLR_VERSION_LOWER(major, minor, micro) (!LAB_WLR_VERSION_AT_LEAST(major, minor, micro))
#endif /* LABWC_MACROS_H */ #endif /* LABWC_MACROS_H */

View file

@ -36,6 +36,12 @@ enum tearing_mode {
LAB_TEARING_FULLSCREEN_FORCED, LAB_TEARING_FULLSCREEN_FORCED,
}; };
enum render_bit_depth {
LAB_RENDER_BIT_DEPTH_DEFAULT = 0,
LAB_RENDER_BIT_DEPTH_8,
LAB_RENDER_BIT_DEPTH_10,
};
enum tiling_events_mode { enum tiling_events_mode {
LAB_TILING_EVENTS_NEVER = 0, LAB_TILING_EVENTS_NEVER = 0,
LAB_TILING_EVENTS_REGION = 1 << 0, LAB_TILING_EVENTS_REGION = 1 << 0,
@ -74,6 +80,7 @@ struct rcxml {
int gap; int gap;
enum adaptive_sync_mode adaptive_sync; enum adaptive_sync_mode adaptive_sync;
enum tearing_mode allow_tearing; enum tearing_mode allow_tearing;
enum render_bit_depth target_render_depth;
bool auto_enable_outputs; bool auto_enable_outputs;
bool reuse_output_mode; bool reuse_output_mode;
uint32_t allowed_interfaces; uint32_t allowed_interfaces;

View file

@ -148,6 +148,8 @@ struct seat {
}; };
struct server { struct server {
uint32_t wlr_version;
struct wl_display *wl_display; struct wl_display *wl_display;
struct wl_event_loop *wl_event_loop; /* Can be used for timer events */ struct wl_event_loop *wl_event_loop; /* Can be used for timer events */

View file

@ -71,6 +71,9 @@ struct wlr_box output_usable_area_in_layout_coords(struct output *output);
void handle_output_power_manager_set_mode(struct wl_listener *listener, void handle_output_power_manager_set_mode(struct wl_listener *listener,
void *data); void *data);
void output_enable_adaptive_sync(struct output *output, bool enabled); void output_enable_adaptive_sync(struct output *output, bool enabled);
void output_enable_hdr(struct output *output, struct wlr_output_state *os,
bool enabled, bool silent);
void output_state_setup_hdr(struct output *output, bool silent);
/** /**
* Notifies whether a fullscreen view is displayed on the given output. * Notifies whether a fullscreen view is displayed on the given output.

View file

@ -1080,6 +1080,16 @@ set_tearing_mode(const char *str, enum tearing_mode *variable)
} }
} }
static void
set_hdr_mode(const char *str, enum render_bit_depth *variable)
{
if (parse_bool(str, -1) == 1) {
*variable = LAB_RENDER_BIT_DEPTH_10;
} else {
*variable = LAB_RENDER_BIT_DEPTH_8;
}
}
/* Returns true if the node's children should also be traversed */ /* Returns true if the node's children should also be traversed */
static bool static bool
entry(xmlNode *node, char *nodename, char *content) entry(xmlNode *node, char *nodename, char *content)
@ -1144,6 +1154,8 @@ entry(xmlNode *node, char *nodename, char *content)
set_adaptive_sync_mode(content, &rc.adaptive_sync); set_adaptive_sync_mode(content, &rc.adaptive_sync);
} else if (!strcasecmp(nodename, "allowTearing.core")) { } else if (!strcasecmp(nodename, "allowTearing.core")) {
set_tearing_mode(content, &rc.allow_tearing); set_tearing_mode(content, &rc.allow_tearing);
} else if (!strcasecmp(nodename, "Hdr.core")) {
set_hdr_mode(content, &rc.target_render_depth);
} else if (!strcasecmp(nodename, "autoEnableOutputs.core")) { } else if (!strcasecmp(nodename, "autoEnableOutputs.core")) {
set_bool(content, &rc.auto_enable_outputs); set_bool(content, &rc.auto_enable_outputs);
} else if (!strcasecmp(nodename, "reuseOutputMode.core")) { } else if (!strcasecmp(nodename, "reuseOutputMode.core")) {
@ -1518,6 +1530,7 @@ rcxml_init(void)
rc.gap = 0; rc.gap = 0;
rc.adaptive_sync = LAB_ADAPTIVE_SYNC_DISABLED; rc.adaptive_sync = LAB_ADAPTIVE_SYNC_DISABLED;
rc.allow_tearing = LAB_TEARING_DISABLED; rc.allow_tearing = LAB_TEARING_DISABLED;
rc.target_render_depth = LAB_RENDER_BIT_DEPTH_DEFAULT;
rc.auto_enable_outputs = true; rc.auto_enable_outputs = true;
rc.reuse_output_mode = false; rc.reuse_output_mode = false;
rc.allowed_interfaces = UINT32_MAX; rc.allowed_interfaces = UINT32_MAX;

View file

@ -9,6 +9,7 @@
#include "common/mem.h" #include "common/mem.h"
#include "common/scene-helpers.h" #include "common/scene-helpers.h"
#include "config/rcxml.h" #include "config/rcxml.h"
#include "config/types.h"
#include "labwc.h" #include "labwc.h"
#include "node.h" #include "node.h"
#include "output.h" #include "output.h"
@ -322,6 +323,27 @@ handle_osd_tree_destroy(struct wl_listener *listener, void *data)
free(osd_output); free(osd_output);
} }
static enum lab_view_criteria
get_view_criteria(struct cycle_filter *filter)
{
enum lab_view_criteria criteria =
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER
| LAB_VIEW_CRITERIA_NO_DIALOG;
if (filter->workspace == CYCLE_WORKSPACE_CURRENT) {
criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
}
return criteria;
}
static const char *
get_cycle_app_id(struct cycle_filter *filter)
{
if (filter->app_id == CYCLE_APP_ID_CURRENT && server.active_view) {
return server.active_view->app_id;
}
return NULL;
}
static struct wl_list *prev(struct wl_list *elm) { return elm->prev; } static struct wl_list *prev(struct wl_list *elm) { return elm->prev; }
static struct wl_list *next(struct wl_list *elm) { return elm->next; } static struct wl_list *next(struct wl_list *elm) { return elm->next; }
@ -331,17 +353,10 @@ cycle_immediate(enum lab_cycle_dir direction, struct cycle_filter filter)
if (wl_list_empty(&server.views)) { if (wl_list_empty(&server.views)) {
return; return;
} }
enum lab_view_criteria criteria =
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER enum lab_view_criteria criteria = get_view_criteria(&filter);
| LAB_VIEW_CRITERIA_NO_DIALOG;
if (filter.workspace == CYCLE_WORKSPACE_CURRENT) {
criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
}
uint64_t cycle_outputs = get_outputs_by_filter(filter.output); uint64_t cycle_outputs = get_outputs_by_filter(filter.output);
const char *cycle_app_id = NULL; const char *cycle_app_id = get_cycle_app_id(&filter);
if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) {
cycle_app_id = server.active_view->app_id;
}
struct wl_list *head = &server.views; struct wl_list *head = &server.views;
struct wl_list *(*iter)(struct wl_list *list); struct wl_list *(*iter)(struct wl_list *list);
@ -381,20 +396,9 @@ cycle_immediate(enum lab_cycle_dir direction, struct cycle_filter filter)
static bool static bool
init_cycle(struct cycle_filter filter) init_cycle(struct cycle_filter filter)
{ {
enum lab_view_criteria criteria = enum lab_view_criteria criteria = get_view_criteria(&filter);
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER uint64_t cycle_outputs = get_outputs_by_filter(filter.output);
| LAB_VIEW_CRITERIA_NO_DIALOG; const char *cycle_app_id = get_cycle_app_id(&filter);
if (filter.workspace == CYCLE_WORKSPACE_CURRENT) {
criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
}
uint64_t cycle_outputs =
get_outputs_by_filter(filter.output);
const char *cycle_app_id = NULL;
if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) {
cycle_app_id = server.active_view->app_id;
}
struct view *view; struct view *view;
for_each_view(view, &server.views, criteria) { for_each_view(view, &server.views, criteria) {

View file

@ -4,8 +4,10 @@
#include <pango/pangocairo.h> #include <pango/pangocairo.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <wlr/version.h>
#include "common/fd-util.h" #include "common/fd-util.h"
#include "common/font.h" #include "common/font.h"
#include "common/macros.h"
#include "common/spawn.h" #include "common/spawn.h"
#include "config/rcxml.h" #include "config/rcxml.h"
#include "config/session.h" #include "config/session.h"
@ -65,12 +67,15 @@ static void
print_version(void) print_version(void)
{ {
#define FEATURE_ENABLED(feature) (HAVE_##feature ? "+" : "-") #define FEATURE_ENABLED(feature) (HAVE_##feature ? "+" : "-")
printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo)\n", printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo) running on wlroots %d.%d.%d\n",
LABWC_VERSION, LABWC_VERSION,
FEATURE_ENABLED(XWAYLAND), FEATURE_ENABLED(XWAYLAND),
FEATURE_ENABLED(NLS), FEATURE_ENABLED(NLS),
FEATURE_ENABLED(RSVG), FEATURE_ENABLED(RSVG),
FEATURE_ENABLED(LIBSFDO) FEATURE_ENABLED(LIBSFDO),
wlr_version_get_major(),
wlr_version_get_minor(),
wlr_version_get_micro()
); );
#undef FEATURE_ENABLED #undef FEATURE_ENABLED
} }
@ -164,6 +169,12 @@ main(int argc, char *argv[])
char *primary_client = NULL; char *primary_client = NULL;
enum wlr_log_importance verbosity = WLR_ERROR; enum wlr_log_importance verbosity = WLR_ERROR;
server.wlr_version = _LAB_CALC_WLR_VERSION_NUM(
wlr_version_get_major(),
wlr_version_get_minor(),
wlr_version_get_micro()
);
int c; int c;
while (1) { while (1) {
int index = 0; int index = 0;

View file

@ -24,6 +24,7 @@ output_state_init(struct output *output)
backup_config, output->wlr_output); backup_config, output->wlr_output);
wlr_output_head_v1_state_apply(&backup_head->state, &output->pending); wlr_output_head_v1_state_apply(&backup_head->state, &output->pending);
wlr_output_configuration_v1_destroy(backup_config); wlr_output_configuration_v1_destroy(backup_config);
} }

View file

@ -9,6 +9,7 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include "output.h" #include "output.h"
#include <assert.h> #include <assert.h>
#include <drm_fourcc.h>
#include <strings.h> #include <strings.h>
#include <wlr/backend/wayland.h> #include <wlr/backend/wayland.h>
#include <wlr/config.h> #include <wlr/config.h>
@ -51,6 +52,150 @@
#include <wlr/backend/session.h> #include <wlr/backend/session.h>
#endif #endif
static uint32_t output_formats_8bit[] = {
/* 32 bpp RGB with 8 bit component width */
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGBX8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_RGBA8888,
DRM_FORMAT_BGRA8888,
/* 24 bpp RGB */
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
};
uint32_t output_formats_10bit[] = {
/* 32 bpp RGB with 10 bit component width */
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
DRM_FORMAT_RGBX1010102,
DRM_FORMAT_BGRX1010102,
DRM_FORMAT_ARGB2101010,
DRM_FORMAT_ABGR2101010,
DRM_FORMAT_RGBA1010102,
DRM_FORMAT_BGRA1010102,
};
static bool
output_set_render_format(struct output *output, uint32_t candidates[], size_t count)
{
for (size_t i = 0; i < count; i++) {
wlr_output_state_set_render_format(&output->pending, candidates[i]);
if (wlr_output_test_state(output->wlr_output, &output->pending)) {
return true;
}
}
return false;
}
static bool
output_format_in_candidates(uint32_t render_format, uint32_t candidates[], size_t count)
{
for (size_t i = 0; i < count; i++) {
if (candidates[i] == render_format) {
return true;
}
}
return false;
}
static enum render_bit_depth
bit_depth_from_format(uint32_t render_format)
{
if (output_format_in_candidates(render_format, output_formats_10bit,
ARRAY_SIZE(output_formats_10bit))) {
return LAB_RENDER_BIT_DEPTH_10;
} else if (output_format_in_candidates(render_format, output_formats_8bit,
ARRAY_SIZE(output_formats_8bit))) {
return LAB_RENDER_BIT_DEPTH_8;
}
return LAB_RENDER_BIT_DEPTH_DEFAULT;
}
static enum render_bit_depth
get_config_render_bit_depth(void)
{
return rc.target_render_depth;
}
static bool
output_supports_hdr(const struct wlr_output *output, const char **unsupported_reason_ptr)
{
const char *unsupported_reason = NULL;
if (!(output->supported_primaries & WLR_COLOR_NAMED_PRIMARIES_BT2020)) {
unsupported_reason = "BT2020 primaries not supported by output";
} else if (!(output->supported_transfer_functions &
WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ)) {
unsupported_reason = "PQ transfer function not supported by output";
} else if (!server.renderer->features.output_color_transform) {
unsupported_reason = "renderer doesn't support output color transforms";
}
if (unsupported_reason_ptr) {
*unsupported_reason_ptr = unsupported_reason;
}
return !unsupported_reason;
}
void
output_state_setup_hdr(struct output *output, bool silent)
{
uint32_t render_format = output->wlr_output->render_format;
const char *unsupported_reason = NULL;
bool hdr_supported = output_supports_hdr(output->wlr_output,
&unsupported_reason);
bool hdr_succeeded = false;
enum render_bit_depth render_bit_depth = get_config_render_bit_depth();
if (render_bit_depth == LAB_RENDER_BIT_DEPTH_DEFAULT) {
render_bit_depth = bit_depth_from_format(render_format);
}
if (!hdr_supported && render_bit_depth == LAB_RENDER_BIT_DEPTH_10) {
if (!silent) {
wlr_log(WLR_INFO, "Cannot enable HDR on output %s: %s",
output->wlr_output->name, unsupported_reason);
}
render_bit_depth = LAB_RENDER_BIT_DEPTH_8;
}
if (render_bit_depth == LAB_RENDER_BIT_DEPTH_10 &&
bit_depth_from_format(render_format) == render_bit_depth) {
/* 10-bit was set successfully before, try to save some
* tests by reusing the format
*/
hdr_succeeded = true;
} else if (render_bit_depth == LAB_RENDER_BIT_DEPTH_10) {
hdr_succeeded = output_set_render_format(output, output_formats_10bit,
ARRAY_SIZE(output_formats_10bit));
if (!hdr_succeeded) {
if (!silent) {
wlr_log(WLR_INFO, "No 10 bit color formats"
" supported, HDR disabled.");
}
if (!output_set_render_format(output, output_formats_8bit,
ARRAY_SIZE(output_formats_8bit))) {
if (!silent) {
wlr_log(WLR_ERROR, "No 8 bit color formats"
" supported either!");
}
}
}
} else {
if (!output_set_render_format(output, output_formats_8bit,
ARRAY_SIZE(output_formats_8bit)) && !silent) {
wlr_log(WLR_ERROR, "No 8 bit color formats supported!");
}
}
output_enable_hdr(output, &output->pending, hdr_succeeded, silent);
}
bool bool
output_get_tearing_allowance(struct output *output) output_get_tearing_allowance(struct output *output)
{ {
@ -371,10 +516,7 @@ configure_new_output(struct output *output)
output_enable_adaptive_sync(output, true); output_enable_adaptive_sync(output, true);
} }
output_state_commit(output); output_state_setup_hdr(output, false);
wlr_output_effective_resolution(wlr_output,
&output->usable_area.width, &output->usable_area.height);
/* /*
* Wait until wlr_output_layout_add_auto() returns before * Wait until wlr_output_layout_add_auto() returns before
@ -384,6 +526,19 @@ configure_new_output(struct output *output)
server.pending_output_layout_change++; server.pending_output_layout_change++;
add_output_to_layout(output); add_output_to_layout(output);
server.pending_output_layout_change--; server.pending_output_layout_change--;
/*
* Commit the output this way instead, HDR needs a buffer, and
* this commit must be called after the output is added to the
* layout above.
*/
lab_wlr_scene_output_commit(output->scene_output, &output->pending);
/*
* Collect the effective resolution after the final commit.
*/
wlr_output_effective_resolution(wlr_output,
&output->usable_area.width, &output->usable_area.height);
} }
static uint64_t static uint64_t
@ -653,6 +808,7 @@ output_config_apply(struct wlr_output_configuration_v1 *config)
wlr_output_state_set_transform(os, head->state.transform); wlr_output_state_set_transform(os, head->state.transform);
output_enable_adaptive_sync(output, output_enable_adaptive_sync(output,
head->state.adaptive_sync_enabled); head->state.adaptive_sync_enabled);
output_state_setup_hdr(output, false);
} }
if (!output_state_commit(output)) { if (!output_state_commit(output)) {
/* /*
@ -666,6 +822,19 @@ output_config_apply(struct wlr_output_configuration_v1 *config)
break; break;
} }
if (output_enabled) {
/*
* The above commit was likely made without an image
* buffer attached. This will break applying HDR color
* transformation, since image descriptions must be
* committed with a buffer attached. Queue the HDR mode
* again if output is enabled, but make it silent,
* since it would have emitted messages already when
* called above.
*/
output_state_setup_hdr(output, true);
}
/* /*
* Add or remove output from layout only if the commit went * Add or remove output from layout only if the commit went
* through. Note that at startup, the output may have already * through. Note that at startup, the output may have already
@ -1136,3 +1305,34 @@ output_set_has_fullscreen_view(struct output *output, bool has_fullscreen_view)
output_enable_adaptive_sync(output, has_fullscreen_view); output_enable_adaptive_sync(output, has_fullscreen_view);
output_state_commit(output); output_state_commit(output);
} }
void
output_enable_hdr(struct output *output, struct wlr_output_state *os,
bool enabled, bool silent)
{
if (enabled && !output_supports_hdr(output->wlr_output, NULL)) {
enabled = false;
}
if (!enabled) {
if (output->wlr_output->supported_primaries != 0 ||
output->wlr_output->supported_transfer_functions != 0) {
if (!silent) {
wlr_log(WLR_DEBUG, "Disabling HDR on output %s",
output->wlr_output->name);
}
wlr_output_state_set_image_description(os, NULL);
}
return;
}
if (!silent) {
wlr_log(WLR_DEBUG, "Enabling HDR on output %s",
output->wlr_output->name);
}
const struct wlr_output_image_description image_desc = {
.primaries = WLR_COLOR_NAMED_PRIMARIES_BT2020,
.transfer_function = WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ,
};
wlr_output_state_set_image_description(os, &image_desc);
}