diff options
author | Olivier Blin <olivier.blin@softathome.com> | 2015-10-12 17:27:51 +0200 |
---|---|---|
committer | Olivier Blin <qt@blino.org> | 2015-10-20 09:06:24 +0000 |
commit | 3a584414d9df972721a4fbf4b1088bce5e95484b (patch) | |
tree | f721e6133a3e93e27586e43d57da06922ea52803 | |
parent | 7f646611ca996320fec933633711b9d89833863c (diff) | |
download | qtwayland-3a584414d9df972721a4fbf4b1088bce5e95484b.tar.gz |
Update focusResource if needed when wl_keyboard is bound
If a QtWayland compositor gives focus to a surface right after its
creation during the client startup, the keyboard resource may not be
bound yet by the client.
In this case, the surface is correctly marked as focused, but the
keyboard resource is never marked as focused, and thus no keys are
ever sent to the client.
To fix this, the focusResource is updated if needed after wl_keyboard
is bound.
This can be reproduced with weston-simple-im (patched to use wl_shell
instead of xdg_shell) and qml-compositor, modified to enable
TextInputExtension and call takeFocus() at the end of windowAdded().
Change-Id: I551cb5bc56c05a1e5187b23108f4ef80468782dc
Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
-rw-r--r-- | src/compositor/wayland_wrapper/qwlkeyboard.cpp | 42 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlkeyboard_p.h | 3 |
2 files changed, 37 insertions, 8 deletions
diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp index 7520fae3..7a5ed5f2 100644 --- a/src/compositor/wayland_wrapper/qwlkeyboard.cpp +++ b/src/compositor/wayland_wrapper/qwlkeyboard.cpp @@ -116,6 +116,30 @@ KeyboardGrabber *Keyboard::currentGrab() const return m_grab; } +void Keyboard::checkFocusResource(wl_keyboard::Resource *keyboardResource) +{ + if (!keyboardResource || !m_focus) + return; + + // this is already the current resource, do no send enter twice + if (m_focusResource == keyboardResource) + return; + + // check if new wl_keyboard resource is from the client owning the focus surface + struct ::wl_client *focusedClient = m_focus->resource()->client(); + if (focusedClient == keyboardResource->client()) { + sendEnter(m_focus, keyboardResource); + m_focusResource = keyboardResource; + } +} + +void Keyboard::sendEnter(Surface *surface, wl_keyboard::Resource *keyboardResource) +{ + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_modifiers(keyboardResource->handle, serial, m_modsDepressed, m_modsLatched, m_modsLocked, m_group); + send_enter(keyboardResource->handle, serial, surface->resource()->handle, QByteArray::fromRawData((char *)m_keys.data(), m_keys.size() * sizeof(uint32_t))); +} + void Keyboard::focused(Surface *surface) { if (m_focus != surface) { @@ -132,9 +156,7 @@ void Keyboard::focused(Surface *surface) Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; if (resource && (m_focus != surface || m_focusResource != resource)) { - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - send_modifiers(resource->handle, serial, m_modsDepressed, m_modsLatched, m_modsLocked, m_group); - send_enter(resource->handle, serial, surface->resource()->handle, QByteArray::fromRawData((char *)m_keys.data(), m_keys.size() * sizeof(uint32_t))); + sendEnter(surface, resource); } m_focusResource = resource; @@ -200,13 +222,17 @@ void Keyboard::keyboard_bind_resource(wl_keyboard::Resource *resource) if (m_context) { send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, m_keymap_fd, m_keymap_size); - return; } + else #endif - int null_fd = open("/dev/null", O_RDONLY); - send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */, - null_fd, 0); - close(null_fd); + { + int null_fd = open("/dev/null", O_RDONLY); + send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */, + null_fd, 0); + close(null_fd); + } + + checkFocusResource(resource); } void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource) diff --git a/src/compositor/wayland_wrapper/qwlkeyboard_p.h b/src/compositor/wayland_wrapper/qwlkeyboard_p.h index e47bd210..15185ed5 100644 --- a/src/compositor/wayland_wrapper/qwlkeyboard_p.h +++ b/src/compositor/wayland_wrapper/qwlkeyboard_p.h @@ -132,6 +132,9 @@ protected: void keyboard_release(Resource *resource) Q_DECL_OVERRIDE; private: + void checkFocusResource(wl_keyboard::Resource *resource); + void sendEnter(Surface *surface, wl_keyboard::Resource *resource); + void sendKeyEvent(uint code, uint32_t state); void focusDestroyed(void *data); |