[PATCH v2 3/9] text: Send more information with keysym events
Jan Arne Petersen
jpetersen at openismus.com
Thu Nov 15 02:29:47 PST 2012
From: Jan Arne Petersen <jpetersen at openismus.com>
Send state and modifier from the demo keyboard with the keysym event and
take them into account in the editor example.
Signed-off-by: Jan Arne Petersen <jpetersen at openismus.com>
---
clients/editor.c | 50 +++++++++++++++++++++++++++++---------------------
clients/keyboard.c | 32 +++++++++++++++++++++++---------
clients/window.c | 18 ++++++++++++++++++
clients/window.h | 3 +++
4 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/clients/editor.c b/clients/editor.c
index 0a52faf..7f03e2b 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -55,6 +55,7 @@ struct text_entry {
uint32_t preedit_cursor;
struct text_model *model;
struct text_layout *layout;
+ xkb_mod_mask_t shift_mask;
};
struct editor {
@@ -370,39 +371,42 @@ text_model_keysym(void *data,
uint32_t modifiers)
{
struct text_entry *entry = data;
- const char *state_label;
- const char *key_label = "released";
+ const char *state_label = "release";
+ const char *key_label = "Unknown";
const char *new_char;
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
state_label = "pressed";
}
+ if (key == XKB_KEY_Left ||
+ key == XKB_KEY_Right) {
+ if (state != WL_KEYBOARD_KEY_STATE_RELEASED)
+ return;
+
+ if (key == XKB_KEY_Left)
+ new_char = utf8_prev_char(entry->text, entry->text + entry->cursor);
+ else
+ new_char = utf8_next_char(entry->text + entry->cursor);
+
+ if (new_char != NULL) {
+ entry->cursor = new_char - entry->text;
+ if (!(modifiers & entry->shift_mask))
+ entry->anchor = entry->cursor;
+ widget_schedule_redraw(entry->widget);
+ }
+
+ return;
+ }
+
switch (key) {
case XKB_KEY_Tab:
key_label = "Tab";
break;
case XKB_KEY_KP_Enter:
+ case XKB_KEY_Return:
key_label = "Enter";
break;
- case XKB_KEY_Left:
- new_char = utf8_prev_char(entry->text, entry->text + entry->cursor);
- if (new_char != NULL) {
- entry->cursor = new_char - entry->text;
- entry->anchor = entry->cursor;
- widget_schedule_redraw(entry->widget);
- }
- break;
- case XKB_KEY_Right:
- new_char = utf8_next_char(entry->text + entry->cursor);
- if (new_char != NULL) {
- entry->cursor = new_char - entry->text;
- entry->anchor = entry->cursor;
- widget_schedule_redraw(entry->widget);
- }
- break;
- default:
- key_label = "Unknown";
}
fprintf(stderr, "%s key was %s.\n", key_label, state_label);
@@ -470,7 +474,7 @@ text_entry_create(struct editor *editor, const char *text)
{
struct text_entry *entry;
- entry = malloc(sizeof *entry);
+ entry = calloc(1, sizeof *entry);
entry->widget = widget_add_widget(editor->widget, entry);
entry->window = editor->window;
@@ -864,6 +868,10 @@ text_entry_button_handler(struct widget *widget,
widget_get_allocation(entry->widget, &allocation);
input_get_position(input, &x, &y);
+ if (!entry->shift_mask) {
+ entry->shift_mask = input_get_mod_mask(input, MOD_SHIFT_MASK);
+ }
+
if (button != BTN_LEFT) {
return;
}
diff --git a/clients/keyboard.c b/clients/keyboard.c
index d1e5dbf..2d6aa86 100644
--- a/clients/keyboard.c
+++ b/clients/keyboard.c
@@ -234,12 +234,17 @@ virtual_keyboard_commit_preedit(struct virtual_keyboard *keyboard)
}
static void
-keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key)
+keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key, struct input *input, enum wl_pointer_button_state state)
{
const char *label = keyboard->state == keyboardstate_default ? key->label : key->alt;
+ xkb_mod_mask_t mod_mask = input_get_mod_mask(input, keyboard->state == keyboardstate_default ? 0 : MOD_SHIFT_MASK);
+ uint32_t key_state = (state == WL_POINTER_BUTTON_STATE_PRESSED) ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED;
switch (key->key_type) {
case keytype_default:
+ if (state != WL_POINTER_BUTTON_STATE_PRESSED)
+ break;
+
keyboard->keyboard->preedit_string = strcat(keyboard->keyboard->preedit_string,
label);
input_method_context_preedit_string(keyboard->keyboard->context,
@@ -247,6 +252,9 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
strlen(keyboard->keyboard->preedit_string));
break;
case keytype_backspace:
+ if (state != WL_POINTER_BUTTON_STATE_PRESSED)
+ break;
+
if (strlen(keyboard->keyboard->preedit_string) == 0) {
input_method_context_delete_surrounding_text(keyboard->keyboard->context,
-1, 1);
@@ -262,55 +270,61 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
input_method_context_keysym(keyboard->keyboard->context,
display_get_serial(keyboard->keyboard->display),
time,
- XKB_KEY_KP_Enter, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
+ XKB_KEY_Return, key_state, mod_mask);
break;
case keytype_space:
+ if (state != WL_POINTER_BUTTON_STATE_PRESSED)
+ break;
keyboard->keyboard->preedit_string = strcat(keyboard->keyboard->preedit_string,
" ");
virtual_keyboard_commit_preedit(keyboard->keyboard);
break;
case keytype_switch:
+ if (state != WL_POINTER_BUTTON_STATE_PRESSED)
+ break;
if (keyboard->state == keyboardstate_default)
keyboard->state = keyboardstate_uppercase;
else
keyboard->state = keyboardstate_default;
break;
case keytype_symbols:
+ if (state != WL_POINTER_BUTTON_STATE_PRESSED)
+ break;
break;
case keytype_tab:
virtual_keyboard_commit_preedit(keyboard->keyboard);
input_method_context_keysym(keyboard->keyboard->context,
display_get_serial(keyboard->keyboard->display),
time,
- XKB_KEY_Tab, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
+ XKB_KEY_Tab, key_state, mod_mask);
break;
case keytype_arrow_up:
virtual_keyboard_commit_preedit(keyboard->keyboard);
input_method_context_keysym(keyboard->keyboard->context,
display_get_serial(keyboard->keyboard->display),
time,
- XKB_KEY_Up, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
+ XKB_KEY_Up, key_state, mod_mask);
break;
case keytype_arrow_left:
virtual_keyboard_commit_preedit(keyboard->keyboard);
input_method_context_keysym(keyboard->keyboard->context,
display_get_serial(keyboard->keyboard->display),
time,
- XKB_KEY_Left, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
+ XKB_KEY_Left, key_state, mod_mask);
break;
case keytype_arrow_right:
virtual_keyboard_commit_preedit(keyboard->keyboard);
input_method_context_keysym(keyboard->keyboard->context,
display_get_serial(keyboard->keyboard->display),
time,
- XKB_KEY_Right, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
+ XKB_KEY_Right, key_state, mod_mask);
break;
case keytype_arrow_down:
virtual_keyboard_commit_preedit(keyboard->keyboard);
input_method_context_keysym(keyboard->keyboard->context,
display_get_serial(keyboard->keyboard->display),
time,
- XKB_KEY_Down, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
+ XKB_KEY_Down, key_state, mod_mask);
break;
}
}
@@ -327,7 +341,7 @@ button_handler(struct widget *widget,
int row, col;
unsigned int i;
- if (state != WL_POINTER_BUTTON_STATE_PRESSED || button != BTN_LEFT) {
+ if (button != BTN_LEFT) {
return;
}
@@ -342,7 +356,7 @@ button_handler(struct widget *widget,
for (i = 0; i < sizeof(keys) / sizeof(*keys); ++i) {
col -= keys[i].width;
if (col < 0) {
- keyboard_handle_key(keyboard, time, &keys[i]);
+ keyboard_handle_key(keyboard, time, &keys[i], input, state);
break;
}
}
diff --git a/clients/window.c b/clients/window.c
index 288a526..a370c34 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2432,6 +2432,24 @@ input_get_modifiers(struct input *input)
return input->modifiers;
}
+xkb_mod_mask_t
+input_get_mod_mask(struct input *input, uint32_t modifier)
+{
+ xkb_mod_mask_t mod_mask = 0;
+
+ if (!input->keyboard)
+ return modifier;
+
+ if (modifier & MOD_SHIFT_MASK)
+ mod_mask |= input->xkb.shift_mask;
+ if (modifier & MOD_ALT_MASK)
+ mod_mask |= input->xkb.alt_mask;
+ if (modifier & MOD_CONTROL_MASK)
+ mod_mask |= input->xkb.control_mask;
+
+ return mod_mask;
+}
+
struct widget *
input_get_focus_widget(struct input *input)
{
diff --git a/clients/window.h b/clients/window.h
index 84846ff..6ba83b1 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -411,6 +411,9 @@ input_get_position(struct input *input, int32_t *x, int32_t *y);
uint32_t
input_get_modifiers(struct input *input);
+xkb_mod_mask_t
+input_get_mod_mask(struct input *input, uint32_t modifier);
+
void
input_grab(struct input *input, struct widget *widget, uint32_t button);
--
1.7.11.7
More information about the wayland-devel
mailing list