Fix system (xklavier) layout handling.

This commit is contained in:
Daiki Ueno
2011-08-18 14:32:53 +09:00
parent e5f5c8273e
commit 786496b3c4
5 changed files with 117 additions and 76 deletions

View File

@ -152,6 +152,11 @@ main (int argc, char **argv)
keyboard_id = eekboard_context_add_keyboard (context, keyboard_id = eekboard_context_add_keyboard (context,
opt_set_keyboard, opt_set_keyboard,
NULL); NULL);
if (keyboard_id == 0) {
g_printerr ("Can't create keyboard\n");
retval = 1;
goto out;
}
eekboard_context_set_keyboard (context, keyboard_id, NULL); eekboard_context_set_keyboard (context, keyboard_id, NULL);
} }

View File

@ -102,20 +102,39 @@ enum {
FOCUS_IBUS FOCUS_IBUS
}; };
static gboolean
set_keyboard (EekboardClient *client,
const gchar *keyboard)
{
if (g_strcmp0 (keyboard, "system") == 0) {
if (!eekboard_client_enable_xkl (client)) {
g_printerr ("Can't register xklavier event listeners\n");
return FALSE;
}
} else {
if (!eekboard_client_set_keyboard (client, keyboard)) {
g_printerr ("Can't set keyboard \"%s\"\n", keyboard);
return FALSE;
}
}
return TRUE;
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
EekboardClient *client; EekboardClient *client = NULL;
EekboardEekboard *eekboard; EekboardEekboard *eekboard;
EekboardContext *context; EekboardContext *context;
GBusType bus_type; GBusType bus_type;
GDBusConnection *connection; GDBusConnection *connection;
GError *error; GError *error;
GOptionContext *option_context; GOptionContext *option_context;
GMainLoop *loop; GMainLoop *loop = NULL;
gint focus; gint focus;
GSettings *settings; GSettings *settings = NULL;
gchar *keyboard; gchar *keyboard;
gint retval = 0;
if (!gtk_init_check (&argc, &argv)) { if (!gtk_init_check (&argc, &argv)) {
g_printerr ("Can't init GTK\n"); g_printerr ("Can't init GTK\n");
@ -186,8 +205,8 @@ main (int argc, char **argv)
else { else {
g_printerr ("Unknown focus listener \"%s\". " g_printerr ("Unknown focus listener \"%s\". "
"Try \"atspi\" or \"ibus\"\n", focus_listener); "Try \"atspi\" or \"ibus\"\n", focus_listener);
g_object_unref (client); retval = 1;
exit (1); goto out;
} }
} }
@ -202,27 +221,27 @@ main (int argc, char **argv)
if (accessibility_enabled) { if (accessibility_enabled) {
if (atspi_init () != 0) { if (atspi_init () != 0) {
g_printerr ("Can't init AT-SPI 2\n"); g_printerr ("Can't init AT-SPI 2\n");
g_object_unref (client); retval = 1;
exit (1); goto out;
} }
if (focus == FOCUS_ATSPI && if (focus == FOCUS_ATSPI &&
!eekboard_client_enable_atspi_focus (client)) { !eekboard_client_enable_atspi_focus (client)) {
g_printerr ("Can't register AT-SPI focus change event listeners\n"); g_printerr ("Can't register AT-SPI focus change event listeners\n");
g_object_unref (client); retval = 1;
exit (1); goto out;
} }
if (opt_keystroke && if (opt_keystroke &&
!eekboard_client_enable_atspi_keystroke (client)) { !eekboard_client_enable_atspi_keystroke (client)) {
g_printerr ("Can't register AT-SPI keystroke event listeners\n"); g_printerr ("Can't register AT-SPI keystroke event listeners\n");
g_object_unref (client); retval = 1;
exit (1); goto out;
} }
} else { } else {
g_printerr ("Desktop accessibility support is disabled\n"); g_printerr ("Desktop accessibility support is disabled\n");
g_object_unref (client); retval = 1;
exit (1); goto out;
} }
} }
#endif /* HAVE_ATSPI */ #endif /* HAVE_ATSPI */
@ -231,21 +250,14 @@ main (int argc, char **argv)
if (focus == FOCUS_IBUS) { if (focus == FOCUS_IBUS) {
ibus_init (); ibus_init ();
if (focus == FOCUS_IBUS && if (!eekboard_client_enable_ibus_focus (client)) {
!eekboard_client_enable_ibus_focus (client)) {
g_printerr ("Can't register IBus focus change event listeners\n"); g_printerr ("Can't register IBus focus change event listeners\n");
g_object_unref (client); retval = 1;
exit (1); goto out;
} }
} }
#endif /* HAVE_IBUS */ #endif /* HAVE_IBUS */
if (!eekboard_client_enable_xkl (client)) {
g_printerr ("Can't register xklavier event listeners\n");
g_object_unref (client);
exit (1);
}
#ifdef HAVE_XTEST #ifdef HAVE_XTEST
if (!eekboard_client_enable_xtest (client)) { if (!eekboard_client_enable_xtest (client)) {
g_printerr ("Can't init xtest\n"); g_printerr ("Can't init xtest\n");
@ -254,11 +266,8 @@ main (int argc, char **argv)
} }
#endif /* HAVE_XTEST */ #endif /* HAVE_XTEST */
keyboard = g_settings_get_string (settings, "keyboard");
eekboard_client_set_keyboard (client, keyboard);
g_free (keyboard);
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
if (!opt_focus) { if (!opt_focus) {
g_object_get (client, "context", &context, NULL); g_object_get (client, "context", &context, NULL);
g_signal_connect (context, "notify::keyboard-visible", g_signal_connect (context, "notify::keyboard-visible",
@ -278,11 +287,25 @@ main (int argc, char **argv)
g_object_get (client, "eekboard", &eekboard, NULL); g_object_get (client, "eekboard", &eekboard, NULL);
g_signal_connect (eekboard, "destroyed", g_signal_connect (eekboard, "destroyed",
G_CALLBACK(on_destroyed), loop); G_CALLBACK(on_destroyed), loop);
g_object_unref (eekboard);
keyboard = g_settings_get_string (settings, "keyboard");
if (!set_keyboard (client, keyboard)) {
g_free (keyboard);
retval = 1;
goto out;
}
g_free (keyboard);
g_main_loop_run (loop); g_main_loop_run (loop);
out:
if (loop)
g_main_loop_unref (loop); g_main_loop_unref (loop);
if (client)
g_object_unref (client); g_object_unref (client);
if (settings)
g_object_unref (settings); g_object_unref (settings);
return 0; return retval;
} }

View File

@ -67,7 +67,6 @@ struct _EekboardClient {
EekKeyboard *keyboard; EekKeyboard *keyboard;
XklEngine *xkl_engine; XklEngine *xkl_engine;
XklConfigRegistry *xkl_config_registry; XklConfigRegistry *xkl_config_registry;
gboolean use_xkl_layout;
gulong xkl_config_changed_handler; gulong xkl_config_changed_handler;
gulong xkl_state_changed_handler; gulong xkl_state_changed_handler;
@ -102,6 +101,12 @@ struct _EekboardClientClass {
G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_OBJECT); G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_OBJECT);
#if ENABLE_FOCUS_LISTENER
#define IS_KEYBOARD_VISIBLE(client) (!client->follows_focus)
#else /* ENABLE_FOCUS_LISTENER */
#define IS_KEYBOARD_VISIBLE(client) TRUE
#endif /* !ENABLE_FOCUS_LISTENER */
static GdkFilterReturn filter_xkl_event (GdkXEvent *xev, static GdkFilterReturn filter_xkl_event (GdkXEvent *xev,
GdkEvent *event, GdkEvent *event,
gpointer user_data); gpointer user_data);
@ -123,6 +128,7 @@ static gboolean keystroke_listener_cb (const AtspiDeviceEvent *stroke,
#endif /* HAVE_ATSPI */ #endif /* HAVE_ATSPI */
static gboolean set_keyboard (EekboardClient *client, static gboolean set_keyboard (EekboardClient *client,
const gchar *keyboard); const gchar *keyboard);
static gboolean set_keyboard_from_xkl (EekboardClient *client);
#ifdef HAVE_XTEST #ifdef HAVE_XTEST
static void update_modifier_keycodes static void update_modifier_keycodes
(EekboardClient *client); (EekboardClient *client);
@ -277,12 +283,6 @@ eekboard_client_init (EekboardClient *client)
client->settings = g_settings_new ("org.fedorahosted.eekboard"); client->settings = g_settings_new ("org.fedorahosted.eekboard");
} }
#if ENABLE_FOCUS_LISTENER
#define IS_KEYBOARD_VISIBLE(client) (!client->follows_focus)
#else /* ENABLE_FOCUS_LISTENER */
#define IS_KEYBOARD_VISIBLE(client) TRUE
#endif /* !ENABLE_FOCUS_LISTENER */
gboolean gboolean
eekboard_client_set_keyboard (EekboardClient *client, eekboard_client_set_keyboard (EekboardClient *client,
const gchar *keyboard) const gchar *keyboard)
@ -290,7 +290,7 @@ eekboard_client_set_keyboard (EekboardClient *client,
gboolean retval; gboolean retval;
retval = set_keyboard (client, keyboard); retval = set_keyboard (client, keyboard);
if (IS_KEYBOARD_VISIBLE (client)) if (retval && IS_KEYBOARD_VISIBLE (client))
eekboard_context_show_keyboard (client->context, NULL); eekboard_context_show_keyboard (client->context, NULL);
return retval; return retval;
} }
@ -299,6 +299,8 @@ gboolean
eekboard_client_enable_xkl (EekboardClient *client) eekboard_client_enable_xkl (EekboardClient *client)
{ {
GdkDisplay *display = gdk_display_get_default (); GdkDisplay *display = gdk_display_get_default ();
gboolean retval;
g_assert (display); g_assert (display);
if (!client->xkl_engine) { if (!client->xkl_engine) {
@ -327,20 +329,21 @@ eekboard_client_enable_xkl (EekboardClient *client)
(GdkFilterFunc) filter_xkl_event, (GdkFilterFunc) filter_xkl_event,
client); client);
client->use_xkl_layout = FALSE;
xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE); xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
return TRUE; retval = set_keyboard_from_xkl (client);
if (IS_KEYBOARD_VISIBLE (client))
eekboard_context_show_keyboard (client->context, NULL);
return retval;
} }
void void
eekboard_client_disable_xkl (EekboardClient *client) eekboard_client_disable_xkl (EekboardClient *client)
{ {
client->use_xkl_layout = FALSE; if (client->xkl_engine) {
if (client->xkl_engine)
xkl_engine_stop_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE); xkl_engine_stop_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
if (g_signal_handler_is_connected (client->xkl_engine, if (g_signal_handler_is_connected (client->xkl_engine,
client->xkl_config_changed_handler)) client->xkl_config_changed_handler))
g_signal_handler_disconnect (client->xkl_engine, g_signal_handler_disconnect (client->xkl_engine,
@ -349,6 +352,8 @@ eekboard_client_disable_xkl (EekboardClient *client)
client->xkl_state_changed_handler)) client->xkl_state_changed_handler))
g_signal_handler_disconnect (client->xkl_engine, g_signal_handler_disconnect (client->xkl_engine,
client->xkl_state_changed_handler); client->xkl_state_changed_handler);
client->xkl_engine = NULL;
}
} }
#ifdef HAVE_ATSPI #ifdef HAVE_ATSPI
@ -680,22 +685,8 @@ on_xkl_config_changed (XklEngine *xklengine,
EekboardClient *client = user_data; EekboardClient *client = user_data;
gboolean retval; gboolean retval;
if (client->use_xkl_layout) { retval = set_keyboard_from_xkl (client);
XklConfigRec *rec;
gchar *layout, *keyboard;
rec = xkl_config_rec_new ();
xkl_config_rec_get_from_server (rec, client->xkl_engine);
layout = eekboard_xkl_config_rec_to_string (rec);
g_object_unref (rec);
keyboard = g_strdup_printf ("xkl:%s", layout);
g_free (layout);
retval = set_keyboard (client, keyboard);
g_free (keyboard);
g_return_if_fail (retval); g_return_if_fail (retval);
}
#ifdef HAVE_XTEST #ifdef HAVE_XTEST
update_modifier_keycodes (client); update_modifier_keycodes (client);
@ -711,10 +702,33 @@ set_keyboard (EekboardClient *client,
keyboard_id = eekboard_context_add_keyboard (client->context, keyboard_id = eekboard_context_add_keyboard (client->context,
keyboard, keyboard,
NULL); NULL);
if (keyboard_id == 0)
return FALSE;
eekboard_context_set_keyboard (client->context, keyboard_id, NULL); eekboard_context_set_keyboard (client->context, keyboard_id, NULL);
return TRUE; return TRUE;
} }
static gboolean
set_keyboard_from_xkl (EekboardClient *client)
{
XklConfigRec *rec;
gchar *layout, *keyboard;
gboolean retval;
rec = xkl_config_rec_new ();
xkl_config_rec_get_from_server (rec, client->xkl_engine);
layout = eekboard_xkl_config_rec_to_string (rec);
g_object_unref (rec);
keyboard = g_strdup_printf ("xkb:%s", layout);
g_free (layout);
retval = set_keyboard (client, keyboard);
g_free (keyboard);
return retval;
}
static void static void
on_xkl_state_changed (XklEngine *xklengine, on_xkl_state_changed (XklEngine *xklengine,
XklEngineStateChange type, XklEngineStateChange type,
@ -724,11 +738,9 @@ on_xkl_state_changed (XklEngine *xklengine,
{ {
EekboardClient *client = user_data; EekboardClient *client = user_data;
if (type == GROUP_CHANGED) { if (type == GROUP_CHANGED)
if (client->use_xkl_layout)
eekboard_context_set_group (client->context, value, NULL); eekboard_context_set_group (client->context, value, NULL);
} }
}
#ifdef HAVE_XTEST #ifdef HAVE_XTEST
/* The following functions for keyboard mapping change are direct /* The following functions for keyboard mapping change are direct
@ -925,6 +937,7 @@ update_modifier_keycodes (EekboardClient *client)
} }
} }
} }
XFreeModifiermap (mods);
} }
gboolean gboolean

View File

@ -709,7 +709,7 @@ create_keyboard_from_string (const gchar *string)
EekKeyboard *keyboard; EekKeyboard *keyboard;
EekLayout *layout; EekLayout *layout;
if (g_str_has_prefix (string, "xkl:")) { if (g_str_has_prefix (string, "xkb:")) {
XklConfigRec *rec = eekboard_xkl_config_rec_from_string (&string[4]); XklConfigRec *rec = eekboard_xkl_config_rec_from_string (&string[4]);
layout = eek_xkl_layout_new (); layout = eek_xkl_layout_new ();

View File

@ -66,7 +66,7 @@ eekboard_xkl_config_rec_to_string (XklConfigRec *rec)
n_layouts = g_strv_length (rec->layouts); n_layouts = g_strv_length (rec->layouts);
strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *)); strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *));
for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) { for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) {
if (*vp != NULL) if (*vp != NULL && **vp != '\0')
*sp = g_strdup_printf ("%s(%s)", *lp, *vp++); *sp = g_strdup_printf ("%s(%s)", *lp, *vp++);
else else
*sp = g_strdup_printf ("%s", *lp); *sp = g_strdup_printf ("%s", *lp);