GNOME Accessibility Team
Common Magnifier Framework
Contents
There are currently two magnifier efforts for GNOME: GnomeMag and GNOME Shell Magnification. Since they implement the same functionality, it is essential that they have the same interface.
Access to magnifier functionality can be done using interprocess communication, or through the use of a settings persistence mechanism. This page documents which functions are best accessed by a desktop service, and which are better dealt with using persistence. Interprocess communication is accomplished using D-Bus, while persistence of user preferences is handled using GSettings.
During the AEGIS Seville Hackfest 2010, Alejandro, Fernando, and Joseph met to explore these issues. The following is a summary of their discussion.
Interprocess Communication API (D-Bus)
Certain magnifier properties and functions are best managed using interprocess communication, wherein some client invokes magnifier functions. States that are transient and do not involve a user preference are best handled this way. An example is the region of the screen that is currently magnified. That region will vary, for example, as the mouse moves, or as keyboard focus changes. Furthermore, when the user finishes for the day, and logs out, it is very unlikely that they expect to come back to the exact same magnified content when they next reconnect. In short, this situation is not properly characterized as a persistent property of the magnifier.
The functions, states, and properties outlined in what follows are based on the CORBA magnifier interface. That interface forms the starting point of this new magnifier framework. If the reader wants to compare, the IDL for the CORBA interface is available from gnome mag's git repository.
Note that the magnifier is a manager of "zoom regions". Thus, the D-Bus provides an interface for both the magnifier itself, and for the zoom region construct. The functions and properties for each are outlined below.
org.gnome.Magnifier
- Turning the magnifier on/off:
void setActive(boolean);
boolean isActive();
Comment: activating the magnifier is a proposed preference in the new universal preferences panel, specifically, its "Use magnification" checkbox. Hence, the active state of the magnifier is arguably a persistent user preference, and not a function of the D-Bus service. Another possibility is that it is both a service request and a user preference, although that requires synchronization between the two.
- Showing/hiding system mouse cursor:
void showCursor();
void hideCursor();
Comment: are these needed? That is, are there use cases where a client of the service needs to hide the system mouse cursor? In the past, they were needed for a bug in FireFox (ref?), but does that bug still exist?
- Disposing of the magnifier:
void dispose();
- Comment: disposing the magnifier is most likely a stub in the case of GNOME Shell magnifier (gs-mag). Still, it's not clear what this is for. Does it occur when the magnifier service is being shut down? If so, that does not happen with gs-mag unless GNOME Shell itself exits.
ZoomRegion management:
Note: in what follows, "ROI" stands for Region Of Interest.
Note: a RectBounds is a structure of integers of the form { left, top, right, bottom }.
dbusObjectPath createZoomRegion(double xMagFactor, double yMagFactor, RectBounds ROI, RectBounds viewPort);
[dbusObjectPaths] getZoomRegions();
boolean addZoomRegion(dbusObjectPath zoomRegion);
void clearAllZoomRegions();
JSON notation for org.gnome.Magnifier D-Bus interface
{ name: 'setActive', inSignature: 'b', outSignature: '' }
{ name: 'isActive', inSignature: '', outSignature: 'b' }
{ name: 'showCursor', inSignature: '', outSignature: '' }
{ name: 'hideCursor', inSignature: '', outSignature: '' }
{ name: 'dispose', inSignature: '', outSignature: '' }
{ name: 'createZoomRegion', inSignature: 'dd{iiii}{iiii}', outSignature: 'o' }
{ name: 'getZoomRegions', inSignature: '', outSignature: 'ao' }
{ name: 'addZoomRegion', inSignature: 'o', outSignature: 'b' }
{ name: 'clearAllZoomRegions', inSignature: '', outSignature: '' }
org.gnome.Magnifier.ZoomRegion
A ZoomRegion is the part of the magnifier that has actual screen presence. A ZoomRegion appears as a rectangle on the screen and contains an enhanced view of some region of the desktop. The following are service functions that a client can call to manipulate individual ZoomRegions.
Change the contents of the magnified view. The first method, shiftContentsTo(), is supplied a point on the screen that is to be placed at the centre of the magnified view. The second method, setRoi(), is given a rectangular region of the screen that should be placed within the magnified view.
void shiftContentsTo(Point);
void setRoi(RectBounds);
RectBounds getRoi();
- Define an update region:
void markDirty(RectBounds);
Move and/or resize the ZoomRegion view:
void moveResize(RectBounds);
Dispose of the ZoomRegion:
void dispose();
JSON notation for org.gnome.Magnifier.ZoomRegion D-Bus interface:
{ name: 'shiftContentsTo', inSignature: '{ii}', outSignature: '' }
{ name: 'setRoi', inSignature: '{iiii}', outSignature: '' }
{ name: 'getRoi', inSignature: '', outSignature: '{iiii}' }
{ name: 'markDirty', inSignature: '{iiii}', outSignature: '' }
{ name: 'moveResize', inSignature: '{iiii}', outSignature: '' }
{ name: 'dispose', inSignature: '', outSignature: '' }
Persistent User Preferences (GSettings)
Some states and functions of the magnifier reflect user preferences, and, as such, persist between invocations of the magnifier. GSettings is used for managing persistent settings in terms of storing, retrieving, modifying, and reacting to preference changes. The following states and properties were part of the magnifier service layer, but, upon reflection, are now considered preferences. They are listed in quasi-GSettings XML syntax.
Magnifier Preferences
- Magnifier on/off:
<key name="screen-magnifier-enabled" type="b">, default = false
- Use a different set of mouse cursor images:
<key name="cursor-set" type="s">
- Enhance the mouse cursor image in various ways.
<key name="cursor-size" type="i">
<key name="cursor-zoom" type="d">
<key name="cursor-color" type="s"> <!-- e.g., '#ff0000' -->
<key name="cursor-hotspot" type="{ii}">
<key name="cursor-default-size" type="i">
Comment: cursor-default-size, when it was part of the service interface, was marked "read-only". But, user preferences are never "read-only". With respect to GSettings, is cursor-default-size captured as the default value for the cursor-size preference?
- Cross hairs:
<key name="show-cross-hairs" type="b">, default = false
<key name="cross-hairs-thickness" type="i">, default = 8 pixels
<key name="cross-hairs-length" type="i">, default = 4096 pixels
<key name="cross-hairs-clip" type="b">, default = false
<key name="cross-hairs-color" type="s">, default = '#ff0000' (= red)
<key name="cross-hairs-opacity" type="i">, default = 169 (range is [0-255], where 0 == fully transparent; 255 == fully opaque)
- Magnification factor:
<key name="mag-factor" type="d">, default = 2.0 (= 200%)
Comment: magnification factor, as a preference, reflects the preferred magnification factor of the first ZoomRegion only. It is technically a property of a ZoomRegion, not the Magnifier as a whole. Note, also, that it is available from the universal preferences panel.
ZoomRegion Preferences
<key name="mag-factor" type="d">, default = 2.0 (= 200%)
<key name="mouse-tracking" enum="MouseTrackingMode"> , default = 'proportional'
<enum id="MouseTrackingMode">, values are 'none', 'centered', 'proportional', and 'push'
<key name="screen-position" enum="ScreenPosition">, default = 'full-screen'
<enum id="ScreenPosition">, values are 'none', 'full-screen', 'top-half', 'bottom-half', 'right-half', and 'left-half'
<key name="invert-brightness" type="b">, default = false
<key name="contrast" type="s">, default = "#7f7f7f" (= no change in brightness)
<key name="brightness" type="s}">, default = '#7f7f7f' (= no change in contrast)
<key id="lens-mode", type="b">, default = false
- Comment: With lens-mode, the zoom region moves with the mouse to simulate a hand-held magnifying lens.
<key name="scroll-at-edges" type="b">, default = false
- Comment: When scrolling the zoom region's contents due to mouse movements, and the mouse is near an edge of the desktop (e.g., the top), this setting defines whether the contents continue to scroll beyond that edge.
Outstanding Issues
These ZoomRegion properties were part of the CORBA gnome-mag service, but are apparently irrelevant. They are deprecated and no longer supported (Confirmed by Carlos Diógenes):
property boolean Managed read/write
property boolean PollMouse read/write
There was a magnifier property in the CORBA gnome-mag service for source and target monitor size. Should these be part of the org.gnome.Magnfier D-Bus interface? Or are they a user preference?
property RectBounds SourceSize read/write
property RectBounds TargetSize read/write
Appendix: Orca Magnifier Settings
The following was a section of the GNOME Shell Magnifier page and formed part of the initial discussion regarding which magnifier settings are persistent user preferences, and which are communicated using a service. The table has been moved here for posterity.
gnome-mag settings available via the gnome-mag API
The following is a list of settings that Orca provides through its magnifier dialog, and communicates to the GNOME Mag CORBA service. The issue is which of these should migrate to GSettings, and which should remain part of the D-Bus, and which should be handled by both.
GLOBAL MAGNIFIER PROPERTIES:
Property Name |
Doc String |
Default Value |
Use by Orca |
'crosswire-size' |
thickness of crosswire cursor, in target pixels |
0 |
"Enable cross-hair" and "Cross-hair size" -- a value of 0 means disable cross hairs |
'crosswire-length' |
length of crosswire cursor, in target pixels |
0 |
Unused |
'crosswire-color' |
color of crosswire, as A-RGB; note that alpha is required. (use 0 for XOR wire) |
0 |
"Cross-hair color" |
'crosswire-clip' |
whether to inset the cursor over the crosswire or not |
False |
"Enable cross-hair clip" |
'cursor-set' |
? |
? |
Orca forces this to "default" |
'cursor-size' |
cursor size, in pixels |
64 |
"Cursor size" |
'cursor-color' |
foreground color for 1-bit cursors, as ARGB |
0 |
"Cursor color" |
'cursor-default-size' |
default size of current cursor set |
0 |
Unused |
'cursor-scale-factor' |
scale factor for cursors (overrides size) |
0.0 |
Set to the same as the "Scale factor" used for X/Y scale factor |
'cursor-hotspot' |
hotspot relative to cursor's upper-left-corner, at default resolition |
(0, 0) |
Unused |
'source-display-screen' |
source display screen (for multiheaded systems) |
:0.0 |
Used for setting which screen is to be magnified |
'source-display-bounds': source display bounds/size |
rectangle to magnify |
What portion of the screen to magnify |
|
'target-display-screen' |
target display screen |
:0.0 |
Used for setting where the magnified image will live |
'target-display-bounds' |
target display bounds/size |
rectangle to hold magnified image |
top/left/right/bottom position of the single zoomer used by Orca |
PER ZOOMER PROPERTIES:
Property Name |
Doc String |
Default Value |
Use by Orca |
'mag-factor-x' |
x scale factor |
2.0 |
"Scale factor" |
'mag-factor-y' |
y scale factor |
2.0 |
"Scale factor" |
'viewport' |
viewport bounding box |
(0, 0),(0, 0) |
Used indirectly by Orca -- Orca sets ROI and then queries for the new viewport values |
'smooth-scroll-policy' |
scrolling policy, slower versus faster |
0 |
Unused |
'smoothing-type' |
Smoothing type |
? |
"Smoothing type" combo box - bilinear or none |
'poll-mouse' |
If false, zoom region does not poll for pointer location, but is (exclusively) given it by the client |
False |
Orca currently polls the mouse, so poll-mouse is turned off in the magnifier. If the push/proportional/center/etc. modes were supported by the magnifier, this would not be needed. |
'is-managed' |
If false, zoom region does not auto-update, but is drawn into directly by the client |
True |
Orca makes sure this is True |
'border-color' |
border color, as RGBA32 |
0 |
"Border color" |
'border-size' |
size of zoom-region borders, in pixels |
0 |
"Border size" |
'border-size-left' |
size of left zoom-region border, in pixels |
0 |
Set to 0 if on edge of screen, otherwise set to "Border size" |
'border-size-right' |
size of right zoom-region border, in pixels |
0 |
Set to 0 if on edge of screen, otherwise set to "Border size" |
'border-size-bottom' |
size of bottom zoom-region border, in pixels |
0 |
Set to 0 if on edge of screen, otherwise set to "Border size" |
'border-size-top' |
size of top zoom-region border, in pixels |
0 |
Set to 0 if on edge of screen, otherwise set to "Border size" |
'x-alignment' |
x-alignment policy for this region |
0 |
Unused |
'y-alignment' |
y-alignment policy for this region |
0 |
Unused |
'green-brightness' |
green image brightness ratio |
0.0 |
Set via setBrightness API on zoomer |
'green-contrast' |
green image contrast ratio |
0.0 |
Set via setContrast API on zoomer |
'blue-brightness' |
blue image brightness ratio |
0.0 |
Set via setBrightness API on zoomer |
'blue-contrast' |
blue image contrast ratio |
0.0 |
Set via setContrast API on zoomer |
'red-brightness' |
red image brightness ratio |
0.0 |
Set via setBrightness API on zoomer |
'red-contrast' |
red image contrast ratio |
0.0 |
Set via setContrast API on zoomer |
'inverse-video' |
inverse video display |
True |
"Invert colors" |
'color-blind-filter' |
color blind filter to apply in an image |
0 |
"Color filtering" combobox |
'draw-cursor' |
If false, zoom region does not draw the cursor. |
False |
"Enable cursor" |
'timing-iterations' |
Title: timing iterations |
0 |
Unused |
'timing-pan-rate' |
timing pan rate |
0 |
Unused |
'timing-output' |
timing output |
False |
Unused |
'exit-magnifier' |
timing output |
False |
Unused |
'use-test-pattern' |
use test pattern for source |
False |
Unused |
GNOME Shell Magnifier is part of the ÆGIS (Ontario) Project. It is funded and supported by the Ontario Ministry of Economic Development and Innovation and the ÆGIS (Europe) Project.