river: update for wlroots 0.13.0
This commit is contained in:
parent
3c1f1df0c0
commit
9e3e92050e
10 changed files with 104 additions and 59 deletions
|
@ -33,7 +33,7 @@ installed:
|
|||
- [zig](https://ziglang.org/download/) 0.7.1
|
||||
- wayland
|
||||
- wayland-protocols
|
||||
- [wlroots](https://github.com/swaywm/wlroots) 0.12.0
|
||||
- [wlroots](https://github.com/swaywm/wlroots) 0.13.0
|
||||
- xkbcommon
|
||||
- libevdev
|
||||
- pixman
|
||||
|
|
2
deps/zig-wlroots
vendored
2
deps/zig-wlroots
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 35e5676b1a77b2a44f370280b78b0d38598d97ee
|
||||
Subproject commit 6c62568adfe92a1852566b7d091e99f4b28cbabb
|
|
@ -25,7 +25,7 @@
|
|||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_layer_shell_v1" version="3">
|
||||
<interface name="zwlr_layer_shell_v1" version="4">
|
||||
<description summary="create surfaces that are layers of the desktop">
|
||||
Clients can use this interface to assign the surface_layer role to
|
||||
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
|
@ -47,6 +47,12 @@
|
|||
or manipulate a buffer prior to the first layer_surface.configure call
|
||||
must also be treated as errors.
|
||||
|
||||
After creating a layer_surface object and setting it up, the client
|
||||
must perform an initial commit without any buffer attached.
|
||||
The compositor will reply with a layer_surface.configure event.
|
||||
The client must acknowledge it and is then allowed to attach a buffer
|
||||
to map the surface.
|
||||
|
||||
You may pass NULL for output to allow the compositor to decide which
|
||||
output to use. Generally this will be the one that the user most
|
||||
recently interacted with.
|
||||
|
@ -94,7 +100,7 @@
|
|||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_layer_surface_v1" version="3">
|
||||
<interface name="zwlr_layer_surface_v1" version="4">
|
||||
<description summary="layer metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for surfaces that
|
||||
are designed to be rendered as a layer of a stacked desktop-like
|
||||
|
@ -103,6 +109,14 @@
|
|||
Layer surface state (layer, size, anchor, exclusive zone,
|
||||
margin, interactivity) is double-buffered, and will be applied at the
|
||||
time wl_surface.commit of the corresponding wl_surface is called.
|
||||
|
||||
Attaching a null buffer to a layer surface unmaps it.
|
||||
|
||||
Unmapping a layer_surface means that the surface cannot be shown by the
|
||||
compositor until it is explicitly mapped again. The layer_surface
|
||||
returns to the state it had right after layer_shell.get_layer_surface.
|
||||
The client can re-map the surface by performing a commit without any
|
||||
buffer attached, waiting for a configure event and handling it as usual.
|
||||
</description>
|
||||
|
||||
<request name="set_size">
|
||||
|
@ -189,21 +203,85 @@
|
|||
<arg name="left" type="int"/>
|
||||
</request>
|
||||
|
||||
<enum name="keyboard_interactivity">
|
||||
<description summary="types of keyboard interaction possible for a layer shell surface">
|
||||
Types of keyboard interaction possible for layer shell surfaces. The
|
||||
rationale for this is twofold: (1) some applications are not interested
|
||||
in keyboard events and not allowing them to be focused can improve the
|
||||
desktop experience; (2) some applications will want to take exclusive
|
||||
keyboard focus.
|
||||
</description>
|
||||
|
||||
<entry name="none" value="0">
|
||||
<description summary="no keyboard focus is possible">
|
||||
This value indicates that this surface is not interested in keyboard
|
||||
events and the compositor should never assign it the keyboard focus.
|
||||
|
||||
This is the default value, set for newly created layer shell surfaces.
|
||||
|
||||
This is useful for e.g. desktop widgets that display information or
|
||||
only have interaction with non-keyboard input devices.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="exclusive" value="1">
|
||||
<description summary="request exclusive keyboard focus">
|
||||
Request exclusive keyboard focus if this surface is above the shell surface layer.
|
||||
|
||||
For the top and overlay layers, the seat will always give
|
||||
exclusive keyboard focus to the top-most layer which has keyboard
|
||||
interactivity set to exclusive. If this layer contains multiple
|
||||
surfaces with keyboard interactivity set to exclusive, the compositor
|
||||
determines the one receiving keyboard events in an implementation-
|
||||
defined manner. In this case, no guarantee is made when this surface
|
||||
will receive keyboard focus (if ever).
|
||||
|
||||
For the bottom and background layers, the compositor is allowed to use
|
||||
normal focus semantics.
|
||||
|
||||
This setting is mainly intended for applications that need to ensure
|
||||
they receive all keyboard events, such as a lock screen or a password
|
||||
prompt.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="on_demand" value="2" since="4">
|
||||
<description summary="request regular keyboard focus semantics">
|
||||
This requests the compositor to allow this surface to be focused and
|
||||
unfocused by the user in an implementation-defined manner. The user
|
||||
should be able to unfocus this surface even regardless of the layer
|
||||
it is on.
|
||||
|
||||
Typically, the compositor will want to use its normal mechanism to
|
||||
manage keyboard focus between layer shell surfaces with this setting
|
||||
and regular toplevels on the desktop layer (e.g. click to focus).
|
||||
Nevertheless, it is possible for a compositor to require a special
|
||||
interaction to focus or unfocus layer shell surfaces (e.g. requiring
|
||||
a click even if focus follows the mouse normally, or providing a
|
||||
keybinding to switch focus between layers).
|
||||
|
||||
This setting is mainly intended for desktop shell components (e.g.
|
||||
panels) that allow keyboard interaction. Using this option can allow
|
||||
implementing a desktop shell that can be fully usable without the
|
||||
mouse.
|
||||
</description>
|
||||
</entry>
|
||||
</enum>
|
||||
|
||||
<request name="set_keyboard_interactivity">
|
||||
<description summary="requests keyboard events">
|
||||
Set to 1 to request that the seat send keyboard events to this layer
|
||||
surface. For layers below the shell surface layer, the seat will use
|
||||
normal focus semantics. For layers above the shell surface layers, the
|
||||
seat will always give exclusive keyboard focus to the top-most layer
|
||||
which has keyboard interactivity set to true.
|
||||
Set how keyboard events are delivered to this surface. By default,
|
||||
layer shell surfaces do not receive keyboard events; this request can
|
||||
be used to change this.
|
||||
|
||||
This setting is inherited by child surfaces set by the get_popup
|
||||
request.
|
||||
|
||||
Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||
you do not want to receive them, set the input region on your surface
|
||||
to an empty region.
|
||||
|
||||
Events is double-buffered, see wl_surface.commit.
|
||||
Keyboard interactivity is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="keyboard_interactivity" type="uint"/>
|
||||
<arg name="keyboard_interactivity" type="uint" enum="keyboard_interactivity"/>
|
||||
</request>
|
||||
|
||||
<request name="get_popup">
|
||||
|
@ -288,6 +366,7 @@
|
|||
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
|
||||
<entry name="invalid_size" value="1" summary="size is invalid"/>
|
||||
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
|
||||
<entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/>
|
||||
</enum>
|
||||
|
||||
<enum name="anchor" bitfield="true">
|
||||
|
|
|
@ -239,7 +239,7 @@ fn handleButton(listener: *wl.Listener(*wlr.Pointer.event.Button), event: *wlr.P
|
|||
// give it keyboard focus.
|
||||
if (surface.isLayerSurface()) {
|
||||
const wlr_layer_surface = wlr.LayerSurfaceV1.fromWlrSurface(surface);
|
||||
if (wlr_layer_surface.current.keyboard_interactive) {
|
||||
if (wlr_layer_surface.current.keyboard_interactive == .exclusive) {
|
||||
const layer_surface = @intToPtr(*LayerSurface, wlr_layer_surface.data);
|
||||
self.seat.focusOutput(layer_surface.output);
|
||||
self.seat.setFocusRaw(.{ .layer = layer_surface });
|
||||
|
|
|
@ -348,7 +348,7 @@ pub fn arrangeLayers(self: *Self) void {
|
|||
var it = self.getLayer(layer).last;
|
||||
while (it) |node| : (it = node.prev) {
|
||||
const layer_surface = &node.data;
|
||||
if (layer_surface.wlr_layer_surface.current.keyboard_interactive) {
|
||||
if (layer_surface.wlr_layer_surface.current.keyboard_interactive == .exclusive) {
|
||||
break :outer layer_surface;
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ pub fn arrangeLayers(self: *Self) void {
|
|||
} else if (seat.focused == .layer) {
|
||||
// If the seat is currently focusing a layer without keyboard
|
||||
// interactivity, stop focusing that layer.
|
||||
if (!seat.focused.layer.wlr_layer_surface.current.keyboard_interactive) {
|
||||
if (seat.focused.layer.wlr_layer_surface.current.keyboard_interactive != .exclusive) {
|
||||
seat.setFocusRaw(.{ .none = {} });
|
||||
seat.focus(null);
|
||||
}
|
||||
|
|
|
@ -517,14 +517,10 @@ fn applyHeadToOutput(head: *wlr.OutputConfigurationV1.Head, wlr_output: *wlr.Out
|
|||
if (head.state.mode) |mode| {
|
||||
wlr_output.setMode(mode);
|
||||
} else {
|
||||
std.log.scoped(.output_manager).info("custom modes are not supported until the next wlroots release: ignoring", .{});
|
||||
// TODO(wlroots) uncomment the following lines when wlroots 0.13.0 is released
|
||||
// See https://github.com/swaywm/wlroots/pull/2517
|
||||
//const custom_mode = &head.state.custom_mode;
|
||||
//wlr_output.setCustomMode(custom_mode.width, custom_mode.height, custom_mode.refresh);
|
||||
const custom_mode = &head.state.custom_mode;
|
||||
wlr_output.setCustomMode(custom_mode.width, custom_mode.height, custom_mode.refresh);
|
||||
}
|
||||
// TODO(wlroots) Figure out if this conversion is needed or if that is a bug in wlroots
|
||||
wlr_output.setScale(@floatCast(f32, head.state.scale));
|
||||
wlr_output.setScale(head.state.scale);
|
||||
wlr_output.setTransform(head.state.transform);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ pub fn init(self: *Self) !void {
|
|||
errdefer self.sigterm_source.remove();
|
||||
|
||||
// This frees itself when the wl.Server is destroyed
|
||||
self.backend = try wlr.Backend.autocreate(self.wl_server, null);
|
||||
self.backend = try wlr.Backend.autocreate(self.wl_server);
|
||||
|
||||
// This backend is used to create a noop output for use when no actual
|
||||
// outputs are available. This frees itself when the wl.Server is destroyed.
|
||||
|
@ -140,7 +140,6 @@ pub fn deinit(self: *Self) void {
|
|||
|
||||
self.root.deinit();
|
||||
|
||||
self.noop_backend.destroy();
|
||||
self.wl_server.destroy();
|
||||
|
||||
self.input_manager.deinit();
|
||||
|
|
|
@ -333,14 +333,14 @@ pub fn close(self: Self) void {
|
|||
}
|
||||
}
|
||||
|
||||
pub inline fn forEachPopup(
|
||||
pub inline fn forEachPopupSurface(
|
||||
self: Self,
|
||||
comptime T: type,
|
||||
iterator: fn (surface: *wlr.Surface, sx: c_int, sy: c_int, data: T) callconv(.C) void,
|
||||
user_data: T,
|
||||
) void {
|
||||
switch (self.impl) {
|
||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.forEachPopup(T, iterator, user_data),
|
||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.forEachPopupSurface(T, iterator, user_data),
|
||||
.xwayland_view => {},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,13 +104,13 @@ pub fn close(self: Self) void {
|
|||
self.xdg_surface.role_data.toplevel.sendClose();
|
||||
}
|
||||
|
||||
pub inline fn forEachPopup(
|
||||
pub inline fn forEachPopupSurface(
|
||||
self: Self,
|
||||
comptime T: type,
|
||||
iterator: fn (surface: *wlr.Surface, sx: c_int, sy: c_int, data: T) callconv(.C) void,
|
||||
user_data: T,
|
||||
) void {
|
||||
self.xdg_surface.forEachPopup(T, iterator, user_data);
|
||||
self.xdg_surface.forEachPopupSurface(T, iterator, user_data);
|
||||
}
|
||||
|
||||
/// Return the surface at output coordinates ox, oy and set sx, sy to the
|
||||
|
|
|
@ -54,7 +54,7 @@ pub fn renderOutput(output: *Output) void {
|
|||
|
||||
output.wlr_output.attachRender(null) catch return;
|
||||
|
||||
renderer.begin(output.wlr_output.width, output.wlr_output.height);
|
||||
renderer.begin(@intCast(u32, output.wlr_output.width), @intCast(u32, output.wlr_output.height));
|
||||
|
||||
// Find the first visible fullscreen view in the stack if there is one
|
||||
var it = ViewStack(View).iter(output.views.first, .forward, output.current.tags, renderFilter);
|
||||
|
@ -130,18 +130,6 @@ pub fn renderOutput(output: *Output) void {
|
|||
// on-screen.
|
||||
renderer.end();
|
||||
|
||||
// TODO(wlroots): remove this with the next release. It is here due to
|
||||
// a wlroots bug in the screencopy damage implementation
|
||||
{
|
||||
var w: c_int = undefined;
|
||||
var h: c_int = undefined;
|
||||
output.wlr_output.transformedResolution(&w, &h);
|
||||
var damage: pixman.Region32 = undefined;
|
||||
damage.init();
|
||||
_ = damage.unionRect(&damage, 0, 0, @intCast(c_uint, w), @intCast(c_uint, h));
|
||||
output.wlr_output.setDamage(&damage);
|
||||
}
|
||||
|
||||
// TODO: handle failure
|
||||
output.wlr_output.commit() catch
|
||||
log.err("output commit failed for {}", .{output.wlr_output.name});
|
||||
|
@ -178,7 +166,7 @@ fn renderLayer(
|
|||
renderSurfaceIterator,
|
||||
&rdata,
|
||||
),
|
||||
.popups => layer_surface.wlr_layer_surface.forEachPopup(
|
||||
.popups => layer_surface.wlr_layer_surface.forEachPopupSurface(
|
||||
*SurfaceRenderData,
|
||||
renderSurfaceIterator,
|
||||
&rdata,
|
||||
|
@ -227,24 +215,7 @@ fn renderViewPopups(output: *const Output, view: *View, now: *os.timespec) void
|
|||
.when = now,
|
||||
.opacity = view.opacity,
|
||||
};
|
||||
view.forEachPopup(*SurfaceRenderData, renderPopupSurfaceIterator, &rdata);
|
||||
}
|
||||
|
||||
// TODO(wlroots): replace with wlr_xdg_surface_for_each_popup_surface()
|
||||
fn renderPopupSurfaceIterator(
|
||||
surface: *wlr.Surface,
|
||||
surface_x: c_int,
|
||||
surface_y: c_int,
|
||||
rdata: *SurfaceRenderData,
|
||||
) callconv(.C) void {
|
||||
var new_rdata = SurfaceRenderData{
|
||||
.output = rdata.output,
|
||||
.output_x = rdata.output_x + surface_x,
|
||||
.output_y = rdata.output_y + surface_y,
|
||||
.when = rdata.when,
|
||||
.opacity = rdata.opacity,
|
||||
};
|
||||
surface.forEachSurface(*SurfaceRenderData, renderSurfaceIterator, &new_rdata);
|
||||
view.forEachPopupSurface(*SurfaceRenderData, renderSurfaceIterator, &rdata);
|
||||
}
|
||||
|
||||
fn renderDragIcons(output: *const Output, now: *os.timespec) void {
|
||||
|
|
Loading…
Reference in a new issue