diff --git a/eekboard/eekboard-client.c b/eekboard/eekboard-client.c index bc76e33f..b853ae9d 100644 --- a/eekboard/eekboard-client.c +++ b/eekboard/eekboard-client.c @@ -325,6 +325,38 @@ eekboard_client_pop_context (EekboardClient *client, NULL); } +void +eekboard_client_show_keyboard (EekboardClient *client, + GCancellable *cancellable) +{ + g_return_if_fail (EEKBOARD_IS_CLIENT(client)); + + g_dbus_proxy_call (G_DBUS_PROXY(client), + "ShowKeyboard", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + eekboard_async_ready_callback, + NULL); +} + +void +eekboard_client_hide_keyboard (EekboardClient *client, + GCancellable *cancellable) +{ + g_return_if_fail (EEKBOARD_IS_CLIENT(client)); + + g_dbus_proxy_call (G_DBUS_PROXY(client), + "HideKeyboard", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + eekboard_async_ready_callback, + NULL); +} + static void send_destroy_context (EekboardClient *client, EekboardContext *context, diff --git a/eekboard/eekboard-client.h b/eekboard/eekboard-client.h index c19c0525..b09db298 100644 --- a/eekboard/eekboard-client.h +++ b/eekboard/eekboard-client.h @@ -67,6 +67,10 @@ void eekboard_client_push_context (EekboardClient *eekboard, GCancellable *cancellable); void eekboard_client_pop_context (EekboardClient *eekboard, GCancellable *cancellable); +void eekboard_client_show_keyboard (EekboardClient *eekboard, + GCancellable *cancellable); +void eekboard_client_hide_keyboard (EekboardClient *eekboard, + GCancellable *cancellable); void eekboard_client_destroy_context (EekboardClient *eekboard, EekboardContext *context, GCancellable *cancellable); diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index 11bd518a..4eeab661 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -201,6 +201,26 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self, return keyboard; } +static void +eekboard_context_service_real_show_keyboard (EekboardContextService *self) +{ + gboolean visible = self->priv->visible; + self->priv->visible = TRUE; + if (visible != self->priv->visible) + emit_visibility_changed_signal (self, + self->priv->visible); +} + +static void +eekboard_context_service_real_hide_keyboard (EekboardContextService *self) +{ + gboolean visible = self->priv->visible; + self->priv->visible = FALSE; + if (visible != self->priv->visible) + emit_visibility_changed_signal (self, + self->priv->visible); +} + static void eekboard_context_service_set_property (GObject *object, guint prop_id, @@ -209,7 +229,6 @@ eekboard_context_service_set_property (GObject *object, { EekboardContextService *context = EEKBOARD_CONTEXT_SERVICE(object); GDBusConnection *connection; - gboolean was_visible; switch (prop_id) { case PROP_OBJECT_PATH: @@ -234,11 +253,12 @@ eekboard_context_service_set_property (GObject *object, context->priv->keyboard = g_value_get_object (value); break; case PROP_VISIBLE: - was_visible = context->priv->visible; - context->priv->visible = g_value_get_boolean (value); - if (was_visible != context->priv->visible) - emit_visibility_changed_signal (context, - context->priv->visible); + if (context->priv->keyboard) { + if (g_value_get_boolean (value)) + eekboard_context_service_show_keyboard (context); + else + eekboard_context_service_hide_keyboard (context); + } break; case PROP_FULLSCREEN: context->priv->fullscreen = g_value_get_boolean (value); @@ -358,8 +378,8 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass) sizeof (EekboardContextServicePrivate)); klass->create_keyboard = eekboard_context_service_real_create_keyboard; - klass->show_keyboard = NULL; - klass->hide_keyboard = NULL; + 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; @@ -864,15 +884,13 @@ handle_method_call (GDBusConnection *connection, return; } - if (klass->show_keyboard) - klass->show_keyboard (context); + eekboard_context_service_show_keyboard (context); g_dbus_method_invocation_return_value (invocation, NULL); return; } if (g_strcmp0 (method_name, "HideKeyboard") == 0) { - if (klass->hide_keyboard) - klass->hide_keyboard (context); + eekboard_context_service_hide_keyboard (context); g_dbus_method_invocation_return_value (invocation, NULL); return; } @@ -999,6 +1017,24 @@ eekboard_context_service_disable (EekboardContextService *context) } } +void +eekboard_context_service_show_keyboard (EekboardContextService *context) +{ + g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); + g_return_if_fail (context->priv->connection); + + EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->show_keyboard (context); +} + +void +eekboard_context_service_hide_keyboard (EekboardContextService *context) +{ + g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context)); + g_return_if_fail (context->priv->connection); + + EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->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 3804ea4a..4d415e20 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -84,6 +84,10 @@ 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_hide_keyboard + (EekboardContextService *context); void eekboard_context_service_destroy (EekboardContextService *context); EekKeyboard *eekboard_context_service_get_keyboard (EekboardContextService *context); diff --git a/eekboard/eekboard-service.c b/eekboard/eekboard-service.c index ffde7c79..e27a9835 100644 --- a/eekboard/eekboard-service.c +++ b/eekboard/eekboard-service.c @@ -55,6 +55,7 @@ struct _EekboardServicePrivate { GHashTable *context_hash; GSList *context_stack; + gboolean visible; }; G_DEFINE_TYPE (EekboardService, eekboard_service, G_TYPE_OBJECT); @@ -70,6 +71,8 @@ static const gchar introspection_xml[] = " " " " " " + " " + " " " " /* signals */ " " @@ -358,6 +361,14 @@ context_destroyed_cb (EekboardContextService *context, EekboardService *service) g_free (object_path); } +static void +on_notify_visible (GObject *object, GParamSpec *spec, gpointer user_data) +{ + EekboardService *service = user_data; + + g_object_get (object, "visible", &service->priv->visible, NULL); +} + static void handle_method_call (GDBusConnection *connection, const gchar *sender, @@ -424,6 +435,10 @@ handle_method_call (GDBusConnection *connection, service->priv->context_stack = g_slist_prepend (service->priv->context_stack, g_object_ref (context)); eekboard_context_service_enable (context); + g_signal_connect (context, "notify::visible", + G_CALLBACK(on_notify_visible), service); + if (service->priv->visible) + eekboard_context_service_show_keyboard (context); g_dbus_method_invocation_return_value (invocation, NULL); return; @@ -448,6 +463,9 @@ handle_method_call (GDBusConnection *connection, } g_free (object_path); + g_signal_handlers_disconnect_by_func (context, + G_CALLBACK(on_notify_visible), + service); eekboard_context_service_disable (context); service->priv->context_stack = g_slist_next (service->priv->context_stack); if (service->priv->context_stack) @@ -458,6 +476,24 @@ handle_method_call (GDBusConnection *connection, return; } + if (g_strcmp0 (method_name, "ShowKeyboard") == 0) { + if (service->priv->context_stack) { + eekboard_context_service_show_keyboard (service->priv->context_stack->data); + } else { + service->priv->visible = TRUE; + } + return; + } + + if (g_strcmp0 (method_name, "HideKeyboard") == 0) { + if (service->priv->context_stack) { + eekboard_context_service_hide_keyboard (service->priv->context_stack->data); + } else { + service->priv->visible = FALSE; + } + return; + } + if (g_strcmp0 (method_name, "Destroy") == 0) { g_signal_emit (service, signals[DESTROYED], 0); g_dbus_method_invocation_return_value (invocation, NULL); diff --git a/src/client.c b/src/client.c index ee0c5770..fed1809f 100644 --- a/src/client.c +++ b/src/client.c @@ -305,7 +305,7 @@ client_set_keyboards (Client *client, gboolean retval; retval = set_keyboards (client, keyboards); if (retval && IS_KEYBOARD_VISIBLE (client)) - eekboard_context_show_keyboard (client->context, NULL); + eekboard_client_show_keyboard (client->eekboard, NULL); return retval; } @@ -347,7 +347,7 @@ client_enable_xkl (Client *client) retval = set_keyboards_from_xkl (client); if (IS_KEYBOARD_VISIBLE (client)) - eekboard_context_show_keyboard (client->context, NULL); + eekboard_client_show_keyboard (client->eekboard, NULL); return retval; } @@ -538,21 +538,21 @@ focus_listener_cb (const AtspiEvent *event, case ATSPI_ROLE_TERMINAL: if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) { client->acc = accessible; - eekboard_context_show_keyboard (client->context, NULL); + eekboard_client_show_keyboard (client->eekboard, NULL); } else if (g_settings_get_boolean (client->settings, "auto-hide") && event->detail1 == 0 && accessible == client->acc) { client->acc = NULL; - eekboard_context_hide_keyboard (client->context, NULL); + eekboard_client_hide_keyboard (client->eekboard, NULL); } break; case ATSPI_ROLE_ENTRY: if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) { client->acc = accessible; - eekboard_context_show_keyboard (client->context, NULL); + eekboard_client_show_keyboard (client->eekboard, NULL); } else if (g_settings_get_boolean (client->settings, "auto-hide") && event->detail1 == 0) { client->acc = NULL; - eekboard_context_hide_keyboard (client->context, NULL); + eekboard_client_hide_keyboard (client->eekboard, NULL); } break; @@ -560,7 +560,7 @@ focus_listener_cb (const AtspiEvent *event, ; } } else { - eekboard_context_hide_keyboard (client->context, NULL); + eekboard_client_hide_keyboard (client->eekboard, NULL); } } @@ -612,7 +612,7 @@ add_match_rule (GDBusConnection *connection, static gboolean on_hide_keyboard_timeout (Client *client) { - eekboard_context_hide_keyboard (client->context, NULL); + eekboard_client_hide_keyboard (client->eekboard, NULL); client->hide_keyboard_timeout_id = 0; return FALSE; } @@ -635,7 +635,7 @@ focus_message_filter (GDBusConnection *connection, g_source_remove (client->hide_keyboard_timeout_id); client->hide_keyboard_timeout_id = 0; } - eekboard_context_show_keyboard (client->context, NULL); + eekboard_client_show_keyboard (client->eekboard, NULL); } else if (g_settings_get_boolean (client->settings, "auto-hide") && g_strcmp0 (member, "FocusOut") == 0) { guint delay; diff --git a/src/server-context-service.c b/src/server-context-service.c index ddbc2b53..e9723622 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -332,6 +332,9 @@ server_context_service_real_show_keyboard (EekboardContextService *_context) update_widget (context); g_assert (context->window); gtk_widget_show_all (context->window); + + EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)-> + show_keyboard (_context); } static void @@ -341,6 +344,9 @@ server_context_service_real_hide_keyboard (EekboardContextService *_context) if (context->window) gtk_widget_hide (context->window); + + EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)-> + hide_keyboard (_context); } static void