mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-07 03:48:02 +02:00
Merge branch 'feature/vkbd_design' into 'main'
Virtual Keyboard: Design Overhaul and Bug Fixes See merge request wayland/weston!2043
This commit is contained in:
commit
af8958ee4f
4 changed files with 361 additions and 138 deletions
|
|
@ -62,6 +62,8 @@ struct virtual_keyboard {
|
|||
bool toplevel;
|
||||
bool overlay;
|
||||
struct zwp_input_panel_surface_v1 *ips;
|
||||
|
||||
struct weston_config *config;
|
||||
};
|
||||
|
||||
enum key_type {
|
||||
|
|
@ -76,7 +78,8 @@ enum key_type {
|
|||
keytype_arrow_left,
|
||||
keytype_arrow_right,
|
||||
keytype_arrow_down,
|
||||
keytype_style
|
||||
keytype_style,
|
||||
keytype_none,
|
||||
};
|
||||
|
||||
struct key {
|
||||
|
|
@ -101,126 +104,121 @@ struct layout {
|
|||
};
|
||||
|
||||
static const struct key normal_keys[] = {
|
||||
{ keytype_default, "q", "Q", "1", 1},
|
||||
{ keytype_default, "w", "W", "2", 1},
|
||||
{ keytype_default, "e", "E", "3", 1},
|
||||
{ keytype_default, "r", "R", "4", 1},
|
||||
{ keytype_default, "t", "T", "5", 1},
|
||||
{ keytype_default, "y", "Y", "6", 1},
|
||||
{ keytype_default, "u", "U", "7", 1},
|
||||
{ keytype_default, "i", "I", "8", 1},
|
||||
{ keytype_default, "o", "O", "9", 1},
|
||||
{ keytype_default, "p", "P", "0", 1},
|
||||
{ keytype_none, "", "", "", 2},
|
||||
{ keytype_default, "q", "Q", "1", 2},
|
||||
{ keytype_default, "w", "W", "2", 2},
|
||||
{ keytype_default, "e", "E", "3", 2},
|
||||
{ keytype_default, "r", "R", "4", 2},
|
||||
{ keytype_default, "t", "T", "5", 2},
|
||||
{ keytype_default, "y", "Y", "6", 2},
|
||||
{ keytype_default, "u", "U", "7", 2},
|
||||
{ keytype_default, "i", "I", "8", 2},
|
||||
{ keytype_default, "o", "O", "9", 2},
|
||||
{ keytype_default, "p", "P", "0", 2},
|
||||
{ keytype_backspace, "<--", "<--", "<--", 2},
|
||||
|
||||
{ keytype_tab, "->|", "->|", "->|", 1},
|
||||
{ keytype_default, "a", "A", "-", 1},
|
||||
{ keytype_default, "s", "S", "@", 1},
|
||||
{ keytype_default, "d", "D", "*", 1},
|
||||
{ keytype_default, "f", "F", "^", 1},
|
||||
{ keytype_default, "g", "G", ":", 1},
|
||||
{ keytype_default, "h", "H", ";", 1},
|
||||
{ keytype_default, "j", "J", "(", 1},
|
||||
{ keytype_default, "k", "K", ")", 1},
|
||||
{ keytype_default, "l", "L", "~", 1},
|
||||
{ keytype_enter, "Enter", "Enter", "Enter", 2},
|
||||
{ keytype_tab, "->|", "->|", "->|", 3},
|
||||
{ keytype_default, "a", "A", "-", 2},
|
||||
{ keytype_default, "s", "S", "@", 2},
|
||||
{ keytype_default, "d", "D", "*", 2},
|
||||
{ keytype_default, "f", "F", "^", 2},
|
||||
{ keytype_default, "g", "G", ":", 2},
|
||||
{ keytype_default, "h", "H", ";", 2},
|
||||
{ keytype_default, "j", "J", "(", 2},
|
||||
{ keytype_default, "k", "K", ")", 2},
|
||||
{ keytype_default, "l", "L", "~", 2},
|
||||
{ keytype_enter, "Enter", "Enter", "Enter", 3},
|
||||
|
||||
{ keytype_switch, "ABC", "abc", "ABC", 4},
|
||||
{ keytype_default, "z", "Z", "/", 2},
|
||||
{ keytype_default, "x", "X", "\'", 2},
|
||||
{ keytype_default, "c", "C", "\"", 2},
|
||||
{ keytype_default, "v", "V", "+", 2},
|
||||
{ keytype_default, "b", "B", "=", 2},
|
||||
{ keytype_default, "n", "N", "?", 2},
|
||||
{ keytype_default, "m", "M", "!", 2},
|
||||
{ keytype_default, ",", ",", "\\", 2},
|
||||
{ keytype_default, ".", ".", "|", 2},
|
||||
{ keytype_switch, "ABC", "abc", "ABC", 2},
|
||||
{ keytype_default, "z", "Z", "/", 1},
|
||||
{ keytype_default, "x", "X", "\'", 1},
|
||||
{ keytype_default, "c", "C", "\"", 1},
|
||||
{ keytype_default, "v", "V", "+", 1},
|
||||
{ keytype_default, "b", "B", "=", 1},
|
||||
{ keytype_default, "n", "N", "?", 1},
|
||||
{ keytype_default, "m", "M", "!", 1},
|
||||
{ keytype_default, ",", ",", "\\", 1},
|
||||
{ keytype_default, ".", ".", "|", 1},
|
||||
{ keytype_switch, "ABC", "abc", "ABC", 1},
|
||||
|
||||
{ keytype_symbols, "?123", "?123", "abc", 1},
|
||||
{ keytype_space, "", "", "", 5},
|
||||
{ keytype_arrow_up, "/\\", "/\\", "/\\", 1},
|
||||
{ keytype_arrow_left, "<", "<", "<", 1},
|
||||
{ keytype_arrow_right, ">", ">", ">", 1},
|
||||
{ keytype_arrow_down, "\\/", "\\/", "\\/", 1},
|
||||
{ keytype_style, "", "", "", 2}
|
||||
{ keytype_symbols, "?123", "?123", "abc", 2},
|
||||
{ keytype_space, "", "", "", 10},
|
||||
{ keytype_arrow_up, "/\\", "/\\", "/\\", 2},
|
||||
{ keytype_arrow_left, "<", "<", "<", 2},
|
||||
{ keytype_arrow_right, ">", ">", ">", 2},
|
||||
{ keytype_arrow_down, "\\/", "\\/", "\\/", 2},
|
||||
{ keytype_style, "", "", "", 4}
|
||||
};
|
||||
|
||||
static const struct key numeric_keys[] = {
|
||||
{ keytype_default, "1", "1", "1", 1},
|
||||
{ keytype_default, "2", "2", "2", 1},
|
||||
{ keytype_default, "3", "3", "3", 1},
|
||||
{ keytype_default, "4", "4", "4", 1},
|
||||
{ keytype_default, "5", "5", "5", 1},
|
||||
{ keytype_default, "6", "6", "6", 1},
|
||||
{ keytype_default, "7", "7", "7", 1},
|
||||
{ keytype_default, "8", "8", "8", 1},
|
||||
{ keytype_default, "9", "9", "9", 1},
|
||||
{ keytype_default, "0", "0", "0", 1},
|
||||
{ keytype_backspace, "<--", "<--", "<--", 2},
|
||||
|
||||
{ keytype_space, "", "", "", 4},
|
||||
{ keytype_enter, "Enter", "Enter", "Enter", 2},
|
||||
{ keytype_arrow_up, "/\\", "/\\", "/\\", 1},
|
||||
{ keytype_arrow_left, "<", "<", "<", 1},
|
||||
{ keytype_arrow_right, ">", ">", ">", 1},
|
||||
{ keytype_arrow_down, "\\/", "\\/", "\\/", 1},
|
||||
{ keytype_style, "", "", "", 2}
|
||||
{ keytype_default, "7", "7", "7", 2},
|
||||
{ keytype_default, "8", "8", "8", 2},
|
||||
{ keytype_default, "9", "9", "9", 2},
|
||||
{ keytype_default, "4", "4", "4", 2},
|
||||
{ keytype_default, "5", "5", "5", 2},
|
||||
{ keytype_default, "6", "6", "6", 2},
|
||||
{ keytype_default, "1", "1", "1", 2},
|
||||
{ keytype_default, "2", "2", "2", 2},
|
||||
{ keytype_default, "3", "3", "3", 2},
|
||||
{ keytype_default, "0", "0", "0", 4},
|
||||
{ keytype_default,".", ".", ".", 2},
|
||||
{ keytype_enter, "Enter", "Enter", "Enter", 3},
|
||||
{ keytype_backspace, "<--", "<--", "<--", 3},
|
||||
};
|
||||
|
||||
static const struct key arabic_keys[] = {
|
||||
{ keytype_default, "ض", "ﹶ", "۱", 1},
|
||||
{ keytype_default, "ص", "ﹰ", "۲", 1},
|
||||
{ keytype_default, "ث", "ﹸ", "۳", 1},
|
||||
{ keytype_default, "ق", "ﹲ", "۴", 1},
|
||||
{ keytype_default, "ف", "ﻹ", "۵", 1},
|
||||
{ keytype_default, "غ", "ﺇ", "۶", 1},
|
||||
{ keytype_default, "ع", "`", "۷", 1},
|
||||
{ keytype_default, "ه", "٪", "۸", 1},
|
||||
{ keytype_default, "خ", ">", "۹", 1},
|
||||
{ keytype_default, "ح", "<", "۰", 1},
|
||||
{ keytype_backspace, "-->", "-->", "-->", 2},
|
||||
{ keytype_default, "ض", "ﹶ", "۱", 2},
|
||||
{ keytype_default, "ص", "ﹰ", "۲", 2},
|
||||
{ keytype_default, "ث", "ﹸ", "۳", 2},
|
||||
{ keytype_default, "ق", "ﹲ", "۴", 2},
|
||||
{ keytype_default, "ف", "ﻹ", "۵", 2},
|
||||
{ keytype_default, "غ", "ﺇ", "۶", 2},
|
||||
{ keytype_default, "ع", "`", "۷", 2},
|
||||
{ keytype_default, "ه", "٪", "۸", 2},
|
||||
{ keytype_default, "خ", ">", "۹", 2},
|
||||
{ keytype_default, "ح", "<", "۰", 2},
|
||||
{ keytype_backspace, "-->", "-->", "-->", 4},
|
||||
|
||||
{ keytype_tab, "->|", "->|", "->|", 1},
|
||||
{ keytype_default, "ش", "ﹺ", "ﹼ", 1},
|
||||
{ keytype_default, "س", "ﹴ", "!", 1},
|
||||
{ keytype_default, "ي", "[", "@", 1},
|
||||
{ keytype_default, "ب", "]", "#", 1},
|
||||
{ keytype_default, "ل", "ﻷ", "$", 1},
|
||||
{ keytype_default, "ا", "أ", "%", 1},
|
||||
{ keytype_default, "ت", "-", "^", 1},
|
||||
{ keytype_default, "ن", "x", "&", 1},
|
||||
{ keytype_default, "م", "/", "*", 1},
|
||||
{ keytype_default, "ك", ":", "_", 1},
|
||||
{ keytype_default, "د", "\"", "+", 1},
|
||||
{ keytype_enter, "Enter", "Enter", "Enter", 2},
|
||||
{ keytype_tab, "->|", "->|", "->|", 2},
|
||||
{ keytype_default, "ش", "ﹺ", "ﹼ", 2},
|
||||
{ keytype_default, "س", "ﹴ", "!", 2},
|
||||
{ keytype_default, "ي", "[", "@", 2},
|
||||
{ keytype_default, "ب", "]", "#", 2},
|
||||
{ keytype_default, "ل", "ﻷ", "$", 2},
|
||||
{ keytype_default, "ا", "أ", "%", 2},
|
||||
{ keytype_default, "ت", "-", "^", 2},
|
||||
{ keytype_default, "ن", "x", "&", 2},
|
||||
{ keytype_default, "م", "/", "*", 2},
|
||||
{ keytype_default, "ك", ":", "_", 2},
|
||||
{ keytype_default, "د", "\"", "+", 2},
|
||||
{ keytype_enter, "Enter", "Enter", "Enter", 4},
|
||||
|
||||
{ keytype_switch, "Shift", "Base", "Shift", 2},
|
||||
{ keytype_default, "ئ", "~", ")", 1},
|
||||
{ keytype_default, "ء", "°", "(", 1},
|
||||
{ keytype_default, "ؤ", "{", "\"", 1},
|
||||
{ keytype_default, "ر", "}", "\'", 1},
|
||||
{ keytype_default, "ى", "ﺁ", "؟", 1},
|
||||
{ keytype_default, "ة", "'", "!", 1},
|
||||
{ keytype_default, "و", ",", ";", 1},
|
||||
{ keytype_default, "ﺯ", ".", "\\", 1},
|
||||
{ keytype_default, "ظ", "؟", "=", 1},
|
||||
{ keytype_switch, "Shift", "Base", "Shift", 2},
|
||||
{ keytype_switch, "Shift", "Base", "Shift", 4},
|
||||
{ keytype_default, "ئ", "~", ")", 2},
|
||||
{ keytype_default, "ء", "°", "(", 2},
|
||||
{ keytype_default, "ؤ", "{", "\"", 2},
|
||||
{ keytype_default, "ر", "}", "\'", 2},
|
||||
{ keytype_default, "ى", "ﺁ", "؟", 2},
|
||||
{ keytype_default, "ة", "'", "!", 2},
|
||||
{ keytype_default, "و", ",", ";", 2},
|
||||
{ keytype_default, "ﺯ", ".", "\\", 2},
|
||||
{ keytype_default, "ظ", "؟", "=", 2},
|
||||
{ keytype_switch, "Shift", "Base", "Shift", 4},
|
||||
|
||||
{ keytype_symbols, "؟٣٢١", "؟٣٢١", "Base", 1},
|
||||
{ keytype_default, "ﻻ", "ﻵ", "|", 1},
|
||||
{ keytype_default, ",", "،", "،", 1},
|
||||
{ keytype_space, "", "", "", 6},
|
||||
{ keytype_default, ".", "ذ", "]", 1},
|
||||
{ keytype_default, "ط", "ﺝ", "[", 1},
|
||||
{ keytype_style, "", "", "", 2}
|
||||
{ keytype_symbols, "؟٣٢١", "؟٣٢١", "Base", 2},
|
||||
{ keytype_default, "ﻻ", "ﻵ", "|", 2},
|
||||
{ keytype_default, ",", "،", "،", 2},
|
||||
{ keytype_space, "", "", "", 12},
|
||||
{ keytype_default, ".", "ذ", "]", 2},
|
||||
{ keytype_default, "ط", "ﺝ", "[", 2},
|
||||
{ keytype_style, "", "", "", 4}
|
||||
};
|
||||
|
||||
|
||||
static const struct layout normal_layout = {
|
||||
normal_keys,
|
||||
sizeof(normal_keys) / sizeof(*normal_keys),
|
||||
12,
|
||||
24,
|
||||
4,
|
||||
"en",
|
||||
ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_LTR
|
||||
|
|
@ -229,8 +227,8 @@ static const struct layout normal_layout = {
|
|||
static const struct layout numeric_layout = {
|
||||
numeric_keys,
|
||||
sizeof(numeric_keys) / sizeof(*numeric_keys),
|
||||
12,
|
||||
2,
|
||||
6,
|
||||
5,
|
||||
"en",
|
||||
ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_LTR
|
||||
};
|
||||
|
|
@ -238,12 +236,19 @@ static const struct layout numeric_layout = {
|
|||
static const struct layout arabic_layout = {
|
||||
arabic_keys,
|
||||
sizeof(arabic_keys) / sizeof(*arabic_keys),
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
"ar",
|
||||
ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_RTL
|
||||
};
|
||||
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define max_count MAX(MAX(sizeof(arabic_keys) / sizeof(*arabic_keys), sizeof(numeric_keys) / sizeof(*numeric_keys) ), sizeof(normal_keys) / sizeof(*normal_keys))
|
||||
|
||||
#define min_columns MIN(MIN(normal_layout.columns, numeric_layout.columns), arabic_layout.columns)
|
||||
#define min_rows MIN(MIN(normal_layout.rows, numeric_layout.rows), arabic_layout.rows)
|
||||
|
||||
static const char *style_labels[] = {
|
||||
"default",
|
||||
"none",
|
||||
|
|
@ -255,8 +260,8 @@ static const char *style_labels[] = {
|
|||
"incorrect"
|
||||
};
|
||||
|
||||
static const double key_width = 60;
|
||||
static const double key_height = 50;
|
||||
static const double key_width = 30;
|
||||
static const double key_height = 60;
|
||||
|
||||
enum keyboard_state {
|
||||
KEYBOARD_STATE_DEFAULT,
|
||||
|
|
@ -270,6 +275,22 @@ struct keyboard {
|
|||
struct widget *widget;
|
||||
|
||||
enum keyboard_state state;
|
||||
uint32_t key_state[max_count];
|
||||
int32_t key_touch_event_id[max_count];
|
||||
|
||||
uint32_t key_margin;
|
||||
uint32_t key_radius;
|
||||
|
||||
uint32_t key_fg_color;
|
||||
uint32_t key_bg_color;
|
||||
uint32_t key_pressed_fg_color;
|
||||
uint32_t key_pressed_bg_color;
|
||||
uint32_t special_key_fg_color;
|
||||
uint32_t special_key_bg_color;
|
||||
uint32_t special_key_pressed_fg_color;
|
||||
uint32_t special_key_pressed_bg_color;
|
||||
uint32_t panel_fg_color;
|
||||
uint32_t panel_bg_color;
|
||||
};
|
||||
|
||||
static void __attribute__ ((format (printf, 1, 2)))
|
||||
|
|
@ -284,6 +305,29 @@ dbg(const char *fmt, ...)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
set_hex_color(cairo_t *cr, uint32_t color)
|
||||
{
|
||||
cairo_set_source_rgba(cr,
|
||||
((color >> 16) & 0xff) / 255.0,
|
||||
((color >> 8) & 0xff) / 255.0,
|
||||
((color >> 0) & 0xff) / 255.0,
|
||||
((color >> 24) & 0xff) / 255.0);
|
||||
}
|
||||
|
||||
static bool
|
||||
contains_decimal_point(const char* str)
|
||||
{
|
||||
for (size_t i = 0; i < strlen(str); ++i)
|
||||
{
|
||||
if (str[i] == '.')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *
|
||||
label_from_key(struct keyboard *keyboard,
|
||||
const struct key *key)
|
||||
|
|
@ -291,6 +335,9 @@ label_from_key(struct keyboard *keyboard,
|
|||
if (key->key_type == keytype_style)
|
||||
return style_labels[keyboard->keyboard->preedit_style];
|
||||
|
||||
if (key->key_type == keytype_none)
|
||||
return "";
|
||||
|
||||
switch(keyboard->state) {
|
||||
case KEYBOARD_STATE_DEFAULT:
|
||||
return key->label;
|
||||
|
|
@ -303,26 +350,62 @@ label_from_key(struct keyboard *keyboard,
|
|||
return "";
|
||||
}
|
||||
|
||||
static void
|
||||
rounded_rectangle_path(cairo_t *cr, double x, double y, double width, double height, double radius)
|
||||
{
|
||||
double degrees = M_PI / 180.0;
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
|
||||
cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
|
||||
cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
|
||||
cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
|
||||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_key(struct keyboard *keyboard,
|
||||
const struct key *key,
|
||||
uint32_t key_state,
|
||||
cairo_t *cr,
|
||||
unsigned int row,
|
||||
unsigned int col)
|
||||
{
|
||||
const uint32_t margin = keyboard->key_margin;
|
||||
const char *label;
|
||||
cairo_text_extents_t extents;
|
||||
|
||||
uint32_t fg_color = keyboard->key_fg_color;
|
||||
uint32_t bg_color = keyboard->key_bg_color;
|
||||
|
||||
if (key_state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
fg_color = (key->key_type == keytype_default ? keyboard->key_fg_color : keyboard->special_key_fg_color);
|
||||
bg_color = (key->key_type == keytype_default ? keyboard->key_bg_color : keyboard->special_key_bg_color);
|
||||
} else {
|
||||
fg_color = (key->key_type == keytype_default ? keyboard->key_pressed_fg_color : keyboard->special_key_pressed_fg_color);
|
||||
bg_color = (key->key_type == keytype_default ? keyboard->key_pressed_bg_color : keyboard->special_key_pressed_bg_color);
|
||||
}
|
||||
|
||||
if (key->key_type == keytype_none)
|
||||
return;
|
||||
|
||||
cairo_save(cr);
|
||||
cairo_rectangle(cr,
|
||||
col * key_width, row * key_height,
|
||||
key->width * key_width, key_height);
|
||||
cairo_clip(cr);
|
||||
rounded_rectangle_path(cr,
|
||||
col * key_width + margin, row * key_height + margin,
|
||||
key->width * key_width - 2*margin, key_height - 2*margin,
|
||||
key_width / 5);
|
||||
|
||||
|
||||
/* Paint key background */
|
||||
set_hex_color(cr, bg_color);
|
||||
cairo_fill_preserve(cr);
|
||||
|
||||
/* Paint frame */
|
||||
cairo_rectangle(cr,
|
||||
col * key_width, row * key_height,
|
||||
key->width * key_width, key_height);
|
||||
set_hex_color(cr, fg_color);
|
||||
cairo_set_line_width(cr, 3);
|
||||
cairo_stroke(cr);
|
||||
|
||||
|
|
@ -377,21 +460,22 @@ redraw_handler(struct widget *widget, void *data)
|
|||
cairo_rectangle(cr, allocation.x, allocation.y, allocation.width, allocation.height);
|
||||
cairo_clip(cr);
|
||||
|
||||
cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
|
||||
cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||
cairo_set_font_size(cr, 16);
|
||||
|
||||
cairo_translate(cr, allocation.x, allocation.y);
|
||||
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_rgba(cr, 1, 1, 1, 0.75);
|
||||
cairo_rectangle(cr, 0, 0, layout->columns * key_width, layout->rows * key_height);
|
||||
cairo_paint(cr);
|
||||
set_hex_color(cr, keyboard->panel_bg_color);
|
||||
cairo_fill_preserve(cr);
|
||||
set_hex_color(cr, keyboard->panel_fg_color);
|
||||
cairo_stroke(cr);
|
||||
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
|
||||
for (i = 0; i < layout->count; ++i) {
|
||||
cairo_set_source_rgb(cr, 0, 0, 0);
|
||||
draw_key(keyboard, &layout->keys[i], cr, row, col);
|
||||
draw_key(keyboard, &layout->keys[i], keyboard->key_state[i], cr, row, col);
|
||||
col += layout->keys[i].width;
|
||||
if (col >= layout->columns) {
|
||||
row += 1;
|
||||
|
|
@ -486,6 +570,22 @@ prev_utf8_char(const char *s, const char *p)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int utf8_char_size(const char* c)
|
||||
{
|
||||
if (c != NULL)
|
||||
{
|
||||
if ((*c & 0x80) == 0)
|
||||
return 1;
|
||||
if ((*c & 0xe0) == 0xc0)
|
||||
return 2;
|
||||
if ((*c & 0xf0) == 0xe0)
|
||||
return 3;
|
||||
if ((*c & 0xf8) == 0xf0)
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
delete_before_cursor(struct virtual_keyboard *keyboard)
|
||||
{
|
||||
|
|
@ -506,8 +606,8 @@ delete_before_cursor(struct virtual_keyboard *keyboard)
|
|||
end = keyboard->surrounding_text + keyboard->surrounding_cursor;
|
||||
|
||||
zwp_input_method_context_v1_delete_surrounding_text(keyboard->context,
|
||||
start - keyboard->surrounding_text,
|
||||
end - start);
|
||||
(start - keyboard->surrounding_text) - keyboard->surrounding_cursor,
|
||||
0);
|
||||
zwp_input_method_context_v1_commit_string(keyboard->context,
|
||||
keyboard->serial,
|
||||
"");
|
||||
|
|
@ -535,8 +635,13 @@ append(char *s1, const char *s2)
|
|||
}
|
||||
|
||||
static void
|
||||
keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key, struct input *input, enum wl_pointer_button_state state)
|
||||
keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key, uint32_t key_num, struct input *input, enum wl_pointer_button_state state)
|
||||
{
|
||||
if (keyboard->keyboard->context == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char *label = NULL;
|
||||
|
||||
switch(keyboard->state) {
|
||||
|
|
@ -551,14 +656,27 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
|
|||
break;
|
||||
}
|
||||
|
||||
xkb_mod_mask_t mod_mask = keyboard->state == KEYBOARD_STATE_DEFAULT ? 0 : keyboard->keyboard->keysym.shift_mask;
|
||||
xkb_mod_mask_t mod_mask = (keyboard->state == KEYBOARD_STATE_DEFAULT) ? 0 : keyboard->keyboard->keysym.shift_mask;
|
||||
uint32_t key_state = (state == WL_POINTER_BUTTON_STATE_PRESSED) ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||
|
||||
keyboard->key_state[key_num] = key_state;
|
||||
|
||||
switch (key->key_type) {
|
||||
case keytype_default:
|
||||
if (state != WL_POINTER_BUTTON_STATE_PRESSED)
|
||||
break;
|
||||
|
||||
// Check if content purpose is number
|
||||
if ((((keyboard->keyboard->content_purpose == ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DIGITS) ||
|
||||
(keyboard->keyboard->content_purpose == ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NUMBER)) &&
|
||||
contains_decimal_point(label)) &&
|
||||
(contains_decimal_point(keyboard->keyboard->surrounding_text) ||
|
||||
contains_decimal_point(keyboard->keyboard->preedit_string)))
|
||||
{
|
||||
// Do not enter a second decimal point.
|
||||
return;
|
||||
}
|
||||
|
||||
keyboard->keyboard->preedit_string =
|
||||
append(keyboard->keyboard->preedit_string,
|
||||
label);
|
||||
|
|
@ -571,7 +689,23 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
|
|||
if (strlen(keyboard->keyboard->preedit_string) == 0) {
|
||||
delete_before_cursor(keyboard->keyboard);
|
||||
} else {
|
||||
keyboard->keyboard->preedit_string[strlen(keyboard->keyboard->preedit_string) - 1] = '\0';
|
||||
const size_t len = strlen(keyboard->keyboard->preedit_string);
|
||||
const char *prev_utf8 = prev_utf8_char(keyboard->keyboard->preedit_string + (len - MIN(len, 4)),
|
||||
keyboard->keyboard->preedit_string + strlen(keyboard->keyboard->preedit_string));
|
||||
|
||||
if (prev_utf8)
|
||||
{
|
||||
const int pref_utf8_offset = prev_utf8 - keyboard->keyboard->preedit_string;
|
||||
if ((strlen(keyboard->keyboard->preedit_string + pref_utf8_offset) - utf8_char_size(prev_utf8)) == 0)
|
||||
{
|
||||
keyboard->keyboard->preedit_string[pref_utf8_offset] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard->keyboard->preedit_string[strlen(keyboard->keyboard->preedit_string) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
virtual_keyboard_send_preedit(keyboard->keyboard, -1);
|
||||
}
|
||||
break;
|
||||
|
|
@ -594,14 +728,12 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
|
|||
break;
|
||||
switch(keyboard->state) {
|
||||
case KEYBOARD_STATE_DEFAULT:
|
||||
case KEYBOARD_STATE_SYMBOLS:
|
||||
keyboard->state = KEYBOARD_STATE_UPPERCASE;
|
||||
break;
|
||||
case KEYBOARD_STATE_UPPERCASE:
|
||||
keyboard->state = KEYBOARD_STATE_DEFAULT;
|
||||
break;
|
||||
case KEYBOARD_STATE_SYMBOLS:
|
||||
keyboard->state = KEYBOARD_STATE_UPPERCASE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case keytype_symbols:
|
||||
|
|
@ -609,8 +741,6 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
|
|||
break;
|
||||
switch(keyboard->state) {
|
||||
case KEYBOARD_STATE_DEFAULT:
|
||||
keyboard->state = KEYBOARD_STATE_SYMBOLS;
|
||||
break;
|
||||
case KEYBOARD_STATE_UPPERCASE:
|
||||
keyboard->state = KEYBOARD_STATE_SYMBOLS;
|
||||
break;
|
||||
|
|
@ -660,6 +790,8 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
|
|||
keyboard->keyboard->preedit_style = (keyboard->keyboard->preedit_style + 1) % 8; /* TODO */
|
||||
virtual_keyboard_send_preedit(keyboard->keyboard, -1);
|
||||
break;
|
||||
case keytype_none:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -669,6 +801,10 @@ button_handler(struct widget *widget,
|
|||
uint32_t button,
|
||||
enum wl_pointer_button_state state, void *data)
|
||||
{
|
||||
if (button != BTN_LEFT) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct keyboard *keyboard = data;
|
||||
struct rectangle allocation;
|
||||
int32_t x, y;
|
||||
|
|
@ -678,10 +814,6 @@ button_handler(struct widget *widget,
|
|||
|
||||
layout = get_current_layout(keyboard->keyboard);
|
||||
|
||||
if (button != BTN_LEFT) {
|
||||
return;
|
||||
}
|
||||
|
||||
input_get_position(input, &x, &y);
|
||||
|
||||
widget_get_allocation(keyboard->widget, &allocation);
|
||||
|
|
@ -689,11 +821,11 @@ button_handler(struct widget *widget,
|
|||
y -= allocation.y;
|
||||
|
||||
row = y / key_height;
|
||||
col = x / key_width + row * layout->columns;
|
||||
col = x / (key_width + (row * layout->columns));
|
||||
for (i = 0; i < layout->count; ++i) {
|
||||
col -= layout->keys[i].width;
|
||||
if (col < 0) {
|
||||
keyboard_handle_key(keyboard, time, &layout->keys[i], input, state);
|
||||
keyboard_handle_key(keyboard, time, &layout->keys[i], i, input, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -702,7 +834,7 @@ button_handler(struct widget *widget,
|
|||
}
|
||||
|
||||
static void
|
||||
touch_handler(struct input *input, uint32_t time,
|
||||
touch_handler(struct input *input, uint32_t time, int32_t id,
|
||||
float x, float y, uint32_t state, void *data)
|
||||
{
|
||||
struct keyboard *keyboard = data;
|
||||
|
|
@ -723,8 +855,9 @@ touch_handler(struct input *input, uint32_t time,
|
|||
for (i = 0; i < layout->count; ++i) {
|
||||
col -= layout->keys[i].width;
|
||||
if (col < 0) {
|
||||
keyboard->key_touch_event_id[i] = id;
|
||||
keyboard_handle_key(keyboard, time,
|
||||
&layout->keys[i], input, state);
|
||||
&layout->keys[i], i, input, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -737,7 +870,7 @@ touch_down_handler(struct widget *widget, struct input *input,
|
|||
uint32_t serial, uint32_t time, int32_t id,
|
||||
float x, float y, void *data)
|
||||
{
|
||||
touch_handler(input, time, x, y,
|
||||
touch_handler(input, time, id, x, y,
|
||||
WL_POINTER_BUTTON_STATE_PRESSED, data);
|
||||
}
|
||||
|
||||
|
|
@ -746,11 +879,21 @@ touch_up_handler(struct widget *widget, struct input *input,
|
|||
uint32_t serial, uint32_t time, int32_t id,
|
||||
void *data)
|
||||
{
|
||||
float x, y;
|
||||
struct keyboard *keyboard = data;
|
||||
|
||||
input_get_touch(input, id, &x, &y);
|
||||
for (size_t i = 0; i < max_count; ++i)
|
||||
{
|
||||
if (id == keyboard->key_touch_event_id[i])
|
||||
{
|
||||
keyboard->key_touch_event_id[i] = -1;
|
||||
keyboard->key_state[i] = WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
touch_handler(input, time, x, y,
|
||||
float x, y;
|
||||
input_get_touch(input, id, &x, &y);
|
||||
|
||||
touch_handler(input, time, id, x, y,
|
||||
WL_POINTER_BUTTON_STATE_RELEASED, data);
|
||||
}
|
||||
|
||||
|
|
@ -791,8 +934,28 @@ handle_content_type(void *data,
|
|||
{
|
||||
struct virtual_keyboard *keyboard = data;
|
||||
|
||||
keyboard->content_hint = hint;
|
||||
keyboard->content_purpose = purpose;
|
||||
if ((keyboard->content_hint != hint) || (keyboard->content_purpose != purpose))
|
||||
{
|
||||
keyboard->content_hint = hint;
|
||||
keyboard->content_purpose = purpose;
|
||||
|
||||
// A change of the content type means a new layout.
|
||||
// So we have to update.
|
||||
const struct layout *layout = get_current_layout(keyboard);
|
||||
|
||||
zwp_input_method_context_v1_language(context,
|
||||
keyboard->serial,
|
||||
layout->language);
|
||||
zwp_input_method_context_v1_text_direction(context,
|
||||
keyboard->serial,
|
||||
layout->text_direction);
|
||||
|
||||
window_schedule_resize(keyboard->keyboard->window,
|
||||
layout->columns * key_width,
|
||||
layout->rows * key_height);
|
||||
|
||||
widget_schedule_redraw(keyboard->keyboard->widget);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1011,6 +1174,7 @@ keyboard_create(struct virtual_keyboard *virtual_keyboard)
|
|||
window_set_appid(keyboard->window,
|
||||
"org.freedesktop.weston.virtual-keyboard");
|
||||
window_set_user_data(keyboard->window, keyboard);
|
||||
window_set_min_allocation(keyboard->window, min_columns * (int32_t)key_width, min_rows * (int32_t)key_height);
|
||||
|
||||
widget_set_redraw_handler(keyboard->widget, redraw_handler);
|
||||
widget_set_resize_handler(keyboard->widget, resize_handler);
|
||||
|
|
@ -1043,6 +1207,45 @@ keyboard_destroy(struct virtual_keyboard *virtual_keyboard)
|
|||
free(virtual_keyboard->keyboard);
|
||||
}
|
||||
|
||||
static void
|
||||
config_load(struct virtual_keyboard *virtual_keyboard)
|
||||
{
|
||||
struct weston_config_section *s;
|
||||
const char *config_file;
|
||||
config_file = weston_config_get_name_from_env();
|
||||
virtual_keyboard->config = weston_config_parse(config_file);
|
||||
s = weston_config_get_section(virtual_keyboard->config, "keyboard", NULL, NULL);
|
||||
|
||||
weston_config_section_get_uint(s, "key-margin", &virtual_keyboard->keyboard->key_margin, 0);
|
||||
weston_config_section_get_uint(s, "key-radius", &virtual_keyboard->keyboard->key_radius, 0);
|
||||
|
||||
weston_config_section_get_color(s, "key-fg",
|
||||
&virtual_keyboard->keyboard->key_fg_color, 0xcc000000);
|
||||
weston_config_section_get_color(s, "key-bg",
|
||||
&virtual_keyboard->keyboard->key_bg_color, 0xccffffff);
|
||||
weston_config_section_get_color(s, "key-pressed-fg",
|
||||
&virtual_keyboard->keyboard->key_pressed_fg_color, 0xcc000000);
|
||||
weston_config_section_get_color(s, "key-pressed-bg",
|
||||
&virtual_keyboard->keyboard->key_pressed_bg_color, 0xccffffff);
|
||||
weston_config_section_get_color(s, "special-key-fg",
|
||||
&virtual_keyboard->keyboard->special_key_fg_color, 0xcc000000);
|
||||
weston_config_section_get_color(s, "special-key-bg",
|
||||
&virtual_keyboard->keyboard->special_key_bg_color, 0xccffffff);
|
||||
weston_config_section_get_color(s, "special-key-pressed-fg",
|
||||
&virtual_keyboard->keyboard->special_key_pressed_fg_color, 0xcc000000);
|
||||
weston_config_section_get_color(s, "special-key-pressed-bg",
|
||||
&virtual_keyboard->keyboard->special_key_pressed_bg_color, 0xccffffff);
|
||||
weston_config_section_get_color(s, "panel-bg",
|
||||
&virtual_keyboard->keyboard->panel_bg_color, 0xccffffff);
|
||||
weston_config_section_get_color(s, "panel-fg",
|
||||
&virtual_keyboard->keyboard->panel_fg_color, 0xcc000000);
|
||||
}
|
||||
|
||||
static void config_destroy(struct virtual_keyboard *virtual_keyboard)
|
||||
{
|
||||
weston_config_destroy(virtual_keyboard->config);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
|
@ -1067,10 +1270,13 @@ main(int argc, char *argv[])
|
|||
|
||||
keyboard_create(&virtual_keyboard);
|
||||
|
||||
config_load(&virtual_keyboard);
|
||||
|
||||
display_run(virtual_keyboard.display);
|
||||
|
||||
keyboard_destroy(&virtual_keyboard);
|
||||
display_destroy(virtual_keyboard.display);
|
||||
config_destroy(&virtual_keyboard);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4871,6 +4871,12 @@ window_is_resizing(struct window *window)
|
|||
return window->resizing;
|
||||
}
|
||||
|
||||
void window_set_min_allocation(struct window *window, int32_t width, int32_t height)
|
||||
{
|
||||
window->min_allocation.width = width;
|
||||
window->min_allocation.height = height;
|
||||
}
|
||||
|
||||
void
|
||||
window_set_minimized(struct window *window)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -481,6 +481,9 @@ window_set_maximized(struct window *window, int maximized);
|
|||
int
|
||||
window_is_resizing(struct window *window);
|
||||
|
||||
void
|
||||
window_set_min_allocation(struct window *window, int32_t width, int32_t height);
|
||||
|
||||
void
|
||||
window_set_minimized(struct window *window);
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,15 @@ input_panel_committed(struct weston_surface *surface,
|
|||
return;
|
||||
|
||||
if (weston_surface_is_mapped(surface))
|
||||
{
|
||||
if (shell->showing_input_panels)
|
||||
{
|
||||
struct weston_coord_global pos;
|
||||
if (!calc_input_panel_position(ip_surface, &pos))
|
||||
weston_view_set_position(ip_surface->view, pos);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
weston_surface_map(surface);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue