view: introduce state struct to simplify code
The state struct holds all of the state that is double-buffered and applied through transactions. This more explicit handling simplifies much of the code, and will allow for easier implementation of new feature such as fullscreen.
This commit is contained in:
parent
89d0fb012d
commit
c04112b81a
@ -181,7 +181,7 @@ fn layoutFull(self: *Self, visible_count: u32, output_tags: u32) void {
|
|||||||
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
||||||
while (it.next()) |node| {
|
while (it.next()) |node| {
|
||||||
const view = &node.view;
|
const view = &node.view;
|
||||||
if (view.mode == .layout) view.pending_box = full_box;
|
if (view.pending.mode == .layout) view.pending.box = full_box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,8 +286,8 @@ fn layoutExternal(self: *Self, visible_count: u32, output_tags: u32) !void {
|
|||||||
var view_it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
var view_it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
||||||
while (view_it.next()) |node| {
|
while (view_it.next()) |node| {
|
||||||
const view = &node.view;
|
const view = &node.view;
|
||||||
if (view.mode == .layout) {
|
if (view.pending.mode == .layout) {
|
||||||
view.pending_box = view_boxen.items[i];
|
view.pending.box = view_boxen.items[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,7 +310,7 @@ pub fn arrangeViews(self: *Self) void {
|
|||||||
var count: u32 = 0;
|
var count: u32 = 0;
|
||||||
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
||||||
while (it.next()) |node| {
|
while (it.next()) |node| {
|
||||||
if (node.view.mode == .layout) count += 1;
|
if (node.view.pending.mode == .layout) count += 1;
|
||||||
}
|
}
|
||||||
break :blk count;
|
break :blk count;
|
||||||
};
|
};
|
||||||
|
@ -62,7 +62,7 @@ pub fn sendViewTags(self: Self) void {
|
|||||||
|
|
||||||
var it = ViewStack(View).iterator(self.output.views.first, std.math.maxInt(u32));
|
var it = ViewStack(View).iterator(self.output.views.first, std.math.maxInt(u32));
|
||||||
while (it.next()) |node|
|
while (it.next()) |node|
|
||||||
view_tags.append(node.view.current_tags) catch {
|
view_tags.append(node.view.current.tags) catch {
|
||||||
c.wl_resource_post_no_memory(self.wl_resource);
|
c.wl_resource_post_no_memory(self.wl_resource);
|
||||||
log.crit(.river_status, "out of memory", .{});
|
log.crit(.river_status, "out of memory", .{});
|
||||||
return;
|
return;
|
||||||
|
@ -175,7 +175,7 @@ fn startTransaction(self: *Self) void {
|
|||||||
fn handleTimeout(data: ?*c_void) callconv(.C) c_int {
|
fn handleTimeout(data: ?*c_void) callconv(.C) c_int {
|
||||||
const self = util.voidCast(Self, data.?);
|
const self = util.voidCast(Self, data.?);
|
||||||
|
|
||||||
log.err(.transaction, "time out occurred, some imperfect frames may be shown", .{});
|
log.err(.transaction, "timeout occurred, some imperfect frames may be shown", .{});
|
||||||
|
|
||||||
self.commitTransaction();
|
self.commitTransaction();
|
||||||
|
|
||||||
@ -225,19 +225,10 @@ fn commitTransaction(self: *Self) void {
|
|||||||
var view_it = ViewStack(View).iterator(output.views.first, std.math.maxInt(u32));
|
var view_it = ViewStack(View).iterator(output.views.first, std.math.maxInt(u32));
|
||||||
while (view_it.next()) |view_node| {
|
while (view_it.next()) |view_node| {
|
||||||
const view = &view_node.view;
|
const view = &view_node.view;
|
||||||
// Ensure that all pending state is cleared
|
// Apply pending state
|
||||||
view.pending_serial = null;
|
view.pending_serial = null;
|
||||||
if (view.pending_box) |state| {
|
if (view.pending.tags != view.current.tags) view_tags_changed = true;
|
||||||
view.current_box = state;
|
view.current = view.pending;
|
||||||
view.pending_box = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply possible pending tags
|
|
||||||
if (view.pending_tags) |tags| {
|
|
||||||
view.current_tags = tags;
|
|
||||||
view.pending_tags = null;
|
|
||||||
view_tags_changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
view.dropSavedBuffers();
|
view.dropSavedBuffers();
|
||||||
}
|
}
|
||||||
@ -247,7 +238,5 @@ fn commitTransaction(self: *Self) void {
|
|||||||
|
|
||||||
// Iterate over all seats and update focus
|
// Iterate over all seats and update focus
|
||||||
var it = self.server.input_manager.seats.first;
|
var it = self.server.input_manager.seats.first;
|
||||||
while (it) |seat_node| : (it = seat_node.next) {
|
while (it) |seat_node| : (it = seat_node.next) seat_node.data.focus(null);
|
||||||
seat_node.data.focus(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ pub fn focus(self: *Self, _view: ?*View) void {
|
|||||||
// If view is null or not currently visible
|
// If view is null or not currently visible
|
||||||
if (if (view) |v|
|
if (if (view) |v|
|
||||||
v.output != self.focused_output or
|
v.output != self.focused_output or
|
||||||
v.current_tags & self.focused_output.current_focused_tags == 0
|
v.current.tags & self.focused_output.current_focused_tags == 0
|
||||||
else
|
else
|
||||||
true) {
|
true) {
|
||||||
// Set view to the first currently visible view on in the focus stack if any
|
// Set view to the first currently visible view on in the focus stack if any
|
||||||
|
@ -41,6 +41,18 @@ const Mode = enum {
|
|||||||
float,
|
float,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const State = struct {
|
||||||
|
/// The output-relative coordinates and dimensions of the view. The
|
||||||
|
/// surface itself may have other dimensions which are stored in the
|
||||||
|
/// surface_box member.
|
||||||
|
box: Box,
|
||||||
|
|
||||||
|
/// The tags of the view, as a bitmask
|
||||||
|
tags: u32,
|
||||||
|
|
||||||
|
mode: Mode,
|
||||||
|
};
|
||||||
|
|
||||||
const SavedBuffer = struct {
|
const SavedBuffer = struct {
|
||||||
wlr_buffer: *c.wlr_buffer,
|
wlr_buffer: *c.wlr_buffer,
|
||||||
box: Box,
|
box: Box,
|
||||||
@ -56,19 +68,15 @@ output: *Output,
|
|||||||
/// This is non-null exactly when the view is mapped
|
/// This is non-null exactly when the view is mapped
|
||||||
wlr_surface: ?*c.wlr_surface,
|
wlr_surface: ?*c.wlr_surface,
|
||||||
|
|
||||||
/// The current mode of the view
|
|
||||||
mode: Mode,
|
|
||||||
|
|
||||||
/// True if the view is currently focused by at least one seat
|
/// True if the view is currently focused by at least one seat
|
||||||
focused: bool,
|
focused: bool,
|
||||||
|
|
||||||
/// The current output-relative coordinates and dimensions of the view. The
|
/// The double-buffered state of the view
|
||||||
/// surface itself may have other dimensions which are stored in the
|
current: State,
|
||||||
/// surface_box member.
|
pending: State,
|
||||||
current_box: Box,
|
|
||||||
|
|
||||||
/// Pending dimensions of the view during a transaction
|
/// The serial sent with the currently pending configure event
|
||||||
pending_box: ?Box,
|
pending_serial: ?u32,
|
||||||
|
|
||||||
/// The currently commited geometry of the surface. The x/y may be negative if
|
/// 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.
|
/// for example the client has decided to draw CSD shadows a la GTK.
|
||||||
@ -85,29 +93,24 @@ saved_buffers: std.ArrayList(SavedBuffer),
|
|||||||
natural_width: u32,
|
natural_width: u32,
|
||||||
natural_height: u32,
|
natural_height: u32,
|
||||||
|
|
||||||
current_tags: u32,
|
|
||||||
pending_tags: ?u32,
|
|
||||||
|
|
||||||
pending_serial: ?u32,
|
|
||||||
|
|
||||||
pub fn init(self: *Self, output: *Output, tags: u32, surface: var) void {
|
pub fn init(self: *Self, output: *Output, tags: u32, surface: var) void {
|
||||||
self.output = output;
|
self.output = output;
|
||||||
|
|
||||||
self.wlr_surface = null;
|
self.wlr_surface = null;
|
||||||
self.mode = .layout;
|
|
||||||
|
|
||||||
self.focused = false;
|
self.focused = false;
|
||||||
|
|
||||||
self.current_box = Box{
|
self.current = .{
|
||||||
|
.box = .{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
.height = 0,
|
.height = 0,
|
||||||
.width = 0,
|
.width = 0,
|
||||||
|
},
|
||||||
|
.tags = tags,
|
||||||
|
.mode = .layout,
|
||||||
};
|
};
|
||||||
self.pending_box = null;
|
self.pending = self.current;
|
||||||
|
|
||||||
self.current_tags = tags;
|
|
||||||
self.pending_tags = null;
|
|
||||||
|
|
||||||
self.pending_serial = null;
|
self.pending_serial = null;
|
||||||
|
|
||||||
@ -135,13 +138,9 @@ pub fn needsConfigure(self: Self) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure(self: Self) void {
|
pub fn configure(self: Self) void {
|
||||||
if (self.pending_box) |pending_box| {
|
|
||||||
switch (self.impl) {
|
switch (self.impl) {
|
||||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.configure(pending_box),
|
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.configure(self.pending.box),
|
||||||
.xwayland_view => |xwayland_view| xwayland_view.configure(pending_box),
|
.xwayland_view => |xwayland_view| xwayland_view.configure(self.pending.box),
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.err(.transaction, "configure called on a View with no pending box", .{});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +189,8 @@ fn saveBuffersIterator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the focued bool and the active state of the view if it is a toplevel
|
/// Set the focused bool and the active state of the view if it is a toplevel
|
||||||
|
/// TODO: This is insufficient for multi-seat, probably need a focus counter.
|
||||||
pub fn setFocused(self: *Self, focused: bool) void {
|
pub fn setFocused(self: *Self, focused: bool) void {
|
||||||
self.focused = focused;
|
self.focused = focused;
|
||||||
switch (self.impl) {
|
switch (self.impl) {
|
||||||
@ -199,30 +199,6 @@ pub fn setFocused(self: *Self, focused: bool) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the mode of the view to the given mode
|
|
||||||
pub fn setMode(self: *Self, mode: Mode) void {
|
|
||||||
switch (self.mode) {
|
|
||||||
.layout => switch (mode) {
|
|
||||||
.layout => {},
|
|
||||||
.float => {
|
|
||||||
self.mode = .float;
|
|
||||||
self.pending_box = Box{
|
|
||||||
.x = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.width) -
|
|
||||||
@intCast(i32, self.natural_width), 2)),
|
|
||||||
.y = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.height) -
|
|
||||||
@intCast(i32, self.natural_height), 2)),
|
|
||||||
.width = self.natural_width,
|
|
||||||
.height = self.natural_height,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.float => switch (mode) {
|
|
||||||
.float => {},
|
|
||||||
.layout => self.mode = .layout,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Move a view from one output to another, sending the required enter/leave
|
/// Move a view from one output to another, sending the required enter/leave
|
||||||
/// events.
|
/// events.
|
||||||
pub fn sendToOutput(self: *Self, destination_output: *Output) void {
|
pub fn sendToOutput(self: *Self, destination_output: *Output) void {
|
||||||
|
@ -62,8 +62,6 @@ pub fn init(self: *Self, view: *View, wlr_xdg_surface: *c.wlr_xdg_surface) void
|
|||||||
/// Returns true if a configure must be sent to ensure the dimensions of the
|
/// Returns true if a configure must be sent to ensure the dimensions of the
|
||||||
/// pending_box are applied.
|
/// pending_box are applied.
|
||||||
pub fn needsConfigure(self: Self) bool {
|
pub fn needsConfigure(self: Self) bool {
|
||||||
const pending_box = self.view.pending_box orelse return false;
|
|
||||||
|
|
||||||
const wlr_xdg_toplevel: *c.wlr_xdg_toplevel = @field(
|
const wlr_xdg_toplevel: *c.wlr_xdg_toplevel = @field(
|
||||||
self.wlr_xdg_surface,
|
self.wlr_xdg_surface,
|
||||||
c.wlr_xdg_surface_union,
|
c.wlr_xdg_surface_union,
|
||||||
@ -73,8 +71,8 @@ pub fn needsConfigure(self: Self) bool {
|
|||||||
// sync with the current dimensions or be the dimensions sent with the
|
// sync with the current dimensions or be the dimensions sent with the
|
||||||
// most recent configure. In both cases server_pending has the values we
|
// most recent configure. In both cases server_pending has the values we
|
||||||
// want to check against.
|
// want to check against.
|
||||||
return pending_box.width != wlr_xdg_toplevel.server_pending.width or
|
return self.view.pending.box.width != wlr_xdg_toplevel.server_pending.width or
|
||||||
pending_box.height != wlr_xdg_toplevel.server_pending.height;
|
self.view.pending.box.height != wlr_xdg_toplevel.server_pending.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a configure event, applying the width/height of the pending box.
|
/// Send a configure event, applying the width/height of the pending box.
|
||||||
@ -109,8 +107,8 @@ pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surfa
|
|||||||
const view = self.view;
|
const view = self.view;
|
||||||
return c.wlr_xdg_surface_surface_at(
|
return c.wlr_xdg_surface_surface_at(
|
||||||
self.wlr_xdg_surface,
|
self.wlr_xdg_surface,
|
||||||
ox - @intToFloat(f64, view.current_box.x - view.surface_box.x),
|
ox - @intToFloat(f64, view.current.box.x - view.surface_box.x),
|
||||||
oy - @intToFloat(f64, view.current_box.y - view.surface_box.y),
|
oy - @intToFloat(f64, view.current.box.y - view.surface_box.y),
|
||||||
sx,
|
sx,
|
||||||
sy,
|
sy,
|
||||||
);
|
);
|
||||||
@ -171,7 +169,15 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
|
|||||||
for (root.server.config.float_filter.items) |filter_app_id| {
|
for (root.server.config.float_filter.items) |filter_app_id| {
|
||||||
// Make views with app_ids listed in the float filter float
|
// Make views with app_ids listed in the float filter float
|
||||||
if (std.mem.eql(u8, std.mem.span(app_id), std.mem.span(filter_app_id))) {
|
if (std.mem.eql(u8, std.mem.span(app_id), std.mem.span(filter_app_id))) {
|
||||||
view.setMode(.float);
|
view.pending.mode = .float;
|
||||||
|
view.pending.box = .{
|
||||||
|
.x = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.width) -
|
||||||
|
@intCast(i32, view.natural_width), 2)),
|
||||||
|
.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
|
||||||
|
@intCast(i32, view.natural_height), 2)),
|
||||||
|
.width = view.natural_width,
|
||||||
|
.height = view.natural_height,
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if ((wlr_xdg_toplevel.parent != null) or
|
} else if ((wlr_xdg_toplevel.parent != null) or
|
||||||
@ -179,7 +185,15 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
|
|||||||
(state.min_width == state.max_width or state.min_height == state.max_height)))
|
(state.min_width == state.max_width or state.min_height == state.max_height)))
|
||||||
{
|
{
|
||||||
// If the toplevel has a parent or is of fixed size make it float
|
// If the toplevel has a parent or is of fixed size make it float
|
||||||
view.setMode(.float);
|
view.pending.mode = .float;
|
||||||
|
view.pending.box = .{
|
||||||
|
.x = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.width) -
|
||||||
|
@intCast(i32, view.natural_width), 2)),
|
||||||
|
.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
|
||||||
|
@intCast(i32, view.natural_height), 2)),
|
||||||
|
.width = view.natural_width,
|
||||||
|
.height = view.natural_height,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the toplevel has no parent, inform it that it is tiled. This
|
// If the toplevel has no parent, inform it that it is tiled. This
|
||||||
@ -246,5 +260,5 @@ fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
|
|||||||
|
|
||||||
// This will free itself on destroy
|
// This will free itself on destroy
|
||||||
var xdg_popup = util.gpa.create(XdgPopup) catch unreachable;
|
var xdg_popup = util.gpa.create(XdgPopup) catch unreachable;
|
||||||
xdg_popup.init(self.view.output, &self.view.current_box, wlr_xdg_popup);
|
xdg_popup.init(self.view.output, &self.view.current.box, wlr_xdg_popup);
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,8 @@ pub fn init(self: *Self, view: *View, wlr_xwayland_surface: *c.wlr_xwayland_surf
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn needsConfigure(self: Self) bool {
|
pub fn needsConfigure(self: Self) bool {
|
||||||
const view = self.view;
|
return self.view.current.box.width != self.view.pending.box.width or
|
||||||
if (view.pending_box) |pending_box|
|
self.view.current.box.height != self.view.pending.box.height;
|
||||||
return view.current_box.width != pending_box.width or
|
|
||||||
view.current_box.height != pending_box.height;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tell the client to take a new size
|
/// Tell the client to take a new size
|
||||||
@ -105,8 +102,8 @@ pub fn forEachSurface(
|
|||||||
pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
|
pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
|
||||||
return c.wlr_surface_surface_at(
|
return c.wlr_surface_surface_at(
|
||||||
self.wlr_xwayland_surface.surface,
|
self.wlr_xwayland_surface.surface,
|
||||||
ox - @intToFloat(f64, self.view.current_box.x),
|
ox - @intToFloat(f64, self.view.current.box.x),
|
||||||
oy - @intToFloat(f64, self.view.current_box.y),
|
oy - @intToFloat(f64, self.view.current.box.y),
|
||||||
sx,
|
sx,
|
||||||
sy,
|
sy,
|
||||||
);
|
);
|
||||||
|
@ -43,10 +43,8 @@ pub fn setViewTags(
|
|||||||
) Error!void {
|
) Error!void {
|
||||||
const tags = try parseTags(allocator, args, out);
|
const tags = try parseTags(allocator, args, out);
|
||||||
if (seat.focused_view) |view| {
|
if (seat.focused_view) |view| {
|
||||||
if (view.current_tags != tags) {
|
view.pending.tags = tags;
|
||||||
view.pending_tags = tags;
|
view.output.root.arrange();
|
||||||
seat.input_manager.server.root.arrange();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +73,10 @@ pub fn toggleViewTags(
|
|||||||
) Error!void {
|
) Error!void {
|
||||||
const tags = try parseTags(allocator, args, out);
|
const tags = try parseTags(allocator, args, out);
|
||||||
if (seat.focused_view) |view| {
|
if (seat.focused_view) |view| {
|
||||||
const new_tags = view.current_tags ^ tags;
|
const new_tags = view.current.tags ^ tags;
|
||||||
if (new_tags != 0) {
|
if (new_tags != 0) {
|
||||||
view.pending_tags = new_tags;
|
view.pending.tags = new_tags;
|
||||||
seat.input_manager.server.root.arrange();
|
view.output.root.arrange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,19 @@ pub fn toggleFloat(
|
|||||||
) Error!void {
|
) Error!void {
|
||||||
if (args.len > 1) return Error.TooManyArguments;
|
if (args.len > 1) return Error.TooManyArguments;
|
||||||
if (seat.focused_view) |view| {
|
if (seat.focused_view) |view| {
|
||||||
switch (view.mode) {
|
switch (view.current.mode) {
|
||||||
.layout => view.setMode(.float),
|
.layout => {
|
||||||
.float => view.setMode(.layout),
|
view.pending.mode = .float;
|
||||||
|
view.pending.box = .{
|
||||||
|
.x = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.width) -
|
||||||
|
@intCast(i32, view.natural_width), 2)),
|
||||||
|
.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
|
||||||
|
@intCast(i32, view.natural_height), 2)),
|
||||||
|
.width = view.natural_width,
|
||||||
|
.height = view.natural_height,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.float => view.pending.mode = .layout,
|
||||||
}
|
}
|
||||||
view.output.root.arrange();
|
view.output.root.arrange();
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ pub fn zoom(
|
|||||||
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
|
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
|
||||||
|
|
||||||
// Only zoom views that are part of the layout
|
// Only zoom views that are part of the layout
|
||||||
if (current_focus.mode != .layout) return;
|
if (current_focus.current.mode != .layout) return;
|
||||||
|
|
||||||
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
|
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
|
||||||
const zoom_node = if (focused_node == it.next())
|
const zoom_node = if (focused_node == it.next())
|
||||||
|
@ -68,7 +68,7 @@ pub fn renderOutput(output: *Output) void {
|
|||||||
|
|
||||||
// This check prevents a race condition when a frame is requested
|
// This check prevents a race condition when a frame is requested
|
||||||
// between mapping of a view and the first configure being handled.
|
// between mapping of a view and the first configure being handled.
|
||||||
if (view.current_box.width == 0 or view.current_box.height == 0) continue;
|
if (view.current.box.width == 0 or view.current.box.height == 0) continue;
|
||||||
|
|
||||||
// Focused views are rendered on top of normal views, skip them for now
|
// Focused views are rendered on top of normal views, skip them for now
|
||||||
if (view.focused) continue;
|
if (view.focused) continue;
|
||||||
@ -84,7 +84,7 @@ pub fn renderOutput(output: *Output) void {
|
|||||||
|
|
||||||
// This check prevents a race condition when a frame is requested
|
// This check prevents a race condition when a frame is requested
|
||||||
// between mapping of a view and the first configure being handled.
|
// between mapping of a view and the first configure being handled.
|
||||||
if (view.current_box.width == 0 or view.current_box.height == 0) continue;
|
if (view.current.box.width == 0 or view.current.box.height == 0) continue;
|
||||||
|
|
||||||
// Skip unfocused views since we already rendered them
|
// Skip unfocused views since we already rendered them
|
||||||
if (!view.focused) continue;
|
if (!view.focused) continue;
|
||||||
@ -144,8 +144,8 @@ fn renderView(output: Output, view: *View, now: *c.timespec) void {
|
|||||||
output,
|
output,
|
||||||
saved_buffer.wlr_buffer.texture,
|
saved_buffer.wlr_buffer.texture,
|
||||||
.{
|
.{
|
||||||
.x = saved_buffer.box.x + view.current_box.x - view.saved_surface_box.x,
|
.x = saved_buffer.box.x + view.current.box.x - view.saved_surface_box.x,
|
||||||
.y = saved_buffer.box.y + view.current_box.y - view.saved_surface_box.y,
|
.y = saved_buffer.box.y + view.current.box.y - view.saved_surface_box.y,
|
||||||
.width = @intCast(c_int, saved_buffer.box.width),
|
.width = @intCast(c_int, saved_buffer.box.width),
|
||||||
.height = @intCast(c_int, saved_buffer.box.height),
|
.height = @intCast(c_int, saved_buffer.box.height),
|
||||||
},
|
},
|
||||||
@ -156,8 +156,8 @@ fn renderView(output: Output, view: *View, now: *c.timespec) void {
|
|||||||
// a transaction and may simply render each toplevel surface.
|
// a transaction and may simply render each toplevel surface.
|
||||||
var rdata = SurfaceRenderData{
|
var rdata = SurfaceRenderData{
|
||||||
.output = &output,
|
.output = &output,
|
||||||
.output_x = view.current_box.x - view.surface_box.x,
|
.output_x = view.current.box.x - view.surface_box.x,
|
||||||
.output_y = view.current_box.y - view.surface_box.y,
|
.output_y = view.current.box.y - view.surface_box.y,
|
||||||
.when = now,
|
.when = now,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -248,29 +248,29 @@ fn renderBorders(output: Output, view: *View, now: *c.timespec) void {
|
|||||||
const border_width = output.root.server.config.border_width;
|
const border_width = output.root.server.config.border_width;
|
||||||
|
|
||||||
// left and right, covering the corners as well
|
// left and right, covering the corners as well
|
||||||
border.y = view.current_box.y - @intCast(i32, border_width);
|
border.y = view.current.box.y - @intCast(i32, border_width);
|
||||||
border.width = border_width;
|
border.width = border_width;
|
||||||
border.height = view.current_box.height + border_width * 2;
|
border.height = view.current.box.height + border_width * 2;
|
||||||
|
|
||||||
// left
|
// left
|
||||||
border.x = view.current_box.x - @intCast(i32, border_width);
|
border.x = view.current.box.x - @intCast(i32, border_width);
|
||||||
renderRect(output, border, color);
|
renderRect(output, border, color);
|
||||||
|
|
||||||
// right
|
// right
|
||||||
border.x = view.current_box.x + @intCast(i32, view.current_box.width);
|
border.x = view.current.box.x + @intCast(i32, view.current.box.width);
|
||||||
renderRect(output, border, color);
|
renderRect(output, border, color);
|
||||||
|
|
||||||
// top and bottom
|
// top and bottom
|
||||||
border.x = view.current_box.x;
|
border.x = view.current.box.x;
|
||||||
border.width = view.current_box.width;
|
border.width = view.current.box.width;
|
||||||
border.height = border_width;
|
border.height = border_width;
|
||||||
|
|
||||||
// top
|
// top
|
||||||
border.y = view.current_box.y - @intCast(i32, border_width);
|
border.y = view.current.box.y - @intCast(i32, border_width);
|
||||||
renderRect(output, border, color);
|
renderRect(output, border, color);
|
||||||
|
|
||||||
// bottom border
|
// bottom border
|
||||||
border.y = view.current_box.y + @intCast(i32, view.current_box.height);
|
border.y = view.current.box.y + @intCast(i32, view.current.box.height);
|
||||||
renderRect(output, border, color);
|
renderRect(output, border, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,12 +93,9 @@ pub fn ViewStack(comptime T: type) type {
|
|||||||
pub fn next(self: *Iterator) ?*Node {
|
pub fn next(self: *Iterator) ?*Node {
|
||||||
while (self.it) |node| : (self.it = if (self.reverse) node.prev else node.next) {
|
while (self.it) |node| : (self.it = if (self.reverse) node.prev else node.next) {
|
||||||
if (if (self.pending)
|
if (if (self.pending)
|
||||||
if (node.view.pending_tags) |pending_tags|
|
self.tags & node.view.pending.tags != 0
|
||||||
self.tags & pending_tags != 0
|
|
||||||
else
|
else
|
||||||
self.tags & node.view.current_tags != 0
|
self.tags & node.view.current.tags != 0) {
|
||||||
else
|
|
||||||
self.tags & node.view.current_tags != 0) {
|
|
||||||
self.it = if (self.reverse) node.prev else node.next;
|
self.it = if (self.reverse) node.prev else node.next;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user