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);
}