any event mouse tracking

This commit is contained in:
Mitchell Hashimoto
2022-08-26 14:26:42 -07:00
parent bd5dd69538
commit ab305add6c
3 changed files with 39 additions and 30 deletions

View File

@ -792,7 +792,7 @@ const MouseReportAction = enum { press, release, motion };
fn mouseReport( fn mouseReport(
self: *Window, self: *Window,
button: input.MouseButton, button: ?input.MouseButton,
action: MouseReportAction, action: MouseReportAction,
mods: input.Mods, mods: input.Mods,
unscaled_pos: glfw.Window.CursorPos, unscaled_pos: glfw.Window.CursorPos,
@ -807,17 +807,19 @@ fn mouseReport(
// X10 only reports clicks with mouse button 1, 2, 3. We verify // X10 only reports clicks with mouse button 1, 2, 3. We verify
// the button later. // the button later.
.x10 => if (action != .press or .x10 => if (action != .press or
!(button == .left or button == null or
button == .right or !(button.? == .left or
button == .middle)) return, button.? == .right or
button.? == .middle)) return,
// Doesn't report motion // Doesn't report motion
.normal => if (action == .motion) return, .normal => if (action == .motion) return,
// Everything // Button must be pressed
.button => {}, .button => if (button == null) return,
else => unreachable, // Everything
.any => {},
} }
switch (self.terminal.modes.mouse_format) { switch (self.terminal.modes.mouse_format) {
@ -831,7 +833,9 @@ fn mouseReport(
} }
// For button events, we only report if we moved cells // For button events, we only report if we moved cells
if (self.terminal.modes.mouse_event == .button) { if (self.terminal.modes.mouse_event == .button or
self.terminal.modes.mouse_event == .any)
{
if (self.mouse.event_point.x == viewport_point.x and if (self.mouse.event_point.x == viewport_point.x and
self.mouse.event_point.y == viewport_point.y) return; self.mouse.event_point.y == viewport_point.y) return;
@ -840,14 +844,17 @@ fn mouseReport(
} }
const button_code: u8 = code: { const button_code: u8 = code: {
var acc: u8 = if (action == .release) 3 else @as(u8, switch (button) { var acc: u8 = if (action == .release or button == null)
.left => 0, 3
.right => 1, else
.middle => 2, @as(u8, switch (button.?) {
.four => 64, .left => 0,
.five => 65, .right => 1,
else => return, // unsupported .middle => 2,
}); .four => 64,
.five => 65,
else => return, // unsupported
});
// X10 doesn't have modifiers // X10 doesn't have modifiers
if (self.terminal.modes.mouse_event != .x10) { if (self.terminal.modes.mouse_event != .x10) {
@ -965,24 +972,23 @@ fn cursorPosCallback(
const win = window.getUserPointer(Window) orelse return; const win = window.getUserPointer(Window) orelse return;
// Do a mouse report // Do a mouse report
if (win.terminal.modes.mouse_event == .button) { if (win.terminal.modes.mouse_event == .button or
win.terminal.modes.mouse_event == .any)
{
// We use the first mouse button we find pressed in order to report // We use the first mouse button we find pressed in order to report
// since the spec (afaict) does not say... // since the spec (afaict) does not say...
const button_: ?input.MouseButton = button: for (win.mouse.click_state) |state, i| { const button: ?input.MouseButton = button: for (win.mouse.click_state) |state, i| {
if (state == .press) if (state == .press)
break :button @intToEnum(input.MouseButton, i); break :button @intToEnum(input.MouseButton, i);
} else null; } else null;
// A button must be pressed. win.mouseReport(button, .motion, win.mouse.mods, .{
if (button_) |button| { .xpos = unscaled_xpos,
win.mouseReport(button, .motion, win.mouse.mods, .{ .ypos = unscaled_ypos,
.xpos = unscaled_xpos, }) catch |err| {
.ypos = unscaled_ypos, log.err("error reporting mouse event: {}", .{err});
}) catch |err| { return;
log.err("error reporting mouse event: {}", .{err}); };
return;
};
}
// If we're doing mouse motion tracking, we do not support text // If we're doing mouse motion tracking, we do not support text
// selection. // selection.
@ -1446,6 +1452,7 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void {
.mouse_event_x10 => self.terminal.modes.mouse_event = if (enabled) .x10 else .none, .mouse_event_x10 => self.terminal.modes.mouse_event = if (enabled) .x10 else .none,
.mouse_event_normal => self.terminal.modes.mouse_event = if (enabled) .normal else .none, .mouse_event_normal => self.terminal.modes.mouse_event = if (enabled) .normal else .none,
.mouse_event_button => self.terminal.modes.mouse_event = if (enabled) .button else .none, .mouse_event_button => self.terminal.modes.mouse_event = if (enabled) .button else .none,
.mouse_event_any => self.terminal.modes.mouse_event = if (enabled) .any else .none,
else => if (enabled) log.warn("unimplemented mode: {}", .{mode}), else => if (enabled) log.warn("unimplemented mode: {}", .{mode}),
} }

View File

@ -86,8 +86,6 @@ pub const MouseEvents = enum(u3) {
x10 = 1, // 9 x10 = 1, // 9
normal = 2, // 1000 normal = 2, // 1000
button = 3, // 1002 button = 3, // 1002
// TODO:
any = 4, // 1003 any = 4, // 1003
}; };

View File

@ -76,6 +76,10 @@ pub const Mode = enum(u16) {
/// while the button is pressed when the cell in the grid changes. /// while the button is pressed when the cell in the grid changes.
mouse_event_button = 1002, mouse_event_button = 1002,
/// Same as button mode but doesn't require a button to be pressed
/// to track mouse movement.
mouse_event_any = 1003,
/// Alternate screen mode with save cursor and clear on enter. /// Alternate screen mode with save cursor and clear on enter.
alt_screen_save_cursor_clear_enter = 1049, alt_screen_save_cursor_clear_enter = 1049,