diff options
Diffstat (limited to 'src/gui')
| -rw-r--r-- | src/gui/gui.zig | 85 |
1 files changed, 58 insertions, 27 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig index 4ce554f3..590d749d 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -3538,21 +3538,7 @@ fn dispatch(g: *Gui, in: *Input, sev: *const c.SDL_Event) void { }; g.pointer_mapped = true; g.pointer_cell = mc; - const mods = pointerMods(); - in.post(.{ - .mouse = .{ - .button = button, - .kind = if (b.down) .press else .release, - .col = mc.col, - .row = mc.row, - .tag_hit = mc.tag_hit, - .body_hit = mc.body_hit, - .rule_above = mc.rule_above, - .ctrl = mods.ctrl, - .shift = mods.shift, - .alt = mods.alt, - }, - }); + in.post(.{ .mouse = pointerMouse(button, if (b.down) .press else .release, mc, pointerMods()) }); }, c.SDL_EVENT_MOUSE_MOTION => { const m = sev.motion; @@ -3574,18 +3560,7 @@ fn dispatch(g: *Gui, in: *Input, sev: *const c.SDL_Event) void { }; g.pointer_mapped = true; g.pointer_cell = mc; - const mods = pointerMods(); - in.post(.{ .mouse = .{ - .button = held orelse .none, - .kind = if (held != null) .drag else .motion, - .col = mc.col, - .row = mc.row, - .tag_hit = mc.tag_hit, - .body_hit = mc.body_hit, - .ctrl = mods.ctrl, - .shift = mods.shift, - .alt = mods.alt, - } }); + in.post(.{ .mouse = pointerMouse(held orelse .none, if (held != null) .drag else .motion, mc, pointerMods()) }); }, c.SDL_EVENT_MOUSE_WHEEL => { const w = sev.wheel; @@ -3980,6 +3955,22 @@ const WheelTurn = struct { x: f32 = 0, y: f32 = 0, integer_y: i32 = 0, mods: Poi /// The modifiers held with a pointer event, as the core's Mouse carries them. const PointerMods = struct { ctrl: bool = false, shift: bool = false, alt: bool = false }; +/// The core's Mouse for an SDL press, release or move over cell `mc`. +fn pointerMouse(button: pardes.Mouse.Button, kind: pardes.Mouse.Kind, mc: MouseCell, mods: PointerMods) pardes.Mouse { + return .{ + .button = button, + .kind = kind, + .col = mc.col, + .row = mc.row, + .tag_hit = mc.tag_hit, + .body_hit = mc.body_hit, + .rule_above = (kind == .press or kind == .release) and mc.rule_above, + .ctrl = mods.ctrl, + .shift = mods.shift, + .alt = mods.alt, + }; +} + fn pointerMods() PointerMods { const m = c.SDL_GetModState(); return .{ .ctrl = (m & c.SDL_KMOD_CTRL) != 0, .shift = (m & c.SDL_KMOD_SHIFT) != 0, .alt = (m & c.SDL_KMOD_ALT) != 0 }; @@ -4948,6 +4939,46 @@ test "a wheel's notch is whole lines, a touchpad's fraction is not" { try std.testing.expectEqual(@as(?i32, null), notchOf(std.math.nan(f32), 1)); } +test "a click over codex in a terminal reaches its pty with its modifiers; with Shift it is pardes's" { + if (comptime !pardes.panes.terminal.enabled) return error.SkipZigTest; + const gpa = std.testing.allocator; + const core = try pardes.Pardes.init(gpa, .{ .cols = 60, .rows = 16, .tty_only = true }); + defer core.deinit(); + var frame: std.heap.ArenaAllocator = .init(gpa); + defer frame.deinit(); + _ = try core.render(frame.allocator()); + var in: Input = .{ .core = core }; + var sent: std.ArrayList(u8) = .empty; + defer sent.deinit(gpa); + const take = struct { + fn f(core_: *pardes.Pardes, out: *std.ArrayList(u8)) ![]const u8 { + out.clearRetainingCapacity(); + while (core_.nextEffect()) |effect| { + if (effect == .write and effect.write.pane == 0) try out.appendSlice(std.testing.allocator, effect.write.bytes.slice()); + } + return out.items; + } + }.f; + _ = try take(core, &sent); + const pane = core.panes[0].?; + const r = core.rects[0]; + const mc: MouseCell = .{ .col = r.x + config.GUTTER + 5, .row = core.bodyTop(pane, r) + 3 }; + const next: MouseCell = .{ .col = mc.col + 1, .row = mc.row }; + core.update(.{ .output = .{ .pane = 0, .bytes = "\x1b[?1049h\x1b[?1000h\x1b[?1002h\x1b[?1003h\x1b[?1006h" } }); + _ = try take(core, &sent); + in.post(.{ .mouse = pointerMouse(.none, .motion, mc, .{}) }); + try std.testing.expectEqualStrings("\x1b[<35;6;4M", try take(core, &sent)); + in.post(.{ .mouse = pointerMouse(.left, .press, mc, .{ .ctrl = true }) }); + try std.testing.expectEqualStrings("\x1b[<16;6;4M", try take(core, &sent)); + in.post(.{ .mouse = pointerMouse(.left, .drag, next, .{}) }); + try std.testing.expectEqualStrings("\x1b[<32;7;4M", try take(core, &sent)); + in.post(.{ .mouse = pointerMouse(.left, .release, next, .{}) }); + try std.testing.expectEqualStrings("\x1b[<0;7;4m", try take(core, &sent)); + in.post(.{ .mouse = pointerMouse(.middle, .press, mc, .{ .shift = true }) }); + in.post(.{ .mouse = pointerMouse(.middle, .release, mc, .{ .shift = true }) }); + try std.testing.expectEqualStrings("", try take(core, &sent)); +} + test "a wheel over codex in a terminal reaches its pty as the mouse reports it asked for" { if (comptime !pardes.panes.terminal.enabled) return error.SkipZigTest; const gpa = std.testing.allocator; |
