Make Output a toplevel struct

This commit is contained in:
Isaac Freund 2020-05-02 16:40:05 +02:00
parent 7ddcebbbab
commit 96f2ff793c
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
10 changed files with 496 additions and 497 deletions

View file

@ -2,7 +2,7 @@ const c = @import("../c.zig");
const std = @import("std");
const Arg = @import("../command.zig").Arg;
const Output = @import("../output.zig").Output;
const Output = @import("../output.zig");
const Seat = @import("../seat.zig");
/// Focus either the next or the previous output, depending on the bool passed.

View file

@ -2,7 +2,7 @@ const c = @import("../c.zig");
const std = @import("std");
const Arg = @import("../command.zig").Arg;
const Output = @import("../output.zig").Output;
const Output = @import("../output.zig");
const Seat = @import("../seat.zig");
/// Send the focused view to the the next or the previous output, depending on

View file

@ -3,7 +3,7 @@ const c = @import("c.zig");
const LayerSurface = @import("layer_surface.zig").LayerSurface;
const Log = @import("log.zig").Log;
const Output = @import("output.zig").Output;
const Output = @import("output.zig");
const Seat = @import("seat.zig");
const View = @import("view.zig").View;
const ViewStack = @import("view_stack.zig").ViewStack;

View file

@ -3,7 +3,7 @@ const c = @import("c.zig");
const Box = @import("box.zig");
const Log = @import("log.zig").Log;
const Output = @import("output.zig").Output;
const Output = @import("output.zig");
pub const LayerSurface = struct {
const Self = @This();

View file

@ -1,4 +1,7 @@
const Self = @This();
const std = @import("std");
const c = @import("c.zig");
const render = @import("render.zig");
@ -9,38 +12,35 @@ const Root = @import("root.zig").Root;
const View = @import("view.zig").View;
const ViewStack = @import("view_stack.zig").ViewStack;
pub const Output = struct {
const Self = @This();
root: *Root,
wlr_output: *c.wlr_output,
root: *Root,
wlr_output: *c.wlr_output,
/// All layer surfaces on the output, indexed by the layer enum.
layers: [4]std.TailQueue(LayerSurface),
/// All layer surfaces on the output, indexed by the layer enum.
layers: [4]std.TailQueue(LayerSurface),
/// The area left for views and other layer surfaces after applying the
/// exclusive zones of exclusive layer surfaces.
usable_box: Box,
/// The area left for views and other layer surfaces after applying the
/// exclusive zones of exclusive layer surfaces.
usable_box: Box,
/// The top of the stack is the "most important" view.
views: ViewStack(View),
/// The top of the stack is the "most important" view.
views: ViewStack(View),
/// A bit field of focused tags
current_focused_tags: u32,
pending_focused_tags: ?u32,
/// A bit field of focused tags
current_focused_tags: u32,
pending_focused_tags: ?u32,
/// Number of views in "master" section of the screen.
master_count: u32,
/// Number of views in "master" section of the screen.
master_count: u32,
/// Percentage of the total screen that the master section takes up.
master_factor: f64,
/// Percentage of the total screen that the master section takes up.
master_factor: f64,
// All listeners for this output, in alphabetical order
listen_destroy: c.wl_listener,
listen_frame: c.wl_listener,
listen_mode: c.wl_listener,
// All listeners for this output, in alphabetical order
listen_destroy: c.wl_listener,
listen_frame: c.wl_listener,
listen_mode: c.wl_listener,
pub fn init(self: *Self, root: *Root, wlr_output: *c.wlr_output) !void {
pub fn init(self: *Self, root: *Root, wlr_output: *c.wlr_output) !void {
// Some backends don't have modes. DRM+KMS does, and we need to set a mode
// before we can use the output. The mode is a tuple of (width, height,
// refresh rate), and each monitor supports only a specific set of modes. We
@ -110,9 +110,9 @@ pub const Output = struct {
.height = @intCast(u32, height),
};
}
}
}
pub fn deinit(self: *Self) void {
pub fn deinit(self: *Self) void {
for (self.layers) |*layer| {
while (layer.pop()) |layer_surface_node| {
self.root.server.allocator.destroy(layer_surface_node);
@ -124,29 +124,29 @@ pub const Output = struct {
self.views.remove(node);
self.root.server.allocator.destroy(node);
}
}
}
/// Add a new view to the output. arrangeViews() will be called by the view
/// when it is mapped.
pub fn addView(self: *Self, wlr_xdg_surface: *c.wlr_xdg_surface) void {
/// Add a new view to the output. arrangeViews() will be called by the view
/// when it is mapped.
pub fn addView(self: *Self, wlr_xdg_surface: *c.wlr_xdg_surface) void {
const node = self.root.server.allocator.create(ViewStack(View).Node) catch unreachable;
node.view.init_xdg_toplevel(self, self.current_focused_tags, wlr_xdg_surface);
self.views.push(node);
}
}
/// Add a newly created layer surface to the output.
pub fn addLayerSurface(self: *Self, wlr_layer_surface: *c.wlr_layer_surface_v1) !void {
/// Add a newly created layer surface to the output.
pub fn addLayerSurface(self: *Self, wlr_layer_surface: *c.wlr_layer_surface_v1) !void {
const layer = wlr_layer_surface.client_pending.layer;
const node = try self.layers[@intCast(usize, @enumToInt(layer))].allocateNode(self.root.server.allocator);
node.data.init(self, wlr_layer_surface, layer);
self.layers[@intCast(usize, @enumToInt(layer))].append(node);
self.arrangeLayers();
}
}
/// Arrange all views on the output for the current layout. Modifies only
/// pending state, the changes are not appplied until a transaction is started
/// and completed.
pub fn arrangeViews(self: *Self) void {
/// Arrange all views on the output for the current layout. Modifies only
/// pending state, the changes are not appplied until a transaction is started
/// and completed.
pub fn arrangeViews(self: *Self) void {
// If the output has a zero dimension, trying to arrange would cause
// underflow and is pointless anyway
if (self.usable_box.width == 0 or self.usable_box.height == 0) {
@ -249,10 +249,10 @@ pub const Output = struct {
i += 1;
}
}
}
/// Arrange all layer surfaces of this output and addjust the usable aread
pub fn arrangeLayers(self: *Self) void {
/// Arrange all layer surfaces of this output and addjust the usable aread
pub fn arrangeLayers(self: *Self) void {
const full_box = blk: {
var width: c_int = undefined;
var height: c_int = undefined;
@ -330,16 +330,16 @@ pub const Output = struct {
}
}
}
}
}
/// Arrange the layer surfaces of a given layer
fn arrangeLayer(
/// Arrange the layer surfaces of a given layer
fn arrangeLayer(
self: *Self,
layer: std.TailQueue(LayerSurface),
full_box: Box,
usable_box: *Box,
exclusive: bool,
) void {
) void {
var it = layer.first;
while (it) |node| : (it = node.next) {
const layer_surface = &node.data;
@ -472,11 +472,11 @@ pub const Output = struct {
layer_surface.box.height,
);
}
}
}
/// Called when the output is destroyed. Evacuate all views from the output
/// and then remove it from the list of outputs.
fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
/// Called when the output is destroyed. Evacuate all views from the output
/// and then remove it from the list of outputs.
fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_destroy", listener.?);
const root = self.root;
@ -531,24 +531,23 @@ pub const Output = struct {
self.wlr_output.data = null;
// Remove the destroyed output from the list
const node = @fieldParentPtr(std.TailQueue(Output).Node, "data", self);
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
root.outputs.remove(node);
root.server.allocator.destroy(node);
// Arrange the root in case evacuated views affect the layout
root.arrange();
}
}
fn handleFrame(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleFrame(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// This function is called every time an output is ready to display a frame,
// generally at the output's refresh rate (e.g. 60Hz).
const self = @fieldParentPtr(Self, "listen_frame", listener.?);
render.renderOutput(self);
}
}
fn handleMode(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleMode(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_mode", listener.?);
self.arrangeLayers();
self.root.arrange();
}
};
}

View file

@ -3,7 +3,7 @@ const c = @import("c.zig");
const Box = @import("box.zig");
const LayerSurface = @import("layer_surface.zig").LayerSurface;
const Output = @import("output.zig").Output;
const Output = @import("output.zig");
const Server = @import("server.zig");
const View = @import("view.zig").View;
const ViewStack = @import("view_stack.zig").ViewStack;

View file

@ -4,7 +4,7 @@ const util = @import("util.zig");
const Box = @import("box.zig").Box;
const Log = @import("log.zig").Log;
const Output = @import("output.zig").Output;
const Output = @import("output.zig");
const Server = @import("server.zig");
const Seat = @import("seat.zig").Seat;
const View = @import("view.zig").View;

View file

@ -7,7 +7,7 @@ const Cursor = @import("cursor.zig").Cursor;
const InputManager = @import("input_manager.zig");
const Keyboard = @import("keyboard.zig").Keyboard;
const LayerSurface = @import("layer_surface.zig").LayerSurface;
const Output = @import("output.zig").Output;
const Output = @import("output.zig");
const View = @import("view.zig").View;
const ViewStack = @import("view_stack.zig").ViewStack;

View file

@ -8,7 +8,7 @@ const Config = @import("config.zig");
const DecorationManager = @import("decoration_manager.zig");
const InputManager = @import("input_manager.zig");
const Log = @import("log.zig").Log;
const Output = @import("output.zig").Output;
const Output = @import("output.zig");
const Root = @import("root.zig").Root;
const View = @import("view.zig").View;
const ViewStack = @import("view_stack.zig").ViewStack;

View file

@ -3,7 +3,7 @@ const c = @import("c.zig");
const Box = @import("box.zig");
const Log = @import("log.zig").Log;
const Output = @import("output.zig").Output;
const Output = @import("output.zig");
const Root = @import("root.zig").Root;
const ViewStack = @import("view_stack.zig").ViewStack;
const XdgToplevel = @import("xdg_toplevel.zig");