diff --git a/data/keyboards/geometry/url.xml b/data/keyboards/geometry/url.xml new file mode 100644 index 00000000..01240edb --- /dev/null +++ b/data/keyboards/geometry/url.xml @@ -0,0 +1,120 @@ + + + +
+ + + + + + + + + + + + +
+
+ + + + + + + + + + + + +
+
+ + + + + + + + + + + +
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/data/keyboards/keyboards.xml b/data/keyboards/keyboards.xml index 197e0174..b3fa5d7c 100644 --- a/data/keyboards/keyboards.xml +++ b/data/keyboards/keyboards.xml @@ -96,5 +96,8 @@ + diff --git a/data/keyboards/symbols/special/url.xml b/data/keyboards/symbols/special/url.xml new file mode 100644 index 00000000..541d42a9 --- /dev/null +++ b/data/keyboards/symbols/special/url.xml @@ -0,0 +1,192 @@ + + + + q + Q + 1 + https:// + + + w + W + 2 + quoteleft + + + e + E + 3 + bar + + + r + R + 4 + U00B7 + + + t + T + 5 + squareroot + + + y + Y + 6 + Greek_pi + + + u + U + 7 + division + + + i + I + 8 + multiply + + + o + O + 9 + paragraph + + + p + P + 0 + U25B3 + + + a + A + at + copyright + + + s + S + numbersign + U00AE + + + d + D + dollar + U00A3 + + + f + F + percent + EuroSign + + + g + G + ampersand + U00A5 + + + h + H + minus + asciicircum + + + j + J + underscore + degree + + + k + K + plus + equal + + + l + L + parenleft + braceleft + + + + + parenright + braceright + + + Return + + + Shift_L + Shift_L + Shift_L + Shift_L + + + z + Z + comma + backslash + + + x + X + quotedbl + slash + + + c + C + quoteright + less + + + v + V + colon + greater + + + b + B + semicolon + equal + + + n + N + exclam + bracketleft + + + m + M + question + bracketright + + + period + + + show-numbers + show-numbers + show-letters + show-letters + + + preferences + + + space + + + BackSpace + + diff --git a/data/squeekboard.gresources.xml b/data/squeekboard.gresources.xml index bb094938..e2c7cc95 100644 --- a/data/squeekboard.gresources.xml +++ b/data/squeekboard.gresources.xml @@ -5,6 +5,7 @@ keyboards/geometry/compact.xml keyboards/geometry/extended.xml keyboards/geometry/number-keypad.xml + keyboards/geometry/url.xml keyboards/keyboards.xml keyboards/symbols/ar.xml keyboards/symbols/as-inscript.xml @@ -36,6 +37,7 @@ keyboards/symbols/us.xml keyboards/symbols/zh-bopomofo.xml keyboards/symbols/special/number.xml + keyboards/symbols/special/url.xml icons/key-enter.svg icons/key-shift.svg icons/keyboard-mode-symbolic.svg diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index 1b0f9204..9764d1b6 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -75,8 +75,10 @@ struct _EekKeyboardPrivate GList *locked_keys; GArray *outline_array; - /* Map key names to key objects: */ + /* Map key names to key objects */ GHashTable *names; + /* Map characters to symbols and levels */ + GHashTable *character_map; /* modifiers dynamically assigned at run time */ EekModifierType num_lock_mask; @@ -405,6 +407,7 @@ eek_keyboard_finalize (GObject *object) (GDestroyNotify) eek_modifier_key_free); g_hash_table_destroy (priv->names); + g_hash_table_destroy (priv->character_map); for (i = 0; i < priv->outline_array->len; i++) { EekOutline *outline = &g_array_index (priv->outline_array, @@ -533,6 +536,8 @@ eek_keyboard_init (EekKeyboard *self) self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE; self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline)); self->priv->names = g_hash_table_new (g_str_hash, g_str_equal); + self->priv->character_map = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, g_free); eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0); self->scale = 1.0; } @@ -890,3 +895,29 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard) g_free(symbols); return keymap; } + +void +eek_keyboard_register_symbol (EekKeyboard *keyboard, + EekSymbol *symbol, + EekKey *key, + guint level) +{ + const gchar *label = eek_symbol_get_label(symbol); + + if (label) { + EekKeyPress *key_press = g_malloc0 (sizeof(EekKeyPress)); + key_press->key = key; + key_press->level = level; + + g_hash_table_insert (keyboard->priv->character_map, + (gpointer)label, + key_press); + } +} + +EekKeyPress * +eek_keyboard_get_key_press (EekKeyboard *keyboard, + gchar *ch) +{ + return g_hash_table_lookup (keyboard->priv->character_map, ch); +} diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h index d841732e..52f45719 100644 --- a/eek/eek-keyboard.h +++ b/eek/eek-keyboard.h @@ -124,6 +124,11 @@ struct _EekModifierKey { }; typedef struct _EekModifierKey EekModifierKey; +struct _EekKeyPress { + EekKey *key; + guint level; +}; +typedef struct _EekKeyPress EekKeyPress; EekKeyboard *eek_keyboard_new (EekboardContextService *manager, EekLayout *layout, @@ -198,5 +203,15 @@ void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timest gchar * eek_keyboard_get_keymap (EekKeyboard *keyboard); +void eek_keyboard_register_symbol + (EekKeyboard *keyboard, + EekSymbol *symbol, + EekKey *key, + guint level); + +EekKeyPress * eek_keyboard_get_key_press + (EekKeyboard *keyboard, + gchar *ch); + G_END_DECLS #endif /* EEK_KEYBOARD_H */ diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c index 28eb843c..cdaf5023 100644 --- a/eek/eek-xml-layout.c +++ b/eek/eek-xml-layout.c @@ -749,6 +749,8 @@ symbols_end_element_callback (GMarkupParseContext *pcontext, if (data->label) { eek_symbol_set_label (symbol, data->label); + eek_keyboard_register_symbol (data->keyboard, symbol, data->key, + g_slist_length (data->symbols)); g_free (data->label); data->label = NULL; } @@ -929,6 +931,7 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager, return NULL; } + /* Arrange the sections in the original coordinate system. */ eek_layout_place_sections(keyboard); /* Use pre-defined modifier mask here. */ diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index c5d17645..d525698b 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -309,6 +309,10 @@ settings_update_layout(EekboardContextService *context) case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE: keyboard_layout = g_strdup("number"); break; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL: + keyboard_layout = g_strdup("url"); + break; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL: default: ; } diff --git a/eekboard/key-emitter.c b/eekboard/key-emitter.c index 79dbfa96..f020a74d 100644 --- a/eekboard/key-emitter.c +++ b/eekboard/key-emitter.c @@ -84,14 +84,13 @@ update_modifier_info (SeatEmitter *client) static void send_fake_key (SeatEmitter *emitter, - EekKeyboard *keyboard, + guint level, guint keycode, guint keyboard_modifiers, gboolean pressed, uint32_t timestamp) { uint32_t proto_modifiers = 0; - guint level = eek_element_get_level(EEK_ELEMENT(keyboard)); uint32_t group = (level / 2); if (keyboard_modifiers & EEK_SHIFT_MASK) @@ -102,6 +101,38 @@ send_fake_key (SeatEmitter *emitter, zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group); } +static void +send_fake_text (SeatEmitter *emitter, + EekKeyboard *keyboard, + gchar *text, + uint32_t timestamp) +{ + while (*text) { + gchar buf[7]; + gunichar c = g_utf8_get_char(text); + int n = g_unichar_to_utf8(c, buf); + *(buf + n) = 0; + + EekKeyPress *key_press = eek_keyboard_get_key_press(keyboard, buf); + + if (key_press) { + EekKey *key = key_press->key; + EekSymbolMatrix *matrix = eek_key_get_symbol_matrix(key); + EekSymbol *sym = eek_symbol_matrix_get_symbol(matrix, 0, key_press->level); + + send_fake_key (emitter, key_press->level, eek_key_get_keycode(key), + (key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0, + 1, timestamp); + + send_fake_key (emitter, key_press->level, eek_key_get_keycode(key), + (key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0, + 0, timestamp); + } + + text = g_utf8_find_next_char(text, NULL); + } +} + void emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard, @@ -142,5 +173,12 @@ emit_key_activated (EekboardContextService *manager, emitter.virtual_keyboard = manager->virtual_keyboard; emitter.keymap = keyboard->keymap; update_modifier_info (&emitter); - send_fake_key (&emitter, keyboard, keycode, modifiers, pressed, timestamp); + + guint level = eek_element_get_level(EEK_ELEMENT(keyboard)); + + if (EEK_IS_TEXT(symbol) && pressed) { + gchar *text = (gchar *)eek_text_get_text(EEK_TEXT(symbol)); + send_fake_text (&emitter, keyboard, text, timestamp); + } else + send_fake_key (&emitter, level, keycode, modifiers, pressed, timestamp); }