diff --git a/area.go b/area.go index 4fca39a..63d4602 100644 --- a/area.go +++ b/area.go @@ -72,7 +72,9 @@ type AreaHandler interface { // MouseEvent contains all the information for a mous event sent by Area.Mouse. // Mouse button IDs start at 1, with 1 being the left mouse button, 2 being the middle mouse button, and 3 being the right mouse button. -// If additional buttons are supported, they will be returned with 4 being the first additional button. The association between button numbers and physical buttons are system-defined. +// If additional buttons are supported, they will be returned with 4 being the first additional button. +// The association between button numbers and physical buttons are system-defined. +// For example, on Windows, buttons 4 and 5 are mapped to what are internally referred to as "XBUTTON1" and "XBUTTON2", which often correspond to the dedicated back/forward navigation buttons on the sides of many mice. // (TODO find out if there's a way to query available button count) type MouseEvent struct { // Pos is the position of the mouse in the Area at the time of the event. diff --git a/area_windows.go b/area_windows.go index 3cd1e75..a7ee44c 100644 --- a/area_windows.go +++ b/area_windows.go @@ -483,7 +483,12 @@ func areaMouseEvent(s *sysData, button uint, up bool, count uint, wparam _WPARAM if button != 3 && (wparam & _MK_RBUTTON) != 0 { me.Held = append(me.Held, 3) } - // TODO XBUTTONs? + if button != 4 && (wparam & _MK_XBUTTON1) != 0 { + me.Held = append(me.Held, 4) + } + if button != 5 && (wparam & _MK_XBUTTON2) != 0 { + me.Held = append(me.Held, 5) + } repaint := s.handler.Mouse(me) if repaint { repaintArea(s) @@ -654,7 +659,18 @@ func areaWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lPara case _WM_RBUTTONUP: areaMouseEvent(s, 3, true, 0, wParam, lParam) return 0 - // TODO XBUTTONs? + case _WM_XBUTTONDOWN: + which := uint((wParam >> 16) & 0xFFFF) + 3 // values start at 1; we want them to start at 4 + areaMouseEvent(s, which, false, 1, wParam, lParam) + return _LRESULT(_TRUE) // XBUTTON messages are different! + case _WM_XBUTTONDBLCLK: + which := uint((wParam >> 16) & 0xFFFF) + 3 + areaMouseEvent(s, which, false, 2, wParam, lParam) + return _LRESULT(_TRUE) + case _WM_XBUTTONUP: + which := uint((wParam >> 16) & 0xFFFF) + 3 + areaMouseEvent(s, which, true, 0, wParam, lParam) + return _LRESULT(_TRUE) case _WM_KEYDOWN: areaKeyEvent(s, false, wParam, lParam) return 0