[caribou] Port daemon from Python to Vala
- From: Daiki Ueno <dueno src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [caribou] Port daemon from Python to Vala
- Date: Sun, 17 Feb 2013 01:29:08 +0000 (UTC)
commit 1b7a0c6c7b855e6204830656a699483898329bc1
Author: Daiki Ueno <ueno unixuser org>
Date: Mon Nov 12 13:06:06 2012 +0900
Port daemon from Python to Vala
This eliminates the need of the shell script wrapper.
https://bugzilla.gnome.org/show_bug.cgi?id=688218
Makefile.am | 2 +-
bin/Makefile.am | 2 +-
bin/caribou.in | 41 ---------
caribou/Makefile.am | 3 +-
caribou/daemon/Makefile.am | 7 --
caribou/daemon/__init__.py | 1 -
caribou/daemon/main.py | 123 ---------------------------
configure.ac | 8 +-
daemon/Makefile.am | 23 +++++
daemon/daemon.vala | 196 ++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 227 insertions(+), 179 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 07a7a55..c23aab2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
-SUBDIRS = caribou bin data po libcaribou modules tools vapi
+SUBDIRS = caribou bin data po libcaribou modules tools vapi daemon
if HAVE_VALADOC
SUBDIRS += docs
diff --git a/bin/Makefile.am b/bin/Makefile.am
index b001b10..2b1839a 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -1,4 +1,4 @@
-bin_SCRIPTS = caribou caribou-preferences
+bin_SCRIPTS = caribou-preferences
libexec_SCRIPTS = antler-keyboard
DISTCLEANFILES = $(bin_SCRIPTS) $(libexec_SCRIPTS)
diff --git a/caribou/Makefile.am b/caribou/Makefile.am
index cdb7045..2d7fd50 100644
--- a/caribou/Makefile.am
+++ b/caribou/Makefile.am
@@ -6,8 +6,7 @@ caribou_PYTHON = \
SUBDIRS = \
antler/ \
- settings/ \
- daemon/
+ settings/
DISTCLEANFILES = i18n.py
diff --git a/configure.ac b/configure.ac
index be48c44..228d094 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,7 +32,10 @@ VALADOC_REQUIRED=0.3.1
PKG_CHECK_MODULES(CARIBOU, [
pygobject-3.0 >= $PYGOBJECT_REQUIRED,
gtk+-3.0 >= $GTK_REQUIRED,
- clutter-1.0 >= $CLUTTER_REQUIRED
+ clutter-1.0 >= $CLUTTER_REQUIRED,
+ gdk-3.0 >= $GDK_REQUIRED,
+ x11,
+ atspi-2
])
AC_SUBST(CARIBOU_CFLAGS)
AC_SUBST(CARIBOU_LIBS)
@@ -132,9 +135,7 @@ caribou/Makefile
caribou/i18n.py
caribou/antler/Makefile
caribou/settings/Makefile
-caribou/daemon/Makefile
bin/Makefile
-bin/caribou
bin/caribou-preferences
bin/antler-keyboard
data/Makefile
@@ -151,4 +152,5 @@ modules/gtk2/Makefile
tools/Makefile
docs/Makefile
vapi/Makefile
+daemon/Makefile
])
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
new file mode 100644
index 0000000..13bca11
--- /dev/null
+++ b/daemon/Makefile.am
@@ -0,0 +1,23 @@
+bin_PROGRAMS = caribou
+
+caribou_VALAFLAGS = \
+ --vapidir=$(top_srcdir)/vapi \
+ --pkg config \
+ --pkg gtk+-3.0 \
+ --pkg gdk-x11-3.0 \
+ --pkg atspi-2 \
+ --pkg x11 \
+ --pkg posix \
+ --pkg libxklavier \
+ $(VALAFLAGS)
+
+caribou_CFLAGS = \
+ $(CARIBOU_CFLAGS) \
+ -DLOCALEDIR=\"$(datadir)/locale\"
+
+caribou_LDADD = \
+ $(CARIBOU_LIBS)
+
+caribou_SOURCES = daemon.vala
+
+-include $(top_srcdir)/git.mk
diff --git a/daemon/daemon.vala b/daemon/daemon.vala
new file mode 100644
index 0000000..2f5feee
--- /dev/null
+++ b/daemon/daemon.vala
@@ -0,0 +1,196 @@
+namespace Caribou {
+ // We can't use the name "Keyboard" here since caribou-gtk-module
+ // might register the name first.
+ [DBus (name = "org.gnome.Caribou.Keyboard")]
+ interface _Keyboard : Object {
+ public abstract void set_cursor_location (int x, int y, int w, int h)
+ throws IOError;
+ public abstract void set_entry_location (int x, int y, int w, int h)
+ throws IOError;
+ public abstract void show (uint32 timestamp) throws IOError;
+ public abstract void hide (uint32 timestamp) throws IOError;
+ }
+
+ class Daemon : Object {
+ _Keyboard keyboard;
+ Atspi.Accessible current_acc;
+ unowned Gdk.Display display;
+
+ public Daemon () {
+ display = Gdk.Display.get_default ();
+ }
+
+ void on_get_proxy_ready (GLib.Object? obj, GLib.AsyncResult res) {
+ try {
+ keyboard = Bus.get_proxy.end (res);
+ } catch (Error e) {
+ error ("%s\n".printf (e.message));
+ }
+
+ try {
+ register_event_listeners ();
+ } catch (Error e) {
+ warning ("can't register event listeners: %s", e.message);
+ }
+ }
+
+ uint32 get_timestamp () {
+ return Gdk.X11Display.get_user_time (display);
+ }
+
+ void set_entry_location (Atspi.Accessible acc) throws Error {
+ var text = acc.get_text ();
+ var rect = text.get_character_extents (text.get_caret_offset (),
+ Atspi.CoordType.SCREEN);
+ var component = acc.get_component ();
+ var entry_rect = component.get_extents (Atspi.CoordType.SCREEN);
+ if (rect.x == 0 && rect.y == 0 &&
+ rect.width == 0 && rect.height == 0) {
+ rect = entry_rect;
+ }
+
+ keyboard.set_cursor_location (rect.x, rect.y,
+ rect.width, rect.height);
+
+ keyboard.set_entry_location (entry_rect.x, entry_rect.y,
+ entry_rect.width, entry_rect.height);
+
+ keyboard.show (get_timestamp ());
+ }
+
+ void on_focus (owned Atspi.Event event) throws Error {
+ var acc = event.source;
+ var source_role = acc.get_role ();
+ if (acc.get_state_set ().contains (Atspi.StateType.EDITABLE) ||
+ source_role == Atspi.Role.TERMINAL) {
+ switch (source_role) {
+ case Atspi.Role.TEXT:
+ case Atspi.Role.PARAGRAPH:
+ case Atspi.Role.PASSWORD_TEXT:
+ case Atspi.Role.TERMINAL:
+ case Atspi.Role.ENTRY:
+ if (event.type.has_prefix ("focus") || event.detail1 == 1) {
+ set_entry_location (acc);
+ current_acc = event.source;
+ debug ("enter text widget in %s",
+ event.source.get_application ().name);
+ } else if (event.detail1 == 0 && acc == current_acc) {
+ keyboard.hide (get_timestamp ());
+ current_acc = null;
+ debug ("leave text widget in %s",
+ event.source.get_application ().name);
+ } else {
+ warning ("unhandled editable widget: %s",
+ event.source.name);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void on_focus_ignore_error (owned Atspi.Event event) {
+ try {
+ on_focus (event);
+ } catch (Error e) {
+ warning ("error in focus handler: %s", e.message);
+ }
+ }
+
+ void on_text_caret_moved (owned Atspi.Event event) throws Error {
+ if (current_acc == event.source) {
+ var text = current_acc.get_text ();
+ var rect = text.get_character_extents (text.get_caret_offset (),
+ Atspi.CoordType.SCREEN);
+ if (rect.x == 0 && rect.y == 0 &&
+ rect.width == 0 && rect.height == 0) {
+ var component = current_acc.get_component ();
+ rect = component.get_extents (Atspi.CoordType.SCREEN);
+ }
+
+ keyboard.set_cursor_location (rect.x, rect.y,
+ rect.width, rect.height);
+ debug ("object:text-caret-moved in %s: %d %s",
+ event.source.get_application ().name,
+ event.detail1, event.source.description);
+ }
+ }
+
+ void on_text_caret_moved_ignore_error (owned Atspi.Event event) {
+ try {
+ on_text_caret_moved (event);
+ } catch (Error e) {
+ warning ("error in text caret movement handler: %s", e.message);
+ }
+ }
+
+ void register_event_listeners () throws Error {
+ Atspi.EventListener.register_from_callback (
+ on_focus_ignore_error, "object:state-changed:focused");
+ Atspi.EventListener.register_from_callback (
+ on_focus_ignore_error, "focus:");
+ Atspi.EventListener.register_from_callback (
+ on_text_caret_moved_ignore_error, "object:text-caret-moved");
+ }
+
+ void deregister_event_listeners () throws Error {
+ Atspi.EventListener.deregister_from_callback (
+ on_focus_ignore_error, "object:state-changed:focused");
+ Atspi.EventListener.deregister_from_callback (
+ on_focus_ignore_error, "focus:");
+ Atspi.EventListener.deregister_from_callback (
+ on_text_caret_moved_ignore_error, "object:text-caret-moved");
+ }
+
+ public void run () {
+ Bus.get_proxy.begin<_Keyboard> (BusType.SESSION,
+ "org.gnome.Caribou.Keyboard",
+ "/org/gnome/Caribou/Keyboard",
+ 0,
+ null,
+ on_get_proxy_ready);
+ Gtk.main ();
+ }
+
+ public void quit () {
+ if (keyboard != null) {
+ try {
+ keyboard.hide (get_timestamp ());
+ } catch (IOError e) {
+ warning ("can't hide keyboard: %s", e.message);
+ }
+
+ try {
+ deregister_event_listeners ();
+ } catch (Error e) {
+ warning ("can't deregister event listeners: %s", e.message);
+ }
+ keyboard = null;
+ }
+
+ if (Gtk.main_level () > 0)
+ Gtk.main_quit ();
+ }
+ }
+}
+
+static int main (string[] args) {
+ Gtk.init (ref args);
+
+ Intl.setlocale (LocaleCategory.ALL, "");
+ Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
+ Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8");
+ Intl.textdomain (Config.GETTEXT_PACKAGE);
+
+ Atspi.init ();
+
+ var daemon = new Caribou.Daemon ();
+ Unix.signal_add (Posix.SIGINT, () => {
+ daemon.quit ();
+ return false;
+ });
+ daemon.run ();
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]