aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2021-04-08 00:21:17 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2021-04-08 00:21:17 +0200
commit9e3e92050e04320949c6cd995273c30319ebd515 (patch)
tree16cbaf73d5e40837855dcc1e7e23214368e09bea
parent3c1f1df0c0faa561f5f993e05ba0c8ad3e56954f (diff)
downloadriver-9e3e92050e04320949c6cd995273c30319ebd515.tar.gz
river-9e3e92050e04320949c6cd995273c30319ebd515.tar.xz
river: update for wlroots 0.13.0
-rw-r--r--README.md2
m---------deps/zig-wlroots0
-rw-r--r--protocol/wlr-layer-shell-unstable-v1.xml97
-rw-r--r--river/Cursor.zig2
-rw-r--r--river/Output.zig4
-rw-r--r--river/Root.zig10
-rw-r--r--river/Server.zig3
-rw-r--r--river/View.zig4
-rw-r--r--river/XdgToplevel.zig4
-rw-r--r--river/render.zig35
10 files changed, 103 insertions, 58 deletions
diff --git a/README.md b/README.md
index 0121c6d..2b60008 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/deps/zig-wlroots b/deps/zig-wlroots
-Subproject 35e5676b1a77b2a44f370280b78b0d38598d97e
+Subproject 6c62568adfe92a1852566b7d091e99f4b28cbab
diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml
index fa67001..d62fd51 100644
--- a/protocol/wlr-layer-shell-unstable-v1.xml
+++ b/protocol/wlr-layer-shell-unstable-v1.xml
@@ -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">
diff --git a/river/Cursor.zig b/river/Cursor.zig
index d759dc7..081da03 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -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 });
diff --git a/river/Output.zig b/river/Output.zig
index 3de9631..166b3c0 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -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);
}
diff --git a/river/Root.zig b/river/Root.zig
index 4c70a58..e05495f 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -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);
}
}
diff --git a/river/Server.zig b/river/Server.zig
index 5a6377e..5cc612b 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -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();
diff --git a/river/View.zig b/river/View.zig
index 82b0b40..91f7e1d 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -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 => {},
}
}
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index f4385e7..11389a8 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -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
diff --git a/river/render.zig b/river/render.zig
index 1878c6b..578a685 100644
--- a/river/render.zig
+++ b/river/render.zig
@@ -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 {