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.
|
||||
// You are allowed to do nothing in this handler (to ignore mouse events).
|
||||
// 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.
|
||||
// You are allowed to do nothing except return false in this handler (to ignore keyboard events).
|
||||
// Do not do nothing but return true; this may have unintended consequences.
|
||||
// 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 for handled; this may have unintended consequences.
|
||||
// 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.
|
||||
|
@ -116,16 +118,17 @@ func (e MouseEvent) HeldBits() (h uintptr) {
|
|||
//
|
||||
// When you are finished processing the incoming event,
|
||||
// return whether or not you did something in response
|
||||
// to the given keystroke from your Key() implementation.
|
||||
// If you send false, you indicate that you did not handle
|
||||
// the keypress, and that the system should handle it instead.
|
||||
// (Some systems will stop processing the keyboard event at all
|
||||
// if you return true unconditionally, which may result in unwanted
|
||||
// behavior like global task-switching keystrokes not being processed.)
|
||||
// to the given keystroke as the handled return of your
|
||||
// AreaHandler's Key() implementation. If you send false,
|
||||
// you indicate that you did not handle the keypress, and that
|
||||
// the system should handle it instead. (Some systems will stop
|
||||
// processing the keyboard event at all if you return true
|
||||
// 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,
|
||||
// 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 {
|
||||
// ASCII is a byte representing the character pressed.
|
||||
// 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
|
||||
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))
|
||||
state = translateModifiers(state, gdkwindow)
|
||||
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.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
|
||||
|
@ -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
|
||||
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?
|
||||
}
|
||||
|
||||
|
@ -156,7 +159,7 @@ func our_area_button_release_event_callback(widget *C.GtkWidget, event *C.GdkEve
|
|||
// GDK button ID == our button ID
|
||||
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?
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
e := (*C.GdkEventMotion)(unsafe.Pointer(event))
|
||||
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?
|
||||
}
|
||||
|
||||
var area_motion_notify_event_callback = C.GCallback(C.our_area_motion_notify_event_callback)
|
||||
|
||||
// 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
|
||||
|
||||
e := (*C.GdkEventKey)(unsafe.Pointer(event))
|
||||
|
@ -202,7 +205,11 @@ fmt.Println("$$", up, e.hardware_keycode)
|
|||
state := translateModifiers(e.state, e.window)
|
||||
ke.Modifiers = makeModifiers(state, ke.Modifiers)
|
||||
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
|
||||
|
@ -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)
|
||||
pk(C.GDK_KEY_a, e.window)
|
||||
*/
|
||||
ret := doKeyEvent(event, data, false)
|
||||
ret := doKeyEvent(widget, event, data, false)
|
||||
_ = ret
|
||||
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
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
// TODO mark repaint
|
||||
func areaMouseEvent(s *sysData, button uint, up bool, count uint, wparam _WPARAM, lparam _LPARAM) {
|
||||
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)
|
||||
return 0
|
||||
// TODO XBUTTONs?
|
||||
// TODO mark repaint in key events
|
||||
default:
|
||||
r1, _, _ := defWindowProc.Call(
|
||||
uintptr(hwnd),
|
||||
|
|
|
@ -34,7 +34,9 @@ func (a *keyboardArea) Paint(cliprect image.Rectangle) *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) {
|
||||
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)
|
||||
}
|
||||
|
||||
func (a *keyboardArea) Key(e KeyEvent) bool {
|
||||
func (a *keyboardArea) Key(e KeyEvent) (handled bool, repaint bool) {
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
|
||||
|
@ -68,9 +70,9 @@ func (a *keyboardArea) Key(e KeyEvent) bool {
|
|||
// markkey(a.kbd, modpoints[Super], m &^ Super)
|
||||
// }
|
||||
default:
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
return true
|
||||
return true, true
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
func (a *areaHandler) Mouse(e MouseEvent) {
|
||||
fmt.Printf("%#v\n", e)
|
||||
}
|
||||
func (a *areaHandler) Key(e KeyEvent) bool {
|
||||
func (a *areaHandler) Mouse(e MouseEvent) bool {
|
||||
fmt.Printf("%#v\n", e)
|
||||
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)")
|
||||
func areaTest() {
|
||||
|
|
Loading…
Reference in New Issue