Implement floating views
This commit is contained in:
parent
94760394b4
commit
1362061c4c
@ -29,3 +29,4 @@ pub usingnamespace @import("command/spawn.zig");
|
||||
pub usingnamespace @import("command/toggle_tags.zig");
|
||||
pub usingnamespace @import("command/toggle_view_tags.zig");
|
||||
pub usingnamespace @import("command/zoom.zig");
|
||||
pub usingnamespace @import("command/toggle_float.zig");
|
||||
|
13
src/command/toggle_float.zig
Normal file
13
src/command/toggle_float.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Arg = @import("../command.zig").Arg;
|
||||
const Seat = @import("../seat.zig").Seat;
|
||||
|
||||
/// Make the focused view float or stop floating, depending on its current
|
||||
/// state.
|
||||
pub fn toggleFloat(seat: *Seat, arg: Arg) void {
|
||||
if (seat.focused_view) |view| {
|
||||
view.setFloating(!view.floating);
|
||||
view.output.root.arrange();
|
||||
}
|
||||
}
|
@ -189,5 +189,13 @@ pub const Config = struct {
|
||||
.command = command.sendToOutput,
|
||||
.arg = .{ .direction = .Prev },
|
||||
});
|
||||
|
||||
// Mod+Space to toggle float
|
||||
try self.keybinds.append(Keybind{
|
||||
.keysym = c.XKB_KEY_space,
|
||||
.modifiers = mod,
|
||||
.command = command.toggleFloat,
|
||||
.arg = .{ .none = {} },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -148,7 +148,12 @@ pub const Output = struct {
|
||||
const visible_count = blk: {
|
||||
var count: u32 = 0;
|
||||
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
||||
while (it.next() != null) count += 1;
|
||||
while (it.next()) |node| {
|
||||
if (node.view.floating) {
|
||||
continue;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
break :blk count;
|
||||
};
|
||||
|
||||
@ -178,6 +183,9 @@ pub const Output = struct {
|
||||
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
||||
while (it.next()) |node| {
|
||||
const view = &node.view;
|
||||
if (view.floating) {
|
||||
continue;
|
||||
}
|
||||
if (i < master_count) {
|
||||
// Add the remainder to the first master to ensure every pixel of height is used
|
||||
const master_height = @divTrunc(layout_height, master_count);
|
||||
|
@ -39,6 +39,26 @@ pub fn renderOutput(output: *Output) void {
|
||||
if (view.current_box.width == 0 or view.current_box.height == 0) {
|
||||
continue;
|
||||
}
|
||||
// Floating views are rendered on top of normal views
|
||||
if (view.floating) {
|
||||
continue;
|
||||
}
|
||||
renderView(output.*, view, &now);
|
||||
renderBorders(output.*, view, &now);
|
||||
}
|
||||
|
||||
// Render floating views
|
||||
it = ViewStack(View).reverseIterator(output.views.last, output.current_focused_tags);
|
||||
while (it.next()) |node| {
|
||||
const view = &node.view;
|
||||
// This check prevents a race condition when a frame is requested
|
||||
// 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.floating) {
|
||||
continue;
|
||||
}
|
||||
renderView(output.*, view, &now);
|
||||
renderBorders(output.*, view, &now);
|
||||
}
|
||||
|
32
src/view.zig
32
src/view.zig
@ -14,9 +14,16 @@ pub const View = struct {
|
||||
|
||||
mapped: bool,
|
||||
|
||||
/// If the view is floating or not
|
||||
floating: bool,
|
||||
|
||||
current_box: Box,
|
||||
pending_box: ?Box,
|
||||
|
||||
/// The dimensions the view would have taken if we didn't force it to tile
|
||||
natural_width: u32,
|
||||
natural_height: u32,
|
||||
|
||||
current_tags: u32,
|
||||
pending_tags: ?u32,
|
||||
|
||||
@ -122,6 +129,22 @@ pub const View = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// If true is passsed, make the view float. If false, return it to the tiled
|
||||
/// layout.
|
||||
pub fn setFloating(self: *Self, float: bool) void {
|
||||
if (float and !self.floating) {
|
||||
self.floating = true;
|
||||
self.pending_box = Box{
|
||||
.x = @intCast(i32, (self.output.usable_box.width - self.natural_width) / 2),
|
||||
.y = @intCast(i32, (self.output.usable_box.height - self.natural_height) / 2),
|
||||
.width = self.natural_width,
|
||||
.height = self.natural_height,
|
||||
};
|
||||
} else if (!float and self.floating) {
|
||||
self.floating = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Move a view from one output to another, sending the required enter/leave
|
||||
/// events.
|
||||
pub fn sendToOutput(self: *Self, destination_output: *Output) void {
|
||||
@ -161,6 +184,15 @@ pub const View = struct {
|
||||
c.wl_signal_add(&self.wlr_xdg_surface.surface.*.events.commit, &self.listen_commit);
|
||||
|
||||
self.mapped = true;
|
||||
self.floating = false;
|
||||
|
||||
self.natural_width = @intCast(u32, self.wlr_xdg_surface.geometry.width);
|
||||
self.natural_height = @intCast(u32, self.wlr_xdg_surface.geometry.height);
|
||||
|
||||
if (self.natural_width == 0 and self.natural_height == 0) {
|
||||
self.natural_width = @intCast(u32, self.wlr_xdg_surface.surface.*.current.width);
|
||||
self.natural_height = @intCast(u32, self.wlr_xdg_surface.surface.*.current.height);
|
||||
}
|
||||
|
||||
// Focus the newly mapped view. Note: if a seat is focusing a different output
|
||||
// it will continue to do so.
|
||||
|
Loading…
Reference in New Issue
Block a user