diff --git a/src/Window.zig b/src/Window.zig index 13d8c8aea..ce1c99b30 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -792,7 +792,7 @@ const MouseReportAction = enum { press, release, motion }; fn mouseReport( self: *Window, - button: input.MouseButton, + button: ?input.MouseButton, action: MouseReportAction, mods: input.Mods, unscaled_pos: glfw.Window.CursorPos, @@ -807,17 +807,19 @@ fn mouseReport( // X10 only reports clicks with mouse button 1, 2, 3. We verify // the button later. .x10 => if (action != .press or - !(button == .left or - button == .right or - button == .middle)) return, + button == null or + !(button.? == .left or + button.? == .right or + button.? == .middle)) return, // Doesn't report motion .normal => if (action == .motion) return, - // Everything - .button => {}, + // Button must be pressed + .button => if (button == null) return, - else => unreachable, + // Everything + .any => {}, } switch (self.terminal.modes.mouse_format) { @@ -831,7 +833,9 @@ fn mouseReport( } // 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 self.mouse.event_point.y == viewport_point.y) return; @@ -840,14 +844,17 @@ fn mouseReport( } const button_code: u8 = code: { - var acc: u8 = if (action == .release) 3 else @as(u8, switch (button) { - .left => 0, - .right => 1, - .middle => 2, - .four => 64, - .five => 65, - else => return, // unsupported - }); + var acc: u8 = if (action == .release or button == null) + 3 + else + @as(u8, switch (button.?) { + .left => 0, + .right => 1, + .middle => 2, + .four => 64, + .five => 65, + else => return, // unsupported + }); // X10 doesn't have modifiers if (self.terminal.modes.mouse_event != .x10) { @@ -965,24 +972,23 @@ fn cursorPosCallback( const win = window.getUserPointer(Window) orelse return; // 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 // 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) break :button @intToEnum(input.MouseButton, i); } else null; - // A button must be pressed. - if (button_) |button| { - win.mouseReport(button, .motion, win.mouse.mods, .{ - .xpos = unscaled_xpos, - .ypos = unscaled_ypos, - }) catch |err| { - log.err("error reporting mouse event: {}", .{err}); - return; - }; - } + win.mouseReport(button, .motion, win.mouse.mods, .{ + .xpos = unscaled_xpos, + .ypos = unscaled_ypos, + }) catch |err| { + log.err("error reporting mouse event: {}", .{err}); + return; + }; // If we're doing mouse motion tracking, we do not support text // 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_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_any => self.terminal.modes.mouse_event = if (enabled) .any else .none, else => if (enabled) log.warn("unimplemented mode: {}", .{mode}), } diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 75f739866..b06f1bf9c 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -86,8 +86,6 @@ pub const MouseEvents = enum(u3) { x10 = 1, // 9 normal = 2, // 1000 button = 3, // 1002 - - // TODO: any = 4, // 1003 }; diff --git a/src/terminal/ansi.zig b/src/terminal/ansi.zig index cfb56a91d..9cc46c679 100644 --- a/src/terminal/ansi.zig +++ b/src/terminal/ansi.zig @@ -76,6 +76,10 @@ pub const Mode = enum(u16) { /// while the button is pressed when the cell in the grid changes. 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. alt_screen_save_cursor_clear_enter = 1049,