view: use a mode enum instead of floating bool
This is in preperation for fullscreen support which will add another mode to this enum. This commit also fixes a bug that allowed clicking floating views though layout views in some cases.
This commit is contained in:
parent
3904275373
commit
89d0fb012d
@ -286,8 +286,7 @@ fn processMotion(self: Self, time: u32) void {
|
|||||||
fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
|
fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
|
||||||
// Find the output to check
|
// Find the output to check
|
||||||
const root = self.seat.input_manager.server.root;
|
const root = self.seat.input_manager.server.root;
|
||||||
const wlr_output = c.wlr_output_layout_output_at(root.wlr_output_layout, lx, ly) orelse
|
const wlr_output = c.wlr_output_layout_output_at(root.wlr_output_layout, lx, ly) orelse return null;
|
||||||
return null;
|
|
||||||
const output = util.voidCast(Output, wlr_output.*.data orelse return null);
|
const output = util.voidCast(Output, wlr_output.*.data orelse return null);
|
||||||
|
|
||||||
// Get output-local coords from the layout coords
|
// Get output-local coords from the layout coords
|
||||||
@ -304,36 +303,21 @@ fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Check overlay layer incl. popups
|
// Check overlay layer incl. popups
|
||||||
if (layerSurfaceAt(output.*, output.layers[layer_idxs[0]], ox, oy, sx, sy, false)) |surface| {
|
if (layerSurfaceAt(output.*, output.layers[layer_idxs[0]], ox, oy, sx, sy, false)) |s| return s;
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check top-background popups only
|
// Check top-background popups only
|
||||||
for (layer_idxs[1..4]) |layer_idx| {
|
for (layer_idxs[1..4]) |idx|
|
||||||
if (layerSurfaceAt(output.*, output.layers[layer_idx], ox, oy, sx, sy, true)) |surface| {
|
if (layerSurfaceAt(output.*, output.layers[idx], ox, oy, sx, sy, true)) |s| return s;
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check top layer
|
// Check top layer
|
||||||
if (layerSurfaceAt(output.*, output.layers[layer_idxs[1]], ox, oy, sx, sy, false)) |surface| {
|
if (layerSurfaceAt(output.*, output.layers[layer_idxs[1]], ox, oy, sx, sy, false)) |s| return s;
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check floating views then normal views
|
// Check views
|
||||||
if (viewSurfaceAt(output.*, ox, oy, sx, sy, true)) |surface| {
|
if (viewSurfaceAt(output.*, ox, oy, sx, sy)) |s| return s;
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
if (viewSurfaceAt(output.*, ox, oy, sx, sy, false)) |surface| {
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the bottom-background layers
|
// Check the bottom-background layers
|
||||||
for (layer_idxs[2..4]) |layer_idx| {
|
for (layer_idxs[2..4]) |idx|
|
||||||
if (layerSurfaceAt(output.*, output.layers[layer_idx], ox, oy, sx, sy, false)) |surface| {
|
if (layerSurfaceAt(output.*, output.layers[idx], ox, oy, sx, sy, false)) |s| return s;
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -373,18 +357,10 @@ fn layerSurfaceAt(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the topmost visible view surface (incl. popups) at ox,oy. Will
|
/// Find the topmost visible view surface (incl. popups) at ox,oy.
|
||||||
/// check only floating views if floating is true.
|
fn viewSurfaceAt(output: Output, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
|
||||||
fn viewSurfaceAt(output: Output, ox: f64, oy: f64, sx: *f64, sy: *f64, floating: bool) ?*c.wlr_surface {
|
|
||||||
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
|
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
|
||||||
while (it.next()) |node| {
|
return while (it.next()) |node| {
|
||||||
const view = &node.view;
|
if (node.view.surfaceAt(ox, oy, sx, sy)) |found| break found;
|
||||||
if (view.floating != floating) {
|
} else null;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (view.surfaceAt(ox, oy, sx, sy)) |found| {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
@ -181,8 +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.floating) continue;
|
if (view.mode == .layout) view.pending_box = full_box;
|
||||||
view.pending_box = full_box;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,9 +286,10 @@ 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.floating) continue;
|
if (view.mode == .layout) {
|
||||||
view.pending_box = view_boxen.items[i];
|
view.pending_box = view_boxen.items[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,8 +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.floating) continue;
|
if (node.view.mode == .layout) count += 1;
|
||||||
count += 1;
|
|
||||||
}
|
}
|
||||||
break :blk count;
|
break :blk count;
|
||||||
};
|
};
|
||||||
|
@ -29,16 +29,18 @@ const Output = @import("Output.zig");
|
|||||||
const Root = @import("Root.zig");
|
const Root = @import("Root.zig");
|
||||||
const ViewStack = @import("view_stack.zig").ViewStack;
|
const ViewStack = @import("view_stack.zig").ViewStack;
|
||||||
const XdgToplevel = @import("XdgToplevel.zig");
|
const XdgToplevel = @import("XdgToplevel.zig");
|
||||||
const XwaylandView = if (build_options.xwayland)
|
const XwaylandView = if (build_options.xwayland) @import("XwaylandView.zig") else @import("VoidView.zig");
|
||||||
@import("XwaylandView.zig")
|
|
||||||
else
|
|
||||||
@import("VoidView.zig");
|
|
||||||
|
|
||||||
const Impl = union(enum) {
|
const Impl = union(enum) {
|
||||||
xdg_toplevel: XdgToplevel,
|
xdg_toplevel: XdgToplevel,
|
||||||
xwayland_view: XwaylandView,
|
xwayland_view: XwaylandView,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Mode = enum {
|
||||||
|
layout,
|
||||||
|
float,
|
||||||
|
};
|
||||||
|
|
||||||
const SavedBuffer = struct {
|
const SavedBuffer = struct {
|
||||||
wlr_buffer: *c.wlr_buffer,
|
wlr_buffer: *c.wlr_buffer,
|
||||||
box: Box,
|
box: Box,
|
||||||
@ -54,8 +56,8 @@ 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,
|
||||||
|
|
||||||
/// If the view is floating or not
|
/// The current mode of the view
|
||||||
floating: bool,
|
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,
|
||||||
@ -92,6 +94,7 @@ 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;
|
||||||
|
|
||||||
@ -196,21 +199,27 @@ pub fn setFocused(self: *Self, focused: bool) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If true is passsed, make the view float. If false, return it to the tiled
|
/// Set the mode of the view to the given mode
|
||||||
/// layout.
|
pub fn setMode(self: *Self, mode: Mode) void {
|
||||||
pub fn setFloating(self: *Self, float: bool) void {
|
switch (self.mode) {
|
||||||
if (float and !self.floating) {
|
.layout => switch (mode) {
|
||||||
self.floating = true;
|
.layout => {},
|
||||||
self.pending_box = Box{
|
.float => {
|
||||||
.x = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.width) -
|
self.mode = .float;
|
||||||
@intCast(i32, self.natural_width), 2)),
|
self.pending_box = Box{
|
||||||
.y = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.height) -
|
.x = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.width) -
|
||||||
@intCast(i32, self.natural_height), 2)),
|
@intCast(i32, self.natural_width), 2)),
|
||||||
.width = self.natural_width,
|
.y = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.height) -
|
||||||
.height = self.natural_height,
|
@intCast(i32, self.natural_height), 2)),
|
||||||
};
|
.width = self.natural_width,
|
||||||
} else if (!float and self.floating) {
|
.height = self.natural_height,
|
||||||
self.floating = false;
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.float => switch (mode) {
|
||||||
|
.float => {},
|
||||||
|
.layout => self.mode = .layout,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,6 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
|
|||||||
c.wl_signal_add(&self.wlr_xdg_surface.events.new_popup, &self.listen_new_popup);
|
c.wl_signal_add(&self.wlr_xdg_surface.events.new_popup, &self.listen_new_popup);
|
||||||
|
|
||||||
view.wlr_surface = self.wlr_xdg_surface.surface;
|
view.wlr_surface = self.wlr_xdg_surface.surface;
|
||||||
view.floating = false;
|
|
||||||
|
|
||||||
view.natural_width = @intCast(u32, self.wlr_xdg_surface.geometry.width);
|
view.natural_width = @intCast(u32, self.wlr_xdg_surface.geometry.width);
|
||||||
view.natural_height = @intCast(u32, self.wlr_xdg_surface.geometry.height);
|
view.natural_height = @intCast(u32, self.wlr_xdg_surface.geometry.height);
|
||||||
@ -172,7 +171,7 @@ 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.setFloating(true);
|
view.setMode(.float);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if ((wlr_xdg_toplevel.parent != null) or
|
} else if ((wlr_xdg_toplevel.parent != null) or
|
||||||
@ -180,7 +179,7 @@ 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.setFloating(true);
|
view.setMode(.float);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -140,7 +140,6 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
|
|||||||
c.wl_signal_add(&self.wlr_xwayland_surface.surface.*.events.commit, &self.listen_commit);
|
c.wl_signal_add(&self.wlr_xwayland_surface.surface.*.events.commit, &self.listen_commit);
|
||||||
|
|
||||||
view.wlr_surface = self.wlr_xwayland_surface.surface;
|
view.wlr_surface = self.wlr_xwayland_surface.surface;
|
||||||
view.floating = false;
|
|
||||||
|
|
||||||
view.natural_width = self.wlr_xwayland_surface.width;
|
view.natural_width = self.wlr_xwayland_surface.width;
|
||||||
view.natural_height = self.wlr_xwayland_surface.height;
|
view.natural_height = self.wlr_xwayland_surface.height;
|
||||||
|
@ -30,7 +30,10 @@ 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| {
|
||||||
view.setFloating(!view.floating);
|
switch (view.mode) {
|
||||||
|
.layout => view.setMode(.float),
|
||||||
|
.float => view.setMode(.layout),
|
||||||
|
}
|
||||||
view.output.root.arrange();
|
view.output.root.arrange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ pub fn zoom(
|
|||||||
const output = seat.focused_output;
|
const output = seat.focused_output;
|
||||||
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
|
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
|
||||||
|
|
||||||
// Don't zoom floating views
|
// Only zoom views that are part of the layout
|
||||||
if (current_focus.floating) return;
|
if (current_focus.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())
|
||||||
|
Loading…
Reference in New Issue
Block a user