macos: support mouse buttons 8/9 (back/forward) (#10381)

Add support for mouse buttons 4-11 in the macOS app. Previously only
left, right, and middle buttons were handled. Now otherMouseDown/Up
events properly map NSEvent.buttonNumber to the corresponding Ghostty
mouse button, enabling back/forward button support.

Fixes: https://github.com/ghostty-org/ghostty/issues/2425
Amp-Thread-ID:
https://ampcode.com/threads/T-019bd74e-6b2b-731d-b43a-ac73b3460c32
This commit is contained in:
Mitchell Hashimoto
2026-01-19 12:08:38 -08:00
committed by GitHub
3 changed files with 47 additions and 4 deletions

View File

@@ -66,6 +66,14 @@ typedef enum {
GHOSTTY_MOUSE_LEFT,
GHOSTTY_MOUSE_RIGHT,
GHOSTTY_MOUSE_MIDDLE,
GHOSTTY_MOUSE_FOUR,
GHOSTTY_MOUSE_FIVE,
GHOSTTY_MOUSE_SIX,
GHOSTTY_MOUSE_SEVEN,
GHOSTTY_MOUSE_EIGHT,
GHOSTTY_MOUSE_NINE,
GHOSTTY_MOUSE_TEN,
GHOSTTY_MOUSE_ELEVEN,
} ghostty_input_mouse_button_e;
typedef enum {

View File

@@ -370,6 +370,14 @@ extension Ghostty.Input {
case left
case right
case middle
case four
case five
case six
case seven
case eight
case nine
case ten
case eleven
var cMouseButton: ghostty_input_mouse_button_e {
switch self {
@@ -377,6 +385,33 @@ extension Ghostty.Input {
case .left: GHOSTTY_MOUSE_LEFT
case .right: GHOSTTY_MOUSE_RIGHT
case .middle: GHOSTTY_MOUSE_MIDDLE
case .four: GHOSTTY_MOUSE_FOUR
case .five: GHOSTTY_MOUSE_FIVE
case .six: GHOSTTY_MOUSE_SIX
case .seven: GHOSTTY_MOUSE_SEVEN
case .eight: GHOSTTY_MOUSE_EIGHT
case .nine: GHOSTTY_MOUSE_NINE
case .ten: GHOSTTY_MOUSE_TEN
case .eleven: GHOSTTY_MOUSE_ELEVEN
}
}
/// Initialize from NSEvent.buttonNumber
/// NSEvent buttonNumber: 0=left, 1=right, 2=middle, 3=back (button 8), 4=forward (button 9), etc.
init(fromNSEventButtonNumber buttonNumber: Int) {
switch buttonNumber {
case 0: self = .left
case 1: self = .right
case 2: self = .middle
case 3: self = .eight // Back button
case 4: self = .nine // Forward button
case 5: self = .six
case 6: self = .seven
case 7: self = .four
case 8: self = .five
case 9: self = .ten
case 10: self = .eleven
default: self = .unknown
}
}
}

View File

@@ -860,16 +860,16 @@ extension Ghostty {
override func otherMouseDown(with event: NSEvent) {
guard let surface = self.surface else { return }
guard event.buttonNumber == 2 else { return }
let mods = Ghostty.ghosttyMods(event.modifierFlags)
ghostty_surface_mouse_button(surface, GHOSTTY_MOUSE_PRESS, GHOSTTY_MOUSE_MIDDLE, mods)
let button = Ghostty.Input.MouseButton(fromNSEventButtonNumber: event.buttonNumber)
ghostty_surface_mouse_button(surface, GHOSTTY_MOUSE_PRESS, button.cMouseButton, mods)
}
override func otherMouseUp(with event: NSEvent) {
guard let surface = self.surface else { return }
guard event.buttonNumber == 2 else { return }
let mods = Ghostty.ghosttyMods(event.modifierFlags)
ghostty_surface_mouse_button(surface, GHOSTTY_MOUSE_RELEASE, GHOSTTY_MOUSE_MIDDLE, mods)
let button = Ghostty.Input.MouseButton(fromNSEventButtonNumber: event.buttonNumber)
ghostty_surface_mouse_button(surface, GHOSTTY_MOUSE_RELEASE, button.cMouseButton, mods)
}