Skip to content
Commits on Source (27)
......@@ -6,25 +6,65 @@
### How to reproduce
Please provide steps to reproduce the issue. If possible, please attach
screenshot.
<!-- Please provide steps to reproduce the issue. If possible and relevant, please attach screenshots or videos demonstrating the unwanted behaviour. -->
### How easily reproducible is it?
<!-- Keep one: -->
Always.
More than half of the time.
Sometimes, not more than half of the time.
Occasionally.
Only happened once.
## Which version did you encounter the bug in?
- [ ] I Compiled it myself. If you compiled virtboard from source please provide the
git revision via e.g. by running ``git log -1 --pretty=oneline`` and pasting
the output below.
<!-- Keep only the relevant one(s): -->
I Compiled it myself.
<!-- If you compiled virtboard from source, please check if a clean build on a new git checkout is affected. Please provide:
- the git revision via e.g. by running `git log -1 --pretty=oneline`
- the exact build command & config used) -->
I used the precompiled Debian package.
<!-- Please paste the output of `dpkg -s virtboard` below.-->
- [ ] I used the precompiled Debian package (e.g. by running a prebuilt
image). Please paste the output oof ``dpkg -s virtboard`` below.
## What OS is affected?
<!-- Keep only the relevant one(s): -->
- PureOS
- Purism dev image
- Debian testing
- Other (which?)
## What compositor did you use?
<!-- Keep only the relevant one(s): -->
- rootston (dev image default)
- rootston (from other source than the dev image) <!-- Please provide details -->
- sway (from what source?)
- other (which?)
## What hardware are you running virtboard on?
- [ ] amd64 qemu image
- [ ] Librem5 devkit
- [ ] other (please elaborte)
<!-- Keep only the relevant one(s): -->
- amd64 qemu image
- Librem5 devkit
- other (which?)
## Releveant logfiles
Please provide relevant logs. You can e.g. the logs since last boot read
with ``journalctl -b 0``.
<!-- Please provide relevant logs:
- Wayland logs can be obtained by running `WAYLAND_DEBUG=1 virtboard`
- Core dumps can be found and viewed using `coredumpctl`
- Core dumps can be acquired by running `gdb path/to/virtboard`
- Logs since last boot can be read with `journalctl -b 0`
-->
......@@ -3,6 +3,7 @@ Copyright © 2010-2012 Intel Corporation
Copyright © 2010-2011 Benjamin Franzke
Copyright © 2011-2012 Collabora, Ltd.
Copyright © 2010 Red Hat <mjg@redhat.com>
Copyright © 2018 Purism, SPC
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
......
......@@ -41,7 +41,6 @@
#include <linux/input.h>
#include <cairo.h>
#include <systemd/sd-bus.h>
#include "keymap.h"
#include "window.h"
......@@ -89,6 +88,7 @@ struct virtual_keyboard {
char *preferred_layout;
uint32_t buttons_held;
bool scheduled_hidden; // the keyboard should hide as soon as buttons_held == 0
};
/// Modifiers passed to the virtual_keyboard protocol.
......@@ -98,6 +98,7 @@ enum key_modifier_type {
modifier_shift = 1,
modifier_capslock = 2,
modifier_ctrl = 4,
modifier_super = 64,
modifier_altgr = 128,
};
......@@ -114,6 +115,8 @@ enum key_type {
keytype_arrow_right,
keytype_arrow_down,
keytype_ctrl,
keytype_super,
keytype_esc,
};
struct key {
......@@ -165,7 +168,7 @@ static const struct key normal_keys[] = {
{ keytype_default, "j", "J", "(", NULL, KEY_J, 1},
{ keytype_default, "k", "K", ")", NULL, KEY_K, 1},
{ keytype_default, "l", "L", "~", NULL, KEY_L, 1},
{ keytype_enter, "↵", "↵", "↵", NULL, 0, 2},
{ keytype_enter, "↵", "↵", "↵", NULL, KEY_ENTER, 2},
{ keytype_caps, "ABC", "abc", "ABC", NULL, 0, 2},
{ keytype_default, "z", "Z", "/", NULL, KEY_Z, 1},
......@@ -177,15 +180,16 @@ static const struct key normal_keys[] = {
{ keytype_default, "m", "M", "!", NULL, KEY_M, 1},
{ keytype_default, ",", ",", "\\", NULL, KEY_COMMA, 1},
{ keytype_default, ".", ".", "|", NULL, KEY_DOT, 1},
{ keytype_caps, "ABC", "abc", "ABC", NULL, 0, 1},
{ keytype_esc, "esc", "esc", "esc", NULL, KEY_ESC, 1},
{ keytype_altgr, "?123", "?123", "abc", NULL, 0, 1},
{ keytype_space, "", "", "", NULL, 0, 5},
{ keytype_ctrl, "Ctrl", "Ctrl", "Ctrl", NULL, 0, 2},
{ keytype_super, "Super", "Super", "Super", NULL, 0, 2},
{ keytype_space, "", "", "", NULL, 0, 3},
{ keytype_arrow_up, "↑", "↑", "↑", NULL, 0, 1},
{ keytype_arrow_left, "←", "←", "←", NULL, 0, 1},
{ keytype_arrow_right, "→", "→", "→", NULL, 0, 1},
{ keytype_arrow_down, "↓", "↓", "↓", NULL, 0, 1},
{ keytype_ctrl, "Ctrl", "Ctrl", "Ctrl", NULL, 0, 2}
{ keytype_altgr, "123", "123", "abc", NULL, 0, 1},
};
static const struct key polish_keys[] = {
......@@ -211,7 +215,7 @@ static const struct key polish_keys[] = {
{ keytype_default, "j", "J", ")", "}", KEY_J, 1},
{ keytype_default, "k", "K", "ó", "Ó", KEY_K, 1},
{ keytype_default, "l", "L", "ł", "Ł", KEY_L, 1},
{ keytype_enter, "↵", "↵", "↵", NULL, 0, 2},
{ keytype_enter, "↵", "↵", "↵", NULL, KEY_ENTER, 2},
{ keytype_caps, "ABC", "abc", "abc", NULL, 0, 2},
{ keytype_default, "z", "Z", "ż", "Ż", KEY_Z, 1},
......@@ -248,7 +252,7 @@ static const struct key numeric_keys[] = {
{ keytype_backspace, "<--", "<--", "<--", NULL, 0, 2},
{ keytype_space, "", "", "", NULL, 0, 4},
{ keytype_enter, "Enter", "Enter", "Enter", NULL, 0, 2},
{ keytype_enter, "Enter", "Enter", "Enter", NULL, KEY_ENTER, 2},
{ keytype_arrow_up, "/\\", "/\\", "/\\", NULL, 0, 1},
{ keytype_arrow_left, "<", "<", "<", NULL, 0, 1},
{ keytype_arrow_right, ">", ">", ">", NULL, 0, 1},
......@@ -280,7 +284,7 @@ static const struct key arabic_keys[] = {
{ keytype_default, "م", "/", "*", NULL, 0, 1},
{ keytype_default, "ك", ":", "_", NULL, 0, 1},
{ keytype_default, "د", "\"", "+", NULL, 0, 1},
{ keytype_enter, "Enter", "Enter", "Enter", NULL, 0, 2},
{ keytype_enter, "Enter", "Enter", "Enter", NULL, KEY_ENTER, 2},
{ keytype_caps, "Shift", "Base", "Shift", NULL, 0, 2},
{ keytype_default, "ئ", "~", ")", NULL, 0, 1},
......@@ -353,7 +357,7 @@ static const unsigned layouts_count = sizeof(layouts) / sizeof (*layouts);
static const char* default_keymap_str = keymap_normal;
static const double key_width = 60;
static const double key_height = 50;
static const double key_height = 80;
enum keyboard_state {
KEYBOARD_STATE_DEFAULT,
......@@ -369,6 +373,7 @@ struct keyboard {
enum keyboard_state state;
bool ctrl_on;
bool super_on;
uint32_t scale; // output scale
double width; // width in output units
......@@ -440,25 +445,28 @@ draw_key(struct keyboard *keyboard, const struct key *key, cairo_t *cr,
key->width * key_width, key_height);
cairo_clip(cr);
if (key->key_type == keytype_ctrl && keyboard->ctrl_on) {
if ((key->key_type == keytype_ctrl && keyboard->ctrl_on) ||
(key->key_type == keytype_super && keyboard->super_on)) {
cairo_rectangle(cr,
col * key_width, row * key_height,
key->width * key_width, key_height);
cairo_fill(cr);
cairo_set_source_rgb(cr, 1, 1, 1);
} else {
/* Paint frame */
cairo_rectangle(cr,
col * key_width, row * key_height,
key->width * key_width, key_height);
cairo_set_line_width(cr, 3);
cairo_stroke(cr);
}
/* Paint frame */
cairo_rectangle(cr,
col * key_width, row * key_height,
key->width * key_width, key_height);
cairo_set_line_width(cr, 3);
cairo_stroke(cr);
/* Paint text */
label = label_from_key(keyboard, key);
cairo_text_extents(cr, label, &extents);
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_translate(cr,
col * key_width,
row * key_height);
......@@ -524,10 +532,10 @@ redraw_handler(struct widget *widget, void *data)
/ (layout->columns * key_width);
cairo_scale(cr, scale, scale);
cairo_select_font_face(cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 16);
cairo_set_font_size(cr, 20);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(cr, 1, 1, 1, 0.75);
cairo_set_source_rgb(cr, 0.27450980392156865, 0.26666666666666666, 0.2823529411764706);
cairo_rectangle(cr, 0, 0, layout->columns * key_width, layout->rows * key_height);
cairo_paint(cr);
......@@ -675,6 +683,7 @@ append(char *s1, const char *s2)
static void keyboard_update_mods(struct keyboard *keyboard) {
unsigned mods = keyboard->ctrl_on ? modifier_ctrl : modifier_none;
mods |= keyboard->super_on ? modifier_super : modifier_none;
unsigned locked = 0;
switch(keyboard->state) {
case KEYBOARD_STATE_DEFAULT:
......@@ -694,6 +703,9 @@ static void keyboard_update_mods(struct keyboard *keyboard) {
mods, 0, locked, 0);
}
static void
try_hide(struct virtual_keyboard *keyboard);
static void
keyboard_handle_key(struct keyboard *keyboard, const struct layout *layout,
uint32_t time, const struct key *key,
......@@ -712,7 +724,9 @@ keyboard_handle_key(struct keyboard *keyboard, const struct layout *layout,
switch (key->key_type) {
case keytype_default:
if (!keyboard->keyboard->current.active || keyboard->ctrl_on) {
if (!keyboard->keyboard->current.active
|| keyboard->ctrl_on
|| keyboard->super_on) {
zwp_virtual_keyboard_v1_key(keyboard->keyboard->virtual_keyboard,
time, key->keycode, key_state);
break;
......@@ -729,7 +743,8 @@ keyboard_handle_key(struct keyboard *keyboard, const struct layout *layout,
if (!keyboard->keyboard->current.active
|| (strlen(keyboard->keyboard->preedit_string) == 0
&& strlen(keyboard->keyboard->current.surrounding_text) == 0)
|| keyboard->ctrl_on) {
|| keyboard->ctrl_on
|| keyboard->super_on) {
zwp_virtual_keyboard_v1_key(keyboard->keyboard->virtual_keyboard,
time,
KEY_BACKSPACE, key_state);
......@@ -746,16 +761,20 @@ keyboard_handle_key(struct keyboard *keyboard, const struct layout *layout,
virtual_keyboard_send_preedit(keyboard->keyboard, -1);
}
break;
case keytype_tab:
case keytype_esc:
case keytype_enter:
if (state == WL_POINTER_BUTTON_STATE_PRESSED
&& keyboard->keyboard->current.active) {
virtual_keyboard_commit_preedit(keyboard->keyboard);
}
zwp_virtual_keyboard_v1_key(keyboard->keyboard->virtual_keyboard,
time, KEY_ENTER, key_state);
time, key->keycode, key_state);
break;
case keytype_space:
if (!keyboard->keyboard->current.active || keyboard->ctrl_on) {
if (!keyboard->keyboard->current.active
|| keyboard->ctrl_on
|| keyboard->super_on) {
zwp_virtual_keyboard_v1_key(keyboard->keyboard->virtual_keyboard,
time, KEY_SPACE, key_state);
break;
......@@ -813,14 +832,6 @@ keyboard_handle_key(struct keyboard *keyboard, const struct layout *layout,
}
keyboard_update_mods(keyboard);
break;
case keytype_tab:
if (state != WL_POINTER_BUTTON_STATE_PRESSED
&& keyboard->keyboard->current.active) {
virtual_keyboard_commit_preedit(keyboard->keyboard);
}
zwp_virtual_keyboard_v1_key(keyboard->keyboard->virtual_keyboard,
time, KEY_TAB, key_state);
break;
case keytype_arrow_up:
if (state != WL_POINTER_BUTTON_STATE_PRESSED
&& keyboard->keyboard->current.active) {
......@@ -860,9 +871,20 @@ keyboard_handle_key(struct keyboard *keyboard, const struct layout *layout,
keyboard->ctrl_on ^= true;
keyboard_update_mods(keyboard);
break;
case keytype_super:
if (state != WL_POINTER_BUTTON_STATE_PRESSED)
break;
keyboard->super_on ^= true;
keyboard_update_mods(keyboard);
break;
default:
dbg("Keytype invalid\n");
}
if (keyboard->keyboard->scheduled_hidden
&& keyboard->keyboard->buttons_held == 0) {
try_hide(keyboard->keyboard);
}
}
static int
......@@ -870,8 +892,8 @@ update_keymap(struct virtual_keyboard *virtual_keyboard)
{
const char *keymap_str = default_keymap_str;
for (unsigned i = 0; i < layouts_count; i++) {
if (strcmp(layouts[i]->language,
virtual_keyboard->preferred_layout) == 0) {
if (g_strcmp0(layouts[i]->language,
virtual_keyboard->preferred_layout) == 0) {
keymap_str = layouts[i]->keymap_str;
break;
}
......@@ -971,6 +993,13 @@ button_handler(struct widget *widget, struct input *input, uint32_t time,
break;
}
}
if (!keyboard->window) {
return;
}
if (!keyboard->window) {
return;
}
struct size size = keyboard_get_size(keyboard);
window_schedule_resize(keyboard->window, size.width, size.height);
......@@ -1012,6 +1041,10 @@ touch_handler(struct input *input, uint32_t time,
}
}
if (!keyboard->window) {
return;
}
struct size size = keyboard_get_size(keyboard);
window_schedule_resize(keyboard->window, size.width, size.height);
widget_schedule_redraw(keyboard->widget);
......@@ -1068,7 +1101,7 @@ make_surface(struct output *output, struct virtual_keyboard *virtual_keyboard)
ls = zwlr_layer_shell_v1_get_layer_surface(virtual_keyboard->layer_shell,
window_get_wl_surface(keyboard->window),
output_get_wl_output(output),
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
"keyboard");
zwlr_layer_surface_v1_set_anchor(ls,
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
......@@ -1134,6 +1167,18 @@ make_visible(struct virtual_keyboard *keyboard) {
notify_visible(true);
}
static gboolean
make_visible_in_idle(struct virtual_keyboard *keyboard)
{
if (!dbus_interface || !keyboard->keyboard->scale)
return TRUE;
make_visible(keyboard);
return FALSE;
}
static void
make_hidden(struct virtual_keyboard *keyboard) {
if (!keyboard->layer_surface) {
......@@ -1143,6 +1188,19 @@ make_hidden(struct virtual_keyboard *keyboard) {
notify_visible(false);
}
/** Checks for clicked buttons and hides when they are all unclicked.
*/
static void
try_hide(struct virtual_keyboard *keyboard) {
if (keyboard->buttons_held) {
keyboard->scheduled_hidden = true;
} else {
keyboard->scheduled_hidden = false;
make_hidden(keyboard);
return;
}
}
static void
handle_input_method_activate(void *data, struct zwp_input_method_v2 *input_method)
{
......@@ -1208,7 +1266,7 @@ handle_commit_state(void *data, struct zwp_input_method_v2 *input_method)
if (keyboard->current.active) {
make_visible(keyboard);
} else {
make_hidden(keyboard);
try_hide(keyboard);
}
}
......@@ -1221,7 +1279,7 @@ handle_unavailable(void *data, struct zwp_input_method_v2 *zwp_input_method_v2)
keyboard->current.active = false;
zwp_input_method_v2_destroy(keyboard->input_method);
keyboard->input_method = NULL;
make_hidden(keyboard);
try_hide(keyboard);
}
static const struct zwp_input_method_v2_listener input_method_listener = {
......@@ -1354,7 +1412,7 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
if (arg_visible) {
make_visible(keyboard);
} else {
make_hidden(keyboard);
try_hide(keyboard);
}
sm_puri_osk0_complete_set_visible(object, invocation);
return TRUE;
......@@ -1375,15 +1433,19 @@ bus_name_acquired(GDBusConnection *connection,
{
// but let's follow minminbus for now and register objects here
dbus_interface = sm_puri_osk0_skeleton_new();
struct virtual_keyboard *virtual_keyboard = user_data;
gboolean shown;
sm_puri_osk0_set_visible(dbus_interface, false); // TODO: use actual value
shown = virtual_keyboard->layer_surface ? TRUE : FALSE;
g_debug("Acquired bus name, keyboad %sshown", shown ? "" : "not ");
sm_puri_osk0_set_visible(dbus_interface, shown);
g_signal_connect(dbus_interface, "handle-get-visible",
G_CALLBACK(handle_get_visible), user_data);
g_signal_connect(dbus_interface, "handle-set-visible",
G_CALLBACK(handle_set_visible), user_data);
GError *error;
GError *error = NULL;
if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(dbus_interface),
connection,
dbus_path_name,
......@@ -1520,6 +1582,9 @@ main(int argc, char *argv[])
session_register();
if (virtual_keyboard.input_method_manager == NULL) {
g_idle_add ((GSourceFunc) make_visible_in_idle, &virtual_keyboard);
}
display_run(virtual_keyboard.display);
......
......@@ -244,7 +244,7 @@ struct window {
int redraw_inhibited;
int redraw_needed;
int redraw_task_scheduled;
struct task redraw_task;
guint redraw_task;
int resize_needed;
int custom;
int focused;
......@@ -1590,7 +1590,10 @@ window_destroy(struct window *window)
struct window_output *window_output;
struct window_output *window_output_tmp;
wl_list_remove(&window->redraw_task.link);
if (window->redraw_task) {
g_source_remove(window->redraw_task);
window->redraw_task = 0;
}
wl_list_for_each(input, &display->input_list, link) {
if (input->touch_focus == window)
......@@ -1726,6 +1729,9 @@ widget_destroy(struct widget *widget)
wl_list_for_each(input, &display->input_list, link) {
if (input->focus_widget == widget)
input->focus_widget = NULL;
if (input->grab == widget) {
input->grab = NULL;
}
}
wl_list_remove(&widget->link);
......@@ -3904,8 +3910,10 @@ void
window_inhibit_redraw(struct window *window)
{
window->redraw_inhibited = 1;
wl_list_remove(&window->redraw_task.link);
wl_list_init(&window->redraw_task.link);
if (window->redraw_task)
g_source_remove(window->redraw_task);
window->redraw_task = 0;
window->redraw_task_scheduled = 0;
}
......@@ -4178,6 +4186,11 @@ surface_redraw(struct surface *surface)
return 0;
}
struct window_handle {
struct display* display;
struct window* window;
};
static gboolean
idle_redraw(void *data)
{
......@@ -4188,7 +4201,7 @@ idle_redraw(void *data)
DBG(" --------- \n");
wl_list_init(&window->redraw_task.link);
window->redraw_task = 0;
window->redraw_task_scheduled = 0;
if (window->resize_needed) {
......@@ -4238,7 +4251,7 @@ window_schedule_redraw_task(struct window *window)
return;
if (!window->redraw_task_scheduled) {
g_idle_add(idle_redraw, window);
window->redraw_task = g_idle_add(idle_redraw, window);
window->redraw_task_scheduled = 1;
}
}
......@@ -4839,7 +4852,6 @@ static struct window *
wl_surface_set_user_data(surface->surface, window);
wl_list_insert(display->window_list.prev, &window->link);
wl_list_init(&window->redraw_task.link);
wl_list_init (&window->window_output_list);
......
......@@ -19,6 +19,6 @@ foreach desktop_file : desktop_files
)
endforeach
install_data('dbus/sm.puri.Virtboard.xml',
install_data('dbus/sm.puri.OSK0.xml',
install_dir: dbusdir
)
virtboard (0.0.6) amber-phone; urgency=medium
* Release outstanding changes and upload to amber-phone
-- Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm> Fri, 29 Nov 2019 05:02:39 +0100
virtboard (0.0.5) unstable; urgency=medium
* Added Polish keyboard layout
......
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://source.puri.sm/Librem5/weston
Source: https://source.puri.sm/Librem5/virtboard
Files: *
Copyright: © 2016 Armin Krezović
......
......@@ -111,7 +111,7 @@ endforeach
gnome = import('gnome')
dbus_src = gnome.gdbus_codegen(
'sm.puri.OSK0',
'data/dbus/sm.puri.Virtboard.xml'
'data/dbus/sm.puri.OSK0.xml'
)
sources = [
......