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:
parent
0eaffe120b
commit
3508239bf7
4
area.go
4
area.go
|
@ -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
|
||||
}
|
||||
|
||||
|
|
23
area_unix.go
23
area_unix.go
|
@ -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)
|
||||
|
|
8
todo.md
8
todo.md
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue