Skip to content
Permalink
Browse files

x11: fix raw button events for dead keys

  • Loading branch information
rdb committed Mar 19, 2020
1 parent 43fa7ef commit 329abe2b3edead338452a705c33676908303ae31
Showing with 33 additions and 55 deletions.
  1. +33 −54 panda/src/x11display/x11GraphicsWindow.cxx
  2. +0 −1 panda/src/x11display/x11GraphicsWindow.h
@@ -309,10 +309,6 @@ process_events() {
bool changed_properties = false;

while (XCheckIfEvent(_display, &event, check_event, (char *)this)) {
if (XFilterEvent(&event, None)) {
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
@@ -323,22 +319,42 @@ process_events() {
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_keyrepeat(event.xkey);
if (!XFilterEvent(&event, None)) {
// 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.
ButtonHandle raw_button = map_raw_button(keyrelease_event.keycode);
if (raw_button != ButtonHandle::none()) {
_input->raw_button_up(raw_button);
}

handle_keyrelease(keyrelease_event);
}
}

// Send out a raw key press event before we do XFilterEvent, which will
// filter out dead keys and such.
if (event.type == KeyPress) {
ButtonHandle raw_button = map_raw_button(event.xkey.keycode);
if (raw_button != ButtonHandle::none()) {
_input->raw_button_down(raw_button);
}
}

if (XFilterEvent(&event, None)) {
continue;
}

ButtonHandle button;

switch (event.type) {
@@ -545,6 +561,11 @@ process_events() {
if (got_keyrelease_event) {
// This keyrelease event is not immediately followed by a matching
// keypress event, so it's a genuine release.
ButtonHandle raw_button = map_raw_button(keyrelease_event.keycode);
if (raw_button != ButtonHandle::none()) {
_input->raw_button_up(raw_button);
}

handle_keyrelease(keyrelease_event);
}
}
@@ -1490,41 +1511,6 @@ handle_keypress(XKeyEvent &event) {
}
_input->button_down(button);
}

if (event.keycode >= 9 && event.keycode <= 135) {
ButtonHandle raw_button = map_raw_button(event.keycode);
if (raw_button != ButtonHandle::none()) {
_input->raw_button_down(raw_button);
}
}
}

/**
* Generates a keyrepeat corresponding to the indicated X KeyPress event.
*/
void x11GraphicsWindow::
handle_keyrepeat(XKeyEvent &event) {
if (_properties.get_mouse_mode() != WindowProperties::M_relative) {
_input->set_pointer_in_window(event.x, event.y);
}

// Now get the raw unshifted button.
ButtonHandle button = get_button(event, false);
if (button != ButtonHandle::none()) {
if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) {
_input->button_down(KeyboardButton::control());
}
if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) {
_input->button_down(KeyboardButton::shift());
}
if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) {
_input->button_down(KeyboardButton::alt());
}
if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) {
_input->button_down(KeyboardButton::meta());
}
_input->button_down(button);
}
}

/**
@@ -1553,13 +1539,6 @@ handle_keyrelease(XKeyEvent &event) {
}
_input->button_up(button);
}

if (event.keycode >= 9 && event.keycode <= 135) {
ButtonHandle raw_button = map_raw_button(event.keycode);
if (raw_button != ButtonHandle::none()) {
_input->raw_button_up(raw_button);
}
}
}

/**
@@ -1986,7 +1965,7 @@ map_raw_button(KeyCode key) const {
// In any case, this means we can use the same mapping as our raw
// input code, which uses evdev directly.
int index = key - 8;
if (index >= 0) {
if (index > 0 && index < 128) {
return EvdevInputDevice::map_button(index);
}
#endif
@@ -59,7 +59,6 @@ class x11GraphicsWindow : public GraphicsWindow {
virtual void setup_colormap(XVisualInfo *visual);
void handle_keystroke(XKeyEvent &event);
void handle_keypress(XKeyEvent &event);
void handle_keyrepeat(XKeyEvent &event);
void handle_keyrelease(XKeyEvent &event);

ButtonHandle get_button(XKeyEvent &key_event, bool allow_shift);

0 comments on commit 329abe2

Please sign in to comment.
You can’t perform that action at this time.