Add keyboard selection dialog to preferences.

This commit is contained in:
Daiki Ueno
2012-03-28 11:24:46 +09:00
parent 1943749cb6
commit ee0505c100
20 changed files with 951 additions and 424 deletions

View File

@ -50,6 +50,7 @@ enum {
enum {
ENABLED,
DISABLED,
DESTROYED,
LAST_SIGNAL
};
@ -114,8 +115,9 @@ static const gchar introspection_xml[] =
/* signals */
" <signal name='Enabled'/>"
" <signal name='Disabled'/>"
" <signal name='Destroyed'/>"
" <signal name='KeyActivated'>"
" <arg type='s' name='keyname'/>"
" <arg type='u' name='keycode'/>"
" <arg type='v' name='symbol'/>"
" <arg type='u' name='modifiers'/>"
" </signal>"
@ -399,6 +401,23 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
G_TYPE_NONE,
0);
/**
* EekboardContextService::destroyed:
* @context: an #EekboardContextService
*
* Emitted when @context is destroyed.
*/
signals[DESTROYED] =
g_signal_new (I_("destroyed"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekboardContextServiceClass, destroyed),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EekboardContextService:object-path:
*
@ -574,7 +593,7 @@ emit_key_activated_dbus_signal (EekboardContextService *context,
EekKey *key)
{
if (context->priv->connection && context->priv->enabled) {
const gchar *keyname = eek_element_get_name (EEK_ELEMENT(key));
guint keycode = eek_key_get_keycode (key);
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
guint modifiers = eek_keyboard_get_modifiers (context->priv->keyboard);
GVariant *variant;
@ -589,8 +608,8 @@ emit_key_activated_dbus_signal (EekboardContextService *context,
context->priv->object_path,
EEKBOARD_CONTEXT_SERVICE_INTERFACE,
"KeyActivated",
g_variant_new ("(svu)",
keyname,
g_variant_new ("(uvu)",
keycode,
variant,
modifiers),
&error);
@ -748,13 +767,15 @@ handle_method_call (GDBusConnection *connection,
g_variant_get (parameters, "(u)", &keyboard_id);
current_keyboard_id =
GPOINTER_TO_UINT (g_object_get_data (G_OBJECT(context->priv->keyboard),
"keyboard-id"));
if (keyboard_id == current_keyboard_id) {
disconnect_keyboard_signals (context);
context->priv->keyboard = NULL;
g_object_notify (G_OBJECT(context), "keyboard");
if (context->priv->keyboard != NULL) {
current_keyboard_id =
GPOINTER_TO_UINT (g_object_get_data (G_OBJECT(context->priv->keyboard),
"keyboard-id"));
if (keyboard_id == current_keyboard_id) {
disconnect_keyboard_signals (context);
context->priv->keyboard = NULL;
g_object_notify (G_OBJECT(context), "keyboard");
}
}
g_hash_table_remove (context->priv->keyboard_hash,
@ -978,6 +999,42 @@ eekboard_context_service_disable (EekboardContextService *context)
}
}
/**
* eekboard_context_service_destroy:
* @context: an #EekboardContextService
*
* Destroy @context.
*/
void
eekboard_context_service_destroy (EekboardContextService *context)
{
gboolean retval;
GError *error;
g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context));
g_return_if_fail (context->priv->connection);
if (context->priv->enabled) {
eekboard_context_service_disable (context);
}
error = NULL;
retval = g_dbus_connection_emit_signal (context->priv->connection,
NULL,
context->priv->object_path,
EEKBOARD_CONTEXT_SERVICE_INTERFACE,
"Destroyed",
NULL,
&error);
if (!retval) {
g_warning ("failed to emit Destroyed signal: %s",
error->message);
g_error_free (error);
g_assert_not_reached ();
}
g_signal_emit (context, signals[DESTROYED], 0);
}
/**
* eekboard_context_service_get_keyboard:
* @context: an #EekboardContextService

View File

@ -73,6 +73,7 @@ struct _EekboardContextServiceClass {
/* signals */
void (*enabled) (EekboardContextService *self);
void (*disabled) (EekboardContextService *self);
void (*destroyed) (EekboardContextService *self);
/*< private >*/
/* padding */
@ -83,6 +84,7 @@ 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);
EekKeyboard *eekboard_context_service_get_keyboard
(EekboardContextService *context);
gboolean eekboard_context_service_get_fullscreen

View File

@ -36,8 +36,8 @@
enum {
ENABLED,
DISABLED,
KEY_PRESSED,
DESTROYED,
KEY_ACTIVATED,
LAST_SIGNAL
};
@ -80,14 +80,19 @@ eekboard_context_real_g_signal (GDBusProxy *self,
return;
}
if (g_strcmp0 (signal_name, "Destroyed") == 0) {
g_signal_emit (context, signals[DESTROYED], 0);
return;
}
if (g_strcmp0 (signal_name, "KeyActivated") == 0) {
const gchar *keyname;
guint keycode;
GVariant *variant = NULL;
guint modifiers = 0;
EekSerializable *serializable;
g_variant_get (parameters, "(&svu)",
&keyname, &variant, &modifiers);
g_variant_get (parameters, "(uvu)",
&keycode, &variant, &modifiers);
g_return_if_fail (variant != NULL);
serializable = eek_serializable_deserialize (variant);
@ -95,8 +100,8 @@ eekboard_context_real_g_signal (GDBusProxy *self,
g_return_if_fail (EEK_IS_SYMBOL(serializable));
g_signal_emit (context, signals[KEY_PRESSED], 0,
keyname, EEK_SYMBOL(serializable), modifiers);
g_signal_emit (context, signals[KEY_ACTIVATED], 0,
keycode, EEK_SYMBOL(serializable), modifiers);
g_object_unref (serializable);
return;
@ -140,15 +145,15 @@ eekboard_context_real_disabled (EekboardContext *self)
}
static void
eekboard_context_real_key_pressed (EekboardContext *self,
const gchar *keyname,
EekSymbol *symbol,
guint modifiers)
eekboard_context_real_destroyed (EekboardContext *self)
{
}
static void
eekboard_context_real_destroyed (EekboardContext *self)
eekboard_context_real_key_activated (EekboardContext *self,
const gchar *keyname,
EekSymbol *symbol,
guint modifiers)
{
}
@ -181,8 +186,8 @@ eekboard_context_class_init (EekboardContextClass *klass)
klass->enabled = eekboard_context_real_enabled;
klass->disabled = eekboard_context_real_disabled;
klass->key_pressed = eekboard_context_real_key_pressed;
klass->destroyed = eekboard_context_real_destroyed;
klass->key_activated = eekboard_context_real_key_activated;
proxy_class->g_signal = eekboard_context_real_g_signal;
@ -237,26 +242,26 @@ eekboard_context_class_init (EekboardContextClass *klass)
0);
/**
* EekboardContext::key-pressed:
* EekboardContext::key-activated:
* @context: an #EekboardContext
* @keycode: keycode
* @keycode: a keycode
* @symbol: an #EekSymbol
* @modifiers: modifiers
*
* The ::key-pressed signal is emitted each time a key is pressed
* in @context.
* The ::key-activated signal is emitted each time a key is
* pressed in @context.
*/
signals[KEY_PRESSED] =
g_signal_new (I_("key-pressed"),
signals[KEY_ACTIVATED] =
g_signal_new (I_("key-activated"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekboardContextClass, key_pressed),
G_STRUCT_OFFSET(EekboardContextClass, key_activated),
NULL,
NULL,
_eekboard_marshal_VOID__STRING_OBJECT_UINT,
_eekboard_marshal_VOID__UINT_OBJECT_UINT,
G_TYPE_NONE,
3,
G_TYPE_STRING,
G_TYPE_UINT,
G_TYPE_OBJECT,
G_TYPE_UINT);

View File

@ -66,12 +66,13 @@ struct _EekboardContextClass {
/* signals */
void (*enabled) (EekboardContext *self);
void (*disabled) (EekboardContext *self);
void (*key_pressed) (EekboardContext *self,
const gchar *keyname,
EekSymbol *symbol,
guint modifiers);
void (*destroyed) (EekboardContext *self);
void (*key_activated) (EekboardContext *self,
const gchar *keyname,
EekSymbol *symbol,
guint modifiers);
/*< private >*/
/* padding */
gpointer pdummy[24];

View File

@ -1 +1 @@
VOID:STRING,OBJECT,UINT
VOID:UINT,OBJECT,UINT

View File

@ -70,9 +70,6 @@ static const gchar introspection_xml[] =
" <arg direction='in' type='s' name='object_path'/>"
" </method>"
" <method name='PopContext'/>"
" <method name='DestroyContext'>"
" <arg direction='in' type='s' name='object_path'/>"
" </method>"
" <method name='Destroy'/>"
/* signals */
" </interface>"
@ -349,6 +346,18 @@ service_name_vanished_callback (GDBusConnection *connection,
eekboard_context_service_enable (service->priv->context_stack->data);
}
static void
context_destroyed_cb (EekboardContextService *context, EekboardService *service)
{
gchar *object_path = NULL;
remove_context_from_stack (service, context);
g_object_get (G_OBJECT(context), "object-path", &object_path, NULL);
g_hash_table_remove (service->priv->context_hash, object_path);
g_free (object_path);
}
static void
handle_method_call (GDBusConnection *connection,
const gchar *sender,
@ -387,6 +396,10 @@ handle_method_call (GDBusConnection *connection,
service_name_vanished_callback,
service,
NULL);
g_signal_connect (G_OBJECT(context), "destroyed",
G_CALLBACK(context_destroyed_cb), service);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(s)",
object_path));
@ -445,38 +458,6 @@ handle_method_call (GDBusConnection *connection,
return;
}
if (g_strcmp0 (method_name, "DestroyContext") == 0) {
EekboardContextService *context;
const gchar *object_path;
const gchar *owner;
g_variant_get (parameters, "(&s)", &object_path);
context = g_hash_table_lookup (service->priv->context_hash, object_path);
if (!context) {
g_dbus_method_invocation_return_error (invocation,
G_IO_ERROR,
G_IO_ERROR_FAILED_HANDLED,
"context not found");
return;
}
owner = g_object_get_data (G_OBJECT(context), "owner");
if (g_strcmp0 (owner, sender) != 0) {
g_dbus_method_invocation_return_error
(invocation,
G_IO_ERROR,
G_IO_ERROR_FAILED_HANDLED,
"the context at %s not owned by %s",
object_path, sender);
return;
}
remove_context_from_stack (service, context);
g_hash_table_remove (service->priv->context_hash, object_path);
g_dbus_method_invocation_return_value (invocation, NULL);
return;
}
if (g_strcmp0 (method_name, "Destroy") == 0) {
g_signal_emit (service, signals[DESTROYED], 0);
g_dbus_method_invocation_return_value (invocation, NULL);