mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 890940 - [AccessFu] Refactor coordinate handling to account for widget scaling. r=eeejay
--HG-- extra : rebase_source : 273f9171405c18e38bc9ec9e0d8d01f3d7d5fae4
This commit is contained in:
parent
f0b2dcf9d3
commit
b9c7f12779
@ -356,7 +356,56 @@ this.AccessFu = {
|
||||
|
||||
// Keep track of message managers tha already have a 'content-script.js'
|
||||
// injected.
|
||||
_processedMessageManagers: []
|
||||
_processedMessageManagers: [],
|
||||
|
||||
/**
|
||||
* Adjusts the given bounds relative to the given browser. Converts from screen
|
||||
* or device pixels to either device or CSS pixels.
|
||||
* @param {Rect} aJsonBounds the bounds to adjust
|
||||
* @param {browser} aBrowser the browser we want the bounds relative to
|
||||
* @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to
|
||||
* device pixels)
|
||||
* @param {bool} aFromDevicePixels whether to convert from device pixels (as
|
||||
* opposed to screen pixels)
|
||||
*/
|
||||
adjustContentBounds: function(aJsonBounds, aBrowser, aToCSSPixels, aFromDevicePixels) {
|
||||
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
|
||||
aJsonBounds.right - aJsonBounds.left,
|
||||
aJsonBounds.bottom - aJsonBounds.top);
|
||||
let win = Utils.win;
|
||||
let dpr = win.devicePixelRatio;
|
||||
let vp = Utils.getViewport(win);
|
||||
let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
|
||||
|
||||
if (!aBrowser.contentWindow) {
|
||||
// OOP browser, add offset of browser.
|
||||
// The offset of the browser element in relation to its parent window.
|
||||
let clientRect = aBrowser.getBoundingClientRect();
|
||||
let win = aBrowser.ownerDocument.defaultView;
|
||||
offset.left += clientRect.left + win.mozInnerScreenX;
|
||||
offset.top += clientRect.top + win.mozInnerScreenY;
|
||||
}
|
||||
|
||||
// Here we scale from screen pixels to layout device pixels by dividing by
|
||||
// the resolution (caused by pinch-zooming). The resolution is the viewport
|
||||
// zoom divided by the devicePixelRatio. If there's no viewport, then we're
|
||||
// on a platform without pinch-zooming and we can just ignore this.
|
||||
if (!aFromDevicePixels && vp) {
|
||||
bounds = bounds.scale(vp.zoom / dpr, vp.zoom / dpr);
|
||||
}
|
||||
|
||||
// Add the offset; the offset is in CSS pixels, so multiply the
|
||||
// devicePixelRatio back in before adding to preserve unit consistency.
|
||||
bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
|
||||
|
||||
// If we want to get to CSS pixels from device pixels, this needs to be
|
||||
// further divided by the devicePixelRatio due to widget scaling.
|
||||
if (aToCSSPixels) {
|
||||
bounds = bounds.scale(1 / dpr, 1 / dpr);
|
||||
}
|
||||
|
||||
return bounds.expandToIntegers();
|
||||
}
|
||||
};
|
||||
|
||||
var Output = {
|
||||
@ -472,7 +521,7 @@ var Output = {
|
||||
}
|
||||
|
||||
let padding = aDetails.padding;
|
||||
let r = this._adjustBounds(aDetails.bounds, aBrowser);
|
||||
let r = AccessFu.adjustContentBounds(aDetails.bounds, aBrowser, true);
|
||||
|
||||
// First hide it to avoid flickering when changing the style.
|
||||
highlightBox.style.display = 'none';
|
||||
@ -536,7 +585,7 @@ var Output = {
|
||||
for each (let androidEvent in aDetails) {
|
||||
androidEvent.type = 'Accessibility:Event';
|
||||
if (androidEvent.bounds)
|
||||
androidEvent.bounds = this._adjustBounds(androidEvent.bounds, aBrowser, true);
|
||||
androidEvent.bounds = AccessFu.adjustContentBounds(androidEvent.bounds, aBrowser);
|
||||
|
||||
switch(androidEvent.eventType) {
|
||||
case ANDROID_VIEW_TEXT_CHANGED:
|
||||
@ -559,33 +608,6 @@ var Output = {
|
||||
|
||||
Braille: function Braille(aDetails, aBrowser) {
|
||||
Logger.debug('Braille output: ' + aDetails.text);
|
||||
},
|
||||
|
||||
_adjustBounds: function(aJsonBounds, aBrowser, aIncludeZoom) {
|
||||
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
|
||||
aJsonBounds.right - aJsonBounds.left,
|
||||
aJsonBounds.bottom - aJsonBounds.top);
|
||||
let vp = Utils.getViewport(Utils.win) || { zoom: 1.0, offsetY: 0 };
|
||||
let root = Utils.win;
|
||||
let offset = { left: -root.mozInnerScreenX, top: -root.mozInnerScreenY };
|
||||
let scale = 1 / Utils.getPixelsPerCSSPixel(Utils.win);
|
||||
|
||||
if (!aBrowser.contentWindow) {
|
||||
// OOP browser, add offset of browser.
|
||||
// The offset of the browser element in relation to its parent window.
|
||||
let clientRect = aBrowser.getBoundingClientRect();
|
||||
let win = aBrowser.ownerDocument.defaultView;
|
||||
offset.left += clientRect.left + win.mozInnerScreenX;
|
||||
offset.top += clientRect.top + win.mozInnerScreenY;
|
||||
}
|
||||
|
||||
let newBounds = bounds.scale(scale, scale).translate(offset.left, offset.top);
|
||||
|
||||
if (aIncludeZoom) {
|
||||
newBounds = newBounds.scale(vp.zoom, vp.zoom);
|
||||
}
|
||||
|
||||
return newBounds.expandToIntegers();
|
||||
}
|
||||
};
|
||||
|
||||
@ -615,9 +637,6 @@ var Input = {
|
||||
this._handleKeypress(aEvent);
|
||||
break;
|
||||
case 'mozAccessFuGesture':
|
||||
let vp = Utils.getViewport(Utils.win) || { zoom: 1.0 };
|
||||
aEvent.detail.x *= vp.zoom;
|
||||
aEvent.detail.y *= vp.zoom;
|
||||
this._handleGesture(aEvent.detail);
|
||||
break;
|
||||
}
|
||||
@ -796,10 +815,10 @@ var Input = {
|
||||
|
||||
activateContextMenu: function activateContextMenu(aMessage) {
|
||||
if (Utils.MozBuildApp === 'mobile/android') {
|
||||
let vp = Utils.getViewport(Utils.win) || { zoom: 1.0 };
|
||||
let p = AccessFu.adjustContentBounds(aMessage.bounds, Utils.CurrentBrowser,
|
||||
true, true).center();
|
||||
Services.obs.notifyObservers(null, 'Gesture:LongPress',
|
||||
JSON.stringify({x: aMessage.x / vp.zoom,
|
||||
y: aMessage.y / vp.zoom}));
|
||||
JSON.stringify({x: p.x, y: p.y}));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -326,8 +326,8 @@ this.TouchAdapter = {
|
||||
* of one single touch.
|
||||
*/
|
||||
function TouchPoint(aTouch, aTime, aDPI) {
|
||||
this.startX = this.x = aTouch.screenX;
|
||||
this.startY = this.y = aTouch.screenY;
|
||||
this.startX = this.x = aTouch.screenX * this.scaleFactor;
|
||||
this.startY = this.y = aTouch.screenY * this.scaleFactor;
|
||||
this.startTime = aTime;
|
||||
this.distanceTraveled = 0;
|
||||
this.dpi = aDPI;
|
||||
@ -338,8 +338,8 @@ TouchPoint.prototype = {
|
||||
update: function TouchPoint_update(aTouch, aTime) {
|
||||
let lastX = this.x;
|
||||
let lastY = this.y;
|
||||
this.x = aTouch.screenX;
|
||||
this.y = aTouch.screenY;
|
||||
this.x = aTouch.screenX * this.scaleFactor;
|
||||
this.y = aTouch.screenY * this.scaleFactor;
|
||||
this.time = aTime;
|
||||
|
||||
this.distanceTraveled += this.getDistanceToCoord(lastX, lastY);
|
||||
@ -349,6 +349,20 @@ TouchPoint.prototype = {
|
||||
return Math.sqrt(Math.pow(this.x - aX, 2) + Math.pow(this.y - aY, 2));
|
||||
},
|
||||
|
||||
get scaleFactor() {
|
||||
if (!this._scaleFactor) {
|
||||
// Android events come with the x, y coordinates affected by the widget
|
||||
// scaling; we restore it to normal here.
|
||||
if (Utils.MozBuildApp == 'mobile/android') {
|
||||
this._scaleFactor = Utils.win.devicePixelRatio;
|
||||
} else {
|
||||
this._scaleFactor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return this._scaleFactor;
|
||||
},
|
||||
|
||||
finish: function TouchPoint_finish() {
|
||||
this.done = true;
|
||||
},
|
||||
|
@ -221,11 +221,6 @@ this.Utils = {
|
||||
return doc.QueryInterface(Ci.nsIAccessibleDocument).virtualCursor;
|
||||
},
|
||||
|
||||
getPixelsPerCSSPixel: function getPixelsPerCSSPixel(aWindow) {
|
||||
return aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils).screenPixelsPerCSSPixel;
|
||||
},
|
||||
|
||||
getBounds: function getBounds(aAccessible) {
|
||||
let objX = {}, objY = {}, objW = {}, objH = {};
|
||||
aAccessible.getBounds(objX, objY, objW, objH);
|
||||
@ -684,4 +679,4 @@ PrefCache.prototype = {
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
};
|
||||
|
@ -97,10 +97,8 @@ function moveToPoint(aMessage) {
|
||||
let rule = TraversalRules[details.rule];
|
||||
|
||||
try {
|
||||
if (!this._ppcp) {
|
||||
this._ppcp = Utils.getPixelsPerCSSPixel(content);
|
||||
}
|
||||
vc.moveToPoint(rule, details.x * this._ppcp, details.y * this._ppcp, true);
|
||||
let dpr = content.devicePixelRatio;
|
||||
vc.moveToPoint(rule, details.x * dpr, details.y * dpr, true);
|
||||
forwardToChild(aMessage, moveToPoint, vc.position);
|
||||
} catch (x) {
|
||||
Logger.logException(x, 'Failed move to point');
|
||||
@ -219,9 +217,7 @@ function activateCurrent(aMessage) {
|
||||
function activateContextMenu(aMessage) {
|
||||
function sendContextMenuCoordinates(aAccessible) {
|
||||
let bounds = Utils.getBounds(aAccessible);
|
||||
sendAsyncMessage('AccessFu:ActivateContextMenu',
|
||||
{ x: bounds.left + bounds.width / 2,
|
||||
y: bounds.top + bounds.height / 2 });
|
||||
sendAsyncMessage('AccessFu:ActivateContextMenu', {bounds: bounds});
|
||||
}
|
||||
|
||||
let position = Utils.getVirtualCursor(content.document).position;
|
||||
|
Loading…
Reference in New Issue
Block a user