summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2014-02-25 01:22:36 +0100
committerJasper St. Pierre <jstpierre@mecheye.net>2014-02-26 19:57:41 -0500
commit36009cbae1b6a0e02f271190d706e99490ee1838 (patch)
tree13d67c9e3753e9b5dce61035691412c17de4dce7
parent21f9bf530d3fca83f72c5bb3d63a3d38ac0ccdc2 (diff)
downloadmutter-36009cbae1b6a0e02f271190d706e99490ee1838.tar.gz
Fix input and bounding shapes
For decorated windows, we don't want to apply any input shape, because the frame is always rectangular and eats all the input. The real check is in meta-window-actor, where we consider if we need to apply the bounding shape and the input shape (or the intersection of the two) to the surface-actor, but as an optimization we avoid querying the server in meta-window. Additionally, for undecorated windows, the "has input shape" check is wrong if the window has a bounding shape but not an input shape.
-rw-r--r--src/compositor/meta-window-actor.c21
-rw-r--r--src/core/window.c29
2 files changed, 29 insertions, 21 deletions
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index b3f8d9e0f..67935456d 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -2015,21 +2015,28 @@ meta_window_actor_update_input_region (MetaWindowActor *self)
meta_window_get_client_area_rect (priv->window, &client_area);
- if (priv->window->frame != NULL && priv->window->input_region != NULL)
+ if (priv->window->frame != NULL)
{
region = meta_frame_get_frame_bounds (priv->window->frame);
- cairo_region_subtract_rectangle (region, &client_area);
-
- /* input_region is in client window coordinates, so translate the
+ /* client area is in client window coordinates, so translate the
* input region into that coordinate system and back */
cairo_region_translate (region, -client_area.x, -client_area.y);
- cairo_region_union (region, priv->window->input_region);
+ cairo_region_union_rectangle (region, &client_area);
cairo_region_translate (region, client_area.x, client_area.y);
}
- else if (priv->window->input_region != NULL)
+ else if (priv->window->shape_region != NULL ||
+ priv->window->input_region != NULL)
{
- region = cairo_region_reference (priv->window->input_region);
+ if (priv->window->shape_region != NULL)
+ {
+ region = cairo_region_copy (priv->window->shape_region);
+
+ if (priv->window->input_region != NULL)
+ cairo_region_intersect (region, priv->window->input_region);
+ }
+ else
+ region = cairo_region_reference (priv->window->input_region);
}
else
{
diff --git a/src/core/window.c b/src/core/window.c
index 5e47bd3ee..1a35a1910 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -7771,6 +7771,17 @@ meta_window_update_input_region_x11 (MetaWindow *window)
{
cairo_region_t *region = NULL;
+ /* Decorated windows don't have an input region, because
+ we don't shape the frame to match the client windows
+ (so the events are blocked by the frame anyway)
+ */
+ if (window->decorated)
+ {
+ if (window->input_region)
+ meta_window_set_input_region (window, NULL);
+ return;
+ }
+
#ifdef HAVE_SHAPE
if (META_DISPLAY_HAS_SHAPE (window->display))
{
@@ -7779,17 +7790,7 @@ meta_window_update_input_region_x11 (MetaWindow *window)
XRectangle *rects = NULL;
int n_rects, ordering;
- int x_bounding, y_bounding, x_clip, y_clip;
- unsigned w_bounding, h_bounding, w_clip, h_clip;
- int bounding_shaped, clip_shaped;
-
meta_error_trap_push (window->display);
- XShapeQueryExtents (window->display->xdisplay, window->xwindow,
- &bounding_shaped, &x_bounding, &y_bounding,
- &w_bounding, &h_bounding,
- &clip_shaped, &x_clip, &y_clip,
- &w_clip, &h_clip);
-
rects = XShapeGetRectangles (window->display->xdisplay,
window->xwindow,
ShapeInput,
@@ -7804,10 +7805,10 @@ meta_window_update_input_region_x11 (MetaWindow *window)
{
if (n_rects > 1 ||
(n_rects == 1 &&
- (rects[0].x != x_bounding ||
- rects[0].y != y_bounding ||
- rects[0].width != w_bounding ||
- rects[0].height != h_bounding)))
+ (rects[0].x != 0 ||
+ rects[0].y != 0 ||
+ rects[0].width != window->rect.width ||
+ rects[0].height != window->rect.height)))
region = region_create_from_x_rectangles (rects, n_rects);
XFree (rects);