Added a flag to AreaHandler.Key()/Mouse() to indicate that a repaint is needed after that event has been handled. (Having Repaint() as a method deadlocked for the same reason resizing deadlocked before.)
This commit is contained in:
parent
9dc4f8694c
commit
ab6e7121e4
25
area.go
25
area.go
|
@ -52,13 +52,15 @@ type AreaHandler interface {
|
||||||
// Mouse is called when the Area receives a mouse event.
|
// Mouse is called when the Area receives a mouse event.
|
||||||
// You are allowed to do nothing in this handler (to ignore mouse events).
|
// You are allowed to do nothing in this handler (to ignore mouse events).
|
||||||
// See MouseEvent for details.
|
// See MouseEvent for details.
|
||||||
Mouse(e MouseEvent)
|
// If repaint is true, the Area is marked as needing to be redrawn.
|
||||||
|
Mouse(e MouseEvent) (repaint bool)
|
||||||
|
|
||||||
// Key is called when the Area receives a keyboard event.
|
// Key is called when the Area receives a keyboard event.
|
||||||
// You are allowed to do nothing except return false in this handler (to ignore keyboard events).
|
// You are allowed to do nothing except return false for handled in this handler (to ignore keyboard events).
|
||||||
// Do not do nothing but return true; this may have unintended consequences.
|
// Do not do nothing but return true for handled; this may have unintended consequences.
|
||||||
// See KeyEvent for details.
|
// See KeyEvent for details.
|
||||||
Key(e KeyEvent) bool
|
// If repaint is true, the Area is marked as needing to be redrawn.
|
||||||
|
Key(e KeyEvent) (handled bool, repaint bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MouseEvent contains all the information for a mous event sent by Area.Mouse.
|
// MouseEvent contains all the information for a mous event sent by Area.Mouse.
|
||||||
|
@ -116,16 +118,17 @@ func (e MouseEvent) HeldBits() (h uintptr) {
|
||||||
//
|
//
|
||||||
// When you are finished processing the incoming event,
|
// When you are finished processing the incoming event,
|
||||||
// return whether or not you did something in response
|
// return whether or not you did something in response
|
||||||
// to the given keystroke from your Key() implementation.
|
// to the given keystroke as the handled return of your
|
||||||
// If you send false, you indicate that you did not handle
|
// AreaHandler's Key() implementation. If you send false,
|
||||||
// the keypress, and that the system should handle it instead.
|
// you indicate that you did not handle the keypress, and that
|
||||||
// (Some systems will stop processing the keyboard event at all
|
// the system should handle it instead. (Some systems will stop
|
||||||
// if you return true unconditionally, which may result in unwanted
|
// processing the keyboard event at all if you return true
|
||||||
// behavior like global task-switching keystrokes not being processed.)
|
// unconditionally, which may result in unwanted behavior like
|
||||||
|
// global task-switching keystrokes not being processed.)
|
||||||
//
|
//
|
||||||
// If a key is pressed that is not supported by ASCII, ExtKey,
|
// If a key is pressed that is not supported by ASCII, ExtKey,
|
||||||
// or Modifiers, no KeyEvent will be produced, and package
|
// or Modifiers, no KeyEvent will be produced, and package
|
||||||
// ui will act as if false was returned.
|
// ui will act as if false was returned for handled.
|
||||||
type KeyEvent struct {
|
type KeyEvent struct {
|
||||||
// ASCII is a byte representing the character pressed.
|
// ASCII is a byte representing the character pressed.
|
||||||
// Despite my best efforts, this cannot be trivialized
|
// Despite my best efforts, this cannot be trivialized
|
||||||
|
|
25
area_unix.go
25
area_unix.go
|
@ -103,7 +103,7 @@ func makeModifiers(state C.guint, m Modifiers) Modifiers {
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared code for finishing up and sending a mouse event
|
// shared code for finishing up and sending a mouse event
|
||||||
func finishMouseEvent(data C.gpointer, me MouseEvent, mb uint, x C.gdouble, y C.gdouble, state C.guint, gdkwindow *C.GdkWindow) {
|
func finishMouseEvent(widget *C.GtkWidget, data C.gpointer, me MouseEvent, mb uint, x C.gdouble, y C.gdouble, state C.guint, gdkwindow *C.GdkWindow) {
|
||||||
s := (*sysData)(unsafe.Pointer(data))
|
s := (*sysData)(unsafe.Pointer(data))
|
||||||
state = translateModifiers(state, gdkwindow)
|
state = translateModifiers(state, gdkwindow)
|
||||||
me.Modifiers = makeModifiers(state, 0)
|
me.Modifiers = makeModifiers(state, 0)
|
||||||
|
@ -125,7 +125,10 @@ func finishMouseEvent(data C.gpointer, me MouseEvent, mb uint, x C.gdouble, y C.
|
||||||
me.Held = append(me.Held, 5)
|
me.Held = append(me.Held, 5)
|
||||||
}
|
}
|
||||||
me.Pos = image.Pt(int(x), int(y))
|
me.Pos = image.Pt(int(x), int(y))
|
||||||
s.handler.Mouse(me)
|
repaint := s.handler.Mouse(me)
|
||||||
|
if repaint {
|
||||||
|
C.gtk_widget_queue_draw(widget)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//export our_area_button_press_event_callback
|
//export our_area_button_press_event_callback
|
||||||
|
@ -143,7 +146,7 @@ func our_area_button_press_event_callback(widget *C.GtkWidget, event *C.GdkEvent
|
||||||
default: // ignore triple-clicks and beyond; we don't handle those
|
default: // ignore triple-clicks and beyond; we don't handle those
|
||||||
return C.FALSE // TODO really false?
|
return C.FALSE // TODO really false?
|
||||||
}
|
}
|
||||||
finishMouseEvent(data, me, me.Down, e.x, e.y, e.state, e.window)
|
finishMouseEvent(widget, data, me, me.Down, e.x, e.y, e.state, e.window)
|
||||||
return C.FALSE // TODO really false?
|
return C.FALSE // TODO really false?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +159,7 @@ func our_area_button_release_event_callback(widget *C.GtkWidget, event *C.GdkEve
|
||||||
// GDK button ID == our button ID
|
// GDK button ID == our button ID
|
||||||
Up: uint(e.button),
|
Up: uint(e.button),
|
||||||
}
|
}
|
||||||
finishMouseEvent(data, me, me.Up, e.x, e.y, e.state, e.window)
|
finishMouseEvent(widget, data, me, me.Up, e.x, e.y, e.state, e.window)
|
||||||
return C.FALSE // TODO really false?
|
return C.FALSE // TODO really false?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,14 +169,14 @@ var area_button_release_event_callback = C.GCallback(C.our_area_button_release_e
|
||||||
func our_area_motion_notify_event_callback(widget *C.GtkWidget, event *C.GdkEvent, data C.gpointer) C.gboolean {
|
func our_area_motion_notify_event_callback(widget *C.GtkWidget, event *C.GdkEvent, data C.gpointer) C.gboolean {
|
||||||
e := (*C.GdkEventMotion)(unsafe.Pointer(event))
|
e := (*C.GdkEventMotion)(unsafe.Pointer(event))
|
||||||
me := MouseEvent{}
|
me := MouseEvent{}
|
||||||
finishMouseEvent(data, me, 0, e.x, e.y, e.state, e.window)
|
finishMouseEvent(widget, data, me, 0, e.x, e.y, e.state, e.window)
|
||||||
return C.FALSE // TODO really false?
|
return C.FALSE // TODO really false?
|
||||||
}
|
}
|
||||||
|
|
||||||
var area_motion_notify_event_callback = C.GCallback(C.our_area_motion_notify_event_callback)
|
var area_motion_notify_event_callback = C.GCallback(C.our_area_motion_notify_event_callback)
|
||||||
|
|
||||||
// shared code for doing a key event
|
// shared code for doing a key event
|
||||||
func doKeyEvent(event *C.GdkEvent, data C.gpointer, up bool) bool {
|
func doKeyEvent(widget *C.GtkWidget, event *C.GdkEvent, data C.gpointer, up bool) bool {
|
||||||
var ke KeyEvent
|
var ke KeyEvent
|
||||||
|
|
||||||
e := (*C.GdkEventKey)(unsafe.Pointer(event))
|
e := (*C.GdkEventKey)(unsafe.Pointer(event))
|
||||||
|
@ -202,7 +205,11 @@ fmt.Println("$$", up, e.hardware_keycode)
|
||||||
state := translateModifiers(e.state, e.window)
|
state := translateModifiers(e.state, e.window)
|
||||||
ke.Modifiers = makeModifiers(state, ke.Modifiers)
|
ke.Modifiers = makeModifiers(state, ke.Modifiers)
|
||||||
ke.Up = up
|
ke.Up = up
|
||||||
return s.handler.Key(ke)
|
handled, repaint := s.handler.Key(ke)
|
||||||
|
if repaint {
|
||||||
|
C.gtk_widget_queue_draw(widget)
|
||||||
|
}
|
||||||
|
return handled
|
||||||
}
|
}
|
||||||
|
|
||||||
//export our_area_key_press_event_callback
|
//export our_area_key_press_event_callback
|
||||||
|
@ -218,7 +225,7 @@ func our_area_key_press_event_callback(widget *C.GtkWidget, event *C.GdkEvent, d
|
||||||
fmt.Printf("%d/GDK_KEY_a:\n", C.GDK_KEY_a)
|
fmt.Printf("%d/GDK_KEY_a:\n", C.GDK_KEY_a)
|
||||||
pk(C.GDK_KEY_a, e.window)
|
pk(C.GDK_KEY_a, e.window)
|
||||||
*/
|
*/
|
||||||
ret := doKeyEvent(event, data, false)
|
ret := doKeyEvent(widget, event, data, false)
|
||||||
_ = ret
|
_ = ret
|
||||||
return C.FALSE // TODO really false? should probably return !ret (since true indicates stop processing)
|
return C.FALSE // TODO really false? should probably return !ret (since true indicates stop processing)
|
||||||
}
|
}
|
||||||
|
@ -227,7 +234,7 @@ var area_key_press_event_callback = C.GCallback(C.our_area_key_press_event_callb
|
||||||
|
|
||||||
//export our_area_key_release_event_callback
|
//export our_area_key_release_event_callback
|
||||||
func our_area_key_release_event_callback(widget *C.GtkWidget, event *C.GdkEvent, data C.gpointer) C.gboolean {
|
func our_area_key_release_event_callback(widget *C.GtkWidget, event *C.GdkEvent, data C.gpointer) C.gboolean {
|
||||||
ret := doKeyEvent(event, data, true)
|
ret := doKeyEvent(widget, event, data, true)
|
||||||
_ = ret
|
_ = ret
|
||||||
return C.FALSE // TODO really false? should probably return !ret (since true indicates stop processing)
|
return C.FALSE // TODO really false? should probably return !ret (since true indicates stop processing)
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,7 @@ func getModifiers() (m Modifiers) {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO mark repaint
|
||||||
func areaMouseEvent(s *sysData, button uint, up bool, count uint, wparam _WPARAM, lparam _LPARAM) {
|
func areaMouseEvent(s *sysData, button uint, up bool, count uint, wparam _WPARAM, lparam _LPARAM) {
|
||||||
var me MouseEvent
|
var me MouseEvent
|
||||||
|
|
||||||
|
@ -403,6 +404,7 @@ func areaWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lPara
|
||||||
areaMouseEvent(s, 3, true, 0, wParam, lParam)
|
areaMouseEvent(s, 3, true, 0, wParam, lParam)
|
||||||
return 0
|
return 0
|
||||||
// TODO XBUTTONs?
|
// TODO XBUTTONs?
|
||||||
|
// TODO mark repaint in key events
|
||||||
default:
|
default:
|
||||||
r1, _, _ := defWindowProc.Call(
|
r1, _, _ := defWindowProc.Call(
|
||||||
uintptr(hwnd),
|
uintptr(hwnd),
|
||||||
|
|
|
@ -34,7 +34,9 @@ func (a *keyboardArea) Paint(cliprect image.Rectangle) *image.NRGBA {
|
||||||
return a.kbd.SubImage(cliprect).(*image.NRGBA)
|
return a.kbd.SubImage(cliprect).(*image.NRGBA)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *keyboardArea) Mouse(MouseEvent) {}
|
func (a *keyboardArea) Mouse(MouseEvent) (repaint bool) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func markkey(dest *image.NRGBA, keypt image.Point, m Modifiers) {
|
func markkey(dest *image.NRGBA, keypt image.Point, m Modifiers) {
|
||||||
xr := keyrect(m).Add(keypt)
|
xr := keyrect(m).Add(keypt)
|
||||||
|
@ -42,7 +44,7 @@ func markkey(dest *image.NRGBA, keypt image.Point, m Modifiers) {
|
||||||
draw.Draw(dest, xr, xi, image.ZP, draw.Over)
|
draw.Draw(dest, xr, xi, image.ZP, draw.Over)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *keyboardArea) Key(e KeyEvent) bool {
|
func (a *keyboardArea) Key(e KeyEvent) (handled bool, repaint bool) {
|
||||||
a.lock.Lock()
|
a.lock.Lock()
|
||||||
defer a.lock.Unlock()
|
defer a.lock.Unlock()
|
||||||
|
|
||||||
|
@ -68,9 +70,9 @@ func (a *keyboardArea) Key(e KeyEvent) bool {
|
||||||
// markkey(a.kbd, modpoints[Super], m &^ Super)
|
// markkey(a.kbd, modpoints[Super], m &^ Super)
|
||||||
// }
|
// }
|
||||||
default:
|
default:
|
||||||
return false
|
return false, false
|
||||||
}
|
}
|
||||||
return true
|
return true, true
|
||||||
}
|
}
|
||||||
|
|
||||||
var doKeyboard = flag.Bool("kb", false, "run keyboard test")
|
var doKeyboard = flag.Bool("kb", false, "run keyboard test")
|
||||||
|
|
|
@ -131,13 +131,14 @@ func (a *areaHandler) Paint(rect image.Rectangle) *image.NRGBA {
|
||||||
*/
|
*/
|
||||||
return a.img.SubImage(rect).(*image.NRGBA)
|
return a.img.SubImage(rect).(*image.NRGBA)
|
||||||
}
|
}
|
||||||
func (a *areaHandler) Mouse(e MouseEvent) {
|
func (a *areaHandler) Mouse(e MouseEvent) bool {
|
||||||
fmt.Printf("%#v\n", e)
|
|
||||||
}
|
|
||||||
func (a *areaHandler) Key(e KeyEvent) bool {
|
|
||||||
fmt.Printf("%#v\n", e)
|
fmt.Printf("%#v\n", e)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
func (a *areaHandler) Key(e KeyEvent) (bool, bool) {
|
||||||
|
fmt.Printf("%#v\n", e)
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
|
||||||
var doArea = flag.Bool("area", false, "run area test instead (overrides -kb)")
|
var doArea = flag.Bool("area", false, "run area test instead (overrides -kb)")
|
||||||
func areaTest() {
|
func areaTest() {
|
||||||
|
|
Loading…
Reference in New Issue