Improve Counter-Zoom Handling for Context Views (#149958)

* fixes #149957

* fixes #149741

* use const

* use const
This commit is contained in:
SteVen Batten 2022-05-19 11:20:48 -07:00 committed by GitHub
parent 3f27a6103b
commit 85bf8af5b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 14 deletions

View file

@ -577,6 +577,24 @@ export function getDomNodePagePosition(domNode: HTMLElement): IDomNodePagePositi
};
}
/**
* Returns the effective zoom on a given element before window zoom level is applied
*/
export function getDomNodeZoomLevel(domNode: HTMLElement): number {
let testElement: HTMLElement | null = domNode;
let zoom = 1.0;
do {
const elementZoomLevel = (getComputedStyle(testElement) as any).zoom;
if (elementZoomLevel !== null && elementZoomLevel !== undefined && elementZoomLevel !== '1') {
zoom *= elementZoomLevel;
}
testElement = testElement.parentElement;
} while (testElement !== null && testElement !== document.documentElement);
return zoom;
}
export interface IStandardWindow {
readonly scrollX: number;
readonly scrollY: number;

View file

@ -262,11 +262,16 @@ export class ContextView extends Disposable {
if (DOM.isHTMLElement(anchor)) {
let elementPosition = DOM.getDomNodePagePosition(anchor);
// In areas where zoom is applied to the element or its ancestors, we need to adjust the size of the element
// e.g. The title bar has counter zoom behavior meaning it applies the inverse of zoom level.
// Window Zoom Level: 1.5, Title Bar Zoom: 1/1.5, Size Multiplier: 1.5
const zoom = DOM.getDomNodeZoomLevel(anchor);
around = {
top: elementPosition.top,
left: elementPosition.left,
width: elementPosition.width,
height: elementPosition.height
top: elementPosition.top * zoom,
left: elementPosition.left * zoom,
width: elementPosition.width * zoom,
height: elementPosition.height * zoom
};
} else {
around = {

View file

@ -105,15 +105,7 @@ class NativeContextMenuService extends Disposable implements IContextMenuService
// In areas where zoom is applied to the element or its ancestors, we need to adjust accordingly
// e.g. The title bar has counter zoom behavior meaning it applies the inverse of zoom level.
// Window Zoom Level: 1.5, Title Bar Zoom: 1/1.5, Coordinate Multiplier: 1.5 * 1.0 / 1.5 = 1.0
let testElement: HTMLElement | null = anchor;
do {
const elementZoomLevel = (dom.getComputedStyle(testElement) as any).zoom;
if (elementZoomLevel !== null && elementZoomLevel !== undefined && elementZoomLevel !== '1') {
zoom *= elementZoomLevel;
}
testElement = testElement.parentElement;
} while (testElement !== null && testElement !== document.documentElement);
zoom *= dom.getDomNodeZoomLevel(anchor);
x = elementPosition.left;
y = elementPosition.top + elementPosition.height;

View file

@ -230,7 +230,19 @@ export class HoverWidget extends Widget {
this._hover.containerDomNode.classList.remove('right-aligned');
this._hover.contentsDomNode.style.maxHeight = '';
const targetBounds = this._target.targetElements.map(e => e.getBoundingClientRect());
const getZoomAccountedBoundingClientRect = (e: HTMLElement) => {
const zoom = dom.getDomNodeZoomLevel(e);
const boundingRect = e.getBoundingClientRect();
return {
top: boundingRect.top * zoom,
bottom: boundingRect.bottom * zoom,
right: boundingRect.right * zoom,
left: boundingRect.left * zoom,
};
};
const targetBounds = this._target.targetElements.map(e => getZoomAccountedBoundingClientRect(e));
const top = Math.min(...targetBounds.map(e => e.top));
const right = Math.max(...targetBounds.map(e => e.right));
const bottom = Math.max(...targetBounds.map(e => e.bottom));