Surface: ensure keyToMouseShape respects hidden state

This fixes keyToMouseShape (the new handler for mouse shape state for
key combinations, e.g. during mouse tracking override or rectangle
select) so that it respects whether or not the mouse is currently
hidden, and will not send back a shape to change the mouse to in these
situations.

Fixes #1107.
This commit is contained in:
Chris Marchesi
2023-12-16 22:21:44 -08:00
parent ec2bc74a22
commit a6aad756e5
2 changed files with 34 additions and 3 deletions

View File

@ -1294,6 +1294,7 @@ pub fn keyCallback(
.mouse_shape = self.io.terminal.mouse_shape, .mouse_shape = self.io.terminal.mouse_shape,
.mods = self.mouse.mods, .mods = self.mouse.mods,
.over_link = self.mouse.over_link, .over_link = self.mouse.over_link,
.hidden = self.mouse.hidden,
}).keyToMouseShape()) |shape| }).keyToMouseShape()) |shape|
try self.rt_surface.setMouseShape(shape); try self.rt_surface.setMouseShape(shape);

View File

@ -29,6 +29,9 @@ mods: input.Mods,
/// True if the mouse position is currently over a link. /// True if the mouse position is currently over a link.
over_link: bool, over_link: bool,
/// True if the mouse pointer is currently hidden.
hidden: bool,
/// Translates key state to mouse shape (cursor) state, based on a state /// Translates key state to mouse shape (cursor) state, based on a state
/// machine. /// machine.
/// ///
@ -52,11 +55,11 @@ pub fn keyToMouseShape(self: SurfaceMouse) ?MouseShape {
// Filter for appropriate key events // Filter for appropriate key events
if (!eligibleMouseShapeKeyEvent(self.physical_key)) return null; if (!eligibleMouseShapeKeyEvent(self.physical_key)) return null;
// Exception: link hover overrides any other shape processing currently and // Exceptions: link hover or hidden state overrides any other shape
// does not change state. // processing and does not change state.
// //
// TODO: As we unravel mouse state, we can fix this to be more explicit. // TODO: As we unravel mouse state, we can fix this to be more explicit.
if (self.over_link) { if (self.over_link or self.hidden) {
return null; return null;
} }
@ -129,6 +132,7 @@ test "keyToMouseShape" {
.mouse_shape = .progress, .mouse_shape = .progress,
.mods = .{}, .mods = .{},
.over_link = false, .over_link = false,
.hidden = false,
}; };
const got = m.keyToMouseShape(); const got = m.keyToMouseShape();
@ -144,6 +148,22 @@ test "keyToMouseShape" {
.mouse_shape = .progress, .mouse_shape = .progress,
.mods = .{}, .mods = .{},
.over_link = true, .over_link = true,
.hidden = false,
};
const got = m.keyToMouseShape();
try testing.expect(got == null);
}
{
// Mouse is currently hidden
const m: SurfaceMouse = .{
.physical_key = .left_shift,
.mouse_event = .none,
.mouse_shape = .progress,
.mods = .{},
.over_link = true,
.hidden = true,
}; };
const got = m.keyToMouseShape(); const got = m.keyToMouseShape();
@ -158,6 +178,7 @@ test "keyToMouseShape" {
.mouse_shape = .default, .mouse_shape = .default,
.mods = .{}, .mods = .{},
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .default; const want: MouseShape = .default;
@ -173,6 +194,7 @@ test "keyToMouseShape" {
.mouse_shape = .default, .mouse_shape = .default,
.mods = .{ .ctrl = true, .super = true, .alt = true, .shift = true }, .mods = .{ .ctrl = true, .super = true, .alt = true, .shift = true },
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .crosshair; const want: MouseShape = .crosshair;
@ -188,6 +210,7 @@ test "keyToMouseShape" {
.mouse_shape = .default, .mouse_shape = .default,
.mods = .{ .shift = true }, .mods = .{ .shift = true },
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .text; const want: MouseShape = .text;
@ -203,6 +226,7 @@ test "keyToMouseShape" {
.mouse_shape = .crosshair, .mouse_shape = .crosshair,
.mods = .{ .shift = true }, .mods = .{ .shift = true },
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .text; const want: MouseShape = .text;
@ -218,6 +242,7 @@ test "keyToMouseShape" {
.mouse_shape = .crosshair, .mouse_shape = .crosshair,
.mods = .{}, .mods = .{},
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .default; const want: MouseShape = .default;
@ -233,6 +258,7 @@ test "keyToMouseShape" {
.mouse_shape = .text, .mouse_shape = .text,
.mods = .{ .ctrl = true, .super = true, .alt = true, .shift = true }, .mods = .{ .ctrl = true, .super = true, .alt = true, .shift = true },
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .crosshair; const want: MouseShape = .crosshair;
@ -248,6 +274,7 @@ test "keyToMouseShape" {
.mouse_shape = .text, .mouse_shape = .text,
.mods = .{}, .mods = .{},
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .default; const want: MouseShape = .default;
@ -263,6 +290,7 @@ test "keyToMouseShape" {
.mouse_shape = .text, .mouse_shape = .text,
.mods = .{}, .mods = .{},
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .text; const want: MouseShape = .text;
@ -278,6 +306,7 @@ test "keyToMouseShape" {
.mouse_shape = .text, .mouse_shape = .text,
.mods = .{ .ctrl = true, .super = true, .alt = true }, .mods = .{ .ctrl = true, .super = true, .alt = true },
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .crosshair; const want: MouseShape = .crosshair;
@ -293,6 +322,7 @@ test "keyToMouseShape" {
.mouse_shape = .crosshair, .mouse_shape = .crosshair,
.mods = .{}, .mods = .{},
.over_link = false, .over_link = false,
.hidden = false,
}; };
const want: MouseShape = .text; const want: MouseShape = .text;