diff --git a/src/Window.zig b/src/Window.zig index 863c0630c..e992e5e0f 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -754,6 +754,27 @@ fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void { const win = window.getUserPointer(Window) orelse return; + // If we're scrolling up or down, then send a mouse event + if (yoff != 0) { + const pos = window.getCursorPos() catch |err| { + log.err("error reading cursor position: {}", .{err}); + return; + }; + + // NOTE: a limitation of glfw (perhaps) is that we can't detect + // scroll buttons (mouse four/five) WITH modifier state. So we always + // report this as a "press" followed immediately by a release with no + // modifiers. + win.mouseReport(if (yoff < 0) .four else .five, .press, .{}, pos) catch |err| { + log.err("error reporting mouse event: {}", .{err}); + return; + }; + win.mouseReport(if (yoff < 0) .four else .five, .release, .{}, pos) catch |err| { + log.err("error reporting mouse event: {}", .{err}); + return; + }; + } + //log.info("SCROLL: {} {}", .{ xoff, yoff }); _ = xoff; @@ -779,12 +800,10 @@ fn mouseReport( // TODO: posToViewport currently clamps to the window boundary, // do we want to not report mouse events at all outside the window? - assert(self.terminal.modes.mouse_event != .none); - - _ = mods; - // Depending on the event, we may do nothing at all. switch (self.terminal.modes.mouse_event) { + .none => return, + // X10 only reports clicks with mouse button 1, 2, 3. We verify // the button later. .x10 => if (action != .press or @@ -794,20 +813,21 @@ fn mouseReport( // Everything .normal => {}, + else => {}, } switch (self.terminal.modes.mouse_format) { .x10 => { const button_code: u8 = code: { - var acc: u8 = if (action == .press) switch (button) { + var acc: u8 = if (action == .press) @as(u8, switch (button) { .left => 0, .right => 1, .middle => 2, .four => 64, .five => 65, else => return, // unsupported - } else 3; // release is always 3 + }) else 3; // release is always 3 // Normal mode adds in modifiers if (self.terminal.modes.mouse_event == .normal) { diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 6dd77b585..e9d77c05a 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -83,10 +83,10 @@ modes: packed struct { /// These are all mutually exclusive (hence in a single enum). pub const MouseEvents = enum(u3) { none = 0, - - // TODO: x10 = 1, // 9 normal = 2, // 1000 + + // TODO: button = 3, // 1002 any = 4, // 1003 }; @@ -94,8 +94,9 @@ pub const MouseEvents = enum(u3) { /// The format of mouse events when enabled. /// These are all mutually exclusive (hence in a single enum). pub const MouseFormat = enum(u3) { - // TODO: x10 = 0, + + // TODO: utf8 = 1, // 1005 sgr = 2, // 1006 urxvt = 3, // 1015