Implement IBus based activation.
This commit is contained in:
21
configure.ac
21
configure.ac
@ -136,6 +136,26 @@ fi
|
|||||||
AC_MSG_RESULT($enable_atspi)
|
AC_MSG_RESULT($enable_atspi)
|
||||||
AM_CONDITIONAL(ENABLE_ATSPI, [test x$enable_atspi = xyes])
|
AM_CONDITIONAL(ENABLE_ATSPI, [test x$enable_atspi = xyes])
|
||||||
|
|
||||||
|
dnl use IBus to capture focus events
|
||||||
|
AC_MSG_CHECKING([whether you enable IBus focus tracking])
|
||||||
|
AC_ARG_ENABLE(ibus,
|
||||||
|
AS_HELP_STRING([--enable-ibus=no/yes],
|
||||||
|
[Enable IBus focus tracking default=no]),,
|
||||||
|
enable_atspi=yes)
|
||||||
|
|
||||||
|
if test x$enable_ibus = xyes; then
|
||||||
|
PKG_CHECK_MODULES([IBUS], [ibus-1.0 >= 1.3.99], , enable_ibus=no)
|
||||||
|
if test x$enable_ibus = xyes; then
|
||||||
|
AC_DEFINE([HAVE_IBUS], [1], [Define if IBus is found])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($enable_ibus)
|
||||||
|
AM_CONDITIONAL(ENABLE_IBUS, [test x$enable_ibus = xyes])
|
||||||
|
|
||||||
|
if test x$enable_atspi = xyes -o x$enable_ibus = xyes; then
|
||||||
|
AC_DEFINE(ENABLE_FOCUS_LISTENER, [1], [Define if eekboard can follow focus changes])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Python language binding
|
dnl Python language binding
|
||||||
AC_MSG_CHECKING([whether you enable Python language support])
|
AC_MSG_CHECKING([whether you enable Python language support])
|
||||||
AC_ARG_ENABLE(python,
|
AC_ARG_ENABLE(python,
|
||||||
@ -292,4 +312,5 @@ Build options:
|
|||||||
Build Python binding $enable_python
|
Build Python binding $enable_python
|
||||||
Build document $enable_gtk_doc
|
Build document $enable_gtk_doc
|
||||||
Support accessibility $enable_atspi
|
Support accessibility $enable_atspi
|
||||||
|
Support IBus focus events $enable_ibus
|
||||||
])
|
])
|
||||||
|
|||||||
@ -55,6 +55,13 @@ eekboard_LDADD += \
|
|||||||
$(ATSPI2_LIBS)
|
$(ATSPI2_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if ENABLE_IBUS
|
||||||
|
eekboard_CFLAGS += \
|
||||||
|
$(IBUS_CFLAGS)
|
||||||
|
eekboard_LDADD += \
|
||||||
|
$(IBUS_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
eekboard_headers = client.h
|
eekboard_headers = client.h
|
||||||
eekboard_SOURCES = client.c client-main.c
|
eekboard_SOURCES = client.c client-main.c
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
#include <atspi/atspi.h>
|
#include <atspi/atspi.h>
|
||||||
#endif /* HAVE_ATSPI */
|
#endif /* HAVE_ATSPI */
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
#include <ibus.h>
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include "eekboard/eekboard.h"
|
#include "eekboard/eekboard.h"
|
||||||
@ -37,6 +40,7 @@ static gchar *opt_address = NULL;
|
|||||||
|
|
||||||
static gboolean opt_use_system_layout = FALSE;
|
static gboolean opt_use_system_layout = FALSE;
|
||||||
static gboolean opt_focus = FALSE;
|
static gboolean opt_focus = FALSE;
|
||||||
|
static gchar *opt_focus_method = NULL;
|
||||||
static gboolean opt_keystroke = FALSE;
|
static gboolean opt_keystroke = FALSE;
|
||||||
|
|
||||||
static gchar *opt_keyboard = NULL;
|
static gchar *opt_keyboard = NULL;
|
||||||
@ -56,9 +60,13 @@ static const GOptionEntry options[] = {
|
|||||||
N_("Connect to the given D-Bus address")},
|
N_("Connect to the given D-Bus address")},
|
||||||
{"use-system-layout", 'x', 0, G_OPTION_ARG_NONE, &opt_use_system_layout,
|
{"use-system-layout", 'x', 0, G_OPTION_ARG_NONE, &opt_use_system_layout,
|
||||||
N_("Use system keyboard layout")},
|
N_("Use system keyboard layout")},
|
||||||
#ifdef HAVE_ATSPI
|
#if ENABLE_FOCUS_LISTENER
|
||||||
{"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus,
|
{"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus,
|
||||||
N_("Listen focus change events with AT-SPI")},
|
N_("Listen focus change events")},
|
||||||
|
{"focus-method", '\0', 0, G_OPTION_ARG_STRING, &opt_focus_method,
|
||||||
|
N_("Use the given focus method (\"atspi\" or \"ibus\")")},
|
||||||
|
#endif /* ENABLE_FOCUS_LISTENER */
|
||||||
|
#ifdef HAVE_ATSPI
|
||||||
{"listen-keystroke", 's', 0, G_OPTION_ARG_NONE, &opt_keystroke,
|
{"listen-keystroke", 's', 0, G_OPTION_ARG_NONE, &opt_keystroke,
|
||||||
N_("Listen keystroke events with AT-SPI")},
|
N_("Listen keystroke events with AT-SPI")},
|
||||||
#endif /* HAVE_ATSPI */
|
#endif /* HAVE_ATSPI */
|
||||||
@ -108,6 +116,12 @@ on_destroyed (EekboardEekboard *eekboard,
|
|||||||
g_main_loop_quit (loop);
|
g_main_loop_quit (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FOCUS_NONE,
|
||||||
|
FOCUS_ATSPI,
|
||||||
|
FOCUS_IBUS
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -119,6 +133,7 @@ main (int argc, char **argv)
|
|||||||
GError *error;
|
GError *error;
|
||||||
GOptionContext *option_context;
|
GOptionContext *option_context;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
|
gint focus;
|
||||||
|
|
||||||
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");
|
||||||
@ -172,8 +187,22 @@ main (int argc, char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
focus = FOCUS_NONE;
|
||||||
|
if (opt_focus) {
|
||||||
|
if (opt_focus_method == NULL ||
|
||||||
|
g_strcmp0 (opt_focus_method, "atspi") == 0)
|
||||||
|
focus = FOCUS_ATSPI;
|
||||||
|
else if (g_strcmp0 (opt_focus_method, "ibus") == 0)
|
||||||
|
focus = FOCUS_IBUS;
|
||||||
|
else {
|
||||||
|
g_printerr ("Unknown focus method \"%s\". "
|
||||||
|
"Try \"atspi\" or \"ibus\"\n", opt_focus_method);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ATSPI
|
#ifdef HAVE_ATSPI
|
||||||
if (opt_focus || opt_keystroke) {
|
if (focus == FOCUS_ATSPI || opt_keystroke) {
|
||||||
GSettings *settings = g_settings_new ("org.gnome.desktop.interface");
|
GSettings *settings = g_settings_new ("org.gnome.desktop.interface");
|
||||||
|
|
||||||
if (g_settings_get_boolean (settings, "toolkit-accessibility")) {
|
if (g_settings_get_boolean (settings, "toolkit-accessibility")) {
|
||||||
@ -182,15 +211,15 @@ main (int argc, char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_focus &&
|
if (focus == FOCUS_ATSPI &&
|
||||||
!eekboard_client_enable_atspi_focus (client)) {
|
!eekboard_client_enable_atspi_focus (client)) {
|
||||||
g_printerr ("Can't register focus change event listeners\n");
|
g_printerr ("Can't register AT-SPI focus change event listeners\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_keystroke &&
|
if (opt_keystroke &&
|
||||||
!eekboard_client_enable_atspi_keystroke (client)) {
|
!eekboard_client_enable_atspi_keystroke (client)) {
|
||||||
g_printerr ("Can't register keystroke event listeners\n");
|
g_printerr ("Can't register AT-SPI keystroke event listeners\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -200,6 +229,18 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_ATSPI */
|
#endif /* HAVE_ATSPI */
|
||||||
|
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
if (focus == FOCUS_IBUS) {
|
||||||
|
ibus_init ();
|
||||||
|
|
||||||
|
if (focus == FOCUS_IBUS &&
|
||||||
|
!eekboard_client_enable_ibus_focus (client)) {
|
||||||
|
g_printerr ("Can't register IBus focus change event listeners\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
|
|
||||||
if (opt_use_system_layout && (opt_keyboard || opt_model || opt_layouts || opt_options)) {
|
if (opt_use_system_layout && (opt_keyboard || opt_model || opt_layouts || opt_options)) {
|
||||||
g_printerr ("Can't use --use-system-layout option with keyboard options\n");
|
g_printerr ("Can't use --use-system-layout option with keyboard options\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
|
|||||||
125
src/client.c
125
src/client.c
@ -32,6 +32,10 @@
|
|||||||
#include <fakekey/fakekey.h>
|
#include <fakekey/fakekey.h>
|
||||||
#endif /* HAVE_FAKEKEY */
|
#endif /* HAVE_FAKEKEY */
|
||||||
|
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
#include <ibus.h>
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
|
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
#include "eek/eek-xkl.h"
|
#include "eek/eek-xkl.h"
|
||||||
#include "eekboard/eekboard.h"
|
#include "eekboard/eekboard.h"
|
||||||
@ -68,12 +72,20 @@ struct _EekboardClient {
|
|||||||
gulong key_pressed_handler;
|
gulong key_pressed_handler;
|
||||||
gulong key_released_handler;
|
gulong key_released_handler;
|
||||||
|
|
||||||
|
#if ENABLE_FOCUS_LISTENER
|
||||||
|
gboolean follows_focus;
|
||||||
|
#endif /* ENABLE_FOCUS_LISTENER */
|
||||||
|
|
||||||
#ifdef HAVE_ATSPI
|
#ifdef HAVE_ATSPI
|
||||||
AtspiAccessible *acc;
|
AtspiAccessible *acc;
|
||||||
gboolean follows_focus;
|
|
||||||
AtspiDeviceListener *keystroke_listener;
|
AtspiDeviceListener *keystroke_listener;
|
||||||
#endif /* HAVE_ATSPI */
|
#endif /* HAVE_ATSPI */
|
||||||
|
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
IBusBus *ibus_bus;
|
||||||
|
guint ibus_focus_message_filter;
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
|
|
||||||
#ifdef HAVE_FAKEKEY
|
#ifdef HAVE_FAKEKEY
|
||||||
FakeKey *fakekey;
|
FakeKey *fakekey;
|
||||||
#endif /* HAVE_FAKEKEY */
|
#endif /* HAVE_FAKEKEY */
|
||||||
@ -184,6 +196,14 @@ eekboard_client_dispose (GObject *object)
|
|||||||
eekboard_client_disable_atspi_keystroke (client);
|
eekboard_client_disable_atspi_keystroke (client);
|
||||||
#endif /* HAVE_ATSPI */
|
#endif /* HAVE_ATSPI */
|
||||||
|
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
eekboard_client_disable_ibus_focus (client);
|
||||||
|
if (client->ibus_bus) {
|
||||||
|
g_object_unref (client->ibus_bus);
|
||||||
|
client->ibus_bus = NULL;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
|
|
||||||
#ifdef HAVE_FAKEKEY
|
#ifdef HAVE_FAKEKEY
|
||||||
eekboard_client_disable_fakekey (client);
|
eekboard_client_disable_fakekey (client);
|
||||||
#endif /* HAVE_FAKEKEY */
|
#endif /* HAVE_FAKEKEY */
|
||||||
@ -272,10 +292,16 @@ eekboard_client_init (EekboardClient *client)
|
|||||||
client->key_released_handler = 0;
|
client->key_released_handler = 0;
|
||||||
client->xkl_config_changed_handler = 0;
|
client->xkl_config_changed_handler = 0;
|
||||||
client->xkl_state_changed_handler = 0;
|
client->xkl_state_changed_handler = 0;
|
||||||
#ifdef HAVE_ATSPI
|
#if ENABLE_FOCUS_LISTENER
|
||||||
client->follows_focus = FALSE;
|
client->follows_focus = FALSE;
|
||||||
|
#endif /* ENABLE_FOCUS_LISTENER */
|
||||||
|
#ifdef HAVE_ATSPI
|
||||||
client->keystroke_listener = NULL;
|
client->keystroke_listener = NULL;
|
||||||
#endif /* HAVE_ATSPI */
|
#endif /* HAVE_ATSPI */
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
client->ibus_bus = NULL;
|
||||||
|
client->ibus_focus_message_filter = 0;
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
#ifdef HAVE_FAKEKEY
|
#ifdef HAVE_FAKEKEY
|
||||||
client->fakekey = NULL;
|
client->fakekey = NULL;
|
||||||
#endif /* HAVE_FAKEKEY */
|
#endif /* HAVE_FAKEKEY */
|
||||||
@ -287,19 +313,19 @@ eekboard_client_set_xkl_config (EekboardClient *client,
|
|||||||
const gchar *layouts,
|
const gchar *layouts,
|
||||||
const gchar *options)
|
const gchar *options)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ATSPI
|
#if ENABLE_FOCUS_LISTENER
|
||||||
return set_xkl_keyboard (client,
|
return set_xkl_keyboard (client,
|
||||||
!client->follows_focus,
|
!client->follows_focus,
|
||||||
model,
|
model,
|
||||||
layouts,
|
layouts,
|
||||||
options);
|
options);
|
||||||
#else
|
#else /* ENABLE_FOCUS_LISTENER */
|
||||||
return set_xkl_keyboard (client,
|
return set_xkl_keyboard (client,
|
||||||
TRUE,
|
TRUE,
|
||||||
model,
|
model,
|
||||||
layouts,
|
layouts,
|
||||||
options);
|
options);
|
||||||
#endif
|
#endif /* !ENABLE_FOCUS_LISTENER */
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -338,15 +364,15 @@ eekboard_client_enable_xkl (EekboardClient *client)
|
|||||||
|
|
||||||
xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
|
xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
|
||||||
|
|
||||||
#ifdef HAVE_ATSPI
|
#if ENABLE_FOCUS_LISTENER
|
||||||
return set_xkl_keyboard (client,
|
return set_xkl_keyboard (client,
|
||||||
!client->follows_focus,
|
!client->follows_focus,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
#else
|
#else /* ENABLE_FOCUS_LISTENER */
|
||||||
return set_xkl_keyboard (client, TRUE, NULL, NULL, NULL);
|
return set_xkl_keyboard (client, TRUE, NULL, NULL, NULL);
|
||||||
#endif
|
#endif /* !ENABLE_FOCUS_LISTENER */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -546,6 +572,83 @@ keystroke_listener_cb (const AtspiDeviceEvent *stroke,
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_ATSPI */
|
#endif /* HAVE_ATSPI */
|
||||||
|
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
static void
|
||||||
|
add_match_rule (GDBusConnection *connection,
|
||||||
|
const gchar *match_rule)
|
||||||
|
{
|
||||||
|
GError *error;
|
||||||
|
GDBusMessage *message;
|
||||||
|
|
||||||
|
message = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
|
||||||
|
"/org/freedesktop/DBus", /* path */
|
||||||
|
"org.freedesktop.DBus", /* interface */
|
||||||
|
"AddMatch");
|
||||||
|
g_dbus_message_set_body (message, g_variant_new ("(s)", match_rule));
|
||||||
|
error = NULL;
|
||||||
|
g_dbus_connection_send_message (connection,
|
||||||
|
message,
|
||||||
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
g_object_unref (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GDBusMessage *
|
||||||
|
focus_message_filter (GDBusConnection *connection,
|
||||||
|
GDBusMessage *message,
|
||||||
|
gboolean incoming,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
EekboardClient *client = user_data;
|
||||||
|
|
||||||
|
if (incoming &&
|
||||||
|
g_strcmp0 (g_dbus_message_get_interface (message),
|
||||||
|
IBUS_INTERFACE_INPUT_CONTEXT) == 0) {
|
||||||
|
const gchar *member = g_dbus_message_get_member (message);
|
||||||
|
|
||||||
|
if (g_strcmp0 (member, "FocusIn") == 0) {
|
||||||
|
eekboard_context_show_keyboard (client->context, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
eekboard_client_enable_ibus_focus (EekboardClient *client)
|
||||||
|
{
|
||||||
|
GDBusConnection *connection;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
client->ibus_bus = ibus_bus_new ();
|
||||||
|
connection = ibus_bus_get_connection (client->ibus_bus);
|
||||||
|
add_match_rule (connection,
|
||||||
|
"type='method_call',"
|
||||||
|
"interface='" IBUS_INTERFACE_INPUT_CONTEXT "',"
|
||||||
|
"member='FocusIn'");
|
||||||
|
client->ibus_focus_message_filter =
|
||||||
|
g_dbus_connection_add_filter (connection,
|
||||||
|
focus_message_filter,
|
||||||
|
client,
|
||||||
|
NULL);
|
||||||
|
client->follows_focus = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eekboard_client_disable_ibus_focus (EekboardClient *client)
|
||||||
|
{
|
||||||
|
GDBusConnection *connection;
|
||||||
|
|
||||||
|
client->follows_focus = FALSE;
|
||||||
|
|
||||||
|
connection = ibus_bus_get_connection (client->ibus_bus);
|
||||||
|
g_dbus_connection_remove_filter (connection,
|
||||||
|
client->ibus_focus_message_filter);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ATSPI */
|
||||||
|
|
||||||
EekboardClient *
|
EekboardClient *
|
||||||
eekboard_client_new (GDBusConnection *connection)
|
eekboard_client_new (GDBusConnection *connection)
|
||||||
{
|
{
|
||||||
@ -810,11 +913,11 @@ eekboard_client_load_keyboard_from_file (EekboardClient *client,
|
|||||||
|
|
||||||
layout = eek_xml_layout_new (G_INPUT_STREAM(input));
|
layout = eek_xml_layout_new (G_INPUT_STREAM(input));
|
||||||
g_object_unref (input);
|
g_object_unref (input);
|
||||||
#ifdef HAVE_ATSPI
|
#if ENABLE_FOCUS_LISTENER
|
||||||
retval = set_keyboard (client, !client->follows_focus, layout);
|
retval = set_keyboard (client, !client->follows_focus, layout);
|
||||||
#else
|
#else /* ENABLE_FOCUS_LISTENER */
|
||||||
retval = set_keyboard (client, TRUE, layout);
|
retval = set_keyboard (client, TRUE, layout);
|
||||||
#endif
|
#endif /* !ENABLE_FOCUS_LISTENER */
|
||||||
g_object_unref (layout);
|
g_object_unref (layout);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,5 +57,10 @@ void eekboard_client_disable_atspi_keystroke
|
|||||||
gboolean eekboard_client_enable_fakekey (EekboardClient *client);
|
gboolean eekboard_client_enable_fakekey (EekboardClient *client);
|
||||||
void eekboard_client_disable_fakekey (EekboardClient *client);
|
void eekboard_client_disable_fakekey (EekboardClient *client);
|
||||||
|
|
||||||
|
gboolean eekboard_client_enable_ibus_focus
|
||||||
|
(EekboardClient *client);
|
||||||
|
void eekboard_client_disable_ibus_focus
|
||||||
|
(EekboardClient *client);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEKBOARD_CLIENT_H */
|
#endif /* EEKBOARD_CLIENT_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user