Rework focus-follows-cursor to work with warp
When focus-follows-cursor is used with cursor-warp, some windows will get focus before the cursor properly "enters" the window since they have a larger input-region than their window geometry, this causes the cursor to be yanked to the middle unexpectedly. This fix makes it so the focus is only given when the cursor enters the window geometry.
This commit is contained in:
parent
2c86c2b6e5
commit
931405abe4
@ -112,6 +112,8 @@ hide_cursor_timer: *wl.EventSource,
|
||||
hidden: bool = false,
|
||||
may_need_warp: bool = false,
|
||||
|
||||
last_focus_follows_cursor_target: ?*View = null,
|
||||
|
||||
/// Keeps track of the last known location of all touch points in layout coordinates.
|
||||
/// This information is necessary for proper touch dnd support if there are multiple touch points.
|
||||
touch_points: std.AutoHashMapUnmanaged(i32, LayoutPoint) = .{},
|
||||
@ -1049,21 +1051,33 @@ pub fn checkFocusFollowsCursor(self: *Self) void {
|
||||
if (self.seat.drag == .pointer) return;
|
||||
if (server.config.focus_follows_cursor == .disabled) return;
|
||||
if (self.surfaceAt()) |result| {
|
||||
if (server.config.focus_follows_cursor == .always or
|
||||
self.seat.wlr_seat.pointer_state.focused_surface != result.surface)
|
||||
{
|
||||
switch (result.parent) {
|
||||
.view => |view| {
|
||||
if (self.seat.focused != .view or self.seat.focused.view != view) {
|
||||
self.seat.focusOutput(view.output);
|
||||
self.seat.focus(view);
|
||||
server.root.startTransaction();
|
||||
}
|
||||
},
|
||||
.layer_surface, .lock_surface => {},
|
||||
.xwayland_override_redirect => assert(build_options.xwayland),
|
||||
}
|
||||
switch (result.parent) {
|
||||
.view => |view| {
|
||||
// Don't re-focus the last focused view when the mode is .normal
|
||||
if (server.config.focus_follows_cursor == .normal and
|
||||
self.last_focus_follows_cursor_target == view) return;
|
||||
// Some windows have a input region bigger than their window
|
||||
// geometry, we only want to move focus when the cursor
|
||||
// properly enters the window (the box that we draw borders around)
|
||||
var output_layout_box: wlr.Box = undefined;
|
||||
server.root.output_layout.getBox(view.output.wlr_output, &output_layout_box);
|
||||
const cursor_ox = self.wlr_cursor.x - @intToFloat(f64, output_layout_box.x);
|
||||
const cursor_oy = self.wlr_cursor.y - @intToFloat(f64, output_layout_box.y);
|
||||
if ((self.seat.focused != .view or self.seat.focused.view != view) and
|
||||
view.current.box.containsPoint(cursor_ox, cursor_oy))
|
||||
{
|
||||
self.seat.focusOutput(view.output);
|
||||
self.seat.focus(view);
|
||||
self.last_focus_follows_cursor_target = view;
|
||||
server.root.startTransaction();
|
||||
}
|
||||
},
|
||||
.layer_surface, .lock_surface => {},
|
||||
.xwayland_override_redirect => assert(build_options.xwayland),
|
||||
}
|
||||
} else {
|
||||
// The cursor is not above any view, so clear the last followed check
|
||||
self.last_focus_follows_cursor_target = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user