diff options
Diffstat (limited to 'backend/x11/backend.c')
-rw-r--r-- | backend/x11/backend.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 36d72d9e..8abc5d84 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -7,6 +7,7 @@ #include <wayland-server.h> #include <wlr/backend/interface.h> #include <wlr/backend/x11.h> +#include <wlr/config.h> #include <wlr/interfaces/wlr_input_device.h> #include <wlr/interfaces/wlr_keyboard.h> #include <wlr/interfaces/wlr_output.h> @@ -21,6 +22,9 @@ #elif __FreeBSD__ #include <dev/evdev/input-event-codes.h> #endif +#ifdef WLR_HAS_XCB_XKB +#include <xcb/xkb.h> +#endif #include "backend/x11.h" #include "util/signal.h" @@ -108,10 +112,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e struct wlr_event_pointer_motion_absolute abs = { .device = &x11->pointer_dev, .time_msec = ev->time, - .x_mm = ev->event_x, - .y_mm = ev->event_y, - .width_mm = output->wlr_output.width, - .height_mm = output->wlr_output.height, + .x = (double)ev->event_x / output->wlr_output.width, + .y = (double)ev->event_y / output->wlr_output.height, }; wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); @@ -136,10 +138,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e struct wlr_event_pointer_motion_absolute abs = { .device = &x11->pointer_dev, .time_msec = x11->time, - .x_mm = pointer->root_x, - .y_mm = pointer->root_y, - .width_mm = output->wlr_output.width, - .height_mm = output->wlr_output.height, + .x = (double)pointer->root_x / output->wlr_output.width, + .y = (double)pointer->root_y / output->wlr_output.height, }; wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); @@ -157,6 +157,14 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e break; } default: +#ifdef WLR_HAS_XCB_XKB + if (x11->xkb_supported && event->response_type == x11->xkb_base_event) { + xcb_xkb_state_notify_event_t *ev = + (xcb_xkb_state_notify_event_t *)event; + wlr_keyboard_notify_modifiers(&x11->keyboard, ev->baseMods, + ev->latchedMods, ev->lockedMods, ev->lockedGroup); + } +#endif break; } @@ -282,6 +290,32 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { strlen(title), title); } +#ifdef WLR_HAS_XCB_XKB + const xcb_query_extension_reply_t *reply = + xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id); + if (reply != NULL && reply->present) { + x11->xkb_base_event = reply->first_event; + x11->xkb_base_error = reply->first_error; + + xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension( + x11->xcb_conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); + xcb_xkb_use_extension_reply_t *reply = + xcb_xkb_use_extension_reply(x11->xcb_conn, cookie, NULL); + if (reply != NULL && reply->supported) { + x11->xkb_supported = true; + + xcb_xkb_select_events(x11->xcb_conn, + XCB_XKB_ID_USE_CORE_KBD, + XCB_XKB_EVENT_TYPE_STATE_NOTIFY, + 0, + XCB_XKB_EVENT_TYPE_STATE_NOTIFY, + 0, + 0, + 0); + } + } +#endif + xcb_map_window(x11->xcb_conn, output->win); xcb_flush(x11->xcb_conn); wlr_output_update_enabled(&output->wlr_output, true); |