From ea15f69e735fdfff0ab083c37409ae5c1f25b667 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Wed, 24 Jul 2019 13:10:33 +0000 Subject: [PATCH 1/6] Render the keyboard to a subsurface of the widget --- eek/eek-renderer.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index eeb7cc3d..0b3f9652 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -147,8 +147,8 @@ create_keyboard_surface_section_callback (EekElement *element, cairo_restore (data->cr); } -static cairo_surface_t * -create_keyboard_surface (EekRenderer *renderer) +void +render_keyboard_surface (EekRenderer *renderer) { EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); EekBounds bounds; @@ -165,14 +165,7 @@ create_keyboard_surface (EekRenderer *renderer) eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); - /* Create a surface that encompasses the dimensions of the keyboard as well - as the margin around the edge. */ - keyboard_surface = cairo_image_surface_create ( - CAIRO_FORMAT_ARGB32, - ceil(((bounds.x * 2) + bounds.width) * priv->scale), - ceil(((bounds.y * 2) + bounds.height) * priv->scale)); - - data.cr = cairo_create (keyboard_surface); + data.cr = cairo_create (priv->keyboard_surface); data.renderer = renderer; cairo_translate (data.cr, bounds.x * priv->scale, bounds.y * priv->scale); @@ -196,8 +189,6 @@ create_keyboard_surface (EekRenderer *renderer) create_keyboard_surface_section_callback, &data); cairo_destroy (data.cr); - - return keyboard_surface; } static void @@ -706,8 +697,13 @@ eek_renderer_real_render_keyboard (EekRenderer *self, g_return_if_fail (priv->allocation_width > 0.0); g_return_if_fail (priv->allocation_height > 0.0); - if (!priv->keyboard_surface) - priv->keyboard_surface = create_keyboard_surface (self); + if (!priv->keyboard_surface) { + priv->keyboard_surface = cairo_surface_create_for_rectangle ( + cairo_get_target (cr), 0, 0, + priv->allocation_width, priv->allocation_height); + } + + render_keyboard_surface (self); cairo_set_source_surface (cr, priv->keyboard_surface, 0.0, 0.0); source = cairo_get_source (cr); From 12467763286f0fb051745da89575ca721c7aa18a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Wed, 24 Jul 2019 14:04:28 +0000 Subject: [PATCH 2/6] Create the keyboard surface every time it is needed Icons are still blurry the first time the keyboard is shown after rotation. --- eek/eek-renderer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index 0b3f9652..a10b2eb0 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -697,11 +697,12 @@ eek_renderer_real_render_keyboard (EekRenderer *self, g_return_if_fail (priv->allocation_width > 0.0); g_return_if_fail (priv->allocation_height > 0.0); - if (!priv->keyboard_surface) { - priv->keyboard_surface = cairo_surface_create_for_rectangle ( - cairo_get_target (cr), 0, 0, - priv->allocation_width, priv->allocation_height); - } + if (priv->keyboard_surface) + cairo_surface_destroy (priv->keyboard_surface); + + priv->keyboard_surface = cairo_surface_create_for_rectangle ( + cairo_get_target (cr), 0, 0, + priv->allocation_width, priv->allocation_height); render_keyboard_surface (self); From e9cf572a3c708459fa13171cea73fb7e5c125e7d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 25 Jul 2019 18:07:08 +0000 Subject: [PATCH 3/6] Only recreate the widget when the keyboard layout changes Avoid creating a widget before there is a window to put it in. --- src/server-context-service.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/server-context-service.c b/src/server-context-service.c index b3e1d6cc..54328bfb 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -75,6 +75,9 @@ on_destroy (GtkWidget *widget, gpointer user_data) eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context)); } +static void +make_widget (ServerContextService *context); + static void on_notify_keyboard (GObject *object, GParamSpec *spec, @@ -94,6 +97,9 @@ on_notify_keyboard (GObject *object, keyboard); /* Recreate the keyboard widget to keep in sync with the keymap. */ + if (context->window) + make_widget(context); + gboolean visible; g_object_get (context, "visible", &visible, NULL); @@ -232,7 +238,11 @@ make_widget (ServerContextService *context) EekKeyboard *keyboard; EekTheme *theme; - g_return_if_fail (!context->widget); + if (context->widget) { + gtk_widget_destroy(context->widget); + context->widget = NULL; + } + theme = eek_theme_new ("resource:///sm/puri/squeekboard/style.css", NULL, NULL); @@ -257,12 +267,8 @@ server_context_service_real_show_keyboard (EekboardContextService *_context) if (!context->window) make_window (context); - if (context->widget) { - gtk_widget_destroy(context->widget); - context->widget = NULL; - } - - make_widget (context); + if (!context->widget) + make_widget (context); EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)-> show_keyboard (_context); From 99a7786dc38c0b553f92eb124ea3d2060c19baa7 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 26 Jul 2019 12:01:04 +0200 Subject: [PATCH 4/6] Remove declaration of unused variable --- eek/eek-renderer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index a10b2eb0..677a9c15 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -152,7 +152,6 @@ render_keyboard_surface (EekRenderer *renderer) { EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); EekBounds bounds; - cairo_surface_t *keyboard_surface; CreateKeyboardSurfaceCallbackData data; EekColor foreground, background; From 107399a531ef69634e6f3f7e11e2984752918951 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 26 Jul 2019 22:26:02 +0000 Subject: [PATCH 5/6] Don't set the geometry of the window in normal use Setting the geometry prevents the widget from getting the correct allocation and prevents us from positioning it correctly in landscape mode. --- src/server-context-service.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/server-context-service.c b/src/server-context-service.c index 54328bfb..2bdbc07c 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -174,13 +174,6 @@ set_geometry (ServerContextService *context) gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE); gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE); - } else { - gtk_window_resize (GTK_WINDOW(context->window), - bounds.width, - bounds.height); - gtk_window_move (GTK_WINDOW(context->window), - MAX(rect.width - 20 - bounds.width, 0), - MAX(rect.height - 40 - bounds.height, 0)); } } From d49e0eaa1b997823541fbd4d9ed9828f90407f76 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 26 Jul 2019 22:27:56 +0000 Subject: [PATCH 6/6] Center the keyboard in landscape orientation --- eek/eek-gtk-keyboard.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c index 317f1b60..20718597 100644 --- a/eek/eek-gtk-keyboard.c +++ b/eek/eek-gtk-keyboard.c @@ -57,6 +57,9 @@ typedef struct _EekGtkKeyboardPrivate EekKeyboard *keyboard; EekTheme *theme; + int origin_x; + int origin_y; + GdkEventSequence *sequence; // unowned reference } EekGtkKeyboardPrivate; @@ -108,6 +111,9 @@ eek_gtk_keyboard_real_draw (GtkWidget *self, gtk_widget_get_allocation (self, &allocation); + cairo_save (cr); + cairo_translate (cr, priv->origin_x, priv->origin_y); + if (!priv->renderer) { PangoContext *pcontext; @@ -125,6 +131,8 @@ eek_gtk_keyboard_real_draw (GtkWidget *self, eek_renderer_render_keyboard (priv->renderer, cr); + cairo_restore (cr); + /* redraw pressed key */ list = eek_keyboard_get_pressed_keys (priv->keyboard); for (head = list; head; head = g_list_next (head)) { @@ -149,6 +157,9 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self, EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self)); + priv->origin_x = (allocation->width - 360) / 2; + priv->origin_y = 0; + if (priv->renderer) eek_renderer_set_allocation_size (priv->renderer, allocation->width, @@ -161,7 +172,9 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self, static void depress(EekGtkKeyboard *self, gdouble x, gdouble y, guint32 time) { EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); - EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y); + EekKey *key = eek_renderer_find_key_by_position (priv->renderer, + x - priv->origin_x, y - priv->origin_y); + if (key) { eek_keyboard_press_key(priv->keyboard, key, time); on_key_pressed(key, self); @@ -171,7 +184,8 @@ static void depress(EekGtkKeyboard *self, static void drag(EekGtkKeyboard *self, gdouble x, gdouble y, guint32 time) { EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); - EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y); + EekKey *key = eek_renderer_find_key_by_position (priv->renderer, + x - priv->origin_x, y - priv->origin_y); if (key) { GList *list, *head; @@ -488,6 +502,8 @@ render_pressed_key (GtkWidget *widget, GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); cairo_t *cr = gdk_drawing_context_get_cairo_context (context); + cairo_translate (cr, priv->origin_x, priv->origin_y); + eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE); magnify_bounds (widget, &bounds, &large_bounds, 1.5); @@ -519,6 +535,8 @@ render_locked_key (GtkWidget *widget, GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); cairo_t *cr = gdk_drawing_context_get_cairo_context (context); + cairo_translate (cr, priv->origin_x, priv->origin_y); + eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE); cairo_translate (cr, bounds.x, bounds.y); @@ -542,6 +560,8 @@ render_released_key (GtkWidget *widget, GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); cairo_t *cr = gdk_drawing_context_get_cairo_context (context); + cairo_translate (cr, priv->origin_x, priv->origin_y); + eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE); magnify_bounds (widget, &bounds, &large_bounds, 1.5);