aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/meson.build1
-rw-r--r--backend/x11/backend.c33
-rw-r--r--meson.build51
3 files changed, 60 insertions, 25 deletions
diff --git a/backend/meson.build b/backend/meson.build
index a74ea024..df12d703 100644
--- a/backend/meson.build
+++ b/backend/meson.build
@@ -51,6 +51,7 @@ endif
if conf_data.get('WLR_HAS_X11_BACKEND', false)
backend_files += files('x11/backend.c')
+ backend_deps += xcb_xkb
endif
if conf_data.get('WLR_HAS_ELOGIND', false)
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index 36d72d9e..79b896fe 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -16,6 +16,7 @@
#include <wlr/util/log.h>
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
+#include <xcb/xkb.h>
#ifdef __linux__
#include <linux/input-event-codes.h>
#elif __FreeBSD__
@@ -30,6 +31,10 @@ static const struct wlr_backend_impl backend_impl;
static const struct wlr_output_impl output_impl;
static const struct wlr_input_device_impl input_device_impl = { 0 };
+// TODO: remove global state
+static uint8_t xkb_base_event;
+static uint8_t xkb_base_error;
+
static uint32_t xcb_button_to_wl(uint32_t button) {
switch (button) {
case XCB_BUTTON_INDEX_1: return BTN_LEFT;
@@ -157,6 +162,12 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e
break;
}
default:
+ if (event->response_type == 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);
+ }
break;
}
@@ -225,6 +236,28 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) {
x11->screen->root, 0, 0, 1024, 768, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT,
x11->screen->root_visual, mask, values);
+ const xcb_query_extension_reply_t *reply =
+ xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id);
+ if (reply->present) {
+ xkb_base_event = reply->first_event;
+ 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 && reply->supported) {
+ 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);
+ }
+ }
+
output->surf = wlr_egl_create_surface(&x11->egl, &output->win);
if (!output->surf) {
wlr_log(L_ERROR, "Failed to create EGL surface");
diff --git a/meson.build b/meson.build
index 7740b416..a48984c1 100644
--- a/meson.build
+++ b/meson.build
@@ -82,35 +82,36 @@ if elogind.found() and get_option('enable_elogind') != 'false'
endif
if get_option('enable_x11_backend') or get_option('enable_xwayland')
- xcb = dependency('xcb')
- xcb_composite = dependency('xcb-composite')
- xcb_xfixes = dependency('xcb-xfixes')
- xcb_image = dependency('xcb-image')
- xcb_render = dependency('xcb-render')
- x11_xcb = dependency('x11-xcb')
-
- xcb_icccm = dependency('xcb-icccm', required: false)
- xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true')
-
- if xcb_icccm.found()
- conf_data.set('WLR_HAS_XCB_ICCCM', true)
- endif
-
- if xcb_errors.found() and get_option('enable_xcb_errors') != 'false'
- conf_data.set('WLR_HAS_XCB_ERRORS', true)
- endif
-
- wlr_deps += [
- xcb,
- xcb_composite,
- x11_xcb,
- ]
+ xcb = dependency('xcb')
+ xcb_composite = dependency('xcb-composite')
+ xcb_xfixes = dependency('xcb-xfixes')
+ xcb_xkb = dependency('xcb-xkb') # TODO: make this optional
+ xcb_image = dependency('xcb-image')
+ xcb_render = dependency('xcb-render')
+ x11_xcb = dependency('x11-xcb')
+
+ xcb_icccm = dependency('xcb-icccm', required: false)
+ xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true')
+
+ if xcb_icccm.found()
+ conf_data.set('WLR_HAS_XCB_ICCCM', true)
+ endif
+
+ if xcb_errors.found() and get_option('enable_xcb_errors') != 'false'
+ conf_data.set('WLR_HAS_XCB_ERRORS', true)
+ endif
+
+ wlr_deps += [
+ xcb,
+ xcb_composite,
+ x11_xcb,
+ ]
else
- add_project_arguments('-DMESA_EGL_NO_X11_HEADERS', language: 'c')
+ add_project_arguments('-DMESA_EGL_NO_X11_HEADERS', language: 'c')
endif
if get_option('enable_x11_backend')
- conf_data.set('WLR_HAS_X11_BACKEND', true)
+ conf_data.set('WLR_HAS_X11_BACKEND', true)
endif
if get_option('enable_xwayland')