aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <mail@isaacfreund.com>2023-03-01 17:08:54 +0100
committerIsaac Freund <mail@isaacfreund.com>2023-03-01 17:13:14 +0100
commitbf759c7c57762d09d9b59fa2fa048c8c1bdf969e (patch)
treeb2860aad902231fa32f4ee6bb8b07e2abd5681d5
parent50513390ce4b135785b6731cabcac90add083643 (diff)
downloadriver-bf759c7c57762d09d9b59fa2fa048c8c1bdf969e.tar.gz
river-bf759c7c57762d09d9b59fa2fa048c8c1bdf969e.tar.xz
View: clamp to output on exiting float/fullscreen
-rw-r--r--river/Cursor.zig2
-rw-r--r--river/Root.zig4
-rw-r--r--river/View.zig75
-rw-r--r--river/command/move.zig12
4 files changed, 51 insertions, 42 deletions
diff --git a/river/Cursor.zig b/river/Cursor.zig
index b6c34b8..efe9f4f 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -734,7 +734,7 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
data.delta_y = dy - @trunc(dy);
const view = data.view;
- view.move(@floatToInt(i32, dx), @floatToInt(i32, dy));
+ view.pending.move(@floatToInt(i32, dx), @floatToInt(i32, dy));
self.wlr_cursor.move(
device,
@intToFloat(f64, view.pending.box.x - view.current.box.x),
diff --git a/river/Root.zig b/river/Root.zig
index 6223b0a..c86822e 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -403,6 +403,7 @@ pub fn applyPending(root: *Self) void {
} else if (!view.current.float and view.pending.float) {
// If switching from non-float to float, apply the saved float dimensions.
view.pending.box = view.float_box;
+ view.pending.clampToOutput();
}
if (output.pending.fullscreen == null and view.pending.fullscreen and
@@ -420,7 +421,10 @@ pub fn applyPending(root: *Self) void {
if (output.pending.fullscreen != output.inflight.fullscreen) {
if (output.inflight.fullscreen) |view| {
view.setFullscreen(false);
+
view.pending.box = view.post_fullscreen_box;
+ view.pending.clampToOutput();
+
view.inflight.box = view.pending.box;
}
}
diff --git a/river/View.zig b/river/View.zig
index 5f78cf3..158d1c5 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -47,7 +47,7 @@ const Impl = union(enum) {
xwayland_view: if (build_options.xwayland) XwaylandView else noreturn,
};
-const State = struct {
+pub const State = struct {
/// The output the view is currently assigned to.
/// May be null if there are no outputs or for newly created views.
/// Must be set using setPendingOutput()
@@ -66,6 +66,44 @@ const State = struct {
fullscreen: bool = false,
urgent: bool = false,
borders: bool = true,
+
+ /// Modify the x/y of the given state by delta_x/delta_y, clamping to the
+ /// bounds of the output.
+ pub fn move(state: *State, delta_x: i32, delta_y: i32) void {
+ const border_width = if (state.borders) server.config.border_width else 0;
+
+ var output_width: i32 = math.maxInt(i32);
+ var output_height: i32 = math.maxInt(i32);
+ if (state.output) |output| {
+ output.wlr_output.effectiveResolution(&output_width, &output_height);
+ }
+
+ const max_x = output_width - state.box.width - border_width;
+ state.box.x += delta_x;
+ state.box.x = math.max(state.box.x, border_width);
+ state.box.x = math.min(state.box.x, max_x);
+ state.box.x = math.max(state.box.x, 0);
+
+ const max_y = output_height - state.box.height - border_width;
+ state.box.y += delta_y;
+ state.box.y = math.max(state.box.y, border_width);
+ state.box.y = math.min(state.box.y, max_y);
+ state.box.y = math.max(state.box.y, 0);
+ }
+
+ pub fn clampToOutput(state: *State) void {
+ const output = state.output orelse return;
+
+ var output_width: i32 = undefined;
+ var output_height: i32 = undefined;
+ output.wlr_output.effectiveResolution(&output_width, &output_height);
+
+ const border_width = if (state.borders) server.config.border_width else 0;
+ state.box.width = math.min(state.box.width, output_width - (2 * border_width));
+ state.box.height = math.min(state.box.height, output_height - (2 * border_width));
+
+ state.move(0, 0);
+ }
};
/// The implementation of this view
@@ -296,17 +334,8 @@ pub fn setPendingOutput(view: *Self, output: *Output) void {
}
output.pending.focus_stack.prepend(view);
- // Adapt the floating position/dimensions of the view to the new output.
if (view.pending.float) {
- var output_width: i32 = undefined;
- var output_height: i32 = undefined;
- output.wlr_output.effectiveResolution(&output_width, &output_height);
-
- const border_width = if (view.pending.borders) server.config.border_width else 0;
- view.pending.box.width = math.min(view.pending.box.width, output_width - (2 * border_width));
- view.pending.box.height = math.min(view.pending.box.height, output_height - (2 * border_width));
-
- view.move(0, 0);
+ view.pending.clampToOutput();
}
}
@@ -397,30 +426,6 @@ pub fn getConstraints(self: Self) Constraints {
};
}
-/// Modify the pending x/y of the view by the given deltas, clamping to the
-/// bounds of the output.
-pub fn move(self: *Self, delta_x: i32, delta_y: i32) void {
- const border_width = if (self.pending.borders) server.config.border_width else 0;
-
- var output_width: i32 = math.maxInt(i32);
- var output_height: i32 = math.maxInt(i32);
- if (self.pending.output) |output| {
- output.wlr_output.effectiveResolution(&output_width, &output_height);
- }
-
- const max_x = output_width - self.pending.box.width - border_width;
- self.pending.box.x += delta_x;
- self.pending.box.x = math.max(self.pending.box.x, border_width);
- self.pending.box.x = math.min(self.pending.box.x, max_x);
- self.pending.box.x = math.max(self.pending.box.x, 0);
-
- const max_y = output_height - self.pending.box.height - border_width;
- self.pending.box.y += delta_y;
- self.pending.box.y = math.max(self.pending.box.y, border_width);
- self.pending.box.y = math.min(self.pending.box.y, max_y);
- self.pending.box.y = math.max(self.pending.box.y, 0);
-}
-
/// Find and return the view corresponding to a given surface, if any
pub fn fromWlrSurface(surface: *wlr.Surface) ?*Self {
if (surface.isXdgSurface()) {
diff --git a/river/command/move.zig b/river/command/move.zig
index 73e6b54..741d83e 100644
--- a/river/command/move.zig
+++ b/river/command/move.zig
@@ -39,10 +39,10 @@ pub fn move(
const view = getView(seat) orelse return;
switch (direction) {
- .up => view.move(0, -delta),
- .down => view.move(0, delta),
- .left => view.move(-delta, 0),
- .right => view.move(delta, 0),
+ .up => view.pending.move(0, -delta),
+ .down => view.pending.move(0, delta),
+ .left => view.pending.move(-delta, 0),
+ .right => view.pending.move(delta, 0),
}
apply(view);
@@ -108,7 +108,7 @@ pub fn resize(
view.pending.box.width,
output_width - 2 * server.config.border_width,
);
- view.move(@divFloor(diff_width, 2), 0);
+ view.pending.move(@divFloor(diff_width, 2), 0);
},
.vertical => {
const prev_height = view.pending.box.height;
@@ -120,7 +120,7 @@ pub fn resize(
view.pending.box.height,
output_height - 2 * server.config.border_width,
);
- view.move(0, @divFloor(diff_height, 2));
+ view.pending.move(0, @divFloor(diff_height, 2));
},
}