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.
This commit is contained in:
Giovanni Campagna 2014-02-25 01:22:36 +01:00 committed by Jasper St. Pierre
parent 21f9bf530d
commit 36009cbae1
2 changed files with 29 additions and 21 deletions

View File

@ -2015,20 +2015,27 @@ meta_window_actor_update_input_region (MetaWindowActor *self)
meta_window_get_client_area_rect (priv->window, &client_area); 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); region = meta_frame_get_frame_bounds (priv->window->frame);
cairo_region_subtract_rectangle (region, &client_area); /* client area is in client window coordinates, so translate the
/* input_region is in client window coordinates, so translate the
* input region into that coordinate system and back */ * input region into that coordinate system and back */
cairo_region_translate (region, -client_area.x, -client_area.y); 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); 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)
{ {
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); region = cairo_region_reference (priv->window->input_region);
} }
else else

View File

@ -7771,6 +7771,17 @@ meta_window_update_input_region_x11 (MetaWindow *window)
{ {
cairo_region_t *region = NULL; 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 #ifdef HAVE_SHAPE
if (META_DISPLAY_HAS_SHAPE (window->display)) if (META_DISPLAY_HAS_SHAPE (window->display))
{ {
@ -7779,17 +7790,7 @@ meta_window_update_input_region_x11 (MetaWindow *window)
XRectangle *rects = NULL; XRectangle *rects = NULL;
int n_rects, ordering; 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); 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, rects = XShapeGetRectangles (window->display->xdisplay,
window->xwindow, window->xwindow,
ShapeInput, ShapeInput,
@ -7804,10 +7805,10 @@ meta_window_update_input_region_x11 (MetaWindow *window)
{ {
if (n_rects > 1 || if (n_rects > 1 ||
(n_rects == 1 && (n_rects == 1 &&
(rects[0].x != x_bounding || (rects[0].x != 0 ||
rects[0].y != y_bounding || rects[0].y != 0 ||
rects[0].width != w_bounding || rects[0].width != window->rect.width ||
rects[0].height != h_bounding))) rects[0].height != window->rect.height)))
region = region_create_from_x_rectangles (rects, n_rects); region = region_create_from_x_rectangles (rects, n_rects);
XFree (rects); XFree (rects);