From 4e6368d019e2543e6bf792f182486732d6f5a3f5 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 29 Apr 2012 02:53:47 +0000 Subject: Proper key press and release support on X11. Clearer mouse callback API. --- pugl/pugl.h | 2 +- pugl/pugl_win.cpp | 4 ++-- pugl/pugl_x11.c | 27 ++++++++++++++++++++++++--- 3 files changed, 27 insertions(+), 6 deletions(-) (limited to 'pugl') diff --git a/pugl/pugl.h b/pugl/pugl.h index 853a754..6a6fbe7 100644 --- a/pugl/pugl.h +++ b/pugl/pugl.h @@ -52,7 +52,7 @@ typedef void (*PuglDisplayFunc)(PuglWindow* handle); typedef void (*PuglKeyboardFunc)(PuglWindow* handle, bool press, uint32_t key); typedef void (*PuglMotionFunc)(PuglWindow* handle, int x, int y); typedef void (*PuglMouseFunc)(PuglWindow* handle, - int button, int state, + int button, bool down, int x, int y); typedef void (*PuglReshapeFunc)(PuglWindow* handle, int width, int height); diff --git a/pugl/pugl_win.cpp b/pugl/pugl_win.cpp index a27a2c5..50f42f0 100644 --- a/pugl/pugl_win.cpp +++ b/pugl/pugl_win.cpp @@ -104,10 +104,10 @@ puglDisplay(PuglWindow* win) } static void -processMouseEvent(PuglWindow* win, int button, bool down, LPARAM lParam) +processMouseEvent(PuglWindow* win, int button, bool press, LPARAM lParam) { if (win->mouseFunc) { - win->mouseFunc(win, button, down, + win->mouseFunc(win, button, press, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); } diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c index 33f0b42..5844f2d 100644 --- a/pugl/pugl_x11.c +++ b/pugl/pugl_x11.c @@ -104,7 +104,8 @@ puglCreate(PuglNativeWindow parent, const char* title, int width, int height) attr.border_pixel = 0; attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask - | ButtonPressMask | PointerMotionMask | StructureNotifyMask; + | ButtonPressMask | ButtonReleaseMask + | PointerMotionMask | StructureNotifyMask; impl->win = XCreateWindow( impl->display, xParent, @@ -194,20 +195,40 @@ puglProcessEvents(PuglWindow* win) } break; case ButtonPress: + case ButtonRelease: if (win->mouseFunc) { win->mouseFunc(win, - event.xbutton.button, event.xbutton.state, + event.xbutton.button, event.type == ButtonPress, event.xbutton.x, event.xbutton.y); } break; case KeyPress: - case KeyRelease: if (win->keyboardFunc) { KeySym sym = XKeycodeToKeysym( win->impl->display, event.xkey.keycode, 0); win->keyboardFunc(win, event.type == KeyPress, sym); } break; + case KeyRelease: { + bool retriggered = false; + if (XEventsQueued(win->impl->display, QueuedAfterReading)) { + XEvent next; + XPeekEvent(win->impl->display, &next); + if (next.type == KeyPress && + next.xkey.time == event.xkey.time && + next.xkey.keycode == event.xkey.keycode) { + // Key repeat, ignore fake KeyPress event + XNextEvent(win->impl->display, &event); + retriggered = true; + } + } + + if (!retriggered && win->keyboardFunc) { + KeySym sym = XKeycodeToKeysym( + win->impl->display, event.xkey.keycode, 0); + win->keyboardFunc(win, false, sym); + } + } case ClientMessage: if (!strcmp(XGetAtomName(win->impl->display, event.xclient.message_type), -- cgit v1.2.1