Fix modifier handling using libfakekey.
This commit is contained in:
		@ -47,6 +47,7 @@ struct _EekboardSystemClient {
 | 
			
		||||
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    Accessible *accessible;
 | 
			
		||||
    GdkDisplay *display;
 | 
			
		||||
    XklEngine *xkl_engine;
 | 
			
		||||
    XklConfigRegistry *xkl_config_registry;
 | 
			
		||||
    FakeKey *fakekey;
 | 
			
		||||
@ -135,6 +136,11 @@ eekboard_system_client_dispose (GObject *object)
 | 
			
		||||
        client->fakekey = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (client->display) {
 | 
			
		||||
        gdk_display_close (client->display);
 | 
			
		||||
        client->display = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_system_client_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -162,6 +168,7 @@ eekboard_system_client_init (EekboardSystemClient *client)
 | 
			
		||||
{
 | 
			
		||||
    client->keyboard = NULL;
 | 
			
		||||
    client->accessible = NULL;
 | 
			
		||||
    client->display = NULL;
 | 
			
		||||
    client->xkl_engine = NULL;
 | 
			
		||||
    client->xkl_config_registry = NULL;
 | 
			
		||||
    client->focus_listener = NULL;
 | 
			
		||||
@ -177,12 +184,16 @@ eekboard_system_client_init (EekboardSystemClient *client)
 | 
			
		||||
gboolean
 | 
			
		||||
eekboard_system_client_enable_xkl (EekboardSystemClient *client)
 | 
			
		||||
{
 | 
			
		||||
    if (!client->xkl_engine) {
 | 
			
		||||
        Display *display;
 | 
			
		||||
 | 
			
		||||
        display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 | 
			
		||||
        client->xkl_engine = xkl_engine_get_instance (display);
 | 
			
		||||
    if (!client->display) {
 | 
			
		||||
        client->display = gdk_display_get_default ();
 | 
			
		||||
    }
 | 
			
		||||
    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) {
 | 
			
		||||
        client->xkl_config_registry =
 | 
			
		||||
@ -366,6 +377,9 @@ on_xkl_config_changed (XklEngine *xklengine,
 | 
			
		||||
    EekboardSystemClient *client = user_data;
 | 
			
		||||
 | 
			
		||||
    set_keyboard (client);
 | 
			
		||||
 | 
			
		||||
    if (client->fakekey)
 | 
			
		||||
        fakekey_reload_keysyms (client->fakekey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -379,6 +393,8 @@ set_keyboard (EekboardSystemClient *client)
 | 
			
		||||
        g_object_unref (client->keyboard);
 | 
			
		||||
    layout = eek_xkl_layout_new ();
 | 
			
		||||
    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++);
 | 
			
		||||
    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
 | 
			
		||||
on_key_pressed (EekboardProxy *proxy,
 | 
			
		||||
                guint          keycode,
 | 
			
		||||
@ -412,14 +445,29 @@ on_key_pressed (EekboardProxy *proxy,
 | 
			
		||||
    EekboardSystemClient *client = user_data;
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
 | 
			
		||||
    g_assert (client->fakekey);
 | 
			
		||||
 | 
			
		||||
    modifiers = eek_keyboard_get_modifiers (client->keyboard);
 | 
			
		||||
    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);
 | 
			
		||||
    if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol))
 | 
			
		||||
        fakekey_press_keysym (client->fakekey,
 | 
			
		||||
                              eek_keysym_get_xkeysym (EEK_KEYSYM(symbol)),
 | 
			
		||||
                              eek_keyboard_get_modifiers (client->keyboard));
 | 
			
		||||
    if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol)) {
 | 
			
		||||
        fakekey_send_keyevent (client->fakekey,
 | 
			
		||||
                               keycode,
 | 
			
		||||
                               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
 | 
			
		||||
@ -428,19 +476,28 @@ on_key_released (EekboardProxy *proxy,
 | 
			
		||||
                 gpointer       user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardSystemClient *client = user_data;
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
 | 
			
		||||
    g_assert (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
 | 
			
		||||
eekboard_system_client_enable_fakekey (EekboardSystemClient *client)
 | 
			
		||||
{
 | 
			
		||||
    if (!client->fakekey) {
 | 
			
		||||
        Display *display;
 | 
			
		||||
    if (!client->display) {
 | 
			
		||||
        client->display = gdk_display_get_default ();
 | 
			
		||||
    }
 | 
			
		||||
    g_assert (client->display);
 | 
			
		||||
 | 
			
		||||
        display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 | 
			
		||||
        client->fakekey = fakekey_init (display);
 | 
			
		||||
    if (!client->fakekey) {
 | 
			
		||||
        client->fakekey = fakekey_init (GDK_DISPLAY_XDISPLAY (client->display));
 | 
			
		||||
    }
 | 
			
		||||
    g_assert (client->fakekey);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user