From 375daa68c84a2c61585cf28816c58f7f5a07ef5f Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 12:09:28 +0000 Subject: [PATCH 01/13] layout: Make handling presses uniform --- src/layout.rs | 52 ++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index 76f830c1..c01226d5 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -332,11 +332,12 @@ pub mod c { .map(|place| place.button.state.clone()) }; - if let Some(mut state) = state { - layout.press_key( + if let Some(state) = state { + seat::handle_press_key( + layout, &VirtualKeyboard(virtual_keyboard), - &mut state, Timestamp(time), + &state, ); // maybe TODO: draw on the display buffer here drawing::queue_redraw(ui_keyboard); @@ -379,7 +380,7 @@ pub mod c { )}) }; - if let Some((mut state, _button, _view_position)) = button_info { + if let Some((state, _button, _view_position)) = button_info { let mut found = false; for wrapped_key in pressed { let key: &Rc> = wrapped_key.borrow(); @@ -397,7 +398,12 @@ pub mod c { } } if !found { - layout.press_key(&virtual_keyboard, &mut state, time); + seat::handle_press_key( + layout, + &virtual_keyboard, + time, + &state, + ); // maybe TODO: draw on the display buffer here } } else { @@ -653,24 +659,6 @@ impl Layout { } } - fn press_key( - &mut self, - virtual_keyboard: &VirtualKeyboard, - rckey: &mut Rc>, - time: Timestamp, - ) { - if !self.pressed_keys.insert(::util::Pointer(rckey.clone())) { - eprintln!("Warning: key {:?} was already pressed", rckey); - } - let mut key = rckey.borrow_mut(); - virtual_keyboard.switch( - &key.keycodes, - PressType::Pressed, - time, - ); - key.pressed = PressType::Pressed; - } - /// Calculates size without margins fn calculate_inner_size(&self) -> Size { Size { @@ -864,6 +852,24 @@ mod seat { } } + pub fn handle_press_key( + layout: &mut Layout, + virtual_keyboard: &VirtualKeyboard, + time: Timestamp, + rckey: &Rc>, + ) { + if !layout.pressed_keys.insert(::util::Pointer(rckey.clone())) { + eprintln!("Warning: key {:?} was already pressed", rckey); + } + let mut key = rckey.borrow_mut(); + virtual_keyboard.switch( + &key.keycodes, + PressType::Pressed, + time, + ); + key.pressed = PressType::Pressed; + } + pub fn handle_release_key( layout: &mut Layout, virtual_keyboard: &VirtualKeyboard, From 7e72722a475f70ea053e88610ac3630b6dd8e4f0 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 13:26:40 +0000 Subject: [PATCH 02/13] UI: Drop indirection for show/hide functions --- eekboard/eekboard-context-service.c | 11 ++++------- eekboard/eekboard-context-service.h | 8 ++++---- src/server-context-service.c | 14 +++++--------- src/server-context-service.h | 3 ++- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index 5b0e7add..23b46482 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -135,13 +135,13 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self, return keyboard; } -static void +void eekboard_context_service_real_show_keyboard (EekboardContextService *self) { self->priv->visible = TRUE; } -static void +void eekboard_context_service_real_hide_keyboard (EekboardContextService *self) { self->priv->visible = FALSE; @@ -294,9 +294,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - klass->show_keyboard = eekboard_context_service_real_show_keyboard; - klass->hide_keyboard = eekboard_context_service_real_hide_keyboard; - gobject_class->constructed = eekboard_context_service_constructed; gobject_class->set_property = eekboard_context_service_set_property; gobject_class->get_property = eekboard_context_service_get_property; @@ -446,7 +443,7 @@ eekboard_context_service_show_keyboard (EekboardContextService *context) g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); if (!context->priv->visible) { - EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->show_keyboard (context); + server_context_service_real_show_keyboard (context); } } @@ -456,7 +453,7 @@ eekboard_context_service_hide_keyboard (EekboardContextService *context) g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); if (context->priv->visible) { - EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->hide_keyboard (context); + server_context_service_real_hide_keyboard (context); } } diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h index 38e4a9f2..16586ca0 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -63,8 +63,6 @@ struct _EekboardContextService { /** * EekboardContextServiceClass: * @create_keyboard: virtual function for create a keyboard from string - * @show_keyboard: virtual function for show a keyboard - * @hide_keyboard: virtual function for hide a keyboard * @enabled: class handler for #EekboardContextService::enabled signal * @disabled: class handler for #EekboardContextService::disabled signal */ @@ -75,8 +73,6 @@ struct _EekboardContextServiceClass { /*< public >*/ struct squeek_view *(*create_keyboard) (EekboardContextService *self, const gchar *keyboard_type); - void (*show_keyboard) (EekboardContextService *self); - void (*hide_keyboard) (EekboardContextService *self); /* signals */ void (*enabled) (EekboardContextService *self); @@ -94,6 +90,10 @@ void eekboard_context_service_enable (EekboardContextService *context); void eekboard_context_service_disable (EekboardContextService *context); void eekboard_context_service_show_keyboard (EekboardContextService *context); +void +eekboard_context_service_real_show_keyboard (EekboardContextService *self); +void +eekboard_context_service_real_hide_keyboard (EekboardContextService *self); void eekboard_context_service_hide_keyboard (EekboardContextService *context); void eekboard_context_service_destroy (EekboardContextService *context); diff --git a/src/server-context-service.c b/src/server-context-service.c index 137ae0cf..fd40d6d3 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -24,7 +24,7 @@ #include "eek/eek-gtk-keyboard.h" #include "eek/layersurface.h" #include "wayland.h" - +#include "eekboard/eekboard-context-service.h" #include "server-context-service.h" enum { @@ -238,7 +238,7 @@ make_widget (ServerContextService *context) gtk_widget_show (context->widget); } -static void +void server_context_service_real_show_keyboard (EekboardContextService *_context) { ServerContextService *context = SERVER_CONTEXT_SERVICE(_context); @@ -253,8 +253,7 @@ server_context_service_real_show_keyboard (EekboardContextService *_context) if (!context->widget) make_widget (context); - EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)-> - show_keyboard (_context); + eekboard_context_service_real_show_keyboard (_context); gtk_widget_show (GTK_WIDGET(context->window)); } @@ -267,7 +266,7 @@ on_hide (ServerContextService *context) return G_SOURCE_REMOVE; } -static void +void server_context_service_real_hide_keyboard (EekboardContextService *_context) { ServerContextService *context = SERVER_CONTEXT_SERVICE(_context); @@ -275,8 +274,7 @@ server_context_service_real_hide_keyboard (EekboardContextService *_context) if (!context->hiding) context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context); - EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)-> - hide_keyboard (_context); + eekboard_context_service_real_hide_keyboard (_context); } static void @@ -331,8 +329,6 @@ server_context_service_class_init (ServerContextServiceClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - context_class->show_keyboard = server_context_service_real_show_keyboard; - context_class->hide_keyboard = server_context_service_real_hide_keyboard; context_class->destroyed = server_context_service_real_destroyed; gobject_class->set_property = server_context_service_set_property; diff --git a/src/server-context-service.h b/src/server-context-service.h index 2929640a..44b4f8c3 100644 --- a/src/server-context-service.h +++ b/src/server-context-service.h @@ -35,7 +35,8 @@ typedef struct _ServerContextService ServerContextService; EekboardContextService *server_context_service_new (); enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService*); - +void server_context_service_real_show_keyboard (EekboardContextService *context); +void server_context_service_real_hide_keyboard (EekboardContextService *context); G_END_DECLS #endif /* SERVER_CONTEXT_SERVICE_H */ From 9f59279307a5ced1f62bd93c4806cd0c82cc742d Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 14:14:48 +0000 Subject: [PATCH 03/13] managers: Move visible flag to UI manager --- eekboard/eekboard-context-service.c | 54 ----------------- eekboard/eekboard-context-service.h | 8 --- eekboard/eekboard-service.c | 12 ++-- eekboard/eekboard-service.h | 4 +- src/imservice.c | 13 +---- src/imservice.h | 5 +- src/imservice.rs | 10 ++-- src/server-context-service.c | 89 +++++++++++++++++++++++------ src/server-context-service.h | 10 ++-- src/server-main.c | 9 +-- 10 files changed, 98 insertions(+), 116 deletions(-) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index 23b46482..36fd62bb 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -48,7 +48,6 @@ enum { PROP_0, // Magic: without this, keyboard is not useable in g_object_notify PROP_KEYBOARD, - PROP_VISIBLE, PROP_LAST }; @@ -66,7 +65,6 @@ static guint signals[LAST_SIGNAL] = { 0, }; struct _EekboardContextServicePrivate { gboolean enabled; - gboolean visible; LevelKeyboard *keyboard; // currently used keyboard GHashTable *keyboard_hash; // a table of available keyboards, per layout @@ -135,18 +133,6 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self, return keyboard; } -void -eekboard_context_service_real_show_keyboard (EekboardContextService *self) -{ - self->priv->visible = TRUE; -} - -void -eekboard_context_service_real_hide_keyboard (EekboardContextService *self) -{ - self->priv->visible = FALSE; -} - static void eekboard_context_service_set_property (GObject *object, guint prop_id, @@ -161,9 +147,6 @@ eekboard_context_service_set_property (GObject *object, g_object_unref (context->priv->keyboard); context->priv->keyboard = g_value_get_object (value); break; - case PROP_VISIBLE: - context->priv->visible = g_value_get_boolean (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -182,9 +165,6 @@ eekboard_context_service_get_property (GObject *object, case PROP_KEYBOARD: g_value_set_object (value, context->priv->keyboard); break; - case PROP_VISIBLE: - g_value_set_boolean (value, context->priv->visible); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -362,20 +342,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass) g_object_class_install_property (gobject_class, PROP_KEYBOARD, pspec); - - /** - * EekboardContextService:visible: - * - * Flag to indicate if keyboard is visible or not. - */ - pspec = g_param_spec_boolean ("visible", - "Visible", - "Visible", - FALSE, - G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_VISIBLE, - pspec); } static void @@ -437,26 +403,6 @@ eekboard_context_service_disable (EekboardContextService *context) } } -void -eekboard_context_service_show_keyboard (EekboardContextService *context) -{ - g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); - - if (!context->priv->visible) { - server_context_service_real_show_keyboard (context); - } -} - -void -eekboard_context_service_hide_keyboard (EekboardContextService *context) -{ - g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); - - if (context->priv->visible) { - server_context_service_real_hide_keyboard (context); - } -} - /** * eekboard_context_service_destroy: * @context: an #EekboardContextService diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h index 16586ca0..0f71e4eb 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -88,14 +88,6 @@ GType eekboard_context_service_get_type (void) G_GNUC_CONST; void eekboard_context_service_enable (EekboardContextService *context); void eekboard_context_service_disable (EekboardContextService *context); -void eekboard_context_service_show_keyboard - (EekboardContextService *context); -void -eekboard_context_service_real_show_keyboard (EekboardContextService *self); -void -eekboard_context_service_real_hide_keyboard (EekboardContextService *self); -void eekboard_context_service_hide_keyboard - (EekboardContextService *context); void eekboard_context_service_destroy (EekboardContextService *context); LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context); diff --git a/eekboard/eekboard-service.c b/eekboard/eekboard-service.c index 3128789b..11d87b31 100644 --- a/eekboard/eekboard-service.c +++ b/eekboard/eekboard-service.c @@ -58,7 +58,7 @@ typedef struct _EekboardServicePrivate guint registration_id; char *object_path; - EekboardContextService *context; // unowned reference + ServerContextService *context; // unowned reference } EekboardServicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (EekboardService, eekboard_service, G_TYPE_OBJECT) @@ -162,9 +162,9 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation, if (priv->context) { if (arg_visible) { - eekboard_context_service_show_keyboard (priv->context); + server_context_service_show_keyboard (priv->context); } else { - eekboard_context_service_hide_keyboard (priv->context); + server_context_service_hide_keyboard (priv->context); } } sm_puri_osk0_complete_set_visible(object, invocation); @@ -173,13 +173,13 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation, static void on_visible(EekboardService *service, GParamSpec *pspec, - EekboardContextService *context) + ServerContextService *context) { gboolean visible; EekboardServicePrivate *priv; g_return_if_fail (EEKBOARD_IS_SERVICE (service)); - g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE (context)); + g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (context)); priv = eekboard_service_get_instance_private (service); g_object_get (context, "visible", &visible, NULL); @@ -295,7 +295,7 @@ eekboard_service_new (GDBusConnection *connection, void eekboard_service_set_context(EekboardService *service, - EekboardContextService *context) + ServerContextService *context) { EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); diff --git a/eekboard/eekboard-service.h b/eekboard/eekboard-service.h index 58984bfb..5f65a5d0 100644 --- a/eekboard/eekboard-service.h +++ b/eekboard/eekboard-service.h @@ -20,7 +20,7 @@ #define __EEKBOARD_SERVICE_H_INSIDE__ 1 -#include "eekboard/eekboard-context-service.h" +#include "server-context-service.h" G_BEGIN_DECLS @@ -50,6 +50,6 @@ GType eekboard_service_get_type (void) G_GNUC_CONST; EekboardService * eekboard_service_new (GDBusConnection *connection, const gchar *object_path); void eekboard_service_set_context(EekboardService *service, - EekboardContextService *context); + ServerContextService *context); G_END_DECLS #endif /* EEKBOARD_SERVICE_H */ diff --git a/src/imservice.c b/src/imservice.c index efa6208a..d33f11db 100644 --- a/src/imservice.c +++ b/src/imservice.c @@ -2,9 +2,6 @@ #include -#include "eekboard/eekboard-context-service.h" - - static const struct zwp_input_method_v2_listener input_method_listener = { .activate = imservice_handle_input_method_activate, .deactivate = imservice_handle_input_method_deactivate, @@ -15,7 +12,7 @@ static const struct zwp_input_method_v2_listener input_method_listener = { .unavailable = imservice_handle_unavailable, }; -struct imservice* get_imservice(EekboardContextService *context, +struct imservice* get_imservice(ServerContextService *context, struct zwp_input_method_manager_v2 *manager, struct wl_seat *seat) { struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat); @@ -28,14 +25,6 @@ struct imservice* get_imservice(EekboardContextService *context, return imservice; } -void imservice_make_visible(EekboardContextService *context) { - eekboard_context_service_show_keyboard (context); -} - -void imservice_try_hide(EekboardContextService *context) { - eekboard_context_service_hide_keyboard (context); -} - /// Declared explicitly because _destroy is inline, /// making it unavailable in Rust void imservice_destroy_im(struct zwp_input_method_v2 *im) { diff --git a/src/imservice.h b/src/imservice.h index 71c59275..0f7b1c75 100644 --- a/src/imservice.h +++ b/src/imservice.h @@ -3,16 +3,17 @@ #include "input-method-unstable-v2-client-protocol.h" #include "eek/eek-types.h" +#include "src/server-context-service.h" struct imservice; -struct imservice* get_imservice(EekboardContextService *context, +struct imservice* get_imservice(ServerContextService *context, struct zwp_input_method_manager_v2 *manager, struct wl_seat *seat); // Defined in Rust struct imservice* imservice_new(struct zwp_input_method_v2 *im, - EekboardContextService *context); + ServerContextService *context); void imservice_handle_input_method_activate(void *data, struct zwp_input_method_v2 *input_method); void imservice_handle_input_method_deactivate(void *data, struct zwp_input_method_v2 *input_method); void imservice_handle_surrounding_text(void *data, struct zwp_input_method_v2 *input_method, diff --git a/src/imservice.rs b/src/imservice.rs index d3e4c5d0..df4019b7 100644 --- a/src/imservice.rs +++ b/src/imservice.rs @@ -29,8 +29,8 @@ pub mod c { extern "C" { fn imservice_destroy_im(im: *mut c::InputMethod); fn eekboard_context_service_set_hint_purpose(imservice: *const UIManager, hint: u32, purpose: u32); - fn eekboard_context_service_show_keyboard(imservice: *const UIManager); - fn eekboard_context_service_hide_keyboard(imservice: *const UIManager); + fn server_context_service_show_keyboard(imservice: *const UIManager); + fn server_context_service_hide_keyboard(imservice: *const UIManager); } // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers @@ -150,13 +150,13 @@ pub mod c { }; if active_changed { if imservice.current.active { - eekboard_context_service_show_keyboard(imservice.ui_manager); + server_context_service_show_keyboard(imservice.ui_manager); eekboard_context_service_set_hint_purpose( imservice.ui_manager, imservice.current.content_hint.bits(), imservice.current.content_purpose.clone() as u32); } else { - eekboard_context_service_hide_keyboard(imservice.ui_manager); + server_context_service_hide_keyboard(imservice.ui_manager); } } } @@ -173,7 +173,7 @@ pub mod c { // the keyboard is already decommissioned imservice.current.active = false; - eekboard_context_service_hide_keyboard(imservice.ui_manager); + server_context_service_hide_keyboard(imservice.ui_manager); } // FIXME: destroy and deallocate diff --git a/src/server-context-service.c b/src/server-context-service.c index fd40d6d3..16a1e7eb 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -23,14 +23,15 @@ #include "eek/eek.h" #include "eek/eek-gtk-keyboard.h" #include "eek/layersurface.h" -#include "wayland.h" #include "eekboard/eekboard-context-service.h" +#include "wayland.h" #include "server-context-service.h" enum { PROP_0, PROP_SIZE_CONSTRAINT_LANDSCAPE, PROP_SIZE_CONSTRAINT_PORTRAIT, + PROP_VISIBLE, PROP_LAST }; @@ -39,6 +40,7 @@ typedef struct _ServerContextServiceClass ServerContextServiceClass; struct _ServerContextService { EekboardContextService parent; + gboolean visible; PhoshLayerSurface *window; GtkWidget *widget; guint hiding; @@ -95,8 +97,8 @@ on_notify_keyboard (GObject *object, g_object_get (context, "visible", &visible, NULL); if (visible) { - eekboard_context_service_hide_keyboard(EEKBOARD_CONTEXT_SERVICE(context)); - eekboard_context_service_show_keyboard(EEKBOARD_CONTEXT_SERVICE(context)); + server_context_service_hide_keyboard(context); + server_context_service_show_keyboard(context); } } @@ -238,11 +240,18 @@ make_widget (ServerContextService *context) gtk_widget_show (context->widget); } -void -server_context_service_real_show_keyboard (EekboardContextService *_context) +static gboolean +on_hide (ServerContextService *context) { - ServerContextService *context = SERVER_CONTEXT_SERVICE(_context); + gtk_widget_hide (GTK_WIDGET(context->window)); + context->hiding = 0; + return G_SOURCE_REMOVE; +} + +static void +server_context_service_real_show_keyboard (ServerContextService *context) +{ if (context->hiding) { g_source_remove (context->hiding); context->hiding = 0; @@ -253,28 +262,37 @@ server_context_service_real_show_keyboard (EekboardContextService *_context) if (!context->widget) make_widget (context); - eekboard_context_service_real_show_keyboard (_context); + context->visible = TRUE; gtk_widget_show (GTK_WIDGET(context->window)); } -static gboolean -on_hide (ServerContextService *context) +static void +server_context_service_real_hide_keyboard (ServerContextService *context) { - gtk_widget_hide (GTK_WIDGET(context->window)); - context->hiding = 0; + if (!context->hiding) + context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context); - return G_SOURCE_REMOVE; + context->visible = FALSE; } void -server_context_service_real_hide_keyboard (EekboardContextService *_context) +server_context_service_show_keyboard (ServerContextService *context) { - ServerContextService *context = SERVER_CONTEXT_SERVICE(_context); + g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(context)); - if (!context->hiding) - context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context); + if (!context->visible) { + server_context_service_real_show_keyboard (context); + } +} - eekboard_context_service_real_hide_keyboard (_context); +void +server_context_service_hide_keyboard (ServerContextService *context) +{ + g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(context)); + + if (context->visible) { + server_context_service_real_hide_keyboard (context); + } } static void @@ -304,6 +322,9 @@ server_context_service_set_property (GObject *object, &context->size_constraint_portrait[0], &context->size_constraint_portrait[1]); break; + case PROP_VISIBLE: + context->visible = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -311,6 +332,23 @@ server_context_service_set_property (GObject *object, } } +static void +server_context_service_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ServerContextService *context = SERVER_CONTEXT_SERVICE(object); + switch (prop_id) { + case PROP_VISIBLE: + g_value_set_boolean (value, context->visible); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void server_context_service_dispose (GObject *object) { @@ -332,6 +370,7 @@ server_context_service_class_init (ServerContextServiceClass *klass) context_class->destroyed = server_context_service_real_destroyed; gobject_class->set_property = server_context_service_set_property; + gobject_class->get_property = server_context_service_get_property; gobject_class->dispose = server_context_service_dispose; pspec = g_param_spec_variant ("size-constraint-landscape", @@ -353,6 +392,18 @@ server_context_service_class_init (ServerContextServiceClass *klass) g_object_class_install_property (gobject_class, PROP_SIZE_CONSTRAINT_PORTRAIT, pspec); + + /** + * Flag to indicate if keyboard is visible or not. + */ + pspec = g_param_spec_boolean ("visible", + "Visible", + "Visible", + FALSE, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_VISIBLE, + pspec); } static void @@ -364,10 +415,10 @@ server_context_service_init (ServerContextService *context) context); } -EekboardContextService * +ServerContextService * server_context_service_new () { - return EEKBOARD_CONTEXT_SERVICE(g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL)); + return g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL); } enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService *service) diff --git a/src/server-context-service.h b/src/server-context-service.h index 44b4f8c3..c7f7412a 100644 --- a/src/server-context-service.h +++ b/src/server-context-service.h @@ -18,7 +18,6 @@ #ifndef SERVER_CONTEXT_SERVICE_H #define SERVER_CONTEXT_SERVICE_H 1 -#include "eekboard/eekboard-service.h" #include "src/layout.h" G_BEGIN_DECLS @@ -33,10 +32,13 @@ G_BEGIN_DECLS /** Manages the liecycle of the window displaying layouts. */ typedef struct _ServerContextService ServerContextService; -EekboardContextService *server_context_service_new (); +GType server_context_service_get_type + (void) G_GNUC_CONST; + +ServerContextService *server_context_service_new(); enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService*); -void server_context_service_real_show_keyboard (EekboardContextService *context); -void server_context_service_real_hide_keyboard (EekboardContextService *context); +void server_context_service_show_keyboard (ServerContextService *context); +void server_context_service_hide_keyboard (ServerContextService *context); G_END_DECLS #endif /* SERVER_CONTEXT_SERVICE_H */ diff --git a/src/server-main.c b/src/server-main.c index 56a2fd1f..8bb8c427 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -27,6 +27,7 @@ #include "eekboard/eekboard-service.h" #include "eek/eek.h" +#include "eekboard/eekboard-context-service.h" #include "imservice.h" #include "outputs.h" #include "server-context-service.h" @@ -38,7 +39,7 @@ /// Global application state struct squeekboard { struct squeek_wayland wayland; - EekboardContextService *context; + ServerContextService *context; struct imservice *imservice; }; @@ -80,12 +81,12 @@ on_destroyed (EekboardService *service, g_main_loop_quit (loop); } -static EekboardContextService *create_context() { - EekboardContextService *context = server_context_service_new (); +static ServerContextService *create_context() { + ServerContextService *context = server_context_service_new (); g_object_set_data_full (G_OBJECT(context), "owner", g_strdup ("sender"), (GDestroyNotify)g_free); - eekboard_context_service_enable (context); + eekboard_context_service_enable (EEKBOARD_CONTEXT_SERVICE(context)); return context; } From 033a1cf200efab1ceee809a351d04dbe5d8cae0c Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 15:53:49 +0000 Subject: [PATCH 04/13] dbus_service: Remove unused function --- eekboard/eekboard-service.c | 3 +-- eekboard/eekboard-service.h | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/eekboard/eekboard-service.c b/eekboard/eekboard-service.c index 11d87b31..cb78445d 100644 --- a/eekboard/eekboard-service.c +++ b/eekboard/eekboard-service.c @@ -175,6 +175,7 @@ static void on_visible(EekboardService *service, GParamSpec *pspec, ServerContextService *context) { + (void)pspec; gboolean visible; EekboardServicePrivate *priv; @@ -216,8 +217,6 @@ eekboard_service_class_init (EekboardServiceClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - klass->create_context = NULL; - gobject_class->constructed = eekboard_service_constructed; gobject_class->set_property = eekboard_service_set_property; gobject_class->get_property = eekboard_service_get_property; diff --git a/eekboard/eekboard-service.h b/eekboard/eekboard-service.h index 5f65a5d0..f1a80c71 100644 --- a/eekboard/eekboard-service.h +++ b/eekboard/eekboard-service.h @@ -37,10 +37,6 @@ G_DECLARE_DERIVABLE_TYPE (EekboardService, eekboard_service, EEKBOARD, SERVICE, struct _EekboardServiceClass { /*< private >*/ GObjectClass parent_class; - - /*< public >*/ - EekboardContextService *(*create_context) (EekboardService *self); - /*< private >*/ /* padding */ gpointer pdummy[24]; From 3ecfd701d90744d16e0b32f3091591d648869051 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 16:13:09 +0000 Subject: [PATCH 05/13] dbus: Remove unneeded gobjectness Also removed the code linking dbus interface stop to application quit. DBus going missing was not handled, and isn't a fatal error anyway. --- eekboard/eekboard-service.c | 258 +++++++----------------------------- eekboard/eekboard-service.h | 27 ++-- src/server-main.c | 12 -- 3 files changed, 59 insertions(+), 238 deletions(-) diff --git a/eekboard/eekboard-service.c b/eekboard/eekboard-service.c index cb78445d..0c19d017 100644 --- a/eekboard/eekboard-service.c +++ b/eekboard/eekboard-service.c @@ -28,7 +28,6 @@ #include "config.h" -#include "sm.puri.OSK0.h" #include @@ -36,135 +35,45 @@ #include "eekboard/eekboard-service.h" -enum { - PROP_0, - PROP_OBJECT_PATH, - PROP_CONNECTION, - PROP_LAST -}; - -enum { - DESTROYED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -typedef struct _EekboardServicePrivate +void +eekboard_service_destroy(EekboardService *service) { - GDBusConnection *connection; - SmPuriOSK0 *dbus_interface; - GDBusNodeInfo *introspection_data; - guint registration_id; - char *object_path; + g_free (service->object_path); - ServerContextService *context; // unowned reference -} EekboardServicePrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (EekboardService, eekboard_service, G_TYPE_OBJECT) - -static void -eekboard_service_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekboardService *service = EEKBOARD_SERVICE(object); - EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); - GDBusConnection *connection; - - switch (prop_id) { - case PROP_OBJECT_PATH: - if (priv->object_path) - g_free (priv->object_path); - priv->object_path = g_value_dup_string (value); - break; - case PROP_CONNECTION: - connection = g_value_get_object (value); - if (priv->connection) - g_object_unref (priv->connection); - priv->connection = g_object_ref (connection); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -eekboard_service_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekboardService *service = EEKBOARD_SERVICE(object); - EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); - - switch (prop_id) { - case PROP_OBJECT_PATH: - g_value_set_string (value, priv->object_path); - break; - case PROP_CONNECTION: - g_value_set_object (value, priv->connection); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -eekboard_service_dispose (GObject *object) -{ - EekboardService *service = EEKBOARD_SERVICE(object); - EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); - - if (priv->connection) { - if (priv->registration_id > 0) { - g_dbus_connection_unregister_object (priv->connection, - priv->registration_id); - priv->registration_id = 0; + if (service->connection) { + if (service->registration_id > 0) { + g_dbus_connection_unregister_object (service->connection, + service->registration_id); + service->registration_id = 0; } - g_object_unref (priv->connection); - priv->connection = NULL; + g_object_unref (service->connection); + service->connection = NULL; } - if (priv->introspection_data) { - g_dbus_node_info_unref (priv->introspection_data); - priv->introspection_data = NULL; + if (service->introspection_data) { + g_dbus_node_info_unref (service->introspection_data); + service->introspection_data = NULL; } - if (priv->context) { - g_signal_handlers_disconnect_by_data (priv->context, service); - priv->context = NULL; + if (service->context) { + g_signal_handlers_disconnect_by_data (service->context, service); + service->context = NULL; } - G_OBJECT_CLASS (eekboard_service_parent_class)->dispose (object); -} - -static void -eekboard_service_finalize (GObject *object) -{ - EekboardService *service = EEKBOARD_SERVICE(object); - EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); - - g_free (priv->object_path); - - G_OBJECT_CLASS (eekboard_service_parent_class)->finalize (object); + free(service); } static gboolean handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation, gboolean arg_visible, gpointer user_data) { EekboardService *service = user_data; - EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); - if (priv->context) { + if (service->context) { if (arg_visible) { - server_context_service_show_keyboard (priv->context); + server_context_service_show_keyboard (service->context); } else { - server_context_service_hide_keyboard (priv->context); + server_context_service_hide_keyboard (service->context); } } sm_puri_osk0_complete_set_visible(object, invocation); @@ -177,104 +86,12 @@ static void on_visible(EekboardService *service, { (void)pspec; gboolean visible; - EekboardServicePrivate *priv; - g_return_if_fail (EEKBOARD_IS_SERVICE (service)); g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (context)); - priv = eekboard_service_get_instance_private (service); g_object_get (context, "visible", &visible, NULL); - sm_puri_osk0_set_visible(priv->dbus_interface, visible); -} - -static void -eekboard_service_constructed (GObject *object) -{ - EekboardService *service = EEKBOARD_SERVICE(object); - EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); - - priv->dbus_interface = sm_puri_osk0_skeleton_new(); - g_signal_connect(priv->dbus_interface, "handle-set-visible", - G_CALLBACK(handle_set_visible), service); - - if (priv->connection && priv->object_path) { - GError *error = NULL; - - if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(priv->dbus_interface), - priv->connection, - priv->object_path, - &error)) { - g_warning("Error registering dbus object: %s\n", error->message); - g_clear_error(&error); - } - } -} - -static void -eekboard_service_class_init (EekboardServiceClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gobject_class->constructed = eekboard_service_constructed; - gobject_class->set_property = eekboard_service_set_property; - gobject_class->get_property = eekboard_service_get_property; - gobject_class->dispose = eekboard_service_dispose; - gobject_class->finalize = eekboard_service_finalize; - - /** - * EekboardService::destroyed: - * @service: an #EekboardService - * - * The ::destroyed signal is emitted when the service is vanished. - */ - signals[DESTROYED] = - g_signal_new (I_("destroyed"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - /** - * EekboardService:object-path: - * - * D-Bus object path. - */ - pspec = g_param_spec_string ("object-path", - "Object-path", - "Object-path", - NULL, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_OBJECT_PATH, - pspec); - - /** - * EekboardService:connection: - * - * D-Bus connection. - */ - pspec = g_param_spec_object ("connection", - "Connection", - "Connection", - G_TYPE_DBUS_CONNECTION, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_CONNECTION, - pspec); -} - -static void -eekboard_service_init (EekboardService *self) -{ - EekboardServicePrivate *priv = eekboard_service_get_instance_private (self); - - priv->context = NULL; + sm_puri_osk0_set_visible(service->dbus_interface, visible); } /** @@ -286,23 +103,38 @@ EekboardService * eekboard_service_new (GDBusConnection *connection, const gchar *object_path) { - return g_object_new (EEKBOARD_TYPE_SERVICE, - "object-path", object_path, - "connection", connection, - NULL); + EekboardService *self = calloc(1, sizeof(EekboardService)); + self->object_path = g_strdup(object_path); + self->connection = connection; + + self->dbus_interface = sm_puri_osk0_skeleton_new(); + g_signal_connect(self->dbus_interface, "handle-set-visible", + G_CALLBACK(handle_set_visible), self); + + if (self->connection && self->object_path) { + GError *error = NULL; + + if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(self->dbus_interface), + self->connection, + self->object_path, + &error)) { + g_warning("Error registering dbus object: %s\n", error->message); + g_clear_error(&error); + // TODO: return an error + } + } + return self; } void eekboard_service_set_context(EekboardService *service, ServerContextService *context) { - EekboardServicePrivate *priv = eekboard_service_get_instance_private (service); + g_return_if_fail (!service->context); - g_return_if_fail (!priv->context); + service->context = context; - priv->context = context; - - g_signal_connect_swapped (priv->context, + g_signal_connect_swapped (service->context, "notify::visible", G_CALLBACK(on_visible), service); diff --git a/eekboard/eekboard-service.h b/eekboard/eekboard-service.h index f1a80c71..6b2d5391 100644 --- a/eekboard/eekboard-service.h +++ b/eekboard/eekboard-service.h @@ -22,30 +22,31 @@ #include "server-context-service.h" +#include "sm.puri.OSK0.h" + G_BEGIN_DECLS #define EEKBOARD_SERVICE_PATH "/sm/puri/OSK0" #define EEKBOARD_SERVICE_INTERFACE "sm.puri.OSK0" -#define EEKBOARD_TYPE_SERVICE (eekboard_service_get_type()) -G_DECLARE_DERIVABLE_TYPE (EekboardService, eekboard_service, EEKBOARD, SERVICE, GObject) - /** - * EekboardServiceClass: - * @create_context: virtual function for creating a context + * EekboardService: DBus handling */ -struct _EekboardServiceClass { - /*< private >*/ - GObjectClass parent_class; - /*< private >*/ - /* padding */ - gpointer pdummy[24]; -}; +typedef struct _EekboardService +{ + GDBusConnection *connection; + SmPuriOSK0 *dbus_interface; + GDBusNodeInfo *introspection_data; + guint registration_id; + char *object_path; + + ServerContextService *context; // unowned reference +} EekboardService; -GType eekboard_service_get_type (void) G_GNUC_CONST; EekboardService * eekboard_service_new (GDBusConnection *connection, const gchar *object_path); void eekboard_service_set_context(EekboardService *service, ServerContextService *context); +void eekboard_service_destroy(EekboardService*); G_END_DECLS #endif /* EEKBOARD_SERVICE_H */ diff --git a/src/server-main.c b/src/server-main.c index 8bb8c427..950d43e4 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -71,16 +71,6 @@ on_name_lost (GDBusConnection *connection, exit (1); } -static void -on_destroyed (EekboardService *service, - gpointer user_data) -{ - (void)service; - GMainLoop *loop = user_data; - - g_main_loop_quit (loop); -} - static ServerContextService *create_context() { ServerContextService *context = server_context_service_new (); g_object_set_data_full (G_OBJECT(context), @@ -295,8 +285,6 @@ main (int argc, char **argv) GMainLoop *loop = g_main_loop_new (NULL, FALSE); - g_signal_connect (service, "destroyed", G_CALLBACK(on_destroyed), loop); - g_main_loop_run (loop); g_bus_unown_name (owner_id); From 4c2cef30f2e6cdb810ec374d0ead17985fea1bf1 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 16:25:53 +0000 Subject: [PATCH 06/13] dbus: Rename handler from eekboard_service --- eekboard/eekboard-service.c => src/dbus.c | 33 ++++++----------------- eekboard/eekboard-service.h => src/dbus.h | 26 ++++++++---------- src/meson.build | 2 +- src/server-main.c | 8 +++--- 4 files changed, 24 insertions(+), 45 deletions(-) rename eekboard/eekboard-service.c => src/dbus.c (82%) rename eekboard/eekboard-service.h => src/dbus.h (70%) diff --git a/eekboard/eekboard-service.c b/src/dbus.c similarity index 82% rename from eekboard/eekboard-service.c rename to src/dbus.c index 0c19d017..29783090 100644 --- a/eekboard/eekboard-service.c +++ b/src/dbus.c @@ -16,27 +16,15 @@ * along with this program. If not, see . */ -/** - * SECTION:eekboard-service - * @short_description: base implementation of eekboard service - * - * Provides a dbus object, and contains the context. - * - * The #EekboardService class provides a base server side - * implementation of eekboard service. - */ - #include "config.h" +#include "dbus.h" #include - #include -#include "eekboard/eekboard-service.h" - void -eekboard_service_destroy(EekboardService *service) +dbus_handler_destroy(DBusHandler *service) { g_free (service->object_path); @@ -67,7 +55,7 @@ eekboard_service_destroy(EekboardService *service) static gboolean handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation, gboolean arg_visible, gpointer user_data) { - EekboardService *service = user_data; + DBusHandler *service = user_data; if (service->context) { if (arg_visible) { @@ -80,7 +68,7 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation, return TRUE; } -static void on_visible(EekboardService *service, +static void on_visible(DBusHandler *service, GParamSpec *pspec, ServerContextService *context) { @@ -94,16 +82,11 @@ static void on_visible(EekboardService *service, sm_puri_osk0_set_visible(service->dbus_interface, visible); } -/** - * eekboard_service_new: - * @connection: a #GDBusConnection - * @object_path: object path - */ -EekboardService * -eekboard_service_new (GDBusConnection *connection, +DBusHandler * +dbus_handler_new (GDBusConnection *connection, const gchar *object_path) { - EekboardService *self = calloc(1, sizeof(EekboardService)); + DBusHandler *self = calloc(1, sizeof(DBusHandler)); self->object_path = g_strdup(object_path); self->connection = connection; @@ -127,7 +110,7 @@ eekboard_service_new (GDBusConnection *connection, } void -eekboard_service_set_context(EekboardService *service, +dbus_handler_set_context(DBusHandler *service, ServerContextService *context) { g_return_if_fail (!service->context); diff --git a/eekboard/eekboard-service.h b/src/dbus.h similarity index 70% rename from eekboard/eekboard-service.h rename to src/dbus.h index 6b2d5391..c77ad850 100644 --- a/eekboard/eekboard-service.h +++ b/src/dbus.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2010-2011 Daiki Ueno * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2019-2020 Purism, SPC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,10 +16,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#ifndef EEKBOARD_SERVICE_H -#define EEKBOARD_SERVICE_H 1 - -#define __EEKBOARD_SERVICE_H_INSIDE__ 1 +#ifndef DBUS_H_ +#define DBUS_H_ 1 #include "server-context-service.h" @@ -26,13 +25,10 @@ G_BEGIN_DECLS -#define EEKBOARD_SERVICE_PATH "/sm/puri/OSK0" -#define EEKBOARD_SERVICE_INTERFACE "sm.puri.OSK0" +#define DBUS_SERVICE_PATH "/sm/puri/OSK0" +#define DBUS_SERVICE_INTERFACE "sm.puri.OSK0" -/** - * EekboardService: DBus handling - */ -typedef struct _EekboardService +typedef struct _DBusHandler { GDBusConnection *connection; SmPuriOSK0 *dbus_interface; @@ -41,12 +37,12 @@ typedef struct _EekboardService char *object_path; ServerContextService *context; // unowned reference -} EekboardService; +} DBusHandler; -EekboardService * eekboard_service_new (GDBusConnection *connection, +DBusHandler * dbus_handler_new (GDBusConnection *connection, const gchar *object_path); -void eekboard_service_set_context(EekboardService *service, +void dbus_handler_set_context(DBusHandler *service, ServerContextService *context); -void eekboard_service_destroy(EekboardService*); +void dbus_handler_destroy(DBusHandler*); G_END_DECLS -#endif /* EEKBOARD_SERVICE_H */ +#endif /* DBUS_H_ */ diff --git a/src/meson.build b/src/meson.build index e3a90935..b701eaf5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,6 +12,7 @@ config_h = configure_file( sources = [ config_h, + 'dbus.c', 'imservice.c', 'server-context-service.c', 'wayland.c', @@ -27,7 +28,6 @@ sources = [ dbus_src, '../eekboard/key-emitter.c', '../eekboard/eekboard-context-service.c', - '../eekboard/eekboard-service.c', # '../eekboard/eekboard-xklutil.c', squeekboard_resources, wl_proto_sources, diff --git a/src/server-main.c b/src/server-main.c index 950d43e4..8c6b7e50 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -25,9 +25,9 @@ #include "config.h" -#include "eekboard/eekboard-service.h" #include "eek/eek.h" #include "eekboard/eekboard-context-service.h" +#include "dbus.h" #include "imservice.h" #include "outputs.h" #include "server-context-service.h" @@ -248,17 +248,17 @@ main (int argc, char **argv) break; } - EekboardService *service = eekboard_service_new (connection, EEKBOARD_SERVICE_PATH); + DBusHandler *service = dbus_handler_new(connection, DBUS_SERVICE_PATH); if (service == NULL) { g_printerr ("Can't create dbus server\n"); exit (1); } else { - eekboard_service_set_context(service, instance.context); + dbus_handler_set_context(service, instance.context); } guint owner_id = g_bus_own_name_on_connection (connection, - EEKBOARD_SERVICE_INTERFACE, + DBUS_SERVICE_INTERFACE, G_BUS_NAME_OWNER_FLAGS_NONE, on_name_acquired, on_name_lost, From 7dd8bd54c2ccc1b136ba0fbebfe3c372256594db Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 16:42:17 +0000 Subject: [PATCH 07/13] context: Moved keymap setting together with its generation --- eekboard/eekboard-context-service.c | 15 +++++++-------- src/server-context-service.c | 11 ----------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index 36fd62bb..6e46f0f8 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -139,14 +139,8 @@ eekboard_context_service_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EekboardContextService *context = EEKBOARD_CONTEXT_SERVICE(object); - + (void)value; switch (prop_id) { - case PROP_KEYBOARD: - if (context->priv->keyboard) - g_object_unref (context->priv->keyboard); - context->priv->keyboard = g_value_get_object (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -231,6 +225,11 @@ eekboard_context_service_update_layout(EekboardContextService *context, enum squ g_object_notify (G_OBJECT(context), "keyboard"); + // The keymap will get set even if the window is hidden. + // It's not perfect, + // but simpler than adding a check in the window showing procedure + eekboard_context_service_set_keymap(context, keyboard); + // replacing the keyboard above will cause the previous keyboard to get destroyed from the UI side (eek_gtk_keyboard_dispose) if (previous_keyboard) { level_keyboard_free(previous_keyboard); @@ -338,7 +337,7 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass) pspec = g_param_spec_pointer("keyboard", "Keyboard", "Keyboard", - G_PARAM_READWRITE); + G_PARAM_READABLE); g_object_class_install_property (gobject_class, PROP_KEYBOARD, pspec); diff --git a/src/server-context-service.c b/src/server-context-service.c index 16a1e7eb..1cacb37d 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -78,17 +78,6 @@ on_notify_keyboard (GObject *object, GParamSpec *spec, ServerContextService *context) { - const LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context)); - - if (!keyboard) - g_error("Programmer error: keyboard layout was unset!"); - - // The keymap will get set even if the window is hidden. - // It's not perfect, - // but simpler than adding a check in the window showing procedure - eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context), - keyboard); - /* Recreate the keyboard widget to keep in sync with the keymap. */ if (context->window) make_widget(context); From 14d5881f1e93ac7eebd4f84f4ae8fc1978bafb2c Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 16:47:41 +0000 Subject: [PATCH 08/13] key-emitter: Remove unused --- eek/eek-keyboard.c | 1 - eekboard/eekboard-context-service.c | 3 +- eekboard/eekboard-context-service.h | 2 + eekboard/key-emitter.c | 136 ---------------------------- eekboard/key-emitter.h | 45 --------- src/meson.build | 1 - 6 files changed, 3 insertions(+), 185 deletions(-) delete mode 100644 eekboard/key-emitter.c delete mode 100644 eekboard/key-emitter.h diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index dd72ace9..5245eb8e 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -31,7 +31,6 @@ #include #include "eekboard/eekboard-context-service.h" -#include "eekboard/key-emitter.h" #include "keymap.h" #include "eek-keyboard.h" diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index 6e46f0f8..b0e6e076 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -37,7 +37,6 @@ #include -#include "eekboard/key-emitter.h" #include "wayland.h" #include "eek/eek-xml-layout.h" @@ -71,7 +70,7 @@ struct _EekboardContextServicePrivate { char *overlay; - GSettings *settings; + GSettings *settings; // Owned reference uint32_t hint; uint32_t purpose; }; diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h index 0f71e4eb..668fe0bc 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -46,6 +46,8 @@ typedef struct _EekboardContextServicePrivate EekboardContextServicePrivate; /** * EekboardContextService: * + * Handles layout state, gsettings, and virtual-keyboard. + * * TODO: Restrict to managing keyboard layouts, and maybe button repeats, * and the virtual keyboard protocol. * diff --git a/eekboard/key-emitter.c b/eekboard/key-emitter.c deleted file mode 100644 index b652441e..00000000 --- a/eekboard/key-emitter.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2011 Daiki Ueno - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2019 Purism, SPC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* This file is responsible for managing keycode data and emitting keycodes. */ - -#include "eekboard/key-emitter.h" - -#include -#include - -#include "eekboard/eekboard-context-service.h" - -// TODO: decide whether it's this struct that carries the keyboard around in key-emitter or if the whole manager should be dragged around -// if this is the carrier, then it should be made part of the manager -// hint: check which fields need to be persisted between keypresses; which between keyboards -typedef struct { - struct zwp_virtual_keyboard_v1 *virtual_keyboard; // unowned copy - struct xkb_keymap *keymap; // unowned copy - XkbDescRec *xkb; - guint modifier_keycodes[8]; - guint modifier_indices[MOD_IDX_LAST]; - guint group; -} SeatEmitter; - - -int send_virtual_keyboard_key( - struct zwp_virtual_keyboard_v1 *keyboard, - unsigned int keycode, - unsigned is_press, - uint32_t timestamp -) { - zwp_virtual_keyboard_v1_key(keyboard, timestamp, keycode, (unsigned)is_press); - return 0; -} - -/* Finds the first key code for each modifier and saves it in modifier_keycodes */ -static void -update_modifier_info (SeatEmitter *client) -{ - client->modifier_indices[MOD_IDX_SHIFT] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_SHIFT); - client->modifier_indices[MOD_IDX_CAPS] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_CAPS); - client->modifier_indices[MOD_IDX_CTRL] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_CTRL); - client->modifier_indices[MOD_IDX_ALT] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_ALT); - client->modifier_indices[MOD_IDX_NUM] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_NUM); - client->modifier_indices[MOD_IDX_MOD3] = xkb_keymap_mod_get_index(client->keymap, "Mod3"); - client->modifier_indices[MOD_IDX_LOGO] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_LOGO); - client->modifier_indices[MOD_IDX_ALTGR] = xkb_keymap_mod_get_index(client->keymap, "Mod5"); - client->modifier_indices[MOD_IDX_NUMLK] = xkb_keymap_mod_get_index(client->keymap, "NumLock"); - client->modifier_indices[MOD_IDX_ALSO_ALT] = xkb_keymap_mod_get_index(client->keymap, "Alt"); - client->modifier_indices[MOD_IDX_LVL3] = xkb_keymap_mod_get_index(client->keymap, "LevelThree"); - client->modifier_indices[MOD_IDX_LALT] = xkb_keymap_mod_get_index(client->keymap, "LAlt"); - client->modifier_indices[MOD_IDX_RALT] = xkb_keymap_mod_get_index(client->keymap, "RAlt"); - client->modifier_indices[MOD_IDX_RCONTROL] = xkb_keymap_mod_get_index(client->keymap, "RControl"); - client->modifier_indices[MOD_IDX_LCONTROL] = xkb_keymap_mod_get_index(client->keymap, "LControl"); - client->modifier_indices[MOD_IDX_SCROLLLK] = xkb_keymap_mod_get_index(client->keymap, "ScrollLock"); - client->modifier_indices[MOD_IDX_LVL5] = xkb_keymap_mod_get_index(client->keymap, "LevelFive"); - client->modifier_indices[MOD_IDX_ALSO_ALTGR] = xkb_keymap_mod_get_index(client->keymap, "AltGr"); - client->modifier_indices[MOD_IDX_META] = xkb_keymap_mod_get_index(client->keymap, "Meta"); - client->modifier_indices[MOD_IDX_SUPER] = xkb_keymap_mod_get_index(client->keymap, "Super"); - client->modifier_indices[MOD_IDX_HYPER] = xkb_keymap_mod_get_index(client->keymap, "Hyper"); - - /* - for (xkb_mod_index_t i = 0; - i < xkb_keymap_num_mods(client->keymap); - i++) { - g_log("squeek", G_LOG_LEVEL_DEBUG, "%s", xkb_keymap_mod_get_name(client->keymap, i)); - }*/ -} - -static void -send_fake_key (SeatEmitter *emitter, - LevelKeyboard *keyboard, - guint keycode, - gboolean pressed, - uint32_t timestamp) -{ - zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, 0); - send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp); - zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, 0); -} - -void -emit_key_activated (EekboardContextService *manager, - LevelKeyboard *keyboard, - guint keycode, - gboolean pressed, - uint32_t timestamp) -{ - /* FIXME: figure out how to deal with Client after key presses go through - if (g_strcmp0 (eek_symbol_get_name (symbol), "cycle-keyboard") == 0) { - client->keyboards_head = g_slist_next (client->keyboards_head); - if (client->keyboards_head == NULL) - client->keyboards_head = client->keyboards; - eekboard_context_set_keyboard (client->context, - GPOINTER_TO_UINT(client->keyboards_head->data), - NULL); - return; - } - - if (g_strcmp0 (eek_symbol_get_name (symbol), "preferences") == 0) { - gchar *argv[2]; - GError *error; - - argv[0] = g_build_filename (LIBEXECDIR, "eekboard-setup", NULL); - argv[1] = NULL; - - error = NULL; - if (!g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error)) { - g_warning ("can't spawn %s: %s", argv[0], error->message); - g_error_free (error); - } - g_free (argv[0]); - return; - } -*/ - SeatEmitter emitter = {0}; - emitter.virtual_keyboard = manager->virtual_keyboard; - update_modifier_info (&emitter); - send_fake_key (&emitter, keyboard, keycode, pressed, timestamp); -} diff --git a/eekboard/key-emitter.h b/eekboard/key-emitter.h deleted file mode 100644 index 337e925c..00000000 --- a/eekboard/key-emitter.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef KEYEMITTER_H -#define KEYEMITTER_H - -#include -#include - -#include "eek/eek.h" - -#include "virtual-keyboard-unstable-v1-client-protocol.h" - -/// Indices obtained by xkb_keymap_mod_get_name -enum mod_indices { - MOD_IDX_SHIFT, - MOD_IDX_CAPS, - MOD_IDX_CTRL, - MOD_IDX_ALT, - MOD_IDX_NUM, - MOD_IDX_MOD3, - MOD_IDX_LOGO, - MOD_IDX_ALTGR, - MOD_IDX_NUMLK, // Caution, not sure which is the right one - MOD_IDX_ALSO_ALT, // Not sure why, alt emits the first alt on my setup - MOD_IDX_LVL3, - - // Not sure if the next 4 are used at all - MOD_IDX_LALT, - MOD_IDX_RALT, - MOD_IDX_RCONTROL, - MOD_IDX_LCONTROL, - - MOD_IDX_SCROLLLK, - MOD_IDX_LVL5, - MOD_IDX_ALSO_ALTGR, // Not used on my layout - MOD_IDX_META, - MOD_IDX_SUPER, - MOD_IDX_HYPER, - - MOD_IDX_LAST, -}; - -void -emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard, - guint keycode, - gboolean pressed, uint32_t timestamp); -#endif // KEYEMITTER_H diff --git a/src/meson.build b/src/meson.build index b701eaf5..0eda4cf2 100644 --- a/src/meson.build +++ b/src/meson.build @@ -26,7 +26,6 @@ sources = [ '../eek/eek-xml-layout.c', '../eek/layersurface.c', dbus_src, - '../eekboard/key-emitter.c', '../eekboard/eekboard-context-service.c', # '../eekboard/eekboard-xklutil.c', squeekboard_resources, From 58b087e35a320f11e3425049929011faa1010fa4 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 20:13:22 +0000 Subject: [PATCH 09/13] eekboard_context_service: Drop unused enable property --- eekboard/eekboard-context-service.c | 78 ----------------------------- eekboard/eekboard-context-service.h | 2 - src/server-main.c | 1 - 3 files changed, 81 deletions(-) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index b0e6e076..a8922b8f 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -51,8 +51,6 @@ enum { }; enum { - ENABLED, - DISABLED, DESTROYED, LAST_SIGNAL }; @@ -63,8 +61,6 @@ static guint signals[LAST_SIGNAL] = { 0, }; (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CONTEXT_SERVICE, EekboardContextServicePrivate)) struct _EekboardContextServicePrivate { - gboolean enabled; - LevelKeyboard *keyboard; // currently used keyboard GHashTable *keyboard_hash; // a table of available keyboards, per layout @@ -276,41 +272,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass) gobject_class->set_property = eekboard_context_service_set_property; gobject_class->get_property = eekboard_context_service_get_property; gobject_class->dispose = eekboard_context_service_dispose; - - /** - * EekboardContextService::enabled: - * @context: an #EekboardContextService - * - * Emitted when @context is enabled. - */ - signals[ENABLED] = - g_signal_new (I_("enabled"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EekboardContextServiceClass, enabled), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - /** - * EekboardContextService::disabled: - * @context: an #EekboardContextService - * - * Emitted when @context is enabled. - */ - signals[DISABLED] = - g_signal_new (I_("disabled"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EekboardContextServiceClass, disabled), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - /** * EekboardContextService::destroyed: * @context: an #EekboardContextService @@ -365,42 +326,6 @@ eekboard_context_service_init (EekboardContextService *self) self->priv->overlay = NULL; } -/** - * eekboard_context_service_enable: - * @context: an #EekboardContextService - * - * Enable @context. This function is called when @context is pushed - * by eekboard_service_push_context(). - */ -void -eekboard_context_service_enable (EekboardContextService *context) -{ - g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); - - if (!context->priv->enabled) { - context->priv->enabled = TRUE; - g_signal_emit (context, signals[ENABLED], 0); - } -} - -/** - * eekboard_context_service_disable: - * @context: an #EekboardContextService - * - * Disable @context. This function is called when @context is pushed - * by eekboard_service_pop_context(). - */ -void -eekboard_context_service_disable (EekboardContextService *context) -{ - g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); - - if (context->priv->enabled) { - context->priv->enabled = FALSE; - g_signal_emit (context, signals[DISABLED], 0); - } -} - /** * eekboard_context_service_destroy: * @context: an #EekboardContextService @@ -412,9 +337,6 @@ eekboard_context_service_destroy (EekboardContextService *context) { g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); - if (context->priv->enabled) { - eekboard_context_service_disable (context); - } g_free(context->priv->overlay); g_signal_emit (context, signals[DESTROYED], 0); } diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h index 668fe0bc..9333586e 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -88,8 +88,6 @@ struct _EekboardContextServiceClass { GType eekboard_context_service_get_type (void) G_GNUC_CONST; -void eekboard_context_service_enable (EekboardContextService *context); -void eekboard_context_service_disable (EekboardContextService *context); void eekboard_context_service_destroy (EekboardContextService *context); LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context); diff --git a/src/server-main.c b/src/server-main.c index 8c6b7e50..fa919f02 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -76,7 +76,6 @@ static ServerContextService *create_context() { g_object_set_data_full (G_OBJECT(context), "owner", g_strdup ("sender"), (GDestroyNotify)g_free); - eekboard_context_service_enable (EEKBOARD_CONTEXT_SERVICE(context)); return context; } From 92c9572ac21292f884e8d09ea66658aa624839c2 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 9 Jan 2020 20:49:27 +0000 Subject: [PATCH 10/13] services: Split out layout management from EekboardContextService Layout management was pointlessly bound with the EekboardContextService with inheritance. Splitting it out will make it easier to further break apart layout state management, settings, and input method in the future. --- eekboard/eekboard-context-service.c | 20 +++++++++-- eekboard/eekboard-context-service.h | 4 +-- src/dbus.c | 2 +- src/dbus.h | 2 +- src/imservice.c | 8 ++--- src/imservice.h | 11 +++--- src/imservice.rs | 53 +++++++++++++++++++++++------ src/server-context-service.c | 42 +++++++++++------------ src/server-context-service.h | 6 ++-- src/server-main.c | 36 ++++++++++++-------- 10 files changed, 116 insertions(+), 68 deletions(-) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index a8922b8f..94a6ae4c 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -69,6 +69,10 @@ struct _EekboardContextServicePrivate { GSettings *settings; // Owned reference uint32_t hint; uint32_t purpose; + + // Maybe TODO: it's used only for fetching layout type. + // Maybe let UI push the type to this structure? + ServerContextService *ui; // unowned reference }; G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT); @@ -218,13 +222,13 @@ eekboard_context_service_update_layout(EekboardContextService *context, enum squ LevelKeyboard *previous_keyboard = context->priv->keyboard; context->priv->keyboard = keyboard; - g_object_notify (G_OBJECT(context), "keyboard"); - // The keymap will get set even if the window is hidden. // It's not perfect, // but simpler than adding a check in the window showing procedure eekboard_context_service_set_keymap(context, keyboard); + g_object_notify (G_OBJECT(context), "keyboard"); + // replacing the keyboard above will cause the previous keyboard to get destroyed from the UI side (eek_gtk_keyboard_dispose) if (previous_keyboard) { level_keyboard_free(previous_keyboard); @@ -232,7 +236,12 @@ eekboard_context_service_update_layout(EekboardContextService *context, enum squ } static void update_layout_and_type(EekboardContextService *context) { - eekboard_context_service_update_layout(context, server_context_service_get_layout_type(context)); + EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context); + enum squeek_arrangement_kind layout_kind = ARRANGEMENT_KIND_BASE; + if (priv->ui) { + layout_kind = server_context_service_get_layout_type(priv->ui); + } + eekboard_context_service_update_layout(context, layout_kind); } static gboolean @@ -384,3 +393,8 @@ const char* eekboard_context_service_get_overlay(EekboardContextService *context) { return context->priv->overlay; } + +EekboardContextService *eekboard_context_service_new() +{ + return g_object_new (EEKBOARD_TYPE_CONTEXT_SERVICE, NULL); +} diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h index 9333586e..dab830ce 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -77,8 +77,6 @@ struct _EekboardContextServiceClass { const gchar *keyboard_type); /* signals */ - void (*enabled) (EekboardContextService *self); - void (*disabled) (EekboardContextService *self); void (*destroyed) (EekboardContextService *self); /*< private >*/ @@ -86,8 +84,10 @@ struct _EekboardContextServiceClass { gpointer pdummy[24]; }; +EekboardContextService *eekboard_context_service_new(); GType eekboard_context_service_get_type (void) G_GNUC_CONST; +EekboardContextService *eekboard_context_service_new(void); void eekboard_context_service_destroy (EekboardContextService *context); LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context); diff --git a/src/dbus.c b/src/dbus.c index 29783090..046b6bd8 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -110,7 +110,7 @@ dbus_handler_new (GDBusConnection *connection, } void -dbus_handler_set_context(DBusHandler *service, +dbus_handler_set_ui_context(DBusHandler *service, ServerContextService *context) { g_return_if_fail (!service->context); diff --git a/src/dbus.h b/src/dbus.h index c77ad850..f719e274 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -41,7 +41,7 @@ typedef struct _DBusHandler DBusHandler * dbus_handler_new (GDBusConnection *connection, const gchar *object_path); -void dbus_handler_set_context(DBusHandler *service, +void dbus_handler_set_ui_context(DBusHandler *service, ServerContextService *context); void dbus_handler_destroy(DBusHandler*); G_END_DECLS diff --git a/src/imservice.c b/src/imservice.c index d33f11db..595a3546 100644 --- a/src/imservice.c +++ b/src/imservice.c @@ -12,11 +12,11 @@ static const struct zwp_input_method_v2_listener input_method_listener = { .unavailable = imservice_handle_unavailable, }; -struct imservice* get_imservice(ServerContextService *context, - struct zwp_input_method_manager_v2 *manager, - struct wl_seat *seat) { +struct imservice* get_imservice(struct zwp_input_method_manager_v2 *manager, + struct wl_seat *seat, + EekboardContextService *state) { struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat); - struct imservice *imservice = imservice_new(im, context); + struct imservice *imservice = imservice_new(im, state); /* Add a listener, passing the imservice instance to make it available to callbacks. */ diff --git a/src/imservice.h b/src/imservice.h index 0f7b1c75..5b879bfb 100644 --- a/src/imservice.h +++ b/src/imservice.h @@ -7,13 +7,14 @@ struct imservice; -struct imservice* get_imservice(ServerContextService *context, - struct zwp_input_method_manager_v2 *manager, - struct wl_seat *seat); +struct imservice* get_imservice(struct zwp_input_method_manager_v2 *manager, + struct wl_seat *seat, + EekboardContextService *state); // Defined in Rust -struct imservice* imservice_new(struct zwp_input_method_v2 *im, - ServerContextService *context); +struct imservice* imservice_new(struct zwp_input_method_v2 *im, EekboardContextService *state); +void imservice_set_ui(struct imservice *self, ServerContextService *ui_context); + void imservice_handle_input_method_activate(void *data, struct zwp_input_method_v2 *input_method); void imservice_handle_input_method_deactivate(void *data, struct zwp_input_method_v2 *input_method); void imservice_handle_surrounding_text(void *data, struct zwp_input_method_v2 *input_method, diff --git a/src/imservice.rs b/src/imservice.rs index df4019b7..cc30b01a 100644 --- a/src/imservice.rs +++ b/src/imservice.rs @@ -21,14 +21,18 @@ pub mod c { #[repr(transparent)] pub struct InputMethod(*const c_void); - /// EekboardContextService* + /// ServerContextService* #[repr(transparent)] pub struct UIManager(*const c_void); - + + /// EekboardContextService* + #[repr(transparent)] + pub struct StateManager(*const c_void); + #[no_mangle] extern "C" { fn imservice_destroy_im(im: *mut c::InputMethod); - fn eekboard_context_service_set_hint_purpose(imservice: *const UIManager, hint: u32, purpose: u32); + fn eekboard_context_service_set_hint_purpose(state: *const StateManager, hint: u32, purpose: u32); fn server_context_service_show_keyboard(imservice: *const UIManager); fn server_context_service_hide_keyboard(imservice: *const UIManager); } @@ -36,12 +40,16 @@ pub mod c { // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers #[no_mangle] - pub unsafe extern "C" - fn imservice_new(im: *const InputMethod, ui_manager: *const UIManager) -> *mut IMService { + pub extern "C" + fn imservice_new( + im: *const InputMethod, + state_manager: *const StateManager + ) -> *mut IMService { Box::::into_raw(Box::new( IMService { im: im, - ui_manager: ui_manager, + state_manager: state_manager, + ui_manager: None, pending: IMProtocolState::default(), current: IMProtocolState::default(), preedit_string: String::new(), @@ -49,6 +57,20 @@ pub mod c { } )) } + + #[no_mangle] + pub extern "C" + fn imservice_set_ui(imservice: *mut IMService, ui_manager: *const UIManager) { + if imservice.is_null() { + panic!("Null imservice pointer"); + } + let imservice: &mut IMService = unsafe { &mut *imservice }; + imservice.ui_manager = if ui_manager.is_null() { + None + } else { + Some(ui_manager) + }; + } // TODO: is unsafe needed here? #[no_mangle] @@ -148,15 +170,20 @@ pub mod c { active: imservice.current.active, ..IMProtocolState::default() }; + if active_changed { if imservice.current.active { - server_context_service_show_keyboard(imservice.ui_manager); + if let Some(ui) = imservice.ui_manager { + server_context_service_show_keyboard(ui); + } eekboard_context_service_set_hint_purpose( - imservice.ui_manager, + imservice.state_manager, imservice.current.content_hint.bits(), imservice.current.content_purpose.clone() as u32); } else { - server_context_service_hide_keyboard(imservice.ui_manager); + if let Some(ui) = imservice.ui_manager { + server_context_service_hide_keyboard(ui); + } } } } @@ -173,7 +200,9 @@ pub mod c { // the keyboard is already decommissioned imservice.current.active = false; - server_context_service_hide_keyboard(imservice.ui_manager); + if let Some(ui) = imservice.ui_manager { + server_context_service_hide_keyboard(ui); + } } // FIXME: destroy and deallocate @@ -320,7 +349,9 @@ pub struct IMService { /// Owned reference (still created and destroyed in C) pub im: *const c::InputMethod, /// Unowned reference. Be careful, it's shared with C at large - ui_manager: *const c::UIManager, + ui_manager: Option<*const c::UIManager>, + /// Unowned reference. Be careful, it's shared with C at large + state_manager: *const c::StateManager, pending: IMProtocolState, current: IMProtocolState, // turn current into an idiomatic representation? diff --git a/src/server-context-service.c b/src/server-context-service.c index 1cacb37d..ce2052da 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -38,7 +38,9 @@ enum { typedef struct _ServerContextServiceClass ServerContextServiceClass; struct _ServerContextService { - EekboardContextService parent; + GObject parent; + + EekboardContextService *state; // unowned gboolean visible; PhoshLayerSurface *window; @@ -52,10 +54,10 @@ struct _ServerContextService { }; struct _ServerContextServiceClass { - EekboardContextServiceClass parent_class; + GObjectClass parent_class; }; -G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE); +G_DEFINE_TYPE(ServerContextService, server_context_service, G_TYPE_OBJECT); static void on_destroy (GtkWidget *widget, gpointer user_data) @@ -67,7 +69,7 @@ on_destroy (GtkWidget *widget, gpointer user_data) context->window = NULL; context->widget = NULL; - eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context)); + //eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context)); } static void @@ -220,7 +222,7 @@ make_widget (ServerContextService *context) context->widget = NULL; } - LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context)); + LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (context->state); context->widget = eek_gtk_keyboard_new (keyboard); @@ -284,11 +286,6 @@ server_context_service_hide_keyboard (ServerContextService *context) } } -static void -server_context_service_real_destroyed (EekboardContextService *_context) -{ -} - static void server_context_service_set_property (GObject *object, guint prop_id, @@ -352,12 +349,9 @@ server_context_service_dispose (GObject *object) static void server_context_service_class_init (ServerContextServiceClass *klass) { - EekboardContextServiceClass *context_class = EEKBOARD_CONTEXT_SERVICE_CLASS(klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - context_class->destroyed = server_context_service_real_destroyed; - gobject_class->set_property = server_context_service_set_property; gobject_class->get_property = server_context_service_get_property; gobject_class->dispose = server_context_service_dispose; @@ -396,21 +390,23 @@ server_context_service_class_init (ServerContextServiceClass *klass) } static void -server_context_service_init (ServerContextService *context) -{ - g_signal_connect (context, - "notify::keyboard", - G_CALLBACK(on_notify_keyboard), - context); +server_context_service_init (ServerContextService *state) { + (void)state; } ServerContextService * -server_context_service_new () +server_context_service_new (EekboardContextService *state) { - return g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL); + ServerContextService *ui = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL); + ui->state = state; + g_signal_connect (state, + "notify::keyboard", + G_CALLBACK(on_notify_keyboard), + ui); + return ui; } -enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService *service) +enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *service) { - return SERVER_CONTEXT_SERVICE(service)->last_type; + return service->last_type; } diff --git a/src/server-context-service.h b/src/server-context-service.h index c7f7412a..c316f6b7 100644 --- a/src/server-context-service.h +++ b/src/server-context-service.h @@ -29,14 +29,14 @@ G_BEGIN_DECLS #define SERVER_IS_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SERVER_TYPE_CONTEXT_SERVICE)) #define SERVER_CONTEXT_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SERVER_TYPE_CONTEXT_SERVICE, ServerContextServiceClass)) -/** Manages the liecycle of the window displaying layouts. */ +/** Manages the lifecycle of the window displaying layouts. */ typedef struct _ServerContextService ServerContextService; GType server_context_service_get_type (void) G_GNUC_CONST; -ServerContextService *server_context_service_new(); -enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService*); +ServerContextService *server_context_service_new(EekboardContextService *state); +enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *); void server_context_service_show_keyboard (ServerContextService *context); void server_context_service_hide_keyboard (ServerContextService *context); G_END_DECLS diff --git a/src/server-main.c b/src/server-main.c index fa919f02..b9592eaa 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -39,7 +39,9 @@ /// Global application state struct squeekboard { struct squeek_wayland wayland; - ServerContextService *context; + DBusHandler *dbus_handler; + EekboardContextService *settings_context; + ServerContextService *ui_context; struct imservice *imservice; }; @@ -71,14 +73,6 @@ on_name_lost (GDBusConnection *connection, exit (1); } -static ServerContextService *create_context() { - ServerContextService *context = server_context_service_new (); - g_object_set_data_full (G_OBJECT(context), - "owner", g_strdup ("sender"), - (GDestroyNotify)g_free); - return context; -} - // Wayland static void @@ -199,7 +193,7 @@ main (int argc, char **argv) exit(1); } - instance.context = create_context(); + instance.settings_context = eekboard_context_service_new(); // set up dbus @@ -252,9 +246,8 @@ main (int argc, char **argv) if (service == NULL) { g_printerr ("Can't create dbus server\n"); exit (1); - } else { - dbus_handler_set_context(service, instance.context); } + instance.dbus_handler = service; guint owner_id = g_bus_own_name_on_connection (connection, DBUS_SERVICE_INTERFACE, @@ -270,9 +263,9 @@ main (int argc, char **argv) struct imservice *imservice = NULL; if (instance.wayland.input_method_manager) { - imservice = get_imservice(instance.context, - instance.wayland.input_method_manager, - instance.wayland.seat); + imservice = get_imservice(instance.wayland.input_method_manager, + instance.wayland.seat, + instance.settings_context); if (imservice) { instance.imservice = imservice; } else { @@ -280,6 +273,19 @@ main (int argc, char **argv) } } + ServerContextService *ui_context = server_context_service_new(instance.settings_context); + if (!ui_context) { + g_error("Could not initialize GUI"); + exit(1); + } + instance.ui_context = ui_context; + if (instance.imservice) { + imservice_set_ui(instance.imservice, instance.ui_context); + } + if (instance.dbus_handler) { + dbus_handler_set_ui_context(instance.dbus_handler, instance.ui_context); + } + session_register(); GMainLoop *loop = g_main_loop_new (NULL, FALSE); From a78f8e246b0758af2aadc35e3316cf72d7ed9d5d Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Tue, 14 Jan 2020 13:54:10 +0000 Subject: [PATCH 11/13] pre-release: Update deps --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9aa6b212..63ac9f86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ name = "aho-corasick" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -69,7 +69,7 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -221,7 +221,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "gdk 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -284,7 +284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -348,15 +348,15 @@ version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -504,7 +504,7 @@ dependencies = [ "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd940f0d609699e343ef71c4af5f66423afbf30d666f796dabd8fd15229cf5b6" "checksum cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d25596627380be4381247dba06c69ad05ca21b3b065bd9827e416882ac41dcd2" -"checksum cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)" = "e450b8da92aa6f274e7c6437692f9f2ce6d701fb73bacfcf87897b3f89a4c20e" +"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9" @@ -524,7 +524,7 @@ dependencies = [ "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" -"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c2cb169402a3eb1ba034a7cc7d95b8b1c106e9be5ba4be79a5a93dc1a2795f4" "checksum pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6eb49268e69dd0c1da5d3001a61aac08e2e9d2bfbe4ae4b19b9963c998f6453" @@ -532,7 +532,7 @@ dependencies = [ "checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d9d8297cc20bbb6184f8b45ff61c8ee6a9ac56c156cec8e38c3e5084773c44ad" -"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" +"checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" From dca0e55557d75151790cb974ae45839f8627d815 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Tue, 14 Jan 2020 13:56:21 +0000 Subject: [PATCH 12/13] Release 1.8.0 "Conflict-free replicated data type" - The terminal layout is always available from the layout selection popup. - XKB Layout names in the popup are translated using GNOME's database. --- debian/changelog | 17 +++++++++++++++++ meson.build | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 22f09941..f2a51e4b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,20 @@ +squeekboard (1.8.0) amber-phone; urgency=medium + + [ Dorota Czaplejewicz ] + * translations: Use gnome-desktop's xkb info database for layout names + * translations: Make the code cleaner + * overlay: Add terminal + * eek-layout: Remove unused + * pre-release: Update deps + + -- Dorota Czaplejewicz Tue, 14 Jan 2020 13:55:00 +0000 + +squeekboard (1.7.0) amber-phone; urgency=medium + + * New terminal layout appearing on terminal input hint + + -- Dorota Czaplejewicz Wed, 08 Jan 2020 11:53:07 +0000 + squeekboard (1.7.0) amber-phone; urgency=medium * New terminal layout appearing on terminal input hint diff --git a/meson.build b/meson.build index 66340e09..d33b76a1 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'squeekboard', 'c', 'rust', - version: '1.7.0', + version: '1.8.0', license: 'GPLv3', meson_version: '>=0.51.0', default_options: [ From 81e0c15db92ac8af8f83b920a2369ffe1b3e0f03 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Wed, 15 Jan 2020 17:06:00 +0000 Subject: [PATCH 13/13] dbus: Log error on dbus exit --- src/server-main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server-main.c b/src/server-main.c index 56a2fd1f..35377e17 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -64,9 +64,11 @@ on_name_lost (GDBusConnection *connection, gpointer user_data) { // TODO: could conceivable continue working + // if intrnal changes stop sending dbus changes (void)connection; (void)name; (void)user_data; + g_error("DBus unavailable, unclear how to continue."); exit (1); }