river-layout: update to v2
This implements the changes to the river-layout protocol proposed in the previous commit removing river-options.
This commit is contained in:
@ -35,12 +35,12 @@ const LayoutDemand = @import("LayoutDemand.zig");
|
||||
|
||||
const log = std.log.scoped(.layout);
|
||||
|
||||
layout: *river.LayoutV1,
|
||||
layout: *river.LayoutV2,
|
||||
namespace: []const u8,
|
||||
output: *Output,
|
||||
|
||||
pub fn create(client: *wl.Client, version: u32, id: u32, output: *Output, namespace: []const u8) !void {
|
||||
const layout = try river.LayoutV1.create(client, version, id);
|
||||
const layout = try river.LayoutV2.create(client, version, id);
|
||||
|
||||
if (namespaceInUse(namespace, output, client)) {
|
||||
layout.sendNamespaceInUse();
|
||||
@ -91,7 +91,7 @@ fn namespaceInUse(namespace: []const u8, output: *Output, client: *wl.Client) bo
|
||||
|
||||
/// This exists to handle layouts that have been rendered inert (due to the
|
||||
/// namespace already being in use) until the client destroys them.
|
||||
fn handleRequestInert(layout: *river.LayoutV1, request: river.LayoutV1.Request, _: ?*c_void) void {
|
||||
fn handleRequestInert(layout: *river.LayoutV2, request: river.LayoutV2.Request, _: ?*c_void) void {
|
||||
if (request == .destroy) layout.destroy();
|
||||
}
|
||||
|
||||
@ -128,14 +128,10 @@ pub fn startLayoutDemand(self: *Self, views: u32) void {
|
||||
self.output.root.trackLayoutDemands();
|
||||
}
|
||||
|
||||
fn handleRequest(layout: *river.LayoutV1, request: river.LayoutV1.Request, self: *Self) void {
|
||||
fn handleRequest(layout: *river.LayoutV2, request: river.LayoutV2.Request, self: *Self) void {
|
||||
switch (request) {
|
||||
.destroy => layout.destroy(),
|
||||
|
||||
// Parameters of the layout changed. We only care about this, if the
|
||||
// layout is currently in use, in which case we rearrange the output.
|
||||
.parameters_changed => if (self == self.output.pending.layout) self.output.arrangeViews(),
|
||||
|
||||
// We receive this event when the client wants to push a view dimension proposal
|
||||
// to the layout demand matching the serial.
|
||||
.push_view_dimensions => |req| {
|
||||
@ -171,7 +167,7 @@ fn handleRequest(layout: *river.LayoutV1, request: river.LayoutV1.Request, self:
|
||||
}
|
||||
}
|
||||
|
||||
fn handleDestroy(layout: *river.LayoutV1, self: *Self) void {
|
||||
fn handleDestroy(layout: *river.LayoutV2, self: *Self) void {
|
||||
log.debug(
|
||||
"destroying layout '{}' on output '{}'",
|
||||
.{ self.namespace, self.output.wlr_output.name },
|
||||
|
@ -21,7 +21,6 @@ const std = @import("std");
|
||||
const wlr = @import("wlroots");
|
||||
const wayland = @import("wayland");
|
||||
const wl = wayland.server.wl;
|
||||
const zriver = wayland.server.zriver;
|
||||
|
||||
const util = @import("util.zig");
|
||||
|
||||
|
@ -37,7 +37,7 @@ server_destroy: wl.Listener(*wl.Server) = wl.Listener(*wl.Server).init(handleSer
|
||||
|
||||
pub fn init(self: *Self, server: *Server) !void {
|
||||
self.* = .{
|
||||
.global = try wl.Global.create(server.wl_server, river.LayoutManagerV1, 1, *Self, self, bind),
|
||||
.global = try wl.Global.create(server.wl_server, river.LayoutManagerV2, 1, *Self, self, bind),
|
||||
};
|
||||
|
||||
server.wl_server.addDestroyListener(&self.server_destroy);
|
||||
@ -49,7 +49,7 @@ fn handleServerDestroy(listener: *wl.Listener(*wl.Server), wl_server: *wl.Server
|
||||
}
|
||||
|
||||
fn bind(client: *wl.Client, self: *Self, version: u32, id: u32) callconv(.C) void {
|
||||
const layout_manager = river.LayoutManagerV1.create(client, 1, id) catch {
|
||||
const layout_manager = river.LayoutManagerV2.create(client, 1, id) catch {
|
||||
client.postNoMemory();
|
||||
log.crit("out of memory", .{});
|
||||
return;
|
||||
@ -57,7 +57,7 @@ fn bind(client: *wl.Client, self: *Self, version: u32, id: u32) callconv(.C) voi
|
||||
layout_manager.setHandler(*Self, handleRequest, null, self);
|
||||
}
|
||||
|
||||
fn handleRequest(layout_manager: *river.LayoutManagerV1, request: river.LayoutManagerV1.Request, self: *Self) void {
|
||||
fn handleRequest(layout_manager: *river.LayoutManagerV2, request: river.LayoutManagerV2.Request, self: *Self) void {
|
||||
switch (request) {
|
||||
.destroy => layout_manager.destroy(),
|
||||
|
||||
|
@ -75,7 +75,8 @@ drag_icons: std.SinglyLinkedList(DragIcon) = .{},
|
||||
xwayland_unmanaged_views: if (build_options.xwayland)
|
||||
std.TailQueue(XwaylandUnmanaged)
|
||||
else
|
||||
void = if (build_options.xwayland) .{},
|
||||
void = if (build_options.xwayland)
|
||||
.{},
|
||||
|
||||
/// Number of layout demands pending before the transaction may be started.
|
||||
pending_layout_demands: u32 = 0,
|
||||
|
@ -59,12 +59,14 @@ const str_to_impl_fn = [_]struct {
|
||||
.{ .name = "focus-view", .impl = @import("command/focus_view.zig").focusView },
|
||||
.{ .name = "map", .impl = @import("command/map.zig").map },
|
||||
.{ .name = "map-pointer", .impl = @import("command/map.zig").mapPointer },
|
||||
.{ .name = "mod-layout-value", .impl = @import("command/layout.zig").modLayoutValue },
|
||||
.{ .name = "move", .impl = @import("command/move.zig").move },
|
||||
.{ .name = "opacity", .impl = @import("command/opacity.zig").opacity },
|
||||
.{ .name = "output-layout", .impl = @import("command/layout.zig").outputLayout },
|
||||
.{ .name = "resize", .impl = @import("command/move.zig").resize },
|
||||
.{ .name = "send-to-output", .impl = @import("command/send_to_output.zig").sendToOutput },
|
||||
.{ .name = "set-focused-tags", .impl = @import("command/tags.zig").setFocusedTags },
|
||||
.{ .name = "set-layout-value", .impl = @import("command/layout.zig").setLayoutValue },
|
||||
.{ .name = "set-repeat", .impl = @import("command/set_repeat.zig").setRepeat },
|
||||
.{ .name = "set-view-tags", .impl = @import("command/tags.zig").setViewTags },
|
||||
.{ .name = "snap", .impl = @import("command/move.zig").snap },
|
||||
@ -92,6 +94,7 @@ pub const Error = error{
|
||||
InvalidDirection,
|
||||
InvalidPhysicalDirection,
|
||||
InvalidOrientation,
|
||||
InvalidType,
|
||||
InvalidRgba,
|
||||
InvalidValue,
|
||||
UnknownOption,
|
||||
@ -135,6 +138,7 @@ pub fn errToMsg(err: Error) [:0]const u8 {
|
||||
Error.InvalidDirection => "invalid direction. Must be 'next' or 'previous'",
|
||||
Error.InvalidPhysicalDirection => "invalid direction. Must be 'up', 'down', 'left' or 'right'",
|
||||
Error.InvalidOrientation => "invalid orientation. Must be 'horizontal', or 'vertical'",
|
||||
Error.InvalidType => "invalid type",
|
||||
Error.InvalidRgba => "invalid color format, must be #RRGGBB or #RRGGBBAA",
|
||||
Error.InvalidValue => "invalid value",
|
||||
Error.OutOfMemory => "out of memory",
|
||||
|
@ -16,6 +16,8 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const wl = @import("wayland").server.wl;
|
||||
const util = @import("../util.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
@ -52,3 +54,98 @@ pub fn defaultLayout(
|
||||
if (output.layout_namespace == null) output.handleLayoutNamespaceChange();
|
||||
}
|
||||
}
|
||||
|
||||
const SetType = enum {
|
||||
int,
|
||||
fixed,
|
||||
string,
|
||||
};
|
||||
|
||||
/// riverctl set-layout-value rivertile int main_count 42
|
||||
/// riverctl set-layout-value rivertile fixed main_factor 42.0
|
||||
/// riverctl set-layout-value rivertile string main_location top
|
||||
pub fn setLayoutValue(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
out: *?[]const u8,
|
||||
) Error!void {
|
||||
if (args.len < 5) return Error.NotEnoughArguments;
|
||||
if (args.len > 5) return Error.TooManyArguments;
|
||||
|
||||
const target_namespace = args[1];
|
||||
const kind = std.meta.stringToEnum(SetType, args[2]) orelse return Error.InvalidType;
|
||||
|
||||
const output = seat.focused_output;
|
||||
|
||||
var it = output.layouts.first;
|
||||
const layout = while (it) |node| : (it = node.next) {
|
||||
const layout = &node.data;
|
||||
if (mem.eql(u8, layout.namespace, target_namespace)) break layout;
|
||||
} else return;
|
||||
|
||||
const null_terminated_name = try util.gpa.dupeZ(u8, args[3]);
|
||||
defer util.gpa.free(null_terminated_name);
|
||||
|
||||
switch (kind) {
|
||||
.int => {
|
||||
const value = try std.fmt.parseInt(i32, args[4], 10);
|
||||
layout.layout.sendSetIntValue(null_terminated_name, value);
|
||||
},
|
||||
.fixed => {
|
||||
const value = try std.fmt.parseFloat(f64, args[4]);
|
||||
layout.layout.sendSetFixedValue(null_terminated_name, wl.Fixed.fromDouble(value));
|
||||
},
|
||||
.string => {
|
||||
const null_terminated_value = try util.gpa.dupeZ(u8, args[4]);
|
||||
defer util.gpa.free(null_terminated_value);
|
||||
layout.layout.sendSetStringValue(null_terminated_name, null_terminated_value);
|
||||
},
|
||||
}
|
||||
|
||||
output.arrangeViews();
|
||||
}
|
||||
|
||||
const ModType = enum {
|
||||
int,
|
||||
fixed,
|
||||
};
|
||||
|
||||
/// riverctl mode-layout-value rivertile int main_count 42
|
||||
/// riverctl set-layout-value rivertile fixed main_factor 42.0
|
||||
pub fn modLayoutValue(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
out: *?[]const u8,
|
||||
) Error!void {
|
||||
if (args.len < 5) return Error.NotEnoughArguments;
|
||||
if (args.len > 5) return Error.TooManyArguments;
|
||||
|
||||
const target_namespace = args[1];
|
||||
const kind = std.meta.stringToEnum(ModType, args[2]) orelse return Error.InvalidType;
|
||||
|
||||
const output = seat.focused_output;
|
||||
|
||||
var it = output.layouts.first;
|
||||
const layout = while (it) |node| : (it = node.next) {
|
||||
const layout = &node.data;
|
||||
if (mem.eql(u8, layout.namespace, target_namespace)) break layout;
|
||||
} else return;
|
||||
|
||||
const null_terminated_name = try util.gpa.dupeZ(u8, args[3]);
|
||||
defer util.gpa.free(null_terminated_name);
|
||||
|
||||
switch (kind) {
|
||||
.int => {
|
||||
const value = try std.fmt.parseInt(i32, args[4], 10);
|
||||
layout.layout.sendModIntValue(null_terminated_name, value);
|
||||
},
|
||||
.fixed => {
|
||||
const value = try std.fmt.parseFloat(f64, args[4]);
|
||||
layout.layout.sendModFixedValue(null_terminated_name, wl.Fixed.fromDouble(value));
|
||||
},
|
||||
}
|
||||
|
||||
output.arrangeViews();
|
||||
}
|
||||
|
Reference in New Issue
Block a user