mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
wayland-keyboard: Make sure we send an updated modifiers event
Any given clutter event carries the modifier state as it was before it occured but, for the wayland modifiers event, we want the state including the current event. To fix this, we'll keep our xkb_state instance around instead of the serialized mods. https://bugzilla.gnome.org/show_bug.cgi?id=722847
This commit is contained in:
parent
ae8f21a3dc
commit
5cc6becb63
@ -138,10 +138,12 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xkb_info->keymap)
|
|
||||||
xkb_keymap_unref (xkb_info->keymap);
|
xkb_keymap_unref (xkb_info->keymap);
|
||||||
xkb_info->keymap = keymap;
|
xkb_info->keymap = keymap;
|
||||||
|
|
||||||
|
xkb_state_unref (xkb_info->state);
|
||||||
|
xkb_info->state = xkb_state_new (keymap);
|
||||||
|
|
||||||
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
|
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
|
||||||
if (keymap_str == NULL)
|
if (keymap_str == NULL)
|
||||||
{
|
{
|
||||||
@ -316,8 +318,8 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
|||||||
static void
|
static void
|
||||||
meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
||||||
{
|
{
|
||||||
if (xkb_info->keymap)
|
xkb_keymap_unref (xkb_info->keymap);
|
||||||
xkb_map_unref (xkb_info->keymap);
|
xkb_state_unref (xkb_info->state);
|
||||||
|
|
||||||
if (xkb_info->keymap_area)
|
if (xkb_info->keymap_area)
|
||||||
munmap (xkb_info->keymap_area, xkb_info->keymap_size);
|
munmap (xkb_info->keymap_area, xkb_info->keymap_size);
|
||||||
@ -325,44 +327,27 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
|||||||
close (xkb_info->keymap_fd);
|
close (xkb_info->keymap_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
state_equal (MetaWaylandXkbState *one,
|
|
||||||
MetaWaylandXkbState *two)
|
|
||||||
{
|
|
||||||
return one->mods_depressed == two->mods_depressed &&
|
|
||||||
one->mods_latched == two->mods_latched &&
|
|
||||||
one->mods_locked == two->mods_locked &&
|
|
||||||
one->group == two->group;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_modifiers (MetaWaylandKeyboard *keyboard,
|
set_modifiers (MetaWaylandKeyboard *keyboard,
|
||||||
guint32 serial,
|
guint32 serial,
|
||||||
ClutterEvent *event)
|
const ClutterKeyEvent *event)
|
||||||
{
|
{
|
||||||
MetaWaylandKeyboardGrab *grab = keyboard->grab;
|
MetaWaylandKeyboardGrab *grab = keyboard->grab;
|
||||||
MetaWaylandXkbState new_state;
|
struct xkb_state *state = keyboard->xkb_info.state;
|
||||||
guint effective_state;
|
enum xkb_state_component changed_state;
|
||||||
|
|
||||||
clutter_event_get_state_full (event,
|
changed_state = xkb_state_update_key (state,
|
||||||
NULL,
|
event->hardware_keycode,
|
||||||
&new_state.mods_depressed,
|
event->type == CLUTTER_KEY_PRESS ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||||
&new_state.mods_latched,
|
if (changed_state == 0)
|
||||||
&new_state.mods_locked,
|
|
||||||
&effective_state);
|
|
||||||
new_state.group = (effective_state >> 13) & 0x3;
|
|
||||||
|
|
||||||
if (state_equal (&keyboard->modifier_state, &new_state))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
keyboard->modifier_state = new_state;
|
|
||||||
|
|
||||||
grab->interface->modifiers (grab,
|
grab->interface->modifiers (grab,
|
||||||
serial,
|
serial,
|
||||||
new_state.mods_depressed,
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
|
||||||
new_state.mods_latched,
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
|
||||||
new_state.mods_locked,
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
||||||
new_state.group);
|
xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -432,7 +417,7 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
|||||||
|
|
||||||
serial = wl_display_next_serial (keyboard->display);
|
serial = wl_display_next_serial (keyboard->display);
|
||||||
|
|
||||||
set_modifiers (keyboard, serial, (ClutterEvent*)event);
|
set_modifiers (keyboard, serial, event);
|
||||||
|
|
||||||
handled = keyboard->grab->interface->key (keyboard->grab,
|
handled = keyboard->grab->interface->key (keyboard->grab,
|
||||||
event->time,
|
event->time,
|
||||||
@ -484,13 +469,14 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
|||||||
{
|
{
|
||||||
struct wl_client *client = wl_resource_get_client (keyboard->focus_resource);
|
struct wl_client *client = wl_resource_get_client (keyboard->focus_resource);
|
||||||
struct wl_display *display = wl_client_get_display (client);
|
struct wl_display *display = wl_client_get_display (client);
|
||||||
|
struct xkb_state *state = keyboard->xkb_info.state;
|
||||||
uint32_t serial = wl_display_next_serial (display);
|
uint32_t serial = wl_display_next_serial (display);
|
||||||
|
|
||||||
wl_keyboard_send_modifiers (keyboard->focus_resource, serial,
|
wl_keyboard_send_modifiers (keyboard->focus_resource, serial,
|
||||||
keyboard->modifier_state.mods_depressed,
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
|
||||||
keyboard->modifier_state.mods_latched,
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
|
||||||
keyboard->modifier_state.mods_locked,
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
||||||
keyboard->modifier_state.group);
|
xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
|
||||||
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource,
|
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource,
|
||||||
&keyboard->keys);
|
&keyboard->keys);
|
||||||
|
|
||||||
|
@ -69,19 +69,12 @@ struct _MetaWaylandKeyboardGrab
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
|
struct xkb_state *state;
|
||||||
int keymap_fd;
|
int keymap_fd;
|
||||||
size_t keymap_size;
|
size_t keymap_size;
|
||||||
char *keymap_area;
|
char *keymap_area;
|
||||||
} MetaWaylandXkbInfo;
|
} MetaWaylandXkbInfo;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t mods_depressed;
|
|
||||||
uint32_t mods_latched;
|
|
||||||
uint32_t mods_locked;
|
|
||||||
uint32_t group;
|
|
||||||
} MetaWaylandXkbState;
|
|
||||||
|
|
||||||
struct _MetaWaylandKeyboard
|
struct _MetaWaylandKeyboard
|
||||||
{
|
{
|
||||||
struct wl_list resource_list;
|
struct wl_list resource_list;
|
||||||
@ -100,8 +93,6 @@ struct _MetaWaylandKeyboard
|
|||||||
|
|
||||||
struct wl_array keys;
|
struct wl_array keys;
|
||||||
|
|
||||||
MetaWaylandXkbState modifier_state;
|
|
||||||
|
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
|
|
||||||
struct xkb_context *xkb_context;
|
struct xkb_context *xkb_context;
|
||||||
|
Loading…
Reference in New Issue
Block a user