view: unify clamped move logic, fix overflow
This commit is contained in:
parent
1732c69442
commit
c51f2176b3
@ -19,6 +19,7 @@ const Self = @This();
|
|||||||
|
|
||||||
const build_options = @import("build_options");
|
const build_options = @import("build_options");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const math = std.math;
|
||||||
const wlr = @import("wlroots");
|
const wlr = @import("wlroots");
|
||||||
const wayland = @import("wayland");
|
const wayland = @import("wayland");
|
||||||
const wl = wayland.server.wl;
|
const wl = wayland.server.wl;
|
||||||
@ -468,8 +469,6 @@ fn leaveMode(self: *Self, event: *wlr.Pointer.event.Button) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64, delta_y: f64) void {
|
fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64, delta_y: f64) void {
|
||||||
const config = self.seat.input_manager.server.config;
|
|
||||||
|
|
||||||
switch (self.mode) {
|
switch (self.mode) {
|
||||||
.passthrough => {
|
.passthrough => {
|
||||||
self.wlr_cursor.move(device, delta_x, delta_y);
|
self.wlr_cursor.move(device, delta_x, delta_y);
|
||||||
@ -484,42 +483,28 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
.move => |view| {
|
.move => |view| {
|
||||||
const border_width = if (view.draw_borders) config.border_width else 0;
|
view.move(@floatToInt(i32, delta_x), @floatToInt(i32, delta_y));
|
||||||
|
|
||||||
// Set x/y of cursor and view, clamp to output dimensions
|
|
||||||
const output_resolution = view.output.getEffectiveResolution();
|
|
||||||
view.pending.box.x = std.math.clamp(
|
|
||||||
view.pending.box.x + @floatToInt(i32, delta_x),
|
|
||||||
@intCast(i32, border_width),
|
|
||||||
@intCast(i32, output_resolution.width - view.pending.box.width - border_width),
|
|
||||||
);
|
|
||||||
view.pending.box.y = std.math.clamp(
|
|
||||||
view.pending.box.y + @floatToInt(i32, delta_y),
|
|
||||||
@intCast(i32, border_width),
|
|
||||||
@intCast(i32, output_resolution.height - view.pending.box.height - border_width),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.wlr_cursor.move(
|
self.wlr_cursor.move(
|
||||||
device,
|
device,
|
||||||
@intToFloat(f64, view.pending.box.x - view.current.box.x),
|
@intToFloat(f64, view.pending.box.x - view.current.box.x),
|
||||||
@intToFloat(f64, view.pending.box.y - view.current.box.y),
|
@intToFloat(f64, view.pending.box.y - view.current.box.y),
|
||||||
);
|
);
|
||||||
|
|
||||||
view.applyPending();
|
view.applyPending();
|
||||||
},
|
},
|
||||||
.resize => |data| {
|
.resize => |data| {
|
||||||
|
const config = &self.seat.input_manager.server.config;
|
||||||
const border_width = if (data.view.draw_borders) config.border_width else 0;
|
const border_width = if (data.view.draw_borders) config.border_width else 0;
|
||||||
|
|
||||||
// Set width/height of view, clamp to view size constraints and output dimensions
|
// Set width/height of view, clamp to view size constraints and output dimensions
|
||||||
const box = &data.view.pending.box;
|
const box = &data.view.pending.box;
|
||||||
box.width = @intCast(u32, std.math.max(0, @intCast(i32, box.width) + @floatToInt(i32, delta_x)));
|
box.width = @intCast(u32, math.max(0, @intCast(i32, box.width) + @floatToInt(i32, delta_x)));
|
||||||
box.height = @intCast(u32, std.math.max(0, @intCast(i32, box.height) + @floatToInt(i32, delta_y)));
|
box.height = @intCast(u32, math.max(0, @intCast(i32, box.height) + @floatToInt(i32, delta_y)));
|
||||||
|
|
||||||
data.view.applyConstraints();
|
data.view.applyConstraints();
|
||||||
|
|
||||||
const output_resolution = data.view.output.getEffectiveResolution();
|
const output_resolution = data.view.output.getEffectiveResolution();
|
||||||
box.width = std.math.min(box.width, output_resolution.width - border_width - @intCast(u32, box.x));
|
box.width = math.min(box.width, output_resolution.width - border_width - @intCast(u32, box.x));
|
||||||
box.height = std.math.min(box.height, output_resolution.height - border_width - @intCast(u32, box.y));
|
box.height = math.min(box.height, output_resolution.height - border_width - @intCast(u32, box.y));
|
||||||
|
|
||||||
data.view.applyPending();
|
data.view.applyPending();
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const Self = @This();
|
|||||||
|
|
||||||
const build_options = @import("build_options");
|
const build_options = @import("build_options");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const math = std.math;
|
||||||
const os = std.os;
|
const os = std.os;
|
||||||
const wlr = @import("wlroots");
|
const wlr = @import("wlroots");
|
||||||
const wl = @import("wayland").server.wl;
|
const wl = @import("wayland").server.wl;
|
||||||
@ -380,6 +381,26 @@ 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 config = &self.output.root.server.config;
|
||||||
|
const border_width = if (self.draw_borders) @intCast(i32, config.border_width) else 0;
|
||||||
|
const output_resolution = self.output.getEffectiveResolution();
|
||||||
|
|
||||||
|
const max_x = @intCast(i32, output_resolution.width) - @intCast(i32, 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 = @intCast(i32, output_resolution.height) - @intCast(i32, 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
|
/// Find and return the view corresponding to a given surface, if any
|
||||||
pub fn fromWlrSurface(surface: *wlr.Surface) ?*Self {
|
pub fn fromWlrSurface(surface: *wlr.Surface) ?*Self {
|
||||||
if (surface.isXdgSurface()) {
|
if (surface.isXdgSurface()) {
|
||||||
|
@ -41,10 +41,10 @@ pub fn move(
|
|||||||
|
|
||||||
const view = getView(seat) orelse return;
|
const view = getView(seat) orelse return;
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
.up => moveVertical(view, -1 * delta),
|
.up => view.move(0, -delta),
|
||||||
.down => moveVertical(view, delta),
|
.down => view.move(0, delta),
|
||||||
.left => moveHorizontal(view, -1 * delta),
|
.left => view.move(-delta, 0),
|
||||||
.right => moveHorizontal(view, delta),
|
.right => view.move(delta, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(view);
|
apply(view);
|
||||||
@ -110,7 +110,7 @@ pub fn resize(
|
|||||||
output_box.width - @intCast(u32, 2 * border_width),
|
output_box.width - @intCast(u32, 2 * border_width),
|
||||||
);
|
);
|
||||||
real_delta -= @intCast(i32, view.pending.box.width);
|
real_delta -= @intCast(i32, view.pending.box.width);
|
||||||
moveHorizontal(view, @divFloor(real_delta, 2));
|
view.move(@divFloor(real_delta, 2), 0);
|
||||||
},
|
},
|
||||||
.vertical => {
|
.vertical => {
|
||||||
var real_delta: i32 = @intCast(i32, view.pending.box.height);
|
var real_delta: i32 = @intCast(i32, view.pending.box.height);
|
||||||
@ -128,7 +128,7 @@ pub fn resize(
|
|||||||
output_box.height - @intCast(u32, 2 * border_width),
|
output_box.height - @intCast(u32, 2 * border_width),
|
||||||
);
|
);
|
||||||
real_delta -= @intCast(i32, view.pending.box.height);
|
real_delta -= @intCast(i32, view.pending.box.height);
|
||||||
moveVertical(view, @divFloor(real_delta, 2));
|
view.move(0, @divFloor(real_delta, 2));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,23 +155,3 @@ fn getView(seat: *Seat) ?*View {
|
|||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn moveVertical(view: *View, delta: i32) void {
|
|
||||||
const output_box = view.output.getEffectiveResolution();
|
|
||||||
const border_width = @intCast(i32, view.output.root.server.config.border_width);
|
|
||||||
view.pending.box.y = std.math.clamp(
|
|
||||||
view.pending.box.y + delta,
|
|
||||||
border_width,
|
|
||||||
@intCast(i32, output_box.height - view.pending.box.height) - border_width,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn moveHorizontal(view: *View, delta: i32) void {
|
|
||||||
const output_box = view.output.getEffectiveResolution();
|
|
||||||
const border_width = @intCast(i32, view.output.root.server.config.border_width);
|
|
||||||
view.pending.box.x = std.math.clamp(
|
|
||||||
view.pending.box.x + delta,
|
|
||||||
border_width,
|
|
||||||
@intCast(i32, output_box.width - view.pending.box.width) - border_width,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user