bacfdbbb03
ES6 finally adds standard class syntax to the language, so we can replace our custom Lang.Class framework with the new syntax. Any classes that inherit from GObject will need special treatment, so limit the port to regular javascript classes for now. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/361
344 lines
12 KiB
JavaScript
344 lines
12 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
const Gio = imports.gi.Gio;
|
|
const Main = imports.ui.main;
|
|
|
|
const { loadInterfaceXML } = imports.misc.fileUtils;
|
|
|
|
const MAG_SERVICE_PATH = '/org/gnome/Magnifier';
|
|
const ZOOM_SERVICE_PATH = '/org/gnome/Magnifier/ZoomRegion';
|
|
|
|
// Subset of gnome-mag's Magnifier dbus interface -- to be expanded. See:
|
|
// http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml
|
|
const MagnifierIface = loadInterfaceXML('org.gnome.Magnifier');
|
|
|
|
// Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded. See:
|
|
// http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml
|
|
const ZoomRegionIface = loadInterfaceXML('org.gnome.Magnifier.ZoomRegion');
|
|
|
|
// For making unique ZoomRegion DBus proxy object paths of the form:
|
|
// '/org/gnome/Magnifier/ZoomRegion/zoomer0',
|
|
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
|
|
let _zoomRegionInstanceCount = 0;
|
|
|
|
var ShellMagnifier = class ShellMagnifier {
|
|
constructor() {
|
|
this._zoomers = {};
|
|
|
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this);
|
|
this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH);
|
|
}
|
|
|
|
/**
|
|
* setActive:
|
|
* @activate: Boolean to activate or de-activate the magnifier.
|
|
*/
|
|
setActive(activate) {
|
|
Main.magnifier.setActive(activate);
|
|
}
|
|
|
|
/**
|
|
* isActive:
|
|
* @return Whether the magnifier is active (boolean).
|
|
*/
|
|
isActive() {
|
|
return Main.magnifier.isActive();
|
|
}
|
|
|
|
/**
|
|
* showCursor:
|
|
* Show the system mouse pointer.
|
|
*/
|
|
showCursor() {
|
|
Main.magnifier.showSystemCursor();
|
|
}
|
|
|
|
/**
|
|
* hideCursor:
|
|
* Hide the system mouse pointer.
|
|
*/
|
|
hideCursor() {
|
|
Main.magnifier.hideSystemCursor();
|
|
}
|
|
|
|
/**
|
|
* createZoomRegion:
|
|
* Create a new ZoomRegion and return its object path.
|
|
* @xMagFactor: The power to set horizontal magnification of the
|
|
* ZoomRegion. A value of 1.0 means no magnification. A
|
|
* value of 2.0 doubles the size.
|
|
* @yMagFactor: The power to set the vertical magnification of the
|
|
* ZoomRegion.
|
|
* @roi Array of integers defining the region of the
|
|
* screen/desktop to magnify. The array has the form
|
|
* [left, top, right, bottom].
|
|
* @viewPort Array of integers, [left, top, right, bottom] that defines
|
|
* the position of the ZoomRegion on screen.
|
|
*
|
|
* FIXME: The arguments here are redundant, since the width and height of
|
|
* the ROI are determined by the viewport and magnification factors.
|
|
* We ignore the passed in width and height.
|
|
*
|
|
* @return The newly created ZoomRegion.
|
|
*/
|
|
createZoomRegion(xMagFactor, yMagFactor, roi, viewPort) {
|
|
let ROI = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] };
|
|
let viewBox = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
|
|
let realZoomRegion = Main.magnifier.createZoomRegion(xMagFactor, yMagFactor, ROI, viewBox);
|
|
let objectPath = ZOOM_SERVICE_PATH + '/zoomer' + _zoomRegionInstanceCount;
|
|
_zoomRegionInstanceCount++;
|
|
|
|
let zoomRegionProxy = new ShellMagnifierZoomRegion(objectPath, realZoomRegion);
|
|
let proxyAndZoomRegion = {};
|
|
proxyAndZoomRegion.proxy = zoomRegionProxy;
|
|
proxyAndZoomRegion.zoomRegion = realZoomRegion;
|
|
this._zoomers[objectPath] = proxyAndZoomRegion;
|
|
return objectPath;
|
|
}
|
|
|
|
/**
|
|
* addZoomRegion:
|
|
* Append the given ZoomRegion to the magnifier's list of ZoomRegions.
|
|
* @zoomerObjectPath: The object path for the zoom region proxy.
|
|
*/
|
|
addZoomRegion(zoomerObjectPath) {
|
|
let proxyAndZoomRegion = this._zoomers[zoomerObjectPath];
|
|
if (proxyAndZoomRegion && proxyAndZoomRegion.zoomRegion) {
|
|
Main.magnifier.addZoomRegion(proxyAndZoomRegion.zoomRegion);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* getZoomRegions:
|
|
* Return a list of ZoomRegion object paths for this Magnifier.
|
|
* @return: The Magnifier's zoom region list as an array of DBus object
|
|
* paths.
|
|
*/
|
|
getZoomRegions() {
|
|
// There may be more ZoomRegions in the magnifier itself than have
|
|
// been added through dbus. Make sure all of them are associated with
|
|
// an object path and proxy.
|
|
let zoomRegions = Main.magnifier.getZoomRegions();
|
|
let objectPaths = [];
|
|
let thoseZoomers = this._zoomers;
|
|
zoomRegions.forEach ((aZoomRegion, index, array) => {
|
|
let found = false;
|
|
for (let objectPath in thoseZoomers) {
|
|
let proxyAndZoomRegion = thoseZoomers[objectPath];
|
|
if (proxyAndZoomRegion.zoomRegion === aZoomRegion) {
|
|
objectPaths.push(objectPath);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
// Got a ZoomRegion with no DBus proxy, make one.
|
|
let newPath = ZOOM_SERVICE_PATH + '/zoomer' + _zoomRegionInstanceCount;
|
|
_zoomRegionInstanceCount++;
|
|
let zoomRegionProxy = new ShellMagnifierZoomRegion(newPath, aZoomRegion);
|
|
let proxyAndZoomer = {};
|
|
proxyAndZoomer.proxy = zoomRegionProxy;
|
|
proxyAndZoomer.zoomRegion = aZoomRegion;
|
|
thoseZoomers[newPath] = proxyAndZoomer;
|
|
objectPaths.push(newPath);
|
|
}
|
|
});
|
|
return objectPaths;
|
|
}
|
|
|
|
/**
|
|
* clearAllZoomRegions:
|
|
* Remove all the zoom regions from this Magnfier's ZoomRegion list.
|
|
*/
|
|
clearAllZoomRegions() {
|
|
Main.magnifier.clearAllZoomRegions();
|
|
for (let objectPath in this._zoomers) {
|
|
let proxyAndZoomer = this._zoomers[objectPath];
|
|
proxyAndZoomer.proxy.destroy();
|
|
proxyAndZoomer.proxy = null;
|
|
proxyAndZoomer.zoomRegion = null;
|
|
delete this._zoomers[objectPath];
|
|
}
|
|
this._zoomers = {};
|
|
}
|
|
|
|
/**
|
|
* fullScreenCapable:
|
|
* Consult if the Magnifier can magnify in full-screen mode.
|
|
* @return Always return true.
|
|
*/
|
|
fullScreenCapable() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* setCrosswireSize:
|
|
* Set the crosswire size of all ZoomRegions.
|
|
* @size: The thickness of each line in the cross wire.
|
|
*/
|
|
setCrosswireSize(size) {
|
|
Main.magnifier.setCrosshairsThickness(size);
|
|
}
|
|
|
|
/**
|
|
* getCrosswireSize:
|
|
* Get the crosswire size of all ZoomRegions.
|
|
* @return: The thickness of each line in the cross wire.
|
|
*/
|
|
getCrosswireSize() {
|
|
return Main.magnifier.getCrosshairsThickness();
|
|
}
|
|
|
|
/**
|
|
* setCrosswireLength:
|
|
* Set the crosswire length of all zoom-regions..
|
|
* @size: The length of each line in the cross wire.
|
|
*/
|
|
setCrosswireLength(length) {
|
|
Main.magnifier.setCrosshairsLength(length);
|
|
}
|
|
|
|
/**
|
|
* setCrosswireSize:
|
|
* Set the crosswire size of all zoom-regions.
|
|
* @size: The thickness of each line in the cross wire.
|
|
*/
|
|
getCrosswireLength() {
|
|
return Main.magnifier.getCrosshairsLength();
|
|
}
|
|
|
|
/**
|
|
* setCrosswireClip:
|
|
* Set if the crosswire will be clipped by the cursor image..
|
|
* @clip: Flag to indicate whether to clip the crosswire.
|
|
*/
|
|
setCrosswireClip(clip) {
|
|
Main.magnifier.setCrosshairsClip(clip);
|
|
}
|
|
|
|
/**
|
|
* getCrosswireClip:
|
|
* Get the crosswire clip value.
|
|
* @return: Whether the crosswire is clipped by the cursor image.
|
|
*/
|
|
getCrosswireClip() {
|
|
return Main.magnifier.getCrosshairsClip();
|
|
}
|
|
|
|
/**
|
|
* setCrosswireColor:
|
|
* Set the crosswire color of all ZoomRegions.
|
|
* @color: Unsigned int of the form rrggbbaa.
|
|
*/
|
|
setCrosswireColor(color) {
|
|
Main.magnifier.setCrosshairsColor('#%08x'.format(color));
|
|
}
|
|
|
|
/**
|
|
* getCrosswireClip:
|
|
* Get the crosswire color of all ZoomRegions.
|
|
* @return: The crosswire color as an unsigned int in the form rrggbbaa.
|
|
*/
|
|
getCrosswireColor() {
|
|
let colorString = Main.magnifier.getCrosshairsColor();
|
|
// Drop the leading '#'.
|
|
return parseInt(colorString.slice(1), 16);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ShellMagnifierZoomRegion:
|
|
* Object that implements the DBus ZoomRegion interface.
|
|
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
|
|
* @zoomRegion: The actual zoom region associated with the object path.
|
|
*/
|
|
var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
|
|
constructor(zoomerObjectPath, zoomRegion) {
|
|
this._zoomRegion = zoomRegion;
|
|
|
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this);
|
|
this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath);
|
|
}
|
|
|
|
/**
|
|
* setMagFactor:
|
|
* @xMagFactor: The power to set the horizontal magnification factor to
|
|
* of the magnified view. A value of 1.0 means no
|
|
* magnification. A value of 2.0 doubles the size.
|
|
* @yMagFactor: The power to set the vertical magnification factor to
|
|
* of the magnified view.
|
|
*/
|
|
setMagFactor(xMagFactor, yMagFactor) {
|
|
this._zoomRegion.setMagFactor(xMagFactor, yMagFactor);
|
|
}
|
|
|
|
/**
|
|
* getMagFactor:
|
|
* @return an array, [xMagFactor, yMagFactor], containing the horizontal
|
|
* and vertical magnification powers. A value of 1.0 means no
|
|
* magnification. A value of 2.0 means the contents are doubled
|
|
* in size, and so on.
|
|
*/
|
|
getMagFactor() {
|
|
return this._zoomRegion.getMagFactor();
|
|
}
|
|
|
|
/**
|
|
* setRoi:
|
|
* Sets the "region of interest" that the ZoomRegion is magnifying.
|
|
* @roi Array, [left, top, right, bottom], defining the region of the
|
|
* screen to magnify. The values are in screen (unmagnified)
|
|
* coordinate space.
|
|
*/
|
|
setRoi(roi) {
|
|
let roiObject = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] };
|
|
this._zoomRegion.setROI(roiObject);
|
|
}
|
|
|
|
/**
|
|
* getRoi:
|
|
* Retrieves the "region of interest" -- the rectangular bounds of that part
|
|
* of the desktop that the magnified view is showing (x, y, width, height).
|
|
* The bounds are given in non-magnified coordinates.
|
|
* @return an array, [left, top, right, bottom], representing the bounding
|
|
* rectangle of what is shown in the magnified view.
|
|
*/
|
|
getRoi() {
|
|
let roi = this._zoomRegion.getROI();
|
|
roi[2] += roi[0];
|
|
roi[3] += roi[1];
|
|
return roi;
|
|
}
|
|
|
|
/**
|
|
* Set the "region of interest" by centering the given screen coordinate
|
|
* within the zoom region.
|
|
* @x The x-coord of the point to place at the center of the zoom region.
|
|
* @y The y-coord.
|
|
* @return Whether the shift was successful (for GS-mag, this is always
|
|
* true).
|
|
*/
|
|
shiftContentsTo(x, y) {
|
|
this._zoomRegion.scrollContentsTo(x, y);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* moveResize
|
|
* Sets the position and size of the ZoomRegion on screen.
|
|
* @viewPort Array, [left, top, right, bottom], defining the position and
|
|
* size on screen to place the zoom region.
|
|
*/
|
|
moveResize(viewPort) {
|
|
let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
|
|
this._zoomRegion.setViewPort(viewRect);
|
|
}
|
|
|
|
destroy() {
|
|
this._dbusImpl.unexport();
|
|
}
|
|
};
|