mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fixing semantics borders on mobile web (flutter/engine#21856)
* logging * fixing positions with wrong a11y borders screenreader-on/mobile browsers * remove logs from the window class * work on unit tests * using reviewer suggestion for translations * compute bounding matrix * compute bounding matrix * addding more comments * reenable failing test case
This commit is contained in:
parent
100491292d
commit
ba15918f8f
@ -851,13 +851,25 @@ class SemanticsObject {
|
||||
hasIdentityTransform &&
|
||||
verticalContainerAdjustment == 0.0 &&
|
||||
horizontalContainerAdjustment == 0.0) {
|
||||
element.style
|
||||
..removeProperty('transform-origin')
|
||||
..removeProperty('transform');
|
||||
if (containerElement != null) {
|
||||
containerElement.style
|
||||
if (isDesktop) {
|
||||
element.style
|
||||
..removeProperty('transform-origin')
|
||||
..removeProperty('transform');
|
||||
} else {
|
||||
element.style
|
||||
..removeProperty('top')
|
||||
..removeProperty('left');
|
||||
}
|
||||
if (containerElement != null) {
|
||||
if (isDesktop) {
|
||||
containerElement.style
|
||||
..removeProperty('transform-origin')
|
||||
..removeProperty('transform');
|
||||
} else {
|
||||
containerElement.style
|
||||
..removeProperty('top')
|
||||
..removeProperty('left');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -882,13 +894,36 @@ class SemanticsObject {
|
||||
}
|
||||
|
||||
if (!effectiveTransformIsIdentity) {
|
||||
element.style
|
||||
..transformOrigin = '0 0 0'
|
||||
..transform = matrix4ToCssTransform(effectiveTransform);
|
||||
if (isDesktop) {
|
||||
element.style
|
||||
..transformOrigin = '0 0 0'
|
||||
..transform = matrix4ToCssTransform(effectiveTransform);
|
||||
} else {
|
||||
// Mobile screen readers observed to have errors while calculating the
|
||||
// semantics focus borders if css `transform` properties are used.
|
||||
// See: https://github.com/flutter/flutter/issues/68225
|
||||
// Therefore we are calculating a bounding rectangle for the
|
||||
// effective transform and use that rectangle to set TLWH css style
|
||||
// properties.
|
||||
// Note: Identity matrix is not using this code path.
|
||||
final ui.Rect rect =
|
||||
computeBoundingRectangleFromMatrix(effectiveTransform, _rect!);
|
||||
element.style
|
||||
..top = '${rect.top}px'
|
||||
..left = '${rect.left}px'
|
||||
..width = '${rect.width}px'
|
||||
..height = '${rect.height}px';
|
||||
}
|
||||
} else {
|
||||
element.style
|
||||
..removeProperty('transform-origin')
|
||||
..removeProperty('transform');
|
||||
if (isDesktop) {
|
||||
element.style
|
||||
..removeProperty('transform-origin')
|
||||
..removeProperty('transform');
|
||||
} else {
|
||||
element.style
|
||||
..removeProperty('top')
|
||||
..removeProperty('left');
|
||||
}
|
||||
}
|
||||
|
||||
if (containerElement != null) {
|
||||
@ -897,13 +932,25 @@ class SemanticsObject {
|
||||
horizontalContainerAdjustment != 0.0) {
|
||||
final double translateX = -_rect!.left + horizontalContainerAdjustment;
|
||||
final double translateY = -_rect!.top + verticalContainerAdjustment;
|
||||
containerElement.style
|
||||
..transformOrigin = '0 0 0'
|
||||
..transform = 'translate(${translateX}px, ${translateY}px)';
|
||||
if (isDesktop) {
|
||||
containerElement.style
|
||||
..transformOrigin = '0 0 0'
|
||||
..transform = 'translate(${translateX}px, ${translateY}px)';
|
||||
} else {
|
||||
containerElement.style
|
||||
..top = '${translateY}px'
|
||||
..left = '${translateX}px';
|
||||
}
|
||||
} else {
|
||||
containerElement.style
|
||||
..removeProperty('transform-origin')
|
||||
..removeProperty('transform');
|
||||
if (isDesktop) {
|
||||
containerElement.style
|
||||
..removeProperty('transform-origin')
|
||||
..removeProperty('transform');
|
||||
} else {
|
||||
containerElement.style
|
||||
..removeProperty('top')
|
||||
..removeProperty('left');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,3 +596,47 @@ int clampInt(int value, int min, int max) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
ui.Rect computeBoundingRectangleFromMatrix(Matrix4 transform, ui.Rect rect) {
|
||||
final Float32List m = transform.storage;
|
||||
// Apply perspective transform to all 4 corners. Can't use left,top, bottom,
|
||||
// right since for example rotating 45 degrees would yield inaccurate size.
|
||||
double x = rect.left;
|
||||
double y = rect.top;
|
||||
double wp = 1.0 / ((m[3] * x) + (m[7] * y) + m[15]);
|
||||
double xp = ((m[0] * x) + (m[4] * y) + m[12]) * wp;
|
||||
double yp = ((m[1] * x) + (m[5] * y) + m[13]) * wp;
|
||||
double minX = xp, maxX = xp;
|
||||
double minY =yp, maxY = yp;
|
||||
x = rect.right;
|
||||
y = rect.bottom;
|
||||
wp = 1.0 / ((m[3] * x) + (m[7] * y) + m[15]);
|
||||
xp = ((m[0] * x) + (m[4] * y) + m[12]) * wp;
|
||||
yp = ((m[1] * x) + (m[5] * y) + m[13]) * wp;
|
||||
|
||||
minX = math.min(minX, xp);
|
||||
maxX = math.max(maxX, xp);
|
||||
minY = math.min(minY, yp);
|
||||
maxY = math.max(maxY, yp);
|
||||
|
||||
x = rect.left;
|
||||
y = rect.bottom;
|
||||
wp = 1.0 / ((m[3] * x) + (m[7] * y) + m[15]);
|
||||
xp = ((m[0] * x) + (m[4] * y) + m[12]) * wp;
|
||||
yp = ((m[1] * x) + (m[5] * y) + m[13]) * wp;
|
||||
minX = math.min(minX, xp);
|
||||
maxX = math.max(maxX, xp);
|
||||
minY = math.min(minY, yp);
|
||||
maxY = math.max(maxY, yp);
|
||||
|
||||
x = rect.right;
|
||||
y = rect.top;
|
||||
wp = 1.0 / ((m[3] * x) + (m[7] * y) + m[15]);
|
||||
xp = ((m[0] * x) + (m[4] * y) + m[12]) * wp;
|
||||
yp = ((m[1] * x) + (m[5] * y) + m[13]) * wp;
|
||||
minX = math.min(minX, xp);
|
||||
maxX = math.max(maxX, xp);
|
||||
minY = math.min(minY, yp);
|
||||
maxY = math.max(maxY, yp);
|
||||
return ui.Rect.fromLTWH(minX, minY, maxX-minX, maxY-minY);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user