From 03f37087a5e24a76b02404da439ccc6fb7f3da76 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 30 Jun 2024 09:40:06 -0700 Subject: [PATCH] mouse button callbacks returns bool for consumption --- include/ghostty.h | 2 +- .../Sources/Ghostty/SurfaceView_AppKit.swift | 37 +++++++++++++++++-- src/Surface.zig | 19 ++++++---- src/apprt/embedded.zig | 10 ++--- src/apprt/glfw.zig | 2 +- 5 files changed, 52 insertions(+), 18 deletions(-) diff --git a/include/ghostty.h b/include/ghostty.h index e3a9e4223..2f1ce04a3 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -533,7 +533,7 @@ ghostty_input_mods_e ghostty_surface_key_translation_mods(ghostty_surface_t, ghostty_input_mods_e); void ghostty_surface_key(ghostty_surface_t, ghostty_input_key_s); void ghostty_surface_text(ghostty_surface_t, const char*, uintptr_t); -void ghostty_surface_mouse_button(ghostty_surface_t, +bool ghostty_surface_mouse_button(ghostty_surface_t, ghostty_input_mouse_state_e, ghostty_input_mouse_button_e, ghostty_input_mods_e); diff --git a/macos/Sources/Ghostty/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/SurfaceView_AppKit.swift index f41a01d57..47641875a 100644 --- a/macos/Sources/Ghostty/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/SurfaceView_AppKit.swift @@ -471,15 +471,39 @@ extension Ghostty { override func rightMouseDown(with event: NSEvent) { - guard let surface = self.surface else { return } + guard let surface = self.surface else { return super.rightMouseDown(with: event) } + let mods = Ghostty.ghosttyMods(event.modifierFlags) - ghostty_surface_mouse_button(surface, GHOSTTY_MOUSE_PRESS, GHOSTTY_MOUSE_RIGHT, mods) + if (ghostty_surface_mouse_button( + surface, + GHOSTTY_MOUSE_PRESS, + GHOSTTY_MOUSE_RIGHT, + mods + )) { + // Consumed + return + } + + // Mouse event not consumed + super.rightMouseDown(with: event) } override func rightMouseUp(with event: NSEvent) { - guard let surface = self.surface else { return } + guard let surface = self.surface else { return super.rightMouseUp(with: event) } + let mods = Ghostty.ghosttyMods(event.modifierFlags) - ghostty_surface_mouse_button(surface, GHOSTTY_MOUSE_RELEASE, GHOSTTY_MOUSE_RIGHT, mods) + if (ghostty_surface_mouse_button( + surface, + GHOSTTY_MOUSE_RELEASE, + GHOSTTY_MOUSE_RIGHT, + mods + )) { + // Handled + return + } + + // Mouse event not consumed + super.rightMouseUp(with: event) } override func mouseMoved(with event: NSEvent) { @@ -842,6 +866,11 @@ extension Ghostty { ghostty_surface_key(surface, key_ev) } } + + override func menu(for event: NSEvent) -> NSMenu? { + Ghostty.logger.warning("menu: event!") + return nil + } // MARK: Menu Handlers diff --git a/src/Surface.zig b/src/Surface.zig index a4557be78..34042c2e2 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -2129,12 +2129,15 @@ fn mouseShiftCapture(self: *const Surface, lock: bool) bool { }; } +/// Called for mouse button press/release events. This will return true +/// if the mouse event was consumed in some way (i.e. the program is capturing +/// mouse events). If the event was not consumed, then false is returned. pub fn mouseButtonCallback( self: *Surface, action: input.MouseButtonState, button: input.MouseButton, mods: input.Mods, -) !void { +) !bool { // log.debug("mouse action={} button={} mods={}", .{ action, button, mods }); // If we have an inspector, we always queue a render @@ -2155,7 +2158,7 @@ pub fn mouseButtonCallback( const screen = &self.renderer_state.terminal.screen; const p = screen.pages.pin(.{ .viewport = point }) orelse { log.warn("failed to get pin for clicked point", .{}); - return; + return false; }; insp.cell.select( @@ -2166,7 +2169,7 @@ pub fn mouseButtonCallback( ) catch |err| { log.warn("error selecting cell for inspector err={}", .{err}); }; - return; + return false; } } @@ -2205,7 +2208,7 @@ pub fn mouseButtonCallback( if (selection) { const pos = try self.rt_surface.getCursorPos(); try self.cursorPosCallback(pos); - return; + return true; } } } @@ -2216,7 +2219,7 @@ pub fn mouseButtonCallback( if (button == .left and action == .release and self.mouse.over_link) { const pos = try self.rt_surface.getCursorPos(); if (self.processLinks(pos)) |processed| { - if (processed) return; + if (processed) return true; } else |err| { log.warn("error processing links err={}", .{err}); } @@ -2257,7 +2260,7 @@ pub fn mouseButtonCallback( // If we're doing mouse reporting, we do not support any other // selection or highlighting. - return; + return true; } } @@ -2269,7 +2272,7 @@ pub fn mouseButtonCallback( self.renderer_state.mutex.lock(); defer self.renderer_state.mutex.unlock(); try self.clickMoveCursor(pin.*); - return; + return true; } // For left button clicks we always record some information for @@ -2398,6 +2401,8 @@ pub fn mouseButtonCallback( try self.startClipboardRequest(clipboard, .{ .paste = {} }); } } + + return false; } /// Performs the "click-to-move" logic to move the cursor to the given diff --git a/src/apprt/embedded.zig b/src/apprt/embedded.zig index 0ab955206..8507b9835 100644 --- a/src/apprt/embedded.zig +++ b/src/apprt/embedded.zig @@ -710,10 +710,10 @@ pub const Surface = struct { action: input.MouseButtonState, button: input.MouseButton, mods: input.Mods, - ) void { - self.core_surface.mouseButtonCallback(action, button, mods) catch |err| { + ) bool { + return self.core_surface.mouseButtonCallback(action, button, mods) catch |err| { log.err("error in mouse button callback err={}", .{err}); - return; + return false; }; } @@ -1638,8 +1638,8 @@ pub const CAPI = struct { action: input.MouseButtonState, button: input.MouseButton, mods: c_int, - ) void { - surface.mouseButtonCallback( + ) bool { + return surface.mouseButtonCallback( action, button, @bitCast(@as( diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index 932e27de5..911eb6f5e 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -1048,7 +1048,7 @@ pub const Surface = struct { else => unreachable, }; - core_win.mouseButtonCallback(action, button, mods) catch |err| { + _ = core_win.mouseButtonCallback(action, button, mods) catch |err| { log.err("error in scroll callback err={}", .{err}); return; };