diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/Makefile.am | 9 | ||||
-rw-r--r-- | modules/gtk2/Makefile.am | 33 | ||||
l--------- | modules/gtk2/caribou-gtk-modules.vala | 1 | ||||
l--------- | modules/gtk2/caribou-module.c | 1 | ||||
l--------- | modules/gtk2/vapi-fixes.vapi | 1 | ||||
-rw-r--r-- | modules/gtk3/Makefile.am | 32 | ||||
-rw-r--r-- | modules/gtk3/caribou-gtk-modules.vala | 138 | ||||
-rw-r--r-- | modules/gtk3/caribou-module.c | 21 | ||||
-rw-r--r-- | modules/gtk3/vapi-fixes.vapi | 10 |
9 files changed, 246 insertions, 0 deletions
diff --git a/modules/Makefile.am b/modules/Makefile.am new file mode 100644 index 0000000..47ecbb7 --- /dev/null +++ b/modules/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = + +if ENABLE_GTK3_MODULES +SUBDIRS += gtk3 +endif + +if ENABLE_GTK2_MODULES +SUBDIRS += gtk2 +endif diff --git a/modules/gtk2/Makefile.am b/modules/gtk2/Makefile.am new file mode 100644 index 0000000..cff49fd --- /dev/null +++ b/modules/gtk2/Makefile.am @@ -0,0 +1,33 @@ +gtk_modulesdir = @GTK2_MODULES_DIR@ +gtk_modules_LTLIBRARIES = libcaribou.la + +libcaribou_la_SOURCES = \ + caribou-gtk-modules.vala \ + caribou-module.c \ + $(NULL) + +libcaribou_la_VALAFLAGS = \ + -h caribou-gtk-modules.h \ + --vapidir=. \ + --pkg vapi-fixes \ + --pkg gtk+-2.0 \ + -D GTK2 \ + $(VALAGLAFS) + +libcaribou_la_CFLAGS = \ + @GTK2_CFLAGS@ \ + -DG_LOG_DOMAIN=\"CARIBOU\" \ + $(NULL) + +libcaribou_la_LIBADD = \ + @GTK2_LIBS@ \ + $(NULL) + +libcaribou_la_LDFLAGS = \ + -avoid-version \ + -module \ + $(NULL) + +EXTRA_DIST = \ + vapi-fixes.vapi \ + $(NULL) diff --git a/modules/gtk2/caribou-gtk-modules.vala b/modules/gtk2/caribou-gtk-modules.vala new file mode 120000 index 0000000..5b7285b --- /dev/null +++ b/modules/gtk2/caribou-gtk-modules.vala @@ -0,0 +1 @@ +../gtk3/caribou-gtk-modules.vala
\ No newline at end of file diff --git a/modules/gtk2/caribou-module.c b/modules/gtk2/caribou-module.c new file mode 120000 index 0000000..e08e22e --- /dev/null +++ b/modules/gtk2/caribou-module.c @@ -0,0 +1 @@ +../gtk3/caribou-module.c
\ No newline at end of file diff --git a/modules/gtk2/vapi-fixes.vapi b/modules/gtk2/vapi-fixes.vapi new file mode 120000 index 0000000..cb1b309 --- /dev/null +++ b/modules/gtk2/vapi-fixes.vapi @@ -0,0 +1 @@ +../gtk3/vapi-fixes.vapi
\ No newline at end of file diff --git a/modules/gtk3/Makefile.am b/modules/gtk3/Makefile.am new file mode 100644 index 0000000..54ef4cc --- /dev/null +++ b/modules/gtk3/Makefile.am @@ -0,0 +1,32 @@ +gtk_modulesdir = @GTK3_MODULES_DIR@ +gtk_modules_LTLIBRARIES = libcaribou.la + +libcaribou_la_SOURCES = \ + caribou-gtk-modules.vala \ + caribou-module.c \ + $(NULL) + +libcaribou_la_VALAFLAGS = \ + -h caribou-gtk-modules.h \ + --vapidir=. \ + --pkg vapi-fixes \ + --pkg gtk+-3.0 \ + $(VALAGLAFS) + +libcaribou_la_CFLAGS = \ + @GTK3_CFLAGS@ \ + -DG_LOG_DOMAIN=\"CARIBOU\" \ + $(NULL) + +libcaribou_la_LIBADD = \ + @GTK3_LIBS@ \ + $(NULL) + +libcaribou_la_LDFLAGS = \ + -avoid-version \ + -module \ + $(NULL) + +EXTRA_DIST = \ + vapi-fixes.vapi \ + $(NULL) diff --git a/modules/gtk3/caribou-gtk-modules.vala b/modules/gtk3/caribou-gtk-modules.vala new file mode 100644 index 0000000..bc87737 --- /dev/null +++ b/modules/gtk3/caribou-gtk-modules.vala @@ -0,0 +1,138 @@ +namespace Caribou { + [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 GtkModules { + private GLib.List<Gtk.Window> windows; + private Keyboard keyboard; + + public GtkModules () { + windows = new GLib.List<Gtk.Window>(); + try { + keyboard = Bus.get_proxy_sync (BusType.SESSION, + "org.gnome.Caribou.Keyboard", + "/org/gnome/Caribou/Keyboard"); + } catch (Error e) { + stderr.printf ("%s\n", e.message); + } + + add_tracker (); + + GLib.Timeout.add (60, () => { add_tracker (); + return true; }); + } + + private void add_tracker () { + GLib.List<weak Gtk.Window> toplevels; + + toplevels = Gtk.Window.list_toplevels(); + foreach (Gtk.Window window in toplevels) { + if (windows.find(window) == null) { + window.notify["has-toplevel-focus"].connect(get_top_level_focus); + windows.append(window); + } + } + } + + private void get_top_level_focus (Object obj, ParamSpec prop) { + Gtk.Window window = (Gtk.Window) obj; + if (window.has_toplevel_focus) + focus_tracker (window, window.get_focus()); + } + + private void focus_tracker (Gtk.Window window, Gtk.Widget? widget) { + uint32 timestamp = Gtk.get_current_event_time(); + if (widget != null && (widget is Gtk.Entry || widget is Gtk.TextView) && widget is Gtk.Editable) { + Atk.Object focus_object = widget.get_accessible(); + Gdk.Window current_window = widget.get_window(); + int x=0, y=0, w=0, h=0; + if (current_window != null && !get_acc_geometry (focus_object, out x, out y, out w, out h)) { + get_origin_geometry (current_window, out x, out y, out w, out h); + } + try { + keyboard.show (timestamp); + keyboard.set_entry_location (x, y, w, h); + } catch (IOError e) { + stderr.printf ("%s\n", e.message); + } + } + else { + try { + keyboard.hide (timestamp); + } catch (IOError e) { + stderr.printf("%s\n", e.message); + } + } + } + + private void get_origin_geometry (Gdk.Window window, + out int x, out int y, + out int w, out int h) { + window.get_origin (out x, out y); +#if GTK2 + window.get_geometry (null, null, out w, out h, null); +#else + window.get_geometry (null, null, out w, out h); +#endif + } + + private Atk.Object? find_focused_accessible (Atk.Object acc) { + Atk.StateSet state = acc.ref_state_set (); + + bool match = (state.contains_state (Atk.StateType.EDITABLE) && + state.contains_state (Atk.StateType.FOCUSED) && + acc.get_n_accessible_children () == 0); + + if (match) + return acc; + + for (int i=0;i<acc.get_n_accessible_children ();i++) { + Atk.Object child = acc.ref_accessible_child (i); + Atk.Object focused_child = find_focused_accessible (child); + if (focused_child != null) + return focused_child; + } + + return null; + } + + private bool get_acc_geometry (Atk.Object acc, + out int x, out int y, out int w, out int h) { + Atk.Object child = null; + + + if (acc.get_role () == Atk.Role.REDUNDANT_OBJECT) { + /* It is probably Gecko */ + child = Atk.get_focus_object (); + } else { + child = find_focused_accessible (acc); + } + + if (child == null) + return false; + + if (!(child is Atk.Component)) { + stderr.printf ("Accessible is not a component\n"); + return false; + } + + /* We don't want the keyboard on the paragraph in OOo */ + if (child.get_role() == Atk.Role.PARAGRAPH) + child = child.get_parent(); + + Atk.component_get_extents ((Atk.Component) child, + out x, out y, out w, out h, + Atk.CoordType.SCREEN); + + return true; + } + + } +} diff --git a/modules/gtk3/caribou-module.c b/modules/gtk3/caribou-module.c new file mode 100644 index 0000000..228383f --- /dev/null +++ b/modules/gtk3/caribou-module.c @@ -0,0 +1,21 @@ +#include <gtk/gtk.h> +#include <gtk/gtkimmodule.h> +#include "caribou-gtk-modules.h" +#include <stdio.h> + +#define CARIBOU_LOCALDIR "" + +G_MODULE_EXPORT CaribouGtkModules * +gtk_module_init (gint *argc, gchar ***argv[]) { + CaribouGtkModules *context = caribou_gtk_modules_new (); + return context; +} + +G_MODULE_EXPORT const gchar* +g_module_check_init (GModule *module) +{ + return glib_check_version (GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION, + 0); +} + diff --git a/modules/gtk3/vapi-fixes.vapi b/modules/gtk3/vapi-fixes.vapi new file mode 100644 index 0000000..7b21d78 --- /dev/null +++ b/modules/gtk3/vapi-fixes.vapi @@ -0,0 +1,10 @@ +using Atk; + +[CCode (cprefix = "Atk", lower_case_cprefix = "atk_", cheader_filename = "atk/atk.h")] + +namespace Atk { + [CCode (cname = "atk_component_get_extents")] + public void component_get_extents (Atk.Component component, + out int x, out int y, out int w, out int h, + Atk.CoordType coord_type); +}
\ No newline at end of file |