Fix pointer warp for new and closed windows
This commit is contained in:
parent
bfa41f36b0
commit
c953fe3d68
4 changed files with 119 additions and 104 deletions
100
src/Window.zig
100
src/Window.zig
|
|
@ -19,26 +19,29 @@ maximized: bool = false,
|
|||
|
||||
initialized: bool = false,
|
||||
|
||||
/// Used to manage updates to various aspect of Window's state
|
||||
/// Gets reset at the end of every Window.manage() call.
|
||||
///
|
||||
/// It might be a good idea to have two separate versions of this so one
|
||||
/// can be used in renders, but I think it's okay for now.
|
||||
pending_state: PendingState = .{},
|
||||
/// State consumed in manage() phase, reset at end of manage().
|
||||
pending_manage: PendingManage = .{},
|
||||
|
||||
/// State consumed in render() phase, reset at end of render().
|
||||
pending_render: PendingRender = .{},
|
||||
|
||||
link: wl.list.Link,
|
||||
|
||||
/// Used to manage updates to various aspect of Window's state
|
||||
pub const PendingState = struct {
|
||||
pub const PendingManage = struct {
|
||||
width: ?u31 = null,
|
||||
height: ?u31 = null,
|
||||
x: ?i32 = null,
|
||||
y: ?i32 = null,
|
||||
|
||||
fullscreen: ?bool = null,
|
||||
maximized: ?bool = null,
|
||||
};
|
||||
|
||||
pub const PendingRender = struct {
|
||||
x: ?i32 = null,
|
||||
y: ?i32 = null,
|
||||
|
||||
focused: ?bool = null,
|
||||
};
|
||||
|
||||
pub fn init(window: *Window, context: *Context, river_window_v1: *river.WindowV1) void {
|
||||
window.* = .{
|
||||
.context = context,
|
||||
|
|
@ -61,7 +64,18 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event,
|
|||
var it = window.context.wm.seats.iterator(.forward);
|
||||
while (it.next()) |seat| {
|
||||
if (seat.focused == window) {
|
||||
seat.focused = null;
|
||||
// Find another window to focus and warp pointer there
|
||||
if (window.context.wm.getPrevWindow(window)) |next_focus| {
|
||||
if (next_focus != window) {
|
||||
seat.pending_manage.pending_focus = .{ .window = next_focus };
|
||||
seat.pending_manage.should_warp_pointer = true;
|
||||
} else {
|
||||
// Only window in list - clear focus
|
||||
seat.pending_manage.pending_focus = .clear_focus;
|
||||
}
|
||||
} else {
|
||||
seat.pending_manage.pending_focus = .clear_focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,25 +111,19 @@ pub fn manage(window: *Window) void {
|
|||
}
|
||||
|
||||
// Any new state since the last manage event
|
||||
defer window.pending_state = .{};
|
||||
const pending_state = window.pending_state;
|
||||
defer window.pending_manage = .{};
|
||||
const pending_manage = window.pending_manage;
|
||||
// Layout (pre-computed by WindowManager.calculatePrimaryStackLayout())
|
||||
if (pending_state.width) |new_width| {
|
||||
if (pending_state.height) |new_height| {
|
||||
if (pending_manage.width) |new_width| {
|
||||
if (pending_manage.height) |new_height| {
|
||||
window.width = new_width;
|
||||
window.height = new_height;
|
||||
window.window_v1.proposeDimensions(new_width, new_height);
|
||||
}
|
||||
}
|
||||
if (pending_state.x) |new_x| {
|
||||
window.x = new_x;
|
||||
}
|
||||
if (pending_state.y) |new_y| {
|
||||
window.y = new_y;
|
||||
}
|
||||
|
||||
// Fullscreen and maximize operations
|
||||
if (pending_state.fullscreen) |fullscreen| {
|
||||
if (pending_manage.fullscreen) |fullscreen| {
|
||||
window.fullscreen = fullscreen;
|
||||
if (fullscreen) {
|
||||
const output = window.context.wm.outputs.first() orelse @panic("failed to get output");
|
||||
|
|
@ -126,7 +134,7 @@ pub fn manage(window: *Window) void {
|
|||
window.window_v1.informNotFullscreen();
|
||||
}
|
||||
}
|
||||
if (pending_state.maximized) |maximized| {
|
||||
if (pending_manage.maximized) |maximized| {
|
||||
window.maximized = maximized;
|
||||
if (maximized) {
|
||||
window.window_v1.informMaximized();
|
||||
|
|
@ -137,34 +145,38 @@ pub fn manage(window: *Window) void {
|
|||
}
|
||||
|
||||
pub fn render(window: *Window) void {
|
||||
// Set the window position using the pre-computed layout
|
||||
window.node_v1.setPosition(window.x, window.y);
|
||||
defer window.pending_render = .{};
|
||||
|
||||
// TODO: We probably could just move these back to pending_manage and have PendingRiver.new_coords: bool
|
||||
// This would also simplify the pointer warp behaviour in Seat.manage()
|
||||
if (window.pending_render.x) |new_x| {
|
||||
if (window.pending_render.y) |new_y| {
|
||||
window.x = new_x;
|
||||
window.y = new_y;
|
||||
|
||||
window.node_v1.setPosition(window.x, window.y);
|
||||
} else {
|
||||
log.err("Window.pending_render with only x set", .{});
|
||||
}
|
||||
} else if (window.pending_render.y) |_| {
|
||||
log.err("Window.pending_render with only y set", .{});
|
||||
}
|
||||
|
||||
// Set borders
|
||||
if (!window.fullscreen) {
|
||||
const border_width = window.context.config.border_width;
|
||||
if (window.isFocused()) {
|
||||
const border_color_focused = window.context.config.border_color_focused;
|
||||
window.window_v1.setBorders(.{ .top = true, .bottom = true, .left = true, .right = true }, border_width, border_color_focused.red, border_color_focused.green, border_color_focused.blue, border_color_focused.alpha);
|
||||
} else {
|
||||
const border_color_unfocused = window.context.config.border_color_unfocused;
|
||||
window.window_v1.setBorders(.{ .top = true, .bottom = true, .left = true, .right = true }, border_width, border_color_unfocused.red, border_color_unfocused.green, border_color_unfocused.blue, border_color_unfocused.alpha);
|
||||
if (window.pending_render.focused) |focused| {
|
||||
const border_width = window.context.config.border_width;
|
||||
if (focused) {
|
||||
const border_color_focused = window.context.config.border_color_focused;
|
||||
window.window_v1.setBorders(.{ .top = true, .bottom = true, .left = true, .right = true }, border_width, border_color_focused.red, border_color_focused.green, border_color_focused.blue, border_color_focused.alpha);
|
||||
} else {
|
||||
const border_color_unfocused = window.context.config.border_color_unfocused;
|
||||
window.window_v1.setBorders(.{ .top = true, .bottom = true, .left = true, .right = true }, border_width, border_color_unfocused.red, border_color_unfocused.green, border_color_unfocused.blue, border_color_unfocused.alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Should probably make this better. Shouldn't be too bad since we only have one seat
|
||||
// but there's no reason to do it like this
|
||||
fn isFocused(window: *Window) bool {
|
||||
var it = window.context.wm.seats.iterator(.forward);
|
||||
while (it.next()) |seat| {
|
||||
if (seat.focused == window) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue