summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2018-12-05 07:27:23 -0800
committer Vishnu Nair <vishnun@google.com> 2018-12-05 07:27:23 -0800
commit8033a496f29ed76c361822e0d2f11beaea22a27b (patch)
tree4f76ff7863785c76501e79847fcecf55e7e86f62
parent5118e8d029e5e03e8fda19334ba50a356dc0ca72 (diff)
Input: Handle parent surface crops 1/2
- Surface Insets are set to offset the client content and draw a border around the client surface (such as shadows in dialogs). Inputs sent to the client are offset such that 0,0 is the start of the client content. When accounting for surface insets, check if the surface is already cropped by a parent so that the input offset is not set twice. - Restrict the touchable region to the input frame bounds. Test: Open event in calendar. Try to close the event. The event is a dialog and draws shadows. Test: Open app selector in secondary split screen. Ensure input does not go to primary split screen window. Bug: 120413463, 120460606 Change-Id: I0d519f9eb381664b1e71a924b13419dcc1170ba1
-rw-r--r--libs/ui/Rect.cpp8
-rw-r--r--libs/ui/include/ui/Rect.h7
-rw-r--r--services/surfaceflinger/Layer.cpp27
3 files changed, 34 insertions, 8 deletions
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
index d8702e5755..045db31087 100644
--- a/libs/ui/Rect.cpp
+++ b/libs/ui/Rect.cpp
@@ -72,6 +72,14 @@ Rect& Rect::offsetBy(int32_t x, int32_t y) {
return *this;
}
+Rect& Rect::inset(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ this->left += left;
+ this->top += top;
+ this->right -= right;
+ this->bottom -= bottom;
+ return *this;
+}
+
const Rect Rect::operator +(const Point& rhs) const {
const Rect result(left + rhs.x, top + rhs.y, right + rhs.x, bottom + rhs.y);
return result;
diff --git a/libs/ui/include/ui/Rect.h b/libs/ui/include/ui/Rect.h
index 0bec0b7f78..9edb510ee9 100644
--- a/libs/ui/include/ui/Rect.h
+++ b/libs/ui/include/ui/Rect.h
@@ -120,7 +120,7 @@ public:
right = rb.x;
bottom = rb.y;
}
-
+
// the following 4 functions return the 4 corners of the rect as Point
Point leftTop() const {
return Point(left, top);
@@ -175,6 +175,11 @@ public:
Rect& offsetTo(int32_t x, int32_t y);
Rect& offsetBy(int32_t x, int32_t y);
+ /**
+ * Insets the rectangle on all sides specified by the insets.
+ */
+ Rect& inset(int32_t left, int32_t top, int32_t right, int32_t bottom);
+
bool intersect(const Rect& with, Rect* result) const;
// Create a new Rect by transforming this one using a graphics HAL
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 15e416ac2a..f53ffae570 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2121,10 +2121,6 @@ bool Layer::isRemovedFromCurrentState() const {
InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
InputWindowInfo info = mDrawingState.inputInfo;
- info.frameLeft = screenBounds.left + info.surfaceInset;
- info.frameTop = screenBounds.top + info.surfaceInset;
- info.frameRight = screenBounds.right - info.surfaceInset;
- info.frameBottom = screenBounds.bottom - info.surfaceInset;
ui::Transform t = getTransform();
const float xScale = t.sx();
@@ -2135,9 +2131,26 @@ InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
info.touchableRegion.scaleSelf(xScale, yScale);
}
- info.touchableRegion = info.touchableRegion.translate(
- screenBounds.left,
- screenBounds.top);
+ // Transform layer size to screen space and inset it by surface insets.
+ Rect layerBounds = getCroppedBufferSize(getDrawingState());
+ layerBounds = t.transform(layerBounds);
+ layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset);
+
+ // Intersect with screen bounds to shrink the frame by the surface insets. The surface insets
+ // are not set on the screen bounds directly since the surface inset region may already be
+ // cropped by a parent layer.
+ Rect frame;
+ screenBounds.intersect(layerBounds, &frame);
+
+ info.frameLeft = frame.left;
+ info.frameTop = frame.top;
+ info.frameRight = frame.right;
+ info.frameBottom = frame.bottom;
+
+ // Position the touchable region relative to frame screen location and restrict it to frame
+ // bounds.
+ info.touchableRegion = info.touchableRegion.translate(info.frameLeft, info.frameTop);
+ info.touchableRegion = info.touchableRegion.intersect(frame);
info.visible = isVisible();
return info;
}