summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2014-02-25 01:06:26 +0100
committerGiovanni Campagna <gcampagna@src.gnome.org>2014-02-25 01:16:13 +0100
commita3a2109c0ca1b5ac1e52127ae6132c74abe66842 (patch)
tree94ac95bd3eb3e7c3752114e564556616c02295d1
parentbdbeafc222fa8a122853be9c0c0c0f3c81db2a08 (diff)
downloadmutter-wip/surface-two.tar.gz
Fix input and bounding shapeswip/surface-two
1) We need to select for shape events 2) For decorated windows, we don't want to apply any input shape, because the frame is always rectangular and eats all the input 3) 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.c22
-rw-r--r--src/core/window-x11.c56
2 files changed, 55 insertions, 23 deletions
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index fe29a790d..c4bf87977 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1760,21 +1760,27 @@ meta_window_actor_update_input_region (MetaWindowActor *self,
MetaWindowActorPrivate *priv = self->priv;
cairo_region_t *region = NULL;
- 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-x11.c b/src/core/window-x11.c
index e43f4c040..00c7fafd9 100644
--- a/src/core/window-x11.c
+++ b/src/core/window-x11.c
@@ -350,11 +350,43 @@ meta_window_set_input_region (MetaWindow *window,
meta_compositor_window_shape_changed (window->display->compositor, window);
}
+#if 0
+/* Print out a region; useful for debugging */
+static void
+print_region (cairo_region_t *region)
+{
+ int n_rects;
+ int i;
+
+ n_rects = cairo_region_num_rectangles (region);
+ g_print ("[");
+ for (i = 0; i < n_rects; i++)
+ {
+ cairo_rectangle_int_t rect;
+ cairo_region_get_rectangle (region, i, &rect);
+ g_print ("+%d+%dx%dx%d ",
+ rect.x, rect.y, rect.width, rect.height);
+ }
+ g_print ("]\n");
+}
+#endif
+
void
meta_window_x11_update_input_region (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))
{
@@ -363,17 +395,6 @@ meta_window_x11_update_input_region (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,
@@ -388,10 +409,10 @@ meta_window_x11_update_input_region (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);
@@ -1453,6 +1474,11 @@ meta_window_x11_new (MetaDisplay *display,
XISelectEvents (display->xdisplay, xwindow, &mask, 1);
}
+#ifdef HAVE_SHAPE
+ if (META_DISPLAY_HAS_SHAPE (display))
+ XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask);
+#endif
+
/* Get rid of any borders */
if (attrs.border_width != 0)
XSetWindowBorderWidth (display->xdisplay, xwindow, 0);