mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
Fix input and bounding shapes
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
This commit is contained in:
parent
bdbeafc222
commit
a3a2109c0c
@ -1760,21 +1760,27 @@ meta_window_actor_update_input_region (MetaWindowActor *self,
|
|||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
cairo_region_t *region = NULL;
|
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);
|
region = meta_frame_get_frame_bounds (priv->window->frame);
|
||||||
|
/* client area is in client window coordinates, so translate the
|
||||||
cairo_region_subtract_rectangle (region, client_area);
|
|
||||||
|
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -350,11 +350,43 @@ meta_window_set_input_region (MetaWindow *window,
|
|||||||
meta_compositor_window_shape_changed (window->display->compositor, 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
|
void
|
||||||
meta_window_x11_update_input_region (MetaWindow *window)
|
meta_window_x11_update_input_region (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))
|
||||||
{
|
{
|
||||||
@ -363,17 +395,6 @@ meta_window_x11_update_input_region (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);
|
|
||||||
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,
|
||||||
@ -388,10 +409,10 @@ meta_window_x11_update_input_region (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);
|
||||||
@ -1453,6 +1474,11 @@ meta_window_x11_new (MetaDisplay *display,
|
|||||||
XISelectEvents (display->xdisplay, xwindow, &mask, 1);
|
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 */
|
/* Get rid of any borders */
|
||||||
if (attrs.border_width != 0)
|
if (attrs.border_width != 0)
|
||||||
XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
|
XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user