aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <mail@isaacfreund.com>2022-11-11 20:25:21 +0100
committerIsaac Freund <mail@isaacfreund.com>2022-11-13 16:16:07 +0100
commit489a49735ab69054debb5af9bcdba677d7a5c61f (patch)
tree8edf2a134cadd3fc27516047704a596fb0b28d15
parent5eb0e2378044d8876435d8a6f0b6c51d47cdab06 (diff)
downloadriver-489a49735ab69054debb5af9bcdba677d7a5c61f.tar.gz
river-489a49735ab69054debb5af9bcdba677d7a5c61f.tar.xz
river: update to wlroots 0.16
-rw-r--r--README.md2
m---------deps/zig-wayland0
m---------deps/zig-wlroots0
m---------deps/zig-xkbcommon0
-rw-r--r--river/Box.zig42
-rw-r--r--river/Config.zig2
-rw-r--r--river/Cursor.zig27
-rw-r--r--river/InputConfig.zig6
-rw-r--r--river/InputDevice.zig10
-rw-r--r--river/InputManager.zig4
-rw-r--r--river/Keyboard.zig10
-rw-r--r--river/KeyboardGroup.zig7
-rw-r--r--river/LayerSurface.zig3
-rw-r--r--river/Layout.zig14
-rw-r--r--river/LayoutDemand.zig11
-rw-r--r--river/Output.zig97
-rw-r--r--river/PointerConstraint.zig6
-rw-r--r--river/Root.zig12
-rw-r--r--river/Seat.zig13
-rw-r--r--river/Server.zig5
-rw-r--r--river/Switch.zig4
-rw-r--r--river/View.zig65
-rw-r--r--river/VoidView.zig1
-rw-r--r--river/XdgPopup.zig24
-rw-r--r--river/XdgToplevel.zig141
-rw-r--r--river/XwaylandOverrideRedirect.zig1
-rw-r--r--river/XwaylandView.zig47
-rw-r--r--river/command/config.zig2
-rw-r--r--river/command/filter.zig2
-rw-r--r--river/command/move.zig44
-rw-r--r--river/command/output.zig9
-rw-r--r--river/command/set_repeat.zig2
-rw-r--r--river/command/toggle_fullscreen.zig1
-rw-r--r--river/render.zig38
34 files changed, 286 insertions, 366 deletions
diff --git a/README.md b/README.md
index 620f595..7a3eef0 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ distribution.
- [zig](https://ziglang.org/download/) 0.9
- wayland
- wayland-protocols
-- [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.15
+- [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.16
- xkbcommon
- libevdev
- pixman
diff --git a/deps/zig-wayland b/deps/zig-wayland
-Subproject c19ffc58a88573df3e47c08599c472eb715ef7a
+Subproject f64abbd016a918fe6e74e0cf337410cecad5eb5
diff --git a/deps/zig-wlroots b/deps/zig-wlroots
-Subproject 06297208176ac530b4882c92d6b064bda467c00
+Subproject 916aa5041f4300c0e7a0e34d4f256528cdbd050
diff --git a/deps/zig-xkbcommon b/deps/zig-xkbcommon
-Subproject 0f6eda023e6f52ea001c597fda0a7c3e7a2ccce
+Subproject c97f8e18dddda04414067cf8fbfdaa7682dcb44
diff --git a/river/Box.zig b/river/Box.zig
deleted file mode 100644
index ecfe5fd..0000000
--- a/river/Box.zig
+++ /dev/null
@@ -1,42 +0,0 @@
-// This file is part of river, a dynamic tiling wayland compositor.
-//
-// Copyright 2020 The River Developers
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 3.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-const Self = @This();
-
-const wlr = @import("wlroots");
-
-x: i32,
-y: i32,
-width: u32,
-height: u32,
-
-pub fn fromWlrBox(wlr_box: wlr.Box) Self {
- return Self{
- .x = @intCast(i32, wlr_box.x),
- .y = @intCast(i32, wlr_box.y),
- .width = @intCast(u32, wlr_box.width),
- .height = @intCast(u32, wlr_box.height),
- };
-}
-
-pub fn toWlrBox(self: Self) wlr.Box {
- return wlr.Box{
- .x = @intCast(c_int, self.x),
- .y = @intCast(c_int, self.y),
- .width = @intCast(c_int, self.width),
- .height = @intCast(c_int, self.height),
- };
-}
diff --git a/river/Config.zig b/river/Config.zig
index 7916621..f654f99 100644
--- a/river/Config.zig
+++ b/river/Config.zig
@@ -47,7 +47,7 @@ pub const HideCursorWhenTypingMode = enum {
background_color: [4]f32 = [_]f32{ 0.0, 0.16862745, 0.21176471, 1.0 }, // Solarized base03
/// Width of borders in pixels
-border_width: u32 = 2,
+border_width: u31 = 2,
/// Color of border of focused window in RGBA
border_color_focused: [4]f32 = [_]f32{ 0.57647059, 0.63137255, 0.63137255, 1.0 }, // Solarized base1
diff --git a/river/Cursor.zig b/river/Cursor.zig
index 49ae33c..b885d2d 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -30,7 +30,6 @@ const c = @import("c.zig");
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const Config = @import("Config.zig");
const LayerSurface = @import("LayerSurface.zig");
const Output = @import("Output.zig");
@@ -855,8 +854,8 @@ pub fn enterMode(self: *Self, mode: enum { move, resize }, view: *View) void {
const cur_box = &view.current.box;
self.mode = .{ .resize = .{
.view = view,
- .offset_x = cur_box.x + @intCast(i32, cur_box.width) - @floatToInt(i32, self.wlr_cursor.x),
- .offset_y = cur_box.y + @intCast(i32, cur_box.height) - @floatToInt(i32, self.wlr_cursor.y),
+ .offset_x = cur_box.x + cur_box.width - @floatToInt(i32, self.wlr_cursor.x),
+ .offset_y = cur_box.y + cur_box.height - @floatToInt(i32, self.wlr_cursor.y),
} };
view.setResizing(true);
},
@@ -971,23 +970,25 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
const border_width = if (data.view.draw_borders) server.config.border_width else 0;
// Set width/height of view, clamp to view size constraints and output dimensions
- const box = &data.view.pending.box;
- box.width = @intCast(u32, math.max(0, @intCast(i32, box.width) + @floatToInt(i32, dx)));
- box.height = @intCast(u32, math.max(0, @intCast(i32, box.height) + @floatToInt(i32, dy)));
-
+ data.view.pending.box.width += @floatToInt(i32, dx);
+ data.view.pending.box.height += @floatToInt(i32, dy);
data.view.applyConstraints();
- const output_resolution = data.view.output.getEffectiveResolution();
- box.width = math.min(box.width, output_resolution.width - border_width - @intCast(u32, box.x));
- box.height = math.min(box.height, output_resolution.height - border_width - @intCast(u32, box.y));
+ var output_width: i32 = undefined;
+ var output_height: i32 = undefined;
+ data.view.output.wlr_output.effectiveResolution(&output_width, &output_height);
+
+ const box = &data.view.pending.box;
+ box.width = math.min(box.width, output_width - border_width - box.x);
+ box.height = math.min(box.height, output_height - border_width - box.y);
data.view.applyPending();
// Keep cursor locked to the original offset from the bottom right corner
self.wlr_cursor.warpClosest(
device,
- @intToFloat(f64, box.x + @intCast(i32, box.width) - data.offset_x),
- @intToFloat(f64, box.y + @intCast(i32, box.height) - data.offset_y),
+ @intToFloat(f64, box.x + box.width - data.offset_x),
+ @intToFloat(f64, box.y + box.height - data.offset_y),
);
},
}
@@ -1025,7 +1026,7 @@ pub fn updateState(self: *Self) void {
var now: os.timespec = undefined;
os.clock_gettime(os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
const msec = @intCast(u32, now.tv_sec * std.time.ms_per_s +
- @divFloor(now.tv_nsec, std.time.ns_per_ms));
+ @divTrunc(now.tv_nsec, std.time.ns_per_ms));
self.passthrough(msec);
}
}
diff --git a/river/InputConfig.zig b/river/InputConfig.zig
index 0467d95..13432d4 100644
--- a/river/InputConfig.zig
+++ b/river/InputConfig.zig
@@ -40,14 +40,14 @@ pub const EventState = enum {
@"disabled-on-external-mouse",
pub fn apply(event_state: EventState, device: *c.libinput_device) void {
- const want = switch (event_state) {
+ const want: u32 = switch (event_state) {
.enabled => c.LIBINPUT_CONFIG_SEND_EVENTS_ENABLED,
.disabled => c.LIBINPUT_CONFIG_SEND_EVENTS_DISABLED,
.@"disabled-on-external-mouse" => c.LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE,
};
const current = c.libinput_device_config_send_events_get_mode(device);
if (want != current) {
- _ = c.libinput_device_config_send_events_set_mode(device, @intCast(u32, want));
+ _ = c.libinput_device_config_send_events_set_mode(device, want);
}
}
};
@@ -259,7 +259,7 @@ pub const ScrollButton = struct {
pub fn apply(scroll_button: ScrollButton, device: *c.libinput_device) void {
const supports = c.libinput_device_config_scroll_get_methods(device);
- if (supports & ~@intCast(u32, c.LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0) return;
+ if (supports & ~@as(u32, c.LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0) return;
_ = c.libinput_device_config_scroll_set_button(device, scroll_button.button);
}
};
diff --git a/river/InputDevice.zig b/river/InputDevice.zig
index 83da4ed..42514f5 100644
--- a/river/InputDevice.zig
+++ b/river/InputDevice.zig
@@ -50,12 +50,6 @@ pub fn init(device: *InputDevice, seat: *Seat, wlr_device: *wlr.InputDevice) !vo
else => @tagName(wlr_device.type),
};
- // wlroots 0.15 leaves wlr_input_device->name NULL for keyboard groups.
- // This wart has been cleaned up in 0.16, so just work around it until that is released.
- // TODO(wlroots): Remove this hack
-
- const name = if (isKeyboardGroup(wlr_device)) "wlr_keyboard_group" else wlr_device.name;
-
const identifier = try std.fmt.allocPrint(
util.gpa,
"{s}-{}-{}-{s}",
@@ -63,7 +57,7 @@ pub fn init(device: *InputDevice, seat: *Seat, wlr_device: *wlr.InputDevice) !vo
device_type,
wlr_device.vendor,
wlr_device.product,
- mem.trim(u8, mem.span(name), &ascii.spaces),
+ mem.trim(u8, mem.span(wlr_device.name), &ascii.spaces),
},
);
errdefer util.gpa.free(identifier);
@@ -115,7 +109,7 @@ pub fn deinit(device: *InputDevice) void {
fn isKeyboardGroup(wlr_device: *wlr.InputDevice) bool {
return wlr_device.type == .keyboard and
- wlr.KeyboardGroup.fromKeyboard(wlr_device.device.keyboard) != null;
+ wlr.KeyboardGroup.fromKeyboard(wlr_device.toKeyboard()) != null;
}
fn handleDestroy(listener: *wl.Listener(*wlr.InputDevice), _: *wlr.InputDevice) void {
diff --git a/river/InputManager.zig b/river/InputManager.zig
index 055ccdf..1c34239 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -210,7 +210,7 @@ fn handleNewVirtualPointer(
log.debug("Ignoring output suggestion from virtual pointer", .{});
}
- self.defaultSeat().addDevice(&event.new_pointer.input_device);
+ self.defaultSeat().addDevice(&event.new_pointer.pointer.base);
}
fn handleNewVirtualKeyboard(
@@ -218,5 +218,5 @@ fn handleNewVirtualKeyboard(
virtual_keyboard: *wlr.VirtualKeyboardV1,
) void {
const seat = @intToPtr(*Seat, virtual_keyboard.seat.data);
- seat.addDevice(&virtual_keyboard.input_device);
+ seat.addDevice(&virtual_keyboard.keyboard.base);
}
diff --git a/river/Keyboard.zig b/river/Keyboard.zig
index eeec2ee..22f3d0b 100644
--- a/river/Keyboard.zig
+++ b/river/Keyboard.zig
@@ -54,7 +54,7 @@ pub fn init(self: *Self, seat: *Seat, wlr_device: *wlr.InputDevice) !void {
const keymap = xkb.Keymap.newFromNames(context, null, .no_flags) orelse return error.XkbKeymapFailed;
defer keymap.unref();
- const wlr_keyboard = self.device.wlr_device.device.keyboard;
+ const wlr_keyboard = self.device.wlr_device.toKeyboard();
wlr_keyboard.data = @ptrToInt(self);
if (!wlr_keyboard.setKeymap(keymap)) return error.SetKeymapFailed;
@@ -77,7 +77,7 @@ pub fn deinit(self: *Self) void {
fn handleKey(listener: *wl.Listener(*wlr.Keyboard.event.Key), event: *wlr.Keyboard.event.Key) void {
// This event is raised when a key is pressed or released.
const self = @fieldParentPtr(Self, "key", listener);
- const wlr_keyboard = self.device.wlr_device.device.keyboard;
+ const wlr_keyboard = self.device.wlr_device.toKeyboard();
// If the keyboard is in a group, this event will be handled by the group's Keyboard instance.
if (wlr_keyboard.group != null) return;
@@ -125,7 +125,7 @@ fn handleKey(listener: *wl.Listener(*wlr.Keyboard.event.Key), event: *wlr.Keyboa
if (!eaten) {
// If key was not handled, we pass it along to the client.
const wlr_seat = self.device.seat.wlr_seat;
- wlr_seat.setKeyboard(self.device.wlr_device);
+ wlr_seat.setKeyboard(self.device.wlr_device.toKeyboard());
wlr_seat.keyboardNotifyKey(event.time_msec, event.keycode, event.state);
}
}
@@ -136,12 +136,12 @@ fn isModifier(keysym: xkb.Keysym) bool {
fn handleModifiers(listener: *wl.Listener(*wlr.Keyboard), _: *wlr.Keyboard) void {
const self = @fieldParentPtr(Self, "modifiers", listener);
- const wlr_keyboard = self.device.wlr_device.device.keyboard;
+ const wlr_keyboard = self.device.wlr_device.toKeyboard();
// If the keyboard is in a group, this event will be handled by the group's Keyboard instance.
if (wlr_keyboard.group != null) return;
- self.device.seat.wlr_seat.setKeyboard(self.device.wlr_device);
+ self.device.seat.wlr_seat.setKeyboard(self.device.wlr_device.toKeyboard());
self.device.seat.wlr_seat.keyboardNotifyModifiers(&wlr_keyboard.modifiers);
}
diff --git a/river/KeyboardGroup.zig b/river/KeyboardGroup.zig
index e759bc0..617c042 100644
--- a/river/KeyboardGroup.zig
+++ b/river/KeyboardGroup.zig
@@ -55,7 +55,7 @@ pub fn create(seat: *Seat, name: []const u8) !void {
.seat = seat,
};
- seat.addDevice(wlr_group.input_device);
+ seat.addDevice(&wlr_group.keyboard.base);
seat.keyboard_groups.append(node);
}
@@ -95,8 +95,7 @@ pub fn addIdentifier(group: *KeyboardGroup, new_id: []const u8) !void {
if (mem.eql(u8, new_id, device.identifier)) {
log.debug("found existing matching keyboard; adding to group", .{});
- const wlr_keyboard = device.wlr_device.device.keyboard;
- if (!group.wlr_group.addKeyboard(wlr_keyboard)) {
+ if (!group.wlr_group.addKeyboard(device.wlr_device.toKeyboard())) {
// wlroots logs an error message to explain why this failed.
continue;
}
@@ -119,7 +118,7 @@ pub fn removeIdentifier(group: *KeyboardGroup, id: []const u8) !void {
if (device.wlr_device.type != .keyboard) continue;
if (mem.eql(u8, device.identifier, id)) {
- const wlr_keyboard = device.wlr_device.device.keyboard;
+ const wlr_keyboard = device.wlr_device.toKeyboard();
assert(wlr_keyboard.group == group.wlr_group);
group.wlr_group.removeKeyboard(wlr_keyboard);
}
diff --git a/river/LayerSurface.zig b/river/LayerSurface.zig
index 4231bad..7c78ed3 100644
--- a/river/LayerSurface.zig
+++ b/river/LayerSurface.zig
@@ -25,7 +25,6 @@ const zwlr = @import("wayland").server.zwlr;
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const Output = @import("Output.zig");
const Subsurface = @import("Subsurface.zig");
const XdgPopup = @import("XdgPopup.zig");
@@ -35,7 +34,7 @@ const log = std.log.scoped(.layer_shell);
output: *Output,
wlr_layer_surface: *wlr.LayerSurfaceV1,
-box: Box = undefined,
+box: wlr.Box = undefined,
layer: zwlr.LayerShellV1.Layer,
destroy: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleDestroy),
diff --git a/river/Layout.zig b/river/Layout.zig
index c6ecded..1dfc136 100644
--- a/river/Layout.zig
+++ b/river/Layout.zig
@@ -18,6 +18,7 @@ const Self = @This();
const std = @import("std");
const assert = std.debug.assert;
+const math = std.math;
const mem = std.mem;
const wlr = @import("wlroots");
const wayland = @import("wayland");
@@ -27,7 +28,6 @@ const river = wayland.server.river;
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const Server = @import("Server.zig");
const Output = @import("Output.zig");
const View = @import("View.zig");
@@ -111,8 +111,8 @@ pub fn startLayoutDemand(self: *Self, views: u32) void {
self.layout.sendLayoutDemand(
views,
- self.output.usable_box.width,
- self.output.usable_box.height,
+ @intCast(u32, self.output.usable_box.width),
+ @intCast(u32, self.output.usable_box.height),
self.output.pending.tags,
self.output.layout_demand.?.serial,
);
@@ -137,7 +137,13 @@ fn handleRequest(layout: *river.LayoutV3, request: river.LayoutV3.Request, self:
// because we do not keep track of old serials server-side.
// Therefore, simply ignore requests with old/wrong serials.
if (layout_demand.serial != req.serial) return;
- layout_demand.pushViewDimensions(self.output, req.x, req.y, req.width, req.height);
+ layout_demand.pushViewDimensions(
+ self.output,
+ req.x,
+ req.y,
+ @intCast(u31, math.min(math.maxInt(u31), req.width)),
+ @intCast(u31, math.min(math.maxInt(u31), req.height)),
+ );
}
},
diff --git a/river/LayoutDemand.zig b/river/LayoutDemand.zig
index 4ad65e7..2a3ee8f 100644
--- a/river/LayoutDemand.zig
+++ b/river/LayoutDemand.zig
@@ -26,7 +26,6 @@ const server = &@import("main.zig").server;
const util = @import("util.zig");
const Layout = @import("Layout.zig");
-const Box = @import("Box.zig");
const Server = @import("Server.zig");
const Output = @import("Output.zig");
const View = @import("View.zig");
@@ -43,7 +42,7 @@ serial: u32,
/// This will go negative if the client pushes too many dimensions.
views: i32,
/// Proposed view dimensions
-view_boxen: []Box,
+view_boxen: []wlr.Box,
timeout_timer: *wl.EventSource,
pub fn init(layout: *Layout, views: u32) !Self {
@@ -55,7 +54,7 @@ pub fn init(layout: *Layout, views: u32) !Self {
return Self{
.serial = server.wl_server.nextSerial(),
.views = @intCast(i32, views),
- .view_boxen = try util.gpa.alloc(Box, views),
+ .view_boxen = try util.gpa.alloc(wlr.Box, views),
.timeout_timer = timeout_timer,
};
}
@@ -81,7 +80,7 @@ fn handleTimeout(layout: *Layout) callconv(.C) c_int {
}
/// Push a set of proposed view dimensions and position to the list
-pub fn pushViewDimensions(self: *Self, output: *Output, x: i32, y: i32, width: u32, height: u32) void {
+pub fn pushViewDimensions(self: *Self, output: *Output, x: i32, y: i32, width: u31, height: u31) void {
// The client pushed too many dimensions
if (self.views <= 0) {
self.views -= 1;
@@ -92,8 +91,8 @@ pub fn pushViewDimensions(self: *Self, output: *Output, x: i32, y: i32, width: u
// usable area and shrink the dimensions to accomodate the border size.
const border_width = server.config.border_width;
self.view_boxen[self.view_boxen.len - @intCast(usize, self.views)] = .{
- .x = x + output.usable_box.x + @intCast(i32, border_width),
- .y = y + output.usable_box.y + @intCast(i32, border_width),
+ .x = x + output.usable_box.x + border_width,
+ .y = y + output.usable_box.y + border_width,
.width = if (width > 2 * border_width) width - 2 * border_width else width,
.height = if (height > 2 * border_width) height - 2 * border_width else height,
};
diff --git a/river/Output.zig b/river/Output.zig
index ac69dd7..ca4dbff 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -18,6 +18,7 @@ const Self = @This();
const std = @import("std");
const assert = std.debug.assert;
+const math = std.math;
const mem = std.mem;
const fmt = std.fmt;
const wlr = @import("wlroots");
@@ -29,7 +30,6 @@ const render = @import("render.zig");
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const LayerSurface = @import("LayerSurface.zig");
const Layout = @import("Layout.zig");
const LayoutDemand = @import("LayoutDemand.zig");
@@ -62,7 +62,7 @@ layers: [4]std.TailQueue(LayerSurface) = [1]std.TailQueue(LayerSurface){.{}} **
/// The area left for views and other layer surfaces after applying the
/// exclusive zones of exclusive layer surfaces.
/// TODO: this should be part of the output's State
-usable_box: Box,
+usable_box: wlr.Box,
/// The top of the stack is the "most important" view.
views: ViewStack(View) = .{},
@@ -86,7 +86,7 @@ layouts: std.TailQueue(Layout) = .{},
layout_namespace: ?[]const u8 = null,
/// Bitmask that whitelists tags for newly spawned views
-spawn_tagmask: u32 = std.math.maxInt(u32),
+spawn_tagmask: u32 = math.maxInt(u32),
/// List of status tracking objects relaying changes to this output to clients.
status_trackers: std.SinglyLinkedList(OutputStatus) = .{},
@@ -145,13 +145,13 @@ pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
std.log.scoped(.cursor).err("failed to load xcursor theme at scale {}", .{wlr_output.scale});
}
- const effective_resolution = self.getEffectiveResolution();
self.usable_box = .{
.x = 0,
.y = 0,
- .width = effective_resolution.width,
- .height = effective_resolution.height,
+ .width = undefined,
+ .height = undefined,
};
+ self.wlr_output.effectiveResolution(&self.usable_box.width, &self.usable_box.height);
self.setTitle();
}
@@ -230,13 +230,13 @@ const ArrangeLayersTarget = enum { mapped, unmapped };
/// If target is unmapped, this function is pure aside from the
/// wlr.LayerSurfaceV1.configure() calls made on umapped layer surfaces.
pub fn arrangeLayers(self: *Self, target: ArrangeLayersTarget) void {
- const effective_resolution = self.getEffectiveResolution();
- const full_box: Box = .{
+ var full_box: wlr.Box = .{
.x = 0,
.y = 0,
- .width = effective_resolution.width,
- .height = effective_resolution.height,
+ .width = undefined,
+ .height = undefined,
};
+ self.wlr_output.effectiveResolution(&full_box.width, &full_box.height);
// This box is modified as exclusive zones are applied
var usable_box = full_box;
@@ -296,8 +296,8 @@ pub fn arrangeLayers(self: *Self, target: ArrangeLayersTarget) void {
/// Arrange the layer surfaces of a given layer
fn arrangeLayer(
layer: std.TailQueue(LayerSurface),
- full_box: Box,
- usable_box: *Box,
+ full_box: wlr.Box,
+ usable_box: *wlr.Box,
exclusive: bool,
target: ArrangeLayersTarget,
) void {
@@ -306,6 +306,9 @@ fn arrangeLayer(
const layer_surface = &node.data;
const current_state = layer_surface.wlr_layer_surface.current;
+ const desired_width = @intCast(u31, math.min(math.maxInt(u31), current_state.desired_width));
+ const desired_height = @intCast(u31, math.min(math.maxInt(u31), current_state.desired_height));
+
// If the value of exclusive_zone is greater than zero, then it exclusivly
// occupies some area of the screen.
if (exclusive != (current_state.exclusive_zone > 0)) continue;
@@ -314,46 +317,40 @@ fn arrangeLayer(
// to ignore any exclusive zones and use the full area of the output.
const bounds = if (current_state.exclusive_zone == -1) &full_box else usable_box;
- var new_box: Box = undefined;
+ var new_box: wlr.Box = undefined;
// Horizontal alignment
- if (current_state.desired_width == 0) {
+ if (desired_width == 0) {
assert(current_state.anchor.right and current_state.anchor.left);
- new_box.x = bounds.x + @intCast(i32, current_state.margin.left);
+ new_box.x = bounds.x + current_state.margin.left;
new_box.width = bounds.width - (current_state.margin.left + current_state.margin.right);
} else if (current_state.anchor.left == current_state.anchor.right) {
- new_box.x = bounds.x + @intCast(i32, bounds.width / 2 -| current_state.desired_width / 2);
- new_box.width = current_state.desired_width;
+ new_box.x = bounds.x + @divTrunc(bounds.width, 2) - desired_width / 2;
+ new_box.width = desired_width;
} else if (current_state.anchor.left) {
- new_box.x = bounds.x + @intCast(i32, current_state.margin.left);
- new_box.width = current_state.desired_width;
+ new_box.x = bounds.x + current_state.margin.left;
+ new_box.width = desired_width;
} else {
assert(current_state.anchor.right);
- new_box.x = bounds.x + @intCast(i32, bounds.width) -
- @intCast(i32, current_state.desired_width) -
- // TODO(wlroots) this type has been corrected to i32 for the next release
- @intCast(i32, current_state.margin.right);
- new_box.width = current_state.desired_width;
+ new_box.x = bounds.x + bounds.width - desired_width - current_state.margin.right;
+ new_box.width = desired_width;
}
// Vertical alignment
- if (current_state.desired_height == 0) {
+ if (desired_height == 0) {
assert(current_state.anchor.top and current_state.anchor.bottom);
- new_box.y = bounds.y + @intCast(i32, current_state.margin.top);
+ new_box.y = bounds.y + current_state.margin.top;
new_box.height = bounds.height - (current_state.margin.top + current_state.margin.bottom);
} else if (current_state.anchor.top == current_state.anchor.bottom) {
- new_box.y = bounds.y + @intCast(i32, bounds.height / 2 -| current_state.desired_height / 2);
- new_box.height = current_state.desired_height;
+ new_box.y = bounds.y + @divTrunc(bounds.height, 2) - desired_height / 2;
+ new_box.height = desired_height;
} else if (current_state.anchor.top) {
- new_box.y = bounds.y + @intCast(i32, current_state.margin.top);
- new_box.height = current_state.desired_height;
+ new_box.y = bounds.y + current_state.margin.top;
+ new_box.height = desired_height;
} else {
assert(current_state.anchor.bottom);
- new_box.y = bounds.y + @intCast(i32, bounds.height) -
- @intCast(i32, current_state.desired_height) -
- // TODO(wlroots) this type has been corrected to i32 for the next release
- @intCast(i32, current_state.margin.bottom);
- new_box.height = current_state.desired_height;
+ new_box.y = bounds.y + bounds.height - desired_height - current_state.margin.bottom;
+ new_box.height = desired_height;
}
// Apply the exclusive zone to the current bounds
@@ -361,8 +358,8 @@ fn arrangeLayer(
single: zwlr.LayerSurfaceV1.Anchor,
triple: zwlr.LayerSurfaceV1.Anchor,
to_increase: ?*i32,
- to_decrease: *u32,
- margin: u32,
+ to_decrease: *i32,
+ margin: i32,
}{
.{
.single = .{ .top = true },
@@ -396,11 +393,11 @@ fn arrangeLayer(
for (edges) |edge| {
if ((std.meta.eql(current_state.anchor, edge.single) or std.meta.eql(current_state.anchor, edge.triple)) and
- current_state.exclusive_zone + @intCast(i32, edge.margin) > 0)
+ current_state.exclusive_zone + edge.margin > 0)
{
- const delta = current_state.exclusive_zone + @intCast(i32, edge.margin);
+ const delta = current_state.exclusive_zone + edge.margin;
if (edge.to_increase) |value| value.* += delta;
- edge.to_decrease.* -= @intCast(u32, delta);
+ edge.to_decrease.* -= delta;
break;
}
}
@@ -409,10 +406,16 @@ fn arrangeLayer(
.mapped => {
assert(layer_surface.wlr_layer_surface.mapped);
layer_surface.box = new_box;
- _ = layer_surface.wlr_layer_surface.configure(new_box.width, new_box.height);
+ _ = layer_surface.wlr_layer_surface.configure(
+ @intCast(u32, new_box.width),
+ @intCast(u32, new_box.height),
+ );
},
.unmapped => if (!layer_surface.wlr_layer_surface.mapped) {
- _ = layer_surface.wlr_layer_surface.configure(new_box.width, new_box.height);
+ _ = layer_surface.wlr_layer_surface.configure(
+ @intCast(u32, new_box.width),
+ @intCast(u32, new_box.height),
+ );
},
}
}
@@ -484,16 +487,6 @@ fn handleMode(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
server.root.startTransaction();
}
-pub fn getEffectiveResolution(self: *Self) struct { width: u32, height: u32 } {
- var width: c_int = undefined;
- var height: c_int = undefined;
- self.wlr_output.effectiveResolution(&width, &height);
- return .{
- .width = @intCast(u32, width),
- .height = @intCast(u32, height),
- };
-}
-
fn setTitle(self: Self) void {
const title = fmt.allocPrintZ(util.gpa, "river - {s}", .{self.wlr_output.name}) catch return;
defer util.gpa.free(title);
diff --git a/river/PointerConstraint.zig b/river/PointerConstraint.zig
index 62147e9..450de21 100644
--- a/river/PointerConstraint.zig
+++ b/river/PointerConstraint.zig
@@ -80,7 +80,8 @@ fn constrainToRegion(self: *Self) void {
if (self.cursor.constraint != self.constraint) return;
if (View.fromWlrSurface(self.constraint.surface)) |view| {
const output = view.output;
- const output_box = server.root.output_layout.getBox(output.wlr_output).?;
+ var output_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(output.wlr_output, &output_box);
const surface_lx = @intToFloat(f64, output_box.x + view.current.box.x - view.surface_box.x);
const surface_ly = @intToFloat(f64, output_box.y + view.current.box.y - view.surface_box.y);
@@ -126,7 +127,8 @@ pub fn warpToHint(cursor: *Cursor) void {
if (constraint.current.committed.cursor_hint) {
if (View.fromWlrSurface(constraint.surface)) |view| {
const output = view.output;
- const output_box = server.root.output_layout.getBox(output.wlr_output).?;
+ var output_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(output.wlr_output, &output_box);
const surface_lx = @intToFloat(f64, output_box.x + view.current.box.x - view.surface_box.x);
const surface_ly = @intToFloat(f64, output_box.y + view.current.box.y - view.surface_box.y);
diff --git a/river/Root.zig b/river/Root.zig
index 73fb80b..21849a7 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -527,12 +527,12 @@ fn currentOutputConfig(self: *Self) !*wlr.OutputConfigurationV1 {
const output = node.data;
const head = try wlr.OutputConfigurationV1.Head.create(config, output.wlr_output);
- // If the output is not part of the layout (and thus disabled) we dont care
- // about the position
- if (self.output_layout.getBox(output.wlr_output)) |box| {
- head.state.x = box.x;
- head.state.y = box.y;
- }
+ // If the output is not part of the layout (and thus disabled)
+ // the box will be zeroed out.
+ var box: wlr.Box = undefined;
+ self.output_layout.getBox(output.wlr_output, &box);
+ head.state.x = box.x;
+ head.state.y = box.y;
}
return config;
diff --git a/river/Seat.zig b/river/Seat.zig
index 4881092..78981fc 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -316,11 +316,14 @@ pub fn focusOutput(self: *Self, output: *Output) void {
switch (server.config.warp_cursor) {
.disabled => {},
.@"on-output-change" => {
- const layout_box = server.root.output_layout.getBox(output.wlr_output).?;
+ var layout_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(output.wlr_output, &layout_box);
if (!layout_box.containsPoint(self.cursor.wlr_cursor.x, self.cursor.wlr_cursor.y)) {
- const eff_res = output.getEffectiveResolution();
- const lx = @intToFloat(f32, layout_box.x + @intCast(i32, eff_res.width / 2));
- const ly = @intToFloat(f32, layout_box.y + @intCast(i32, eff_res.height / 2));
+ var output_width: i32 = undefined;
+ var output_height: i32 = undefined;
+ output.wlr_output.effectiveResolution(&output_width, &output_height);
+ const lx = @intToFloat(f64, layout_box.x + @divTrunc(output_width, 2));
+ const ly = @intToFloat(f64, layout_box.y + @divTrunc(output_height, 2));
if (!self.cursor.wlr_cursor.warp(null, lx, ly)) {
log.err("failed to warp cursor on output change", .{});
}
@@ -482,7 +485,7 @@ fn tryAddDevice(self: *Self, wlr_device: *wlr.InputDevice) !void {
try keyboard.init(self, wlr_device);
- self.wlr_seat.setKeyboard(keyboard.device.wlr_device);
+ self.wlr_seat.setKeyboard(keyboard.device.wlr_device.toKeyboard());
if (self.wlr_seat.keyboard_state.focused_surface) |wlr_surface| {
self.wlr_seat.keyboardNotifyClearFocus();
self.keyboardNotifyEnter(wlr_surface);
diff --git a/river/Server.zig b/river/Server.zig
index 09595a2..c795013 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -97,8 +97,9 @@ pub fn init(self: *Self) !void {
errdefer self.allocator.destroy();
const compositor = try wlr.Compositor.create(self.wl_server, self.renderer);
+ _ = try wlr.Subcompositor.create(self.wl_server);
- self.xdg_shell = try wlr.XdgShell.create(self.wl_server);
+ self.xdg_shell = try wlr.XdgShell.create(self.wl_server, 2);
self.new_xdg_surface.setNotify(handleNewXdgSurface);
self.xdg_shell.events.new_surface.add(&self.new_xdg_surface);
@@ -188,7 +189,7 @@ fn handleNewXdgSurface(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wl
log.debug("new xdg_toplevel", .{});
const output = self.input_manager.defaultSeat().focused_output;
- XdgToplevel.create(output, xdg_surface) catch {
+ XdgToplevel.create(output, xdg_surface.role_data.toplevel) catch {
log.err("out of memory", .{});
xdg_surface.resource.postNoMemory();
return;
diff --git a/river/Switch.zig b/river/Switch.zig
index 157e3bc..d36fd69 100644
--- a/river/Switch.zig
+++ b/river/Switch.zig
@@ -59,7 +59,7 @@ pub fn init(self: *Self, seat: *Seat, wlr_device: *wlr.InputDevice) !void {
try self.device.init(seat, wlr_device);
errdefer self.device.deinit();
- wlr_device.device.switch_device.events.toggle.add(&self.toggle);
+ wlr_device.toSwitch().events.toggle.add(&self.toggle);
}
pub fn deinit(self: *Self) void {
@@ -83,7 +83,6 @@ fn handleToggle(listener: *wl.Listener(*wlr.Switch.event.Toggle), event: *wlr.Sw
switch_state = switch (event.switch_state) {
.off => .{ .lid = .open },
.on => .{ .lid = .close },
- .toggle => unreachable,
};
},
.tablet_mode => {
@@ -91,7 +90,6 @@ fn handleToggle(listener: *wl.Listener(*wlr.Switch.event.Toggle), event: *wlr.Sw
switch_state = switch (event.switch_state) {
.off => .{ .tablet = .off },
.on => .{ .tablet = .on },
- .toggle => unreachable,
};
},
}
diff --git a/river/View.zig b/river/View.zig
index 272d384..61cecf4 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -27,7 +27,6 @@ const wl = @import("wayland").server.wl;
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const Output = @import("Output.zig");
const Seat = @import("Seat.zig");
const ViewStack = @import("view_stack.zig").ViewStack;
@@ -37,10 +36,10 @@ const XwaylandView = if (build_options.xwayland) @import("XwaylandView.zig") els
const log = std.log.scoped(.view);
pub const Constraints = struct {
- min_width: u32,
- max_width: u32,
- min_height: u32,
- max_height: u32,
+ min_width: u31,
+ max_width: u31,
+ min_height: u31,
+ max_height: u31,
};
const Impl = union(enum) {
@@ -52,7 +51,7 @@ const State = struct {
/// The output-relative effective coordinates and effective dimensions of the view. The
/// surface itself may have other dimensions which are stored in the
/// surface_box member.
- box: Box = Box{ .x = 0, .y = 0, .width = 0, .height = 0 },
+ box: wlr.Box = wlr.Box{ .x = 0, .y = 0, .width = 0, .height = 0 },
/// The tags of the view, as a bitmask
tags: u32,
@@ -68,7 +67,7 @@ const State = struct {
const SavedBuffer = struct {
client_buffer: *wlr.ClientBuffer,
/// x/y relative to the root surface in the surface tree.
- surface_box: Box,
+ surface_box: wlr.Box,
source_box: wlr.FBox,
transform: wl.Output.Transform,
};
@@ -95,22 +94,22 @@ pending_serial: ?u32 = null,
/// The currently commited geometry of the surface. The x/y may be negative if
/// for example the client has decided to draw CSD shadows a la GTK.
-surface_box: Box = undefined,
+surface_box: wlr.Box = undefined,
/// The geometry the view's surface had when the transaction started and
/// buffers were saved.
-saved_surface_box: Box = undefined,
+saved_surface_box: wlr.Box = undefined,
/// These are what we render while a transaction is in progress
saved_buffers: std.ArrayListUnmanaged(SavedBuffer) = .{},
/// The floating dimensions the view, saved so that they can be restored if the
/// view returns to floating mode.
-float_box: Box = undefined,
+float_box: wlr.Box = undefined,
/// This state exists purely to allow for more intuitive behavior when
/// exiting fullscreen if there is no active layout.
-post_fullscreen_box: Box = undefined,
+post_fullscreen_box: wlr.Box = undefined,
draw_borders: bool = true,
@@ -172,13 +171,14 @@ pub fn applyPending(self: *Self) void {
// If switching to fullscreen, set the dimensions to the full area of the output
self.setFullscreen(true);
self.post_fullscreen_box = self.current.box;
- const dimensions = self.output.getEffectiveResolution();
+
self.pending.box = .{
.x = 0,
.y = 0,
- .width = dimensions.width,
- .height = dimensions.height,
+ .width = undefined,
+ .height = undefined,
};
+ self.output.wlr_output.effectiveResolution(&self.pending.box.width, &self.pending.box.height);
} else if (self.lastSetFullscreenState() and !self.pending.fullscreen) {
self.setFullscreen(false);
self.pending.box = self.post_fullscreen_box;
@@ -246,8 +246,8 @@ fn saveBuffersIterator(
.surface_box = .{
.x = surface_x,
.y = surface_y,
- .width = @intCast(u32, surface.current.width),
- .height = @intCast(u32, surface.current.height),
+ .width = surface.current.width,
+ .height = surface.current.height,
},
.source_box = source_box,
.transform = surface.current.transform,
@@ -284,22 +284,19 @@ pub fn sendToOutput(self: *Self, destination_output: *Output) void {
}
self.output = destination_output;
- const dimensions = destination_output.getEffectiveResolution();
+
+ var output_width: i32 = undefined;
+ var output_height: i32 = undefined;
+ destination_output.wlr_output.effectiveResolution(&output_width, &output_height);
if (self.pending.float) {
// Adapt dimensions of view to new output. Only necessary when floating,
// because for tiled views the output will be rearranged, taking care
// of this.
if (self.pending.fullscreen) self.pending.box = self.post_fullscreen_box;
- const border_width = if (self.draw_borders) @intCast(i32, server.config.border_width) else 0;
- self.pending.box.width = math.min(
- self.pending.box.width,
- @intCast(i32, dimensions.width) - (2 * border_width),
- );
- self.pending.box.height = math.min(
- self.pending.box.height,
- @intCast(i32, dimensions.height) - (2 * border_width),
- );
+ const border_width = if (self.draw_borders) server.config.border_width else 0;
+ self.pending.box.width = math.min(self.pending.box.width, output_width - (2 * border_width));
+ self.pending.box.height = math.min(self.pending.box.height, output_height - (2 * border_width));
// Adjust position of view so that it is fully inside the target output.
self.move(0, 0);
@@ -313,8 +310,8 @@ pub fn sendToOutput(self: *Self, destination_output: *Output) void {
self.pending.box = .{
.x = 0,
.y = 0,
- .width = dimensions.width,
- .height = dimensions.height,
+ .width = output_width,
+ .height = output_height,
};
}
}
@@ -374,7 +371,7 @@ pub inline fn forEachSurface(
) void {
switch (self.impl) {
.xdg_toplevel => |xdg_toplevel| {
- xdg_toplevel.xdg_surface.forEachSurface(T, iterator, user_data);
+ xdg_toplevel.xdg_toplevel.base.forEachSurface(T, iterator, user_data);
},
.xwayland_view => {
assert(build_options.xwayland);
@@ -427,16 +424,18 @@ pub fn getConstraints(self: Self) Constraints {
/// Modify the pending x/y of the view by the given deltas, clamping to the
/// bounds of the output.
pub fn move(self: *Self, delta_x: i32, delta_y: i32) void {
- const border_width = if (self.draw_borders) @intCast(i32, server.config.border_width) else 0;
- const output_resolution = self.output.getEffectiveResolution();
+ const border_width = if (self.draw_borders) server.config.border_width else 0;
+ var output_width: i32 = undefined;
+ var output_height: i32 = undefined;
+ self.output.wlr_output.effectiveResolution(&output_width, &output_height);
- const max_x = @intCast(i32, output_resolution.width) - @intCast(i32, self.pending.box.width) - border_width;
+ const max_x = output_width - self.pending.box.width - border_width;
self.pending.box.x += delta_x;
self.pending.box.x = math.max(self.pending.box.x, border_width);
self.pending.box.x = math.min(self.pending.box.x, max_x);
self.pending.box.x = math.max(self.pending.box.x, 0);
- const max_y = @intCast(i32, output_resolution.height) - @intCast(i32, self.pending.box.height) - border_width;
+ const max_y = output_height - self.pending.box.height - border_width;
self.pending.box.y += delta_y;
self.pending.box.y = math.max(self.pending.box.y, border_width);
self.pending.box.y = math.min(self.pending.box.y, max_y);
diff --git a/river/VoidView.zig b/river/VoidView.zig
index dfd9e82..4337763 100644
--- a/river/VoidView.zig
+++ b/river/VoidView.zig
@@ -19,7 +19,6 @@ const Self = @This();
const std = @import("std");
const wlr = @import("wlroots");
-const Box = @import("Box.zig");
const View = @import("View.zig");
pub fn needsConfigure(_: Self) bool {
diff --git a/river/XdgPopup.zig b/river/XdgPopup.zig
index 8ac250f..4b85561 100644
--- a/river/XdgPopup.zig
+++ b/river/XdgPopup.zig
@@ -31,9 +31,9 @@ parent: Parent,
wlr_xdg_popup: *wlr.XdgPopup,
// Always active
-surface_destroy: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleDestroy),
-map: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleMap),
-unmap: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleUnmap),
+surface_destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
+map: wl.Listener(void) = wl.Listener(void).init(handleMap),
+unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleNewSubsurface),
@@ -55,25 +55,25 @@ pub fn create(wlr_xdg_popup: *wlr.XdgPopup, parent: Parent) void {
switch (parent) {
.xdg_toplevel => |xdg_toplevel| {
- const output_dimensions = xdg_toplevel.view.output.getEffectiveResolution();
// The output box relative to the parent of the xdg_popup
var box = wlr.Box{
.x = xdg_toplevel.view.surface_box.x - xdg_toplevel.view.pending.box.x,
.y = xdg_toplevel.view.surface_box.y - xdg_toplevel.view.pending.box.y,
- .width = @intCast(c_int, output_dimensions.width),
- .height = @intCast(c_int, output_dimensions.height),
+ .width = undefined,
+ .height = undefined,
};
+ xdg_toplevel.view.output.wlr_output.effectiveResolution(&box.width, &box.height);
wlr_xdg_popup.unconstrainFromBox(&box);
},
.layer_surface => |layer_surface| {
- const output_dimensions = layer_surface.output.getEffectiveResolution();
// The output box relative to the parent of the xdg_popup
var box = wlr.Box{
.x = -layer_surface.box.x,
.y = -layer_surface.box.y,
- .width = @intCast(c_int, output_dimensions.width),
- .height = @intCast(c_int, output_dimensions.height),
+ .width = undefined,
+ .height = undefined,
};
+ layer_surface.output.wlr_output.effectiveResolution(&box.width, &box.height);
wlr_xdg_popup.unconstrainFromBox(&box);
},
.drag_icon => unreachable,
@@ -111,19 +111,19 @@ pub fn destroyPopups(wlr_xdg_surface: *wlr.XdgSurface) void {
}
}
-fn handleDestroy(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) void {
+fn handleDestroy(listener: *wl.Listener(void)) void {
const xdg_popup = @fieldParentPtr(XdgPopup, "surface_destroy", listener);
xdg_popup.destroy();
}
-fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) void {
+fn handleMap(listener: *wl.Listener(void)) void {
const xdg_popup = @fieldParentPtr(XdgPopup, "map", listener);
xdg_popup.wlr_xdg_popup.base.surface.events.commit.add(&xdg_popup.commit);
xdg_popup.parent.damageWholeOutput();
}
-fn handleUnmap(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) void {
+fn handleUnmap(listener: *wl.Listener(void)) void {
const xdg_popup = @fieldParentPtr(XdgPopup, "unmap", listener);
xdg_popup.commit.link.remove();
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index 9793adb..5579323 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -24,7 +24,6 @@ const wl = @import("wayland").server.wl;
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const Output = @import("Output.zig");
const Seat = @import("Seat.zig");
const Subsurface = @import("Subsurface.zig");
@@ -38,15 +37,15 @@ const log = std.log.scoped(.xdg_shell);
view: *View,
/// The corresponding wlroots object
-xdg_surface: *wlr.XdgSurface,
+xdg_toplevel: *wlr.XdgToplevel,
/// Set to true when the client acks the configure with serial View.pending_serial.
acked_pending_serial: bool = false,
// Listeners that are always active over the view's lifetime
-destroy: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleDestroy),
-map: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleMap),
-unmap: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleUnmap),
+destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
+map: wl.Listener(void) = wl.Listener(void).init(handleMap),
+unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleNewSubsurface),
@@ -54,42 +53,41 @@ new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init
ack_configure: wl.Listener(*wlr.XdgSurface.Configure) =
wl.Listener(*wlr.XdgSurface.Configure).init(handleAckConfigure),
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
-request_fullscreen: wl.Listener(*wlr.XdgToplevel.event.SetFullscreen) =
- wl.Listener(*wlr.XdgToplevel.event.SetFullscreen).init(handleRequestFullscreen),
+request_fullscreen: wl.Listener(void) = wl.Listener(void).init(handleRequestFullscreen),
request_move: wl.Listener(*wlr.XdgToplevel.event.Move) =
wl.Listener(*wlr.XdgToplevel.event.Move).init(handleRequestMove),
request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) =
wl.Listener(*wlr.XdgToplevel.event.Resize).init(handleRequestResize),
-set_title: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleSetTitle),
-set_app_id: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleSetAppId),
+set_title: wl.Listener(void) = wl.Listener(void).init(handleSetTitle),
+set_app_id: wl.Listener(void) = wl.Listener(void).init(handleSetAppId),
/// The View will add itself to the output's view stack on map
-pub fn create(output: *Output, xdg_surface: *wlr.XdgSurface) error{OutOfMemory}!void {
+pub fn create(output: *Output, xdg_toplevel: *wlr.XdgToplevel) error{OutOfMemory}!void {
const node = try util.gpa.create(ViewStack(View).Node);
const view = &node.view;
view.init(output, .{ .xdg_toplevel = .{
.view = view,
- .xdg_surface = xdg_surface,
+ .xdg_toplevel = xdg_toplevel,
} });
const self = &node.view.impl.xdg_toplevel;
- xdg_surface.data = @ptrToInt(self);
+ xdg_toplevel.base.data = @ptrToInt(self);
// Add listeners that are active over the view's entire lifetime
- xdg_surface.events.destroy.add(&self.destroy);
- xdg_surface.events.map.add(&self.map);
- xdg_surface.events.unmap.add(&self.unmap);
- xdg_surface.events.new_popup.add(&self.new_popup);
- xdg_surface.surface.events.new_subsurface.add(&self.new_subsurface);
+ xdg_toplevel.base.events.destroy.add(&self.destroy);
+ xdg_toplevel.base.events.map.add(&self.map);
+ xdg_toplevel.base.events.unmap.add(&self.unmap);
+ xdg_toplevel.base.events.new_popup.add(&self.new_popup);
+ xdg_toplevel.base.surface.events.new_subsurface.add(&self.new_subsurface);
- Subsurface.handleExisting(xdg_surface.surface, .{ .xdg_toplevel = self });
+ Subsurface.handleExisting(xdg_toplevel.base.surface, .{ .xdg_toplevel = self });
}
/// Returns true if a configure must be sent to ensure that the pending
/// dimensions are applied.
pub fn needsConfigure(self: Self) bool {
- const scheduled = &self.xdg_surface.role_data.toplevel.scheduled;
+ const scheduled = &self.xdg_toplevel.scheduled;
const state = &self.view.pending;
// We avoid a special case for newly mapped views which we have not yet
@@ -100,38 +98,37 @@ pub fn needsConfigure(self: Self) bool {
/// Send a configure event, applying the pending state of the view.
pub fn configure(self: *Self) void {
- const toplevel = self.xdg_surface.role_data.toplevel;
const state = &self.view.pending;
- self.view.pending_serial = toplevel.setSize(state.box.width, state.box.height);
+ self.view.pending_serial = self.xdg_toplevel.setSize(state.box.width, state.box.height);
self.acked_pending_serial = false;
}
pub fn lastSetFullscreenState(self: Self) bool {
- return self.xdg_surface.role_data.toplevel.scheduled.fullscreen;
+ return self.xdg_toplevel.scheduled.fullscreen;
}
/// Close the view. This will lead to the unmap and destroy events being sent
pub fn close(self: Self) void {
- self.xdg_surface.role_data.toplevel.sendClose();
+ self.xdg_toplevel.sendClose();
}
pub fn setActivated(self: Self, activated: bool) void {
- _ = self.xdg_surface.role_data.toplevel.setActivated(activated);
+ _ = self.xdg_toplevel.setActivated(activated);
}
pub fn setFullscreen(self: Self, fullscreen: bool) void {
- _ = self.xdg_surface.role_data.toplevel.setFullscreen(fullscreen);
+ _ = self.xdg_toplevel.setFullscreen(fullscreen);
}
pub fn setResizing(self: Self, resizing: bool) void {
- _ = self.xdg_surface.role_data.toplevel.setResizing(resizing);
+ _ = self.xdg_toplevel.setResizing(resizing);
}
/// Return the surface at output coordinates ox, oy and set sx, sy to the
/// corresponding surface-relative coordinates, if there is a surface.
pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*wlr.Surface {
const view = self.view;
- return self.xdg_surface.surfaceAt(
+ return self.xdg_toplevel.base.surfaceAt(
ox - @intToFloat(f64, view.current.box.x - view.surface_box.x),
oy - @intToFloat(f64, view.current.box.y - view.surface_box.y),
sx,
@@ -141,26 +138,26 @@ pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*wlr.Surface
/// Return the current title of the toplevel if any.
pub fn getTitle(self: Self) ?[*:0]const u8 {
- return self.xdg_surface.role_data.toplevel.title;
+ return self.xdg_toplevel.title;
}
/// Return the current app_id of the toplevel if any .
pub fn getAppId(self: Self) ?[*:0]const u8 {
- return self.xdg_surface.role_data.toplevel.app_id;
+ return self.xdg_toplevel.app_id;
}
/// Return bounds on the dimensions of the toplevel.
pub fn getConstraints(self: Self) View.Constraints {
- const state = &self.xdg_surface.role_data.toplevel.current;
+ const state = &self.xdg_toplevel.current;
return .{
- .min_width = math.max(state.min_width, 1),
- .max_width = if (state.max_width > 0) state.max_width else math.maxInt(u32),
- .min_height = math.max(state.min_height, 1),
- .max_height = if (state.max_height > 0) state.max_height else math.maxInt(u32),
+ .min_width = @intCast(u31, math.max(state.min_width, 1)),
+ .max_width = if (state.max_width > 0) @intCast(u31, state.max_width) else math.maxInt(u31),
+ .min_height = @intCast(u31, math.max(state.min_height, 1)),
+ .max_height = if (state.max_height > 0) @intCast(u31, state.max_height) else math.maxInt(u31),
};
}
-fn handleDestroy(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) void {
+fn handleDestroy(listener: *wl.Listener(void)) void {
const self = @fieldParentPtr(Self, "destroy", listener);
// Remove listeners that are active for the entire lifetime of the view
@@ -170,55 +167,55 @@ fn handleDestroy(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) vo
self.new_popup.link.remove();
self.new_subsurface.link.remove();
- Subsurface.destroySubsurfaces(self.xdg_surface.surface);
- XdgPopup.destroyPopups(self.xdg_surface);
+ Subsurface.destroySubsurfaces(self.xdg_toplevel.base.surface);
+ XdgPopup.destroyPopups(self.xdg_toplevel.base);
self.view.destroy();
}
-fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurface) void {
+fn handleMap(listener: *wl.Listener(void)) void {
const self = @fieldParentPtr(Self, "map", listener);
const view = self.view;
- const toplevel = self.xdg_surface.role_data.toplevel;
// Add listeners that are only active while mapped
- self.xdg_surface.events.ack_configure.add(&self.ack_configure);
- self.xdg_surface.surface.events.commit.add(&self.commit);
- toplevel.events.request_fullscreen.add(&self.request_fullscreen);
- toplevel.events.request_move.add(&self.request_move);
- toplevel.events.request_resize.add(&self.request_resize);
- toplevel.events.set_title.add(&self.set_title);
- toplevel.events.set_app_id.add(&self.set_app_id);
+ self.xdg_toplevel.base.events.ack_configure.add(&self.ack_configure);
+ self.xdg_toplevel.base.surface.events.commit.add(&self.commit);
+ self.xdg_toplevel.events.request_fullscreen.add(&self.request_fullscreen);
+ self.xdg_toplevel.events.request_move.add(&self.request_move);
+ self.xdg_toplevel.events.request_resize.add(&self.request_resize);
+ self.xdg_toplevel.events.set_title.add(&self.set_title);
+ self.xdg_toplevel.events.set_app_id.add(&self.set_app_id);
// Use the view's initial size centered on the output as the default
// floating dimensions
var initial_box: wlr.Box = undefined;
- self.xdg_surface.getGeometry(&initial_box);
- view.float_box.width = @intCast(u32, initial_box.width);
- view.float_box.height = @intCast(u32, initial_box.height);
- view.float_box.x = math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.width) -
- @intCast(i32, view.float_box.width), 2));
- view.float_box.y = math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
- @intCast(i32, view.float_box.height), 2));
+ self.xdg_toplevel.base.getGeometry(&initial_box);
+
+ view.float_box = .{
+ .x = @divTrunc(math.max(0, view.output.usable_box.width - initial_box.width), 2),
+ .y = @divTrunc(math.max(0, view.output.usable_box.height - initial_box.height), 2),
+ .width = initial_box.width,
+ .height = initial_box.height,
+ };
// We initialize these to avoid special-casing newly mapped views in
// the check preformed in needsConfigure().
- toplevel.scheduled.width = @intCast(u32, initial_box.width);
- toplevel.scheduled.height = @intCast(u32, initial_box.height);
+ self.xdg_toplevel.scheduled.width = initial_box.width;
+ self.xdg_toplevel.scheduled.height = initial_box.height;
- view.surface = self.xdg_surface.surface;
- view.surface_box = Box.fromWlrBox(initial_box);
+ view.surface = self.xdg_toplevel.base.surface;
+ view.surface_box = initial_box;
// Also use the view's "natural" size as the initial regular dimensions,
// for the case that it does not get arranged by a lyaout.
view.pending.box = view.float_box;
- const state = &toplevel.current;
+ const state = &self.xdg_toplevel.current;
const has_fixed_size = state.min_width != 0 and state.min_height != 0 and
(state.min_width == state.max_width or state.min_height == state.max_height);
- if (toplevel.parent != null or has_fixed_size) {
- // If the toplevel has a parent or has a fixed size make it float
+ if (self.xdg_toplevel.parent != null or has_fixed_size) {
+ // If the self.xdg_toplevel has a parent or has a fixed size make it float
view.current.float = true;
view.pending.float = true;
view.pending.box = view.float_box;
@@ -233,17 +230,17 @@ fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurfa
if (server.config.csdAllowed(view)) {
view.draw_borders = false;
} else {
- _ = toplevel.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true });
+ _ = self.xdg_toplevel.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true });
}
view.map() catch {
log.err("out of memory", .{});
- xdg_surface.resource.getClient().postNoMemory();
+ self.xdg_toplevel.resource.getClient().postNoMemory();
};
}
/// Called when the surface is unmapped and will no longer be displayed.
-fn handleUnmap(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) void {
+fn handleUnmap(listener: *wl.Listener(void)) void {
const self = @fieldParentPtr(Self, "unmap", listener);
// Remove listeners that are only active while mapped
@@ -274,9 +271,8 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
const self = @fieldParentPtr(Self, "commit", listener);
const view = self.view;
- var wlr_box: wlr.Box = undefined;
- self.xdg_surface.getGeometry(&wlr_box);
- const new_box = Box.fromWlrBox(wlr_box);
+ var new_box: wlr.Box = undefined;
+ self.xdg_toplevel.base.getGeometry(&new_box);
// If we have sent a configure changing the size
if (view.pending_serial != null) {
@@ -338,13 +334,10 @@ fn handleNewSubsurface(listener: *wl.Listener(*wlr.Subsurface), new_wlr_subsurfa
/// Called when the client asks to be fullscreened. We always honor the request
/// for now, perhaps it should be denied in some cases in the future.
-fn handleRequestFullscreen(
- listener: *wl.Listener(*wlr.XdgToplevel.event.SetFullscreen),
- event: *wlr.XdgToplevel.event.SetFullscreen,
-) void {
+fn handleRequestFullscreen(listener: *wl.Listener(void)) void {
const self = @fieldParentPtr(Self, "request_fullscreen", listener);
- if (self.view.pending.fullscreen != event.fullscreen) {
- self.view.pending.fullscreen = event.fullscreen;
+ if (self.view.pending.fullscreen != self.xdg_toplevel.requested.fullscreen) {
+ self.view.pending.fullscreen = self.xdg_toplevel.requested.fullscreen;
self.view.applyPending();
}
}
@@ -370,13 +363,13 @@ fn handleRequestResize(listener: *wl.Listener(*wlr.XdgToplevel.event.Resize), ev
}
/// Called when the client sets / updates its title
-fn handleSetTitle(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) void {
+fn handleSetTitle(listener: *wl.Listener(void)) void {
const self = @fieldParentPtr(Self, "set_title", listener);
self.view.notifyTitle();
}
/// Called when the client sets / updates its app_id
-fn handleSetAppId(listener: *wl.Listener(*wlr.XdgSurface), _: *wlr.XdgSurface) void {
+fn handleSetAppId(listener: *wl.Listener(void)) void {
const self = @fieldParentPtr(Self, "set_app_id", listener);
self.view.notifyAppId();
}
diff --git a/river/XwaylandOverrideRedirect.zig b/river/XwaylandOverrideRedirect.zig
index 3436c4e..9710824 100644
--- a/river/XwaylandOverrideRedirect.zig
+++ b/river/XwaylandOverrideRedirect.zig
@@ -25,7 +25,6 @@ const wl = @import("wayland").server.wl;
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const View = @import("View.zig");
const XwaylandView = @import("XwaylandView.zig");
const ViewStack = @import("view_stack.zig").ViewStack;
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index 4a00da3..84c8d7c 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -26,7 +26,6 @@ const wl = @import("wayland").server.wl;
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const Output = @import("Output.zig");
const View = @import("View.zig");
const ViewStack = @import("view_stack.zig").ViewStack;
@@ -90,7 +89,8 @@ pub fn create(output: *Output, xwayland_surface: *wlr.XwaylandSurface) error{Out
pub fn needsConfigure(self: Self) bool {
const output = self.view.output;
- const output_box = server.root.output_layout.getBox(output.wlr_output).?;
+ var output_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(output.wlr_output, &output_box);
return self.xwayland_surface.x != self.view.pending.box.x + output_box.x or
self.xwayland_surface.y != self.view.pending.box.y + output_box.y or
self.xwayland_surface.width != self.view.pending.box.width or
@@ -101,7 +101,8 @@ pub fn needsConfigure(self: Self) bool {
/// shouldTrackConfigure() is always false for xwayland views.
pub fn configure(self: Self) void {
const output = self.view.output;
- const output_box = server.root.output_layout.getBox(output.wlr_output).?;
+ var output_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(output.wlr_output, &output_box);
const state = &self.view.pending;
self.xwayland_surface.configure(
@@ -161,22 +162,14 @@ pub fn getConstraints(self: Self) View.Constraints {
const hints = self.xwayland_surface.size_hints orelse return .{
.min_width = 1,
.min_height = 1,
- .max_width = math.maxInt(u32),
- .max_height = math.maxInt(u32),
+ .max_width = math.maxInt(u31),
+ .max_height = math.maxInt(u31),
};
return .{
- .min_width = @intCast(u32, math.max(hints.min_width, 1)),
- .min_height = @intCast(u32, math.max(hints.min_height, 1)),
-
- .max_width = if (hints.max_width > 0)
- @intCast(u32, hints.max_width)
- else
- math.maxInt(u32),
-
- .max_height = if (hints.max_height > 0)
- @intCast(u32, hints.max_height)
- else
- math.maxInt(u32),
+ .min_width = @intCast(u31, math.max(hints.min_width, 1)),
+ .min_height = @intCast(u31, math.max(hints.min_height, 1)),
+ .max_width = if (hints.max_width > 0) @intCast(u31, hints.max_width) else math.maxInt(u31),
+ .max_height = if (hints.max_height > 0) @intCast(u31, hints.max_height) else math.maxInt(u31),
};
}
@@ -211,18 +204,18 @@ pub fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface:
self.view.surface_box = .{
.x = 0,
.y = 0,
- .width = @intCast(u32, surface.current.width),
- .height = @intCast(u32, surface.current.height),
+ .width = surface.current.width,
+ .height = surface.current.height,
};
// Use the view's "natural" size centered on the output as the default
// floating dimensions
- view.float_box.width = self.xwayland_surface.width;
- view.float_box.height = self.xwayland_surface.height;
- view.float_box.x = math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.width) -
- @intCast(i32, view.float_box.width), 2));
- view.float_box.y = math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
- @intCast(i32, view.float_box.height), 2));
+ view.float_box = .{
+ .x = @divTrunc(math.max(0, view.output.usable_box.width - self.xwayland_surface.width), 2),
+ .y = @divTrunc(math.max(0, view.output.usable_box.height - self.xwayland_surface.height), 2),
+ .width = self.xwayland_surface.width,
+ .height = self.xwayland_surface.height,
+ };
const has_fixed_size = if (self.xwayland_surface.size_hints) |size_hints|
size_hints.min_width != 0 and size_hints.min_height != 0 and
@@ -312,8 +305,8 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) voi
self.view.surface_box = .{
.x = 0,
.y = 0,
- .width = @intCast(u32, surface.current.width),
- .height = @intCast(u32, surface.current.height),
+ .width = surface.current.width,
+ .height = surface.current.height,
};
}
diff --git a/river/command/config.zig b/river/command/config.zig
index 3580048..d2d2b43 100644
--- a/river/command/config.zig
+++ b/river/command/config.zig
@@ -32,7 +32,7 @@ pub fn borderWidth(
if (args.len < 2) return Error.NotEnoughArguments;
if (args.len > 2) return Error.TooManyArguments;
- server.config.border_width = try fmt.parseInt(u32, args[1], 10);
+ server.config.border_width = try fmt.parseInt(u31, args[1], 10);
server.root.arrangeAll();
server.root.startTransaction();
}
diff --git a/river/command/filter.zig b/river/command/filter.zig
index 678ff62..ad9bef2 100644
--- a/river/command/filter.zig
+++ b/river/command/filter.zig
@@ -120,7 +120,7 @@ fn csdFilterUpdateViews(kind: FilterKind, pattern: []const u8, operation: enum {
const view = @intToPtr(*View, xdg_toplevel_decoration.surface.data);
if (viewMatchesPattern(kind, pattern, view)) {
- const toplevel = view.impl.xdg_toplevel.xdg_surface.role_data.toplevel;
+ const toplevel = view.impl.xdg_toplevel.xdg_toplevel;
switch (operation) {
.add => {
_ = xdg_toplevel_decoration.setMode(.client_side);
diff --git a/river/command/move.zig b/river/command/move.zig
index cc09a54..b621131 100644
--- a/river/command/move.zig
+++ b/river/command/move.zig
@@ -24,7 +24,6 @@ const PhysicalDirection = @import("../command.zig").PhysicalDirection;
const Orientation = @import("../command.zig").Orientation;
const Seat = @import("../Seat.zig");
const View = @import("../View.zig");
-const Box = @import("../Box.zig");
pub fn move(
seat: *Seat,
@@ -61,15 +60,15 @@ pub fn snap(
return Error.InvalidPhysicalDirection;
const view = getView(seat) orelse return;
- const border_width = @intCast(i32, server.config.border_width);
- const output_box = view.output.getEffectiveResolution();
+ const border_width = server.config.border_width;
+ var output_width: i32 = undefined;
+ var output_height: i32 = undefined;
+ view.output.wlr_output.effectiveResolution(&output_width, &output_height);
switch (direction) {
.up => view.pending.box.y = border_width,
- .down => view.pending.box.y =
- @intCast(i32, output_box.height - view.pending.box.height) - border_width,
+ .down => view.pending.box.y = output_width - view.pending.box.height - border_width,
.left => view.pending.box.x = border_width,
- .right => view.pending.box.x =
- @intCast(i32, output_box.width - view.pending.box.width) - border_width,
+ .right => view.pending.box.x = output_height - view.pending.box.width - border_width,
}
apply(view);
@@ -88,44 +87,27 @@ pub fn resize(
return Error.InvalidOrientation;
const view = getView(seat) orelse return;
- const border_width = @intCast(i32, server.config.border_width);
- const output_box = view.output.getEffectiveResolution();
+ var output_width: i32 = undefined;
+ var output_height: i32 = undefined;
+ view.output.wlr_output.effectiveResolution(&output_width, &output_height);
switch (orientation) {
.horizontal => {
- var real_delta: i32 = @intCast(i32, view.pending.box.width);
- if (delta > 0) {
- view.pending.box.width += @intCast(u32, delta);
- } else {
- // Prevent underflow
- view.pending.box.width -=
- math.min(view.pending.box.width, @intCast(u32, -1 * delta));
- }
+ view.pending.box.width += delta;
view.applyConstraints();
// Do not grow bigger than the output
view.pending.box.width = math.min(
view.pending.box.width,
- output_box.width - @intCast(u32, 2 * border_width),
+ output_width - 2 * server.config.border_width,
);
- real_delta -= @intCast(i32, view.pending.box.width);
- view.move(@divFloor(real_delta, 2), 0);
},
.vertical => {
- var real_delta: i32 = @intCast(i32, view.pending.box.height);
- if (delta > 0) {
- view.pending.box.height += @intCast(u32, delta);
- } else {
- // Prevent underflow
- view.pending.box.height -=
- math.min(view.pending.box.height, @intCast(u32, -1 * delta));
- }
+ view.pending.box.height += delta;
view.applyConstraints();
// Do not grow bigger than the output
view.pending.box.height = math.min(
view.pending.box.height,
- output_box.height - @intCast(u32, 2 * border_width),
+ output_height - 2 * server.config.border_width,
);
- real_delta -= @intCast(i32, view.pending.box.height);
- view.move(0, @divFloor(real_delta, 2));
},
}
diff --git a/river/command/output.zig b/river/command/output.zig
index 34fa108..da7f921 100644
--- a/river/command/output.zig
+++ b/river/command/output.zig
@@ -86,12 +86,15 @@ fn getOutput(seat: *Seat, str: []const u8) !?*Output {
.previous => if (focused_node.prev) |node| &node.data else &server.root.outputs.last.?.data,
};
} else if (std.meta.stringToEnum(wlr.OutputLayout.Direction, str)) |direction| { // Spacial direction
- const focus_box = server.root.output_layout.getBox(seat.focused_output.wlr_output) orelse return null;
+ var focus_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(seat.focused_output.wlr_output, &focus_box);
+ if (focus_box.empty()) return null;
+
const wlr_output = server.root.output_layout.adjacentOutput(
direction,
seat.focused_output.wlr_output,
- @intToFloat(f64, focus_box.x + @divFloor(focus_box.width, 2)),
- @intToFloat(f64, focus_box.y + @divFloor(focus_box.height, 2)),
+ @intToFloat(f64, focus_box.x + @divTrunc(focus_box.width, 2)),
+ @intToFloat(f64, focus_box.y + @divTrunc(focus_box.height, 2)),
) orelse return null;
return @intToPtr(*Output, wlr_output.data);
} else {
diff --git a/river/command/set_repeat.zig b/river/command/set_repeat.zig
index 86f8730..e58908f 100644
--- a/river/command/set_repeat.zig
+++ b/river/command/set_repeat.zig
@@ -39,7 +39,7 @@ pub fn setRepeat(
var it = server.input_manager.devices.iterator(.forward);
while (it.next()) |device| {
if (device.wlr_device.type == .keyboard) {
- device.wlr_device.device.keyboard.setRepeatInfo(rate, delay);
+ device.wlr_device.toKeyboard().setRepeatInfo(rate, delay);
}
}
}
diff --git a/river/command/toggle_fullscreen.zig b/river/command/toggle_fullscreen.zig
index a4ae724..3f2d5f9 100644
--- a/river/command/toggle_fullscreen.zig
+++ b/river/command/toggle_fullscreen.zig
@@ -18,7 +18,6 @@ const std = @import("std");
const server = &@import("../main.zig").server;
-const Box = @import("../Box.zig");
const Error = @import("../command.zig").Error;
const Seat = @import("../Seat.zig");
diff --git a/river/render.zig b/river/render.zig
index 96ab4a5..31a43b2 100644
--- a/river/render.zig
+++ b/river/render.zig
@@ -24,7 +24,6 @@ const pixman = @import("pixman");
const server = &@import("main.zig").server;
const util = @import("util.zig");
-const Box = @import("Box.zig");
const LayerSurface = @import("LayerSurface.zig");
const Output = @import("Output.zig");
const Server = @import("Server.zig");
@@ -201,8 +200,8 @@ fn renderView(output: *const Output, view: *View, now: *os.timespec) void {
.{
.x = saved_buffer.surface_box.x + view.current.box.x - view.saved_surface_box.x,
.y = saved_buffer.surface_box.y + view.current.box.y - view.saved_surface_box.y,
- .width = @intCast(c_int, saved_buffer.surface_box.width),
- .height = @intCast(c_int, saved_buffer.surface_box.height),
+ .width = saved_buffer.surface_box.width,
+ .height = saved_buffer.surface_box.height,
},
&saved_buffer.source_box,
saved_buffer.transform,
@@ -223,7 +222,8 @@ fn renderView(output: *const Output, view: *View, now: *os.timespec) void {
}
fn renderDragIcons(output: *const Output, now: *os.timespec) void {
- const output_box = server.root.output_layout.getBox(output.wlr_output).?;
+ var output_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(output.wlr_output, &output_box);
var it = server.root.drag_icons.first;
while (it) |node| : (it = node.next) {
@@ -243,7 +243,8 @@ fn renderDragIcons(output: *const Output, now: *os.timespec) void {
/// Render all override redirect xwayland windows that appear on the output
fn renderXwaylandOverrideRedirect(output: *const Output, now: *os.timespec) void {
- const output_box = server.root.output_layout.getBox(output.wlr_output).?;
+ var output_box: wlr.Box = undefined;
+ server.root.output_layout.getBox(output.wlr_output, &output_box);
var it = server.root.xwayland_override_redirect_views.last;
while (it) |node| : (it = node.prev) {
@@ -321,42 +322,41 @@ fn renderBorders(output: *const Output, view: *View) void {
if (view.current.focus != 0) break :blk &config.border_color_focused;
break :blk &config.border_color_unfocused;
};
- const border_width = config.border_width;
const actual_box = if (view.saved_buffers.items.len != 0) view.saved_surface_box else view.surface_box;
- var border: Box = undefined;
+ var border: wlr.Box = undefined;
// left and right, covering the corners as well
- border.y = view.current.box.y - @intCast(i32, border_width);
- border.width = border_width;
- border.height = actual_box.height + border_width * 2;
+ border.y = view.current.box.y - config.border_width;
+ border.width = config.border_width;
+ border.height = actual_box.height + config.border_width * 2;
// left
- border.x = view.current.box.x - @intCast(i32, border_width);
+ border.x = view.current.box.x - config.border_width;
renderRect(output, border, color);
// right
- border.x = view.current.box.x + @intCast(i32, actual_box.width);
+ border.x = view.current.box.x + actual_box.width;
renderRect(output, border, color);
// top and bottom
border.x = view.current.box.x;
border.width = actual_box.width;
- border.height = border_width;
+ border.height = config.border_width;
// top
- border.y = view.current.box.y - @intCast(i32, border_width);
+ border.y = view.current.box.y - config.border_width;
renderRect(output, border, color);
// bottom border
- border.y = view.current.box.y + @intCast(i32, actual_box.height);
+ border.y = view.current.box.y + actual_box.height;
renderRect(output, border, color);
}
-fn renderRect(output: *const Output, box: Box, color: *const [4]f32) void {
- var wlr_box = box.toWlrBox();
- scaleBox(&wlr_box, output.wlr_output.scale);
- server.renderer.renderRect(&wlr_box, color, &output.wlr_output.transform_matrix);
+fn renderRect(output: *const Output, box: wlr.Box, color: *const [4]f32) void {
+ var scaled = box;
+ scaleBox(&scaled, output.wlr_output.scale);
+ server.renderer.renderRect(&scaled, color, &output.wlr_output.transform_matrix);
}
/// Scale a wlr_box, taking the possibility of fractional scaling into account.