aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/Cursor.zig52
-rw-r--r--river/Output.zig13
-rw-r--r--river/View.zig51
-rw-r--r--river/XdgToplevel.zig5
-rw-r--r--river/XwaylandView.zig1
-rw-r--r--river/command/toggle_float.zig5
-rw-r--r--river/command/zoom.zig4
7 files changed, 58 insertions, 73 deletions
diff --git a/river/Cursor.zig b/river/Cursor.zig
index e826952..eeae028 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -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 {
// Find the output to check
const root = self.seat.input_manager.server.root;
- const wlr_output = c.wlr_output_layout_output_at(root.wlr_output_layout, lx, ly) orelse
- return null;
+ const wlr_output = c.wlr_output_layout_output_at(root.wlr_output_layout, lx, ly) orelse return null;
const output = util.voidCast(Output, wlr_output.*.data orelse return null);
// 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
- if (layerSurfaceAt(output.*, output.layers[layer_idxs[0]], ox, oy, sx, sy, false)) |surface| {
- return surface;
- }
+ if (layerSurfaceAt(output.*, output.layers[layer_idxs[0]], ox, oy, sx, sy, false)) |s| return s;
// Check top-background popups only
- for (layer_idxs[1..4]) |layer_idx| {
- if (layerSurfaceAt(output.*, output.layers[layer_idx], ox, oy, sx, sy, true)) |surface| {
- return surface;
- }
- }
+ for (layer_idxs[1..4]) |idx|
+ if (layerSurfaceAt(output.*, output.layers[idx], ox, oy, sx, sy, true)) |s| return s;
// Check top layer
- if (layerSurfaceAt(output.*, output.layers[layer_idxs[1]], ox, oy, sx, sy, false)) |surface| {
- return surface;
- }
+ if (layerSurfaceAt(output.*, output.layers[layer_idxs[1]], ox, oy, sx, sy, false)) |s| return s;
- // Check floating views then normal views
- if (viewSurfaceAt(output.*, ox, oy, sx, sy, true)) |surface| {
- return surface;
- }
- if (viewSurfaceAt(output.*, ox, oy, sx, sy, false)) |surface| {
- return surface;
- }
+ // Check views
+ if (viewSurfaceAt(output.*, ox, oy, sx, sy)) |s| return s;
// Check the bottom-background layers
- for (layer_idxs[2..4]) |layer_idx| {
- if (layerSurfaceAt(output.*, output.layers[layer_idx], ox, oy, sx, sy, false)) |surface| {
- return surface;
- }
- }
+ for (layer_idxs[2..4]) |idx|
+ if (layerSurfaceAt(output.*, output.layers[idx], ox, oy, sx, sy, false)) |s| return s;
return null;
}
@@ -373,18 +357,10 @@ fn layerSurfaceAt(
return null;
}
-/// Find the topmost visible view surface (incl. popups) at ox,oy. Will
-/// check only floating views if floating is true.
-fn viewSurfaceAt(output: Output, ox: f64, oy: f64, sx: *f64, sy: *f64, floating: bool) ?*c.wlr_surface {
+/// Find the topmost visible view surface (incl. popups) at ox,oy.
+fn viewSurfaceAt(output: Output, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
- while (it.next()) |node| {
- const view = &node.view;
- if (view.floating != floating) {
- continue;
- }
- if (view.surfaceAt(ox, oy, sx, sy)) |found| {
- return found;
- }
- }
- return null;
+ return while (it.next()) |node| {
+ if (node.view.surfaceAt(ox, oy, sx, sy)) |found| break found;
+ } else null;
}
diff --git a/river/Output.zig b/river/Output.zig
index 36eb343..f1f4419 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -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);
while (it.next()) |node| {
const view = &node.view;
- if (view.floating) continue;
- view.pending_box = full_box;
+ if (view.mode == .layout) 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);
while (view_it.next()) |node| {
const view = &node.view;
- if (view.floating) continue;
- view.pending_box = view_boxen.items[i];
- i += 1;
+ if (view.mode == .layout) {
+ view.pending_box = view_boxen.items[i];
+ i += 1;
+ }
}
}
@@ -310,8 +310,7 @@ pub fn arrangeViews(self: *Self) void {
var count: u32 = 0;
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
while (it.next()) |node| {
- if (node.view.floating) continue;
- count += 1;
+ if (node.view.mode == .layout) count += 1;
}
break :blk count;
};
diff --git a/river/View.zig b/river/View.zig
index ca9bed0..a50957e 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -29,16 +29,18 @@ const Output = @import("Output.zig");
const Root = @import("Root.zig");
const ViewStack = @import("view_stack.zig").ViewStack;
const XdgToplevel = @import("XdgToplevel.zig");
-const XwaylandView = if (build_options.xwayland)
- @import("XwaylandView.zig")
-else
- @import("VoidView.zig");
+const XwaylandView = if (build_options.xwayland) @import("XwaylandView.zig") else @import("VoidView.zig");
const Impl = union(enum) {
xdg_toplevel: XdgToplevel,
xwayland_view: XwaylandView,
};
+const Mode = enum {
+ layout,
+ float,
+};
+
const SavedBuffer = struct {
wlr_buffer: *c.wlr_buffer,
box: Box,
@@ -54,8 +56,8 @@ output: *Output,
/// This is non-null exactly when the view is mapped
wlr_surface: ?*c.wlr_surface,
-/// If the view is floating or not
-floating: bool,
+/// The current mode of the view
+mode: Mode,
/// True if the view is currently focused by at least one seat
focused: bool,
@@ -92,6 +94,7 @@ pub fn init(self: *Self, output: *Output, tags: u32, surface: var) void {
self.output = output;
self.wlr_surface = null;
+ self.mode = .layout;
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
-/// layout.
-pub fn setFloating(self: *Self, float: bool) void {
- if (float and !self.floating) {
- self.floating = true;
- 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,
- };
- } else if (!float and self.floating) {
- self.floating = false;
+/// 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,
+ },
}
}
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index ea8858d..dbbcb9d 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -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);
view.wlr_surface = self.wlr_xdg_surface.surface;
- view.floating = false;
view.natural_width = @intCast(u32, self.wlr_xdg_surface.geometry.width);
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| {
// 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))) {
- view.setFloating(true);
+ view.setMode(.float);
break;
}
} 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)))
{
// 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
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index 9195d83..6ac5840 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -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);
view.wlr_surface = self.wlr_xwayland_surface.surface;
- view.floating = false;
view.natural_width = self.wlr_xwayland_surface.width;
view.natural_height = self.wlr_xwayland_surface.height;
diff --git a/river/command/toggle_float.zig b/river/command/toggle_float.zig
index 26e725a..4ade683 100644
--- a/river/command/toggle_float.zig
+++ b/river/command/toggle_float.zig
@@ -30,7 +30,10 @@ pub fn toggleFloat(
) Error!void {
if (args.len > 1) return Error.TooManyArguments;
if (seat.focused_view) |view| {
- view.setFloating(!view.floating);
+ switch (view.mode) {
+ .layout => view.setMode(.float),
+ .float => view.setMode(.layout),
+ }
view.output.root.arrange();
}
}
diff --git a/river/command/zoom.zig b/river/command/zoom.zig
index 702698d..e21e038 100644
--- a/river/command/zoom.zig
+++ b/river/command/zoom.zig
@@ -36,8 +36,8 @@ pub fn zoom(
const output = seat.focused_output;
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
- // Don't zoom floating views
- if (current_focus.floating) return;
+ // Only zoom views that are part of the layout
+ if (current_focus.mode != .layout) return;
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
const zoom_node = if (focused_node == it.next())