[g-a-devel] mag.py and Compiz' Enhanced Zoom



I've more or less finished the Enhanced Zoom plugin for Compiz, and it
is able to do much of what orca already does.

I was testing out the dbus interface with orca and realized that the
way orca handles text-caret events is somewhat less than optimal for
ezoom.

With mouse events, everything works perfectly. You can use orca
instead of the built in mouse panning to control ezoom over dbus. It's
dead on. However, text caret events are not.

Ezoom uses a rather simple interface for this: ensure_visibility. The
idea is to pass it exactly what you want to make sure is visible,
nothing more or less. An x1/y1 and an x2/y2 pair in screen
coordinates. Ezoom will calculate how much it needs to move and in
which direction by it self. You can also pass "scale: true" to make it
adjust the zoom level (this is somewhat untested except the most basic
technical test).

The problem seems to be that orca wants to dictate the exact location
of the zoomed area. Since my patch doesn't actually disable gnome-mag
(it's just a quick hack), I set the magnifier location/size to
1/1/2/2. With that setting, Orca would track the upper left corner of
the text cursor. This worked partially, but is not good enough.
Dictating the exact location is not going to work, because Orca won't
know the zoom level (nor should it have to). Of course, given my lack
of experience with mag.py, I might be missing something that should be
obvious.

Could someone more experienced help me make a proper patch? I assume
the right course of action here is to create a separate script to
mag.py, though the amount of code required to make ezoom work is quite
tiny, if the above issues are addressed. My current mag.py patch is at
the bottom of this mail, it is a dirty hack but a decent proof of
concept. As I am new with both Orca and Python, I'll take any help I
can get.

I also believe that much of what Orca does for gnome-mag is better
suited to be handled directly by ezoom, most notably the focus
tracking (who knows more about focus changes than a window manager?)
and the mouse panning. The reason the mouse code should be kept inside
ezoom is the up-coming input redirection, which will make it somewhat
difficult for orca to know what's going on.

I also tried throwing together a pyatspi script that JUST fetches the
text-caret events, I used the example listed on the PythonATSPI page,
but I have yet to be able to convert the data I get to proper screen
coordinates, some help in that area would be much welcomed to, as I
wish to have a script that can do just text-caret tracking, which is
what most users miss in ezoom at the moment (and should be a fair bit
easier than full Orca support).

- Kristian

Index: src/orca/mag.py
===================================================================
--- src/orca/mag.py	(revision 2667)
+++ src/orca/mag.py	(working copy)
@@ -53,6 +53,10 @@

 import time

+import os
+import dbus
+import re
+
 # If True, this module has been initialized.
 #
 _initialized = False
@@ -102,6 +106,42 @@
 #
 _pollMouseDisabled = False

+# The root window id
+_rootWindowId = 0
+
+# init service/interface
+COMPIZ_DBUS_SERVICE = 'org.freedesktop.compiz'
+COMPIZ_DBUS_INTERFACE = 'org.freedesktop.compiz'
+COMPIZ_DBUS_OBJECT = '/org/freedesktop/compiz'
+
+_bus = None
+
+def compiz_call(obj_path, func_name, *args):
+	"""Call method in obj_path in compiz-service over dbus. The compiz-object's
+	path does not need to be passed."""
+	path = COMPIZ_DBUS_OBJECT
+	if obj_path:
+		path += '/' + obj_path
+	obj = _bus.get_object(COMPIZ_DBUS_SERVICE, path)
+	iface = dbus.Interface(obj, COMPIZ_DBUS_INTERFACE)
+	func = getattr(iface, func_name)
+	if func:
+		try:
+			return func(*args)
+		except Exception, ex:
+			print "compiz_call(): Dbus-error: " + str(ex)
+	return None
+
+def get_root_window_id():
+    rootid = 0
+    idline = os.popen('xwininfo -root | grep "id:"').readlines()[0]
+    idmatch = re.search('id: ([^ ]*)', idline)
+    if (idmatch):
+	rootid = int(idmatch.group(1), 16)
+	return rootid
+    else:
+        raise 'Unable to locate the root window ID'
+
 def __setROI(rect):
     """Sets the region of interest.

@@ -112,8 +152,11 @@
     global _roi

     _roi = rect
-    _zoomer.setROI(_roi)
-    _zoomer.markDirty(_roi)  # [[[TODO: WDW - for some reason, this seems
+#    _zoomer.setROI(_roi)
+ #   _zoomer.markDirty(_roi)  # [[[TODO: WDW - for some reason, this seems
+    print 'x1:' , rect.x1 , 'x2' , rect.x2
+    print 'y1:' , rect.y1 , 'y2' , rect.y2
+    compiz_call ('ezoom/allscreens/ensure_visibility', 'activate',
'root', _rootWindowId, 'x1', int(rect.x1), 'x2', int(rect.x2), 'y1',
int(rect.y1), 'y2', int(rect.y2))
                              # necessary.]]]
 def __setROICenter(x, y):
     """Centers the region of interest around the given point.
@@ -141,7 +184,8 @@

     x2 = x1 + _roiWidth
     y2 = y1 + _roiHeight
-
+
+
     __setROI(GNOME.Magnifier.RectBounds(x1, y1, x2, y2))

 def __setROIPush(x, y):
@@ -540,7 +584,9 @@

     global _initialized
     global _magnifier
+    global _rootWindowId

+
     if not _magnifierAvailable:
         return False

@@ -550,8 +596,14 @@
     _magnifier = bonobo.get_object("OAFIID:GNOME_Magnifier_Magnifier:0.9",
                                    "GNOME/Magnifier/Magnifier")

+    _rootWindowId = get_root_window_id ()
+
+    global _bus
+    _bus = dbus.SessionBus()
+
     try:
         applySettings()
+
     except:
         debug.printException(debug.LEVEL_SEVERE)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]