mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
handle keyrepeat specially
This commit is contained in:
parent
a84c3ffec4
commit
106913d722
@ -162,11 +162,41 @@ process_events() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
XEvent event;
|
XEvent event;
|
||||||
|
XKeyEvent keyrelease_event;
|
||||||
|
bool got_keyrelease_event = false;
|
||||||
|
|
||||||
while (XCheckIfEvent(_display, &event, check_event, (char *)this)) {
|
while (XCheckIfEvent(_display, &event, check_event, (char *)this)) {
|
||||||
if (XFilterEvent(&event, None)) {
|
if (XFilterEvent(&event, None)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (got_keyrelease_event) {
|
||||||
|
// If a keyrelease event is immediately followed by a matching
|
||||||
|
// keypress event, that's just key repeat and we should treat
|
||||||
|
// the two events accordingly. It would be nice if X provided a
|
||||||
|
// way to differentiate between keyrepeat and explicit
|
||||||
|
// keypresses more generally.
|
||||||
|
got_keyrelease_event = false;
|
||||||
|
|
||||||
|
if (event.type == KeyPress &&
|
||||||
|
event.xkey.keycode == keyrelease_event.keycode &&
|
||||||
|
(event.xkey.time - keyrelease_event.time <= 1)) {
|
||||||
|
// In particular, we only generate down messages for the
|
||||||
|
// repeated keys, not down-and-up messages.
|
||||||
|
handle_keystroke(event.xkey);
|
||||||
|
|
||||||
|
// We thought about not generating the keypress event, but we
|
||||||
|
// need that repeat for backspace. Rethink later.
|
||||||
|
handle_keypress(event.xkey);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// This keyrelease event is not immediately followed by a
|
||||||
|
// matching keypress event, so it's a genuine release.
|
||||||
|
handle_keyrelease(keyrelease_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WindowProperties properties;
|
WindowProperties properties;
|
||||||
ButtonHandle button;
|
ButtonHandle button;
|
||||||
|
|
||||||
@ -198,39 +228,16 @@ process_events() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
handle_keystroke(event.xkey);
|
||||||
_input_devices[0].set_pointer_in_window(event.xkey.x, event.xkey.y);
|
handle_keypress(event.xkey);
|
||||||
|
|
||||||
// First, get the keystroke as a wide-character sequence.
|
|
||||||
static const int buffer_size = 256;
|
|
||||||
wchar_t buffer[buffer_size];
|
|
||||||
Status status;
|
|
||||||
int len = XwcLookupString(_ic, &event.xkey, buffer, buffer_size, NULL,
|
|
||||||
&status);
|
|
||||||
if (status == XBufferOverflow) {
|
|
||||||
glxdisplay_cat.error()
|
|
||||||
<< "Overflowed input buffer.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now each of the returned wide characters represents a
|
|
||||||
// keystroke.
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
_input_devices[0].keystroke(buffer[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now get the raw unshifted button.
|
|
||||||
ButtonHandle button = get_button(&event.xkey);
|
|
||||||
if (button != ButtonHandle::none()) {
|
|
||||||
_input_devices[0].button_down(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
button = get_button(&event.xkey);
|
// The KeyRelease can't be processed immediately, because we
|
||||||
if (button != ButtonHandle::none()) {
|
// have to check first if it's immediately followed by a
|
||||||
_input_devices[0].button_up(button);
|
// matching KeyPress event.
|
||||||
}
|
keyrelease_event = event.xkey;
|
||||||
|
got_keyrelease_event = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
@ -287,6 +294,12 @@ process_events() {
|
|||||||
<< "unhandled X event type " << event.type << "\n";
|
<< "unhandled X event type " << event.type << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (got_keyrelease_event) {
|
||||||
|
// This keyrelease event is not immediately followed by a
|
||||||
|
// matching keypress event, so it's a genuine release.
|
||||||
|
handle_keyrelease(keyrelease_event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -597,6 +610,68 @@ setup_colormap(XVisualInfo *visual) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsWindow::handle_keystroke
|
||||||
|
// Access: Private
|
||||||
|
// Description: Generates a keystroke corresponding to the indicated
|
||||||
|
// X KeyPress event.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void glxGraphicsWindow::
|
||||||
|
handle_keystroke(XKeyEvent &event) {
|
||||||
|
_input_devices[0].set_pointer_in_window(event.x, event.y);
|
||||||
|
|
||||||
|
// First, get the keystroke as a wide-character sequence.
|
||||||
|
static const int buffer_size = 256;
|
||||||
|
wchar_t buffer[buffer_size];
|
||||||
|
Status status;
|
||||||
|
int len = XwcLookupString(_ic, &event, buffer, buffer_size, NULL,
|
||||||
|
&status);
|
||||||
|
if (status == XBufferOverflow) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Overflowed input buffer.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now each of the returned wide characters represents a
|
||||||
|
// keystroke.
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
_input_devices[0].keystroke(buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsWindow::handle_keypress
|
||||||
|
// Access: Private
|
||||||
|
// Description: Generates a keypress corresponding to the indicated
|
||||||
|
// X KeyPress event.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void glxGraphicsWindow::
|
||||||
|
handle_keypress(XKeyEvent &event) {
|
||||||
|
_input_devices[0].set_pointer_in_window(event.x, event.y);
|
||||||
|
|
||||||
|
// Now get the raw unshifted button.
|
||||||
|
ButtonHandle button = get_button(&event);
|
||||||
|
if (button != ButtonHandle::none()) {
|
||||||
|
_input_devices[0].button_down(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsWindow::handle_keyrelease
|
||||||
|
// Access: Private
|
||||||
|
// Description: Generates a keyrelease corresponding to the indicated
|
||||||
|
// X KeyRelease event.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void glxGraphicsWindow::
|
||||||
|
handle_keyrelease(XKeyEvent &event) {
|
||||||
|
_input_devices[0].set_pointer_in_window(event.x, event.y);
|
||||||
|
|
||||||
|
// Now get the raw unshifted button.
|
||||||
|
ButtonHandle button = get_button(&event);
|
||||||
|
if (button != ButtonHandle::none()) {
|
||||||
|
_input_devices[0].button_up(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: glxGraphicsWindow::get_button
|
// Function: glxGraphicsWindow::get_button
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -56,6 +56,10 @@ private:
|
|||||||
void set_wm_properties(const WindowProperties &properties);
|
void set_wm_properties(const WindowProperties &properties);
|
||||||
|
|
||||||
void setup_colormap(XVisualInfo *visual);
|
void setup_colormap(XVisualInfo *visual);
|
||||||
|
void handle_keystroke(XKeyEvent &event);
|
||||||
|
void handle_keypress(XKeyEvent &event);
|
||||||
|
void handle_keyrelease(XKeyEvent &event);
|
||||||
|
|
||||||
ButtonHandle get_button(XKeyEvent *key_event);
|
ButtonHandle get_button(XKeyEvent *key_event);
|
||||||
|
|
||||||
static Bool check_event(Display *display, XEvent *event, char *arg);
|
static Bool check_event(Display *display, XEvent *event, char *arg);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user