Fix modifier handling using libfakekey.
This commit is contained in:
@ -47,6 +47,7 @@ struct _EekboardSystemClient {
|
|||||||
|
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
Accessible *accessible;
|
Accessible *accessible;
|
||||||
|
GdkDisplay *display;
|
||||||
XklEngine *xkl_engine;
|
XklEngine *xkl_engine;
|
||||||
XklConfigRegistry *xkl_config_registry;
|
XklConfigRegistry *xkl_config_registry;
|
||||||
FakeKey *fakekey;
|
FakeKey *fakekey;
|
||||||
@ -135,6 +136,11 @@ eekboard_system_client_dispose (GObject *object)
|
|||||||
client->fakekey = NULL;
|
client->fakekey = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client->display) {
|
||||||
|
gdk_display_close (client->display);
|
||||||
|
client->display = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (eekboard_system_client_parent_class)->dispose (object);
|
G_OBJECT_CLASS (eekboard_system_client_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +168,7 @@ eekboard_system_client_init (EekboardSystemClient *client)
|
|||||||
{
|
{
|
||||||
client->keyboard = NULL;
|
client->keyboard = NULL;
|
||||||
client->accessible = NULL;
|
client->accessible = NULL;
|
||||||
|
client->display = NULL;
|
||||||
client->xkl_engine = NULL;
|
client->xkl_engine = NULL;
|
||||||
client->xkl_config_registry = NULL;
|
client->xkl_config_registry = NULL;
|
||||||
client->focus_listener = NULL;
|
client->focus_listener = NULL;
|
||||||
@ -177,12 +184,16 @@ eekboard_system_client_init (EekboardSystemClient *client)
|
|||||||
gboolean
|
gboolean
|
||||||
eekboard_system_client_enable_xkl (EekboardSystemClient *client)
|
eekboard_system_client_enable_xkl (EekboardSystemClient *client)
|
||||||
{
|
{
|
||||||
if (!client->xkl_engine) {
|
if (!client->display) {
|
||||||
Display *display;
|
client->display = gdk_display_get_default ();
|
||||||
|
|
||||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
|
||||||
client->xkl_engine = xkl_engine_get_instance (display);
|
|
||||||
}
|
}
|
||||||
|
g_assert (client->display);
|
||||||
|
|
||||||
|
if (!client->xkl_engine) {
|
||||||
|
client->xkl_engine =
|
||||||
|
xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (client->display));
|
||||||
|
}
|
||||||
|
g_assert (client->xkl_engine);
|
||||||
|
|
||||||
if (!client->xkl_config_registry) {
|
if (!client->xkl_config_registry) {
|
||||||
client->xkl_config_registry =
|
client->xkl_config_registry =
|
||||||
@ -366,6 +377,9 @@ on_xkl_config_changed (XklEngine *xklengine,
|
|||||||
EekboardSystemClient *client = user_data;
|
EekboardSystemClient *client = user_data;
|
||||||
|
|
||||||
set_keyboard (client);
|
set_keyboard (client);
|
||||||
|
|
||||||
|
if (client->fakekey)
|
||||||
|
fakekey_reload_keysyms (client->fakekey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -379,6 +393,8 @@ set_keyboard (EekboardSystemClient *client)
|
|||||||
g_object_unref (client->keyboard);
|
g_object_unref (client->keyboard);
|
||||||
layout = eek_xkl_layout_new ();
|
layout = eek_xkl_layout_new ();
|
||||||
client->keyboard = eek_keyboard_new (layout, CSW, CSH);
|
client->keyboard = eek_keyboard_new (layout, CSW, CSH);
|
||||||
|
eek_keyboard_set_modifier_behavior (client->keyboard,
|
||||||
|
EEK_MODIFIER_BEHAVIOR_LATCH);
|
||||||
|
|
||||||
keyboard_name = g_strdup_printf ("keyboard%d", keyboard_serial++);
|
keyboard_name = g_strdup_printf ("keyboard%d", keyboard_serial++);
|
||||||
eek_element_set_name (EEK_ELEMENT(client->keyboard), keyboard_name);
|
eek_element_set_name (EEK_ELEMENT(client->keyboard), keyboard_name);
|
||||||
@ -404,6 +420,23 @@ on_xkl_state_changed (XklEngine *xklengine,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_INLINE_FUNC FakeKeyModifier
|
||||||
|
get_fakekey_modifiers (EekModifierType modifiers)
|
||||||
|
{
|
||||||
|
FakeKeyModifier retval = 0;
|
||||||
|
|
||||||
|
if (modifiers & EEK_SHIFT_MASK)
|
||||||
|
retval |= FAKEKEYMOD_SHIFT;
|
||||||
|
if (modifiers & EEK_CONTROL_MASK)
|
||||||
|
retval |= FAKEKEYMOD_CONTROL;
|
||||||
|
if (modifiers & EEK_MOD1_MASK)
|
||||||
|
retval |= FAKEKEYMOD_ALT;
|
||||||
|
if (modifiers & EEK_META_MASK)
|
||||||
|
retval |= FAKEKEYMOD_META;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_key_pressed (EekboardProxy *proxy,
|
on_key_pressed (EekboardProxy *proxy,
|
||||||
guint keycode,
|
guint keycode,
|
||||||
@ -412,14 +445,29 @@ on_key_pressed (EekboardProxy *proxy,
|
|||||||
EekboardSystemClient *client = user_data;
|
EekboardSystemClient *client = user_data;
|
||||||
EekKey *key;
|
EekKey *key;
|
||||||
EekSymbol *symbol;
|
EekSymbol *symbol;
|
||||||
|
EekModifierType modifiers;
|
||||||
|
|
||||||
g_assert (client->fakekey);
|
g_assert (client->fakekey);
|
||||||
|
|
||||||
|
modifiers = eek_keyboard_get_modifiers (client->keyboard);
|
||||||
key = eek_keyboard_find_key_by_keycode (client->keyboard, keycode);
|
key = eek_keyboard_find_key_by_keycode (client->keyboard, keycode);
|
||||||
|
if (!key) {
|
||||||
|
// g_debug ("Can't find key for keycode %u", keycode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||||
if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol))
|
if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol)) {
|
||||||
fakekey_press_keysym (client->fakekey,
|
fakekey_send_keyevent (client->fakekey,
|
||||||
eek_keysym_get_xkeysym (EEK_KEYSYM(symbol)),
|
keycode,
|
||||||
eek_keyboard_get_modifiers (client->keyboard));
|
True,
|
||||||
|
get_fakekey_modifiers (modifiers));
|
||||||
|
fakekey_send_keyevent (client->fakekey,
|
||||||
|
keycode,
|
||||||
|
False,
|
||||||
|
get_fakekey_modifiers (modifiers));
|
||||||
|
}
|
||||||
|
g_signal_emit_by_name (key, "pressed");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -428,19 +476,28 @@ on_key_released (EekboardProxy *proxy,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
EekboardSystemClient *client = user_data;
|
EekboardSystemClient *client = user_data;
|
||||||
|
EekKey *key;
|
||||||
|
|
||||||
g_assert (client->fakekey);
|
g_assert (client->fakekey);
|
||||||
fakekey_release (client->fakekey);
|
fakekey_release (client->fakekey);
|
||||||
|
key = eek_keyboard_find_key_by_keycode (client->keyboard, keycode);
|
||||||
|
if (!key) {
|
||||||
|
// g_debug ("Can't find key for keycode %u", keycode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_signal_emit_by_name (key, "released");
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
eekboard_system_client_enable_fakekey (EekboardSystemClient *client)
|
eekboard_system_client_enable_fakekey (EekboardSystemClient *client)
|
||||||
{
|
{
|
||||||
if (!client->fakekey) {
|
if (!client->display) {
|
||||||
Display *display;
|
client->display = gdk_display_get_default ();
|
||||||
|
}
|
||||||
|
g_assert (client->display);
|
||||||
|
|
||||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
if (!client->fakekey) {
|
||||||
client->fakekey = fakekey_init (display);
|
client->fakekey = fakekey_init (GDK_DISPLAY_XDISPLAY (client->display));
|
||||||
}
|
}
|
||||||
g_assert (client->fakekey);
|
g_assert (client->fakekey);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user