Completed extending of mouse buttons to the system's limit; defined (as undefined) the mouse drag behavior for buttons >= 3; implemented all that on the GTK+ side, and decided to have MouseEvents.Held[] be sorted (documentation only for now; need to check the code to make sure it follows). Good Lord...

This commit is contained in:
Pietro Gagliardi 2014-05-07 17:51:04 -04:00
parent 0eaffe120b
commit 3508239bf7
3 changed files with 19 additions and 16 deletions

View File

@ -73,6 +73,7 @@ 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.
// For example, on Unix systems where mouse buttons 4 through 7 are pseudobuttons for the scroll wheel directions, the next button, button 8, will be returned as 4, 9 as 5, etc.
// 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.
// The examples here are NOT a guarantee as to how many buttons maximum will be available on a given system.
@ -103,7 +104,8 @@ type MouseEvent struct {
// Held is a slice of button IDs that indicate which mouse buttons are being held during the event.
// Held will not include Down and Up.
// (TODO "There is no guarantee that Held is sorted."?)
// Held will be sorted.
// Only buttons 1, 2, and 3 are guaranteed to be detected by Held properly; whether or not any others are is implementation-defined.
Held []uint
}

View File

@ -108,6 +108,10 @@ func makeModifiers(state C.guint, m Modifiers) Modifiers {
func finishMouseEvent(widget *C.GtkWidget, data C.gpointer, me MouseEvent, mb uint, x C.gdouble, y C.gdouble, state C.guint, gdkwindow *C.GdkWindow) {
var areawidth, areaheight C.gint
// on GTK+, mouse buttons 4-7 are for scrolling; if we got here, that's a mistake (and see the TODOs on return values below)
if mb >= 4 && mb <= 7 {
return
}
s := (*sysData)(unsafe.Pointer(data))
state = translateModifiers(state, gdkwindow)
me.Modifiers = makeModifiers(state, 0)
@ -121,18 +125,19 @@ func finishMouseEvent(widget *C.GtkWidget, data C.gpointer, me MouseEvent, mb ui
if mb != 3 && (state & C.GDK_BUTTON3_MASK) != 0 {
me.Held = append(me.Held, 3)
}
// TODO keep?
if mb != 4 && (state & C.GDK_BUTTON4_MASK) != 0 {
me.Held = append(me.Held, 4)
}
if mb != 5 && (state & C.GDK_BUTTON5_MASK) != 0 {
me.Held = append(me.Held, 5)
}
// don't check GDK_BUTTON4_MASK or GDK_BUTTON5_MASK because those are for the scrolling buttons mentioned above; there doesn't seem to be a way to detect higher buttons... (TODO)
me.Pos = image.Pt(int(x), int(y))
C.gtk_widget_get_size_request(widget, &areawidth, &areaheight)
if !me.Pos.In(image.Rect(0, 0, int(areawidth), int(areaheight))) { // outside the actual Area; no event
return
}
// and finally, if the button ID >= 8, continue counting from 4, as above and as in the MouseEvent spec
if me.Down >= 8 {
me.Down -= 4
}
if me.Up >= 8 {
me.Up -= 4
}
repaint := s.handler.Mouse(me)
if repaint {
C.gtk_widget_queue_draw(widget)
@ -145,7 +150,7 @@ func our_area_button_press_event_callback(widget *C.GtkWidget, event *C.GdkEvent
C.gtk_widget_grab_focus(widget)
e := (*C.GdkEventButton)(unsafe.Pointer(event))
me := MouseEvent{
// GDK button ID == our button ID
// GDK button ID == our button ID with some exceptions taken care of by finishMouseEvent()
Down: uint(e.button),
}
switch e._type {
@ -166,7 +171,7 @@ var area_button_press_event_callback = C.GCallback(C.our_area_button_press_event
func our_area_button_release_event_callback(widget *C.GtkWidget, event *C.GdkEvent, data C.gpointer) C.gboolean {
e := (*C.GdkEventButton)(unsafe.Pointer(event))
me := MouseEvent{
// GDK button ID == our button ID
// GDK button ID == our button ID with some exceptions taken care of by finishMouseEvent()
Up: uint(e.button),
}
finishMouseEvent(widget, data, me, me.Up, e.x, e.y, e.state, e.window)

View File

@ -13,12 +13,8 @@ super ultra important things:
- OS X: handle Insert/Help key change in a sane and deterministic way
- will need old and new Mac keyboards...
- make sure MouseEvent's documentation has dragging described correctly (both Windows and GTK+ do)
- fix OS X so that it follows these rules
- native Windows (not wine) and OS X don't respond to mouse button 4 and 5 drags?!
[16:45] <JeffLaptop> no, just tried, and the navigation buttons don't.
[16:45] <andlabs> ok, thanks a lot
[16:45] <JeffLaptop> only the l, m, and r ones do.
- oh...
- figure out what to do about dragging into or out of a window; will likely need to be undefined as well...
- double-check to make sure MouseEvent.Held[] is sorted on all platforms
- cap click count to 2 on all platforms
- the windows build appears to be unstable:
- 64-bit crashes in malloc in wine with heap corruption warnings aplenty during DLL loading; in windows 7 it works fine