mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 13:24:09 +00:00
handle the client having a shape mask, fixes #101806
2003-01-05 Havoc Pennington <hp@pobox.com> * src/frames.c (meta_frames_apply_shapes): handle the client having a shape mask, fixes #101806 * src/core.c (meta_core_get_client_xwindow): new function * src/frame.c, src/frame.h: keep a flag for whether we need to update the frame shape * src/window.c (meta_window_new): select for ShapeNotify * src/display.h, src/display.c: actually query the shape extension, instead of just using it all over the place. * src/prefs.c (update_application_based): don't let people turn on application_based, as it just causes funky bugs. We can reenable the pref when/if it ever does something useful.
This commit is contained in:
parent
f8b2f6ca5c
commit
6cfcc01334
19
ChangeLog
19
ChangeLog
@ -1,3 +1,22 @@
|
|||||||
|
2003-01-05 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
* src/frames.c (meta_frames_apply_shapes): handle
|
||||||
|
the client having a shape mask, fixes #101806
|
||||||
|
|
||||||
|
* src/core.c (meta_core_get_client_xwindow): new function
|
||||||
|
|
||||||
|
* src/frame.c, src/frame.h: keep a flag for whether we need to
|
||||||
|
update the frame shape
|
||||||
|
|
||||||
|
* src/window.c (meta_window_new): select for ShapeNotify
|
||||||
|
|
||||||
|
* src/display.h, src/display.c: actually query the shape
|
||||||
|
extension, instead of just using it all over the place.
|
||||||
|
|
||||||
|
* src/prefs.c (update_application_based): don't let people turn on
|
||||||
|
application_based, as it just causes funky bugs. We can reenable
|
||||||
|
the pref when/if it ever does something useful.
|
||||||
|
|
||||||
2003-01-03 Havoc Pennington <hp@redhat.com>
|
2003-01-03 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* src/display.c: include the Xrandr header file
|
* src/display.c: include the Xrandr header file
|
||||||
|
16
src/core.c
16
src/core.c
@ -46,6 +46,22 @@ meta_core_get_client_size (Display *xdisplay,
|
|||||||
*height = window->rect.height;
|
*height = window->rect.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window
|
||||||
|
meta_core_get_client_xwindow (Display *xdisplay,
|
||||||
|
Window frame_xwindow)
|
||||||
|
{
|
||||||
|
MetaDisplay *display;
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
display = meta_display_for_x_display (xdisplay);
|
||||||
|
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||||
|
|
||||||
|
if (window == NULL || window->frame == NULL)
|
||||||
|
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||||
|
|
||||||
|
return window->xwindow;
|
||||||
|
}
|
||||||
|
|
||||||
MetaFrameFlags
|
MetaFrameFlags
|
||||||
meta_core_get_frame_flags (Display *xdisplay,
|
meta_core_get_frame_flags (Display *xdisplay,
|
||||||
Window frame_xwindow)
|
Window frame_xwindow)
|
||||||
|
@ -31,6 +31,9 @@ void meta_core_get_client_size (Display *xdisplay,
|
|||||||
int *width,
|
int *width,
|
||||||
int *height);
|
int *height);
|
||||||
|
|
||||||
|
Window meta_core_get_client_xwindow (Display *xdisplay,
|
||||||
|
Window frame_xwindow);
|
||||||
|
|
||||||
MetaFrameFlags meta_core_get_frame_flags (Display *xdisplay,
|
MetaFrameFlags meta_core_get_frame_flags (Display *xdisplay,
|
||||||
Window frame_xwindow);
|
Window frame_xwindow);
|
||||||
MetaFrameType meta_core_get_frame_type (Display *xdisplay,
|
MetaFrameType meta_core_get_frame_type (Display *xdisplay,
|
||||||
|
120
src/display.c
120
src/display.c
@ -45,6 +45,9 @@
|
|||||||
#ifdef HAVE_RANDR
|
#ifdef HAVE_RANDR
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define USE_GDK_DISPLAY
|
#define USE_GDK_DISPLAY
|
||||||
@ -489,6 +492,27 @@ meta_display_open (const char *name)
|
|||||||
#else /* HAVE_XSYNC */
|
#else /* HAVE_XSYNC */
|
||||||
meta_verbose ("Not compiled with Xsync support\n");
|
meta_verbose ("Not compiled with Xsync support\n");
|
||||||
#endif /* !HAVE_XSYNC */
|
#endif /* !HAVE_XSYNC */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
{
|
||||||
|
display->shape_error_base = 0;
|
||||||
|
display->shape_event_base = 0;
|
||||||
|
|
||||||
|
if (!XShapeQueryExtension (display->xdisplay,
|
||||||
|
&display->shape_event_base,
|
||||||
|
&display->shape_error_base))
|
||||||
|
{
|
||||||
|
display->shape_error_base = 0;
|
||||||
|
display->shape_event_base = 0;
|
||||||
|
}
|
||||||
|
meta_verbose ("Attempted to init Shape, found error base %d event base %d\n",
|
||||||
|
display->shape_error_base,
|
||||||
|
display->shape_event_base);
|
||||||
|
}
|
||||||
|
#else /* HAVE_SHAPE */
|
||||||
|
meta_verbose ("Not compiled with Shape support\n");
|
||||||
|
#endif /* !HAVE_SHAPE */
|
||||||
|
|
||||||
screens = NULL;
|
screens = NULL;
|
||||||
|
|
||||||
@ -1189,6 +1213,56 @@ event_callback (XEvent *event,
|
|||||||
meta_window_handle_mouse_grab_op_event (display->grab_window, event);
|
meta_window_handle_mouse_grab_op_event (display->grab_window, event);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_XSYNC */
|
#endif /* HAVE_XSYNC */
|
||||||
|
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
if (META_DISPLAY_HAS_SHAPE (display) &&
|
||||||
|
event->type == (display->shape_event_base + ShapeNotify))
|
||||||
|
{
|
||||||
|
filter_out_event = TRUE; /* GTK doesn't want to see this really */
|
||||||
|
|
||||||
|
if (window && !frame_was_receiver)
|
||||||
|
{
|
||||||
|
XShapeEvent *sev = (XShapeEvent*) event;
|
||||||
|
|
||||||
|
if (sev->kind == ShapeBounding)
|
||||||
|
{
|
||||||
|
if (sev->shaped && !window->has_shape)
|
||||||
|
{
|
||||||
|
window->has_shape = TRUE;
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Window %s now has a shape\n",
|
||||||
|
window->desc);
|
||||||
|
}
|
||||||
|
else if (!sev->shaped && window->has_shape)
|
||||||
|
{
|
||||||
|
window->has_shape = FALSE;
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Window %s no longer has a shape\n",
|
||||||
|
window->desc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Window %s shape changed\n",
|
||||||
|
window->desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->frame)
|
||||||
|
{
|
||||||
|
window->frame->need_reapply_frame_shape = TRUE;
|
||||||
|
meta_window_queue_move_resize (window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n",
|
||||||
|
window ? window->desc : "(none)",
|
||||||
|
frame_was_receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SHAPE */
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
@ -1902,6 +1976,15 @@ event_get_modified_window (MetaDisplay *display,
|
|||||||
return None;
|
return None;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
if (META_DISPLAY_HAS_SHAPE (display) &&
|
||||||
|
event->type == (display->shape_event_base + ShapeNotify))
|
||||||
|
{
|
||||||
|
XShapeEvent *sev = (XShapeEvent*) event;
|
||||||
|
return sev->window;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2360,6 +2443,27 @@ meta_spew_event (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* HAVE_XSYNC */
|
#endif /* HAVE_XSYNC */
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
if (META_DISPLAY_HAS_SHAPE (display) &&
|
||||||
|
event->type == (display->shape_event_base + ShapeNotify))
|
||||||
|
{
|
||||||
|
XShapeEvent *sev = (XShapeEvent*) event;
|
||||||
|
|
||||||
|
name = "ShapeNotify";
|
||||||
|
|
||||||
|
extra =
|
||||||
|
g_strdup_printf ("kind: %s "
|
||||||
|
"x: %d y: %d w: %d h: %d "
|
||||||
|
"shaped: %d",
|
||||||
|
sev->kind == ShapeBounding ?
|
||||||
|
"ShapeBounding" :
|
||||||
|
(sev->kind == ShapeClip ?
|
||||||
|
"ShapeClip" : "(unknown)"),
|
||||||
|
sev->x, sev->y, sev->width, sev->height,
|
||||||
|
sev->shaped);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* HAVE_SHAPE */
|
||||||
{
|
{
|
||||||
name = "(Unknown event)";
|
name = "(Unknown event)";
|
||||||
extra = g_strdup_printf ("type: %d", event->xany.type);
|
extra = g_strdup_printf ("type: %d", event->xany.type);
|
||||||
@ -3046,20 +3150,10 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
|
|||||||
meta_window_queue_move_resize (window);
|
meta_window_queue_move_resize (window);
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
|
window->frame->need_reapply_frame_shape = TRUE;
|
||||||
|
|
||||||
meta_frame_queue_draw (window->frame);
|
meta_frame_queue_draw (window->frame);
|
||||||
|
}
|
||||||
/* FIXME this sucks and is slooooooooow. Do it in the idle with the
|
|
||||||
* redraw or the window resize.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* in case the theme doesn't affect the frame size */
|
|
||||||
meta_ui_apply_frame_shape (window->screen->ui,
|
|
||||||
window->frame->xwindow,
|
|
||||||
window->frame->rect.width,
|
|
||||||
window->frame->rect.height);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
@ -296,6 +296,13 @@ struct _MetaDisplay
|
|||||||
#else
|
#else
|
||||||
#define META_DISPLAY_HAS_XSYNC(display) FALSE
|
#define META_DISPLAY_HAS_XSYNC(display) FALSE
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
int shape_event_base;
|
||||||
|
int shape_error_base;
|
||||||
|
#define META_DISPLAY_HAS_SHAPE(display) ((display)->shape_event_base != 0)
|
||||||
|
#else
|
||||||
|
#define META_DISPLAY_HAS_SHAPE(display) FALSE
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean meta_display_open (const char *name);
|
gboolean meta_display_open (const char *name);
|
||||||
|
47
src/frame.c
47
src/frame.c
@ -58,6 +58,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
frame->current_cursor = 0;
|
frame->current_cursor = 0;
|
||||||
|
|
||||||
frame->mapped = FALSE;
|
frame->mapped = FALSE;
|
||||||
|
frame->need_reapply_frame_shape = TRUE;
|
||||||
|
|
||||||
attrs.event_mask = EVENT_MASK;
|
attrs.event_mask = EVENT_MASK;
|
||||||
|
|
||||||
@ -144,7 +145,9 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
||||||
frame->xwindow,
|
frame->xwindow,
|
||||||
frame->rect.width,
|
frame->rect.width,
|
||||||
frame->rect.height);
|
frame->rect.height,
|
||||||
|
frame->window->has_shape);
|
||||||
|
frame->need_reapply_frame_shape = FALSE;
|
||||||
|
|
||||||
meta_display_ungrab (window->display);
|
meta_display_ungrab (window->display);
|
||||||
}
|
}
|
||||||
@ -277,6 +280,20 @@ meta_frame_calc_geometry (MetaFrame *frame,
|
|||||||
*geomp = geom;
|
*geomp = geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_shape (MetaFrame *frame)
|
||||||
|
{
|
||||||
|
if (frame->need_reapply_frame_shape)
|
||||||
|
{
|
||||||
|
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
||||||
|
frame->xwindow,
|
||||||
|
frame->rect.width,
|
||||||
|
frame->rect.height,
|
||||||
|
frame->window->has_shape);
|
||||||
|
frame->need_reapply_frame_shape = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_frame_sync_to_window (MetaFrame *frame,
|
meta_frame_sync_to_window (MetaFrame *frame,
|
||||||
int resize_gravity,
|
int resize_gravity,
|
||||||
@ -284,8 +301,11 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
|||||||
gboolean need_resize)
|
gboolean need_resize)
|
||||||
{
|
{
|
||||||
if (!(need_move || need_resize))
|
if (!(need_move || need_resize))
|
||||||
return;
|
{
|
||||||
|
update_shape (frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
"Syncing frame geometry %d,%d %dx%d (SE: %d,%d)\n",
|
"Syncing frame geometry %d,%d %dx%d (SE: %d,%d)\n",
|
||||||
frame->rect.x, frame->rect.y,
|
frame->rect.x, frame->rect.y,
|
||||||
@ -301,18 +321,17 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
|||||||
frame->rect.width,
|
frame->rect.width,
|
||||||
frame->rect.height);
|
frame->rect.height);
|
||||||
|
|
||||||
/* Done before the window resize, because doing it before means
|
/* we need new shape if we're resized */
|
||||||
* part of the window being resized becomes unshaped, which may
|
frame->need_reapply_frame_shape = TRUE;
|
||||||
* be sort of hard to see with bg = None. If we did it after
|
|
||||||
* window resize, part of the window being resized would become
|
|
||||||
* shaped, which might be more visible.
|
|
||||||
*/
|
|
||||||
|
|
||||||
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
|
||||||
frame->xwindow,
|
|
||||||
frame->rect.width,
|
|
||||||
frame->rect.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Done before the window resize, because doing it before means
|
||||||
|
* part of the window being resized becomes unshaped, which may
|
||||||
|
* be sort of hard to see with bg = None. If we did it after
|
||||||
|
* window resize, part of the window being resized would become
|
||||||
|
* shaped, which might be more visible.
|
||||||
|
*/
|
||||||
|
update_shape (frame);
|
||||||
|
|
||||||
if (need_move && need_resize)
|
if (need_move && need_resize)
|
||||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||||
|
@ -57,6 +57,7 @@ struct _MetaFrame
|
|||||||
int bottom_height;
|
int bottom_height;
|
||||||
|
|
||||||
guint mapped : 1;
|
guint mapped : 1;
|
||||||
|
guint need_reapply_frame_shape : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_window_ensure_frame (MetaWindow *window);
|
void meta_window_ensure_frame (MetaWindow *window);
|
||||||
|
118
src/frames.c
118
src/frames.c
@ -495,6 +495,7 @@ meta_frames_manage_window (MetaFrames *frames,
|
|||||||
frame->text_height = -1;
|
frame->text_height = -1;
|
||||||
frame->title = NULL;
|
frame->title = NULL;
|
||||||
frame->expose_delayed = FALSE;
|
frame->expose_delayed = FALSE;
|
||||||
|
frame->shape_applied = FALSE;
|
||||||
frame->prelit_control = META_FRAME_CONTROL_NONE;
|
frame->prelit_control = META_FRAME_CONTROL_NONE;
|
||||||
|
|
||||||
meta_core_grab_buttons (gdk_display, frame->xwindow);
|
meta_core_grab_buttons (gdk_display, frame->xwindow);
|
||||||
@ -664,7 +665,8 @@ void
|
|||||||
meta_frames_apply_shapes (MetaFrames *frames,
|
meta_frames_apply_shapes (MetaFrames *frames,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
int new_window_width,
|
int new_window_width,
|
||||||
int new_window_height)
|
int new_window_height,
|
||||||
|
gboolean window_has_shape)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SHAPE
|
#ifdef HAVE_SHAPE
|
||||||
/* Apply shapes as if window had new_window_width, new_window_height */
|
/* Apply shapes as if window had new_window_width, new_window_height */
|
||||||
@ -685,10 +687,25 @@ meta_frames_apply_shapes (MetaFrames *frames,
|
|||||||
if (!(fgeom.top_left_corner_rounded ||
|
if (!(fgeom.top_left_corner_rounded ||
|
||||||
fgeom.top_right_corner_rounded ||
|
fgeom.top_right_corner_rounded ||
|
||||||
fgeom.bottom_left_corner_rounded ||
|
fgeom.bottom_left_corner_rounded ||
|
||||||
fgeom.bottom_right_corner_rounded))
|
fgeom.bottom_right_corner_rounded ||
|
||||||
|
window_has_shape))
|
||||||
{
|
{
|
||||||
XShapeCombineMask (gdk_display, frame->xwindow,
|
if (frame->shape_applied)
|
||||||
ShapeBounding, 0, 0, None, ShapeSet);
|
{
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Unsetting shape mask on frame 0x%lx\n",
|
||||||
|
frame->xwindow);
|
||||||
|
|
||||||
|
XShapeCombineMask (gdk_display, frame->xwindow,
|
||||||
|
ShapeBounding, 0, 0, None, ShapeSet);
|
||||||
|
frame->shape_applied = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Frame 0x%lx still doesn't need a shape mask\n",
|
||||||
|
frame->xwindow);
|
||||||
|
}
|
||||||
|
|
||||||
return; /* nothing to do */
|
return; /* nothing to do */
|
||||||
}
|
}
|
||||||
@ -804,11 +821,98 @@ meta_frames_apply_shapes (MetaFrames *frames,
|
|||||||
|
|
||||||
XSubtractRegion (window_xregion, corners_xregion, window_xregion);
|
XSubtractRegion (window_xregion, corners_xregion, window_xregion);
|
||||||
|
|
||||||
XShapeCombineRegion (gdk_display, frame->xwindow,
|
XDestroyRegion (corners_xregion);
|
||||||
ShapeBounding, 0, 0, window_xregion, ShapeSet);
|
|
||||||
|
if (window_has_shape)
|
||||||
|
{
|
||||||
|
/* The client window is oclock or something and has a shape
|
||||||
|
* mask. To avoid a round trip to get its shape region, we
|
||||||
|
* create a fake window that's never mapped, build up our shape
|
||||||
|
* on that, then combine. Wasting the window is assumed cheaper
|
||||||
|
* than a round trip, but who really knows for sure.
|
||||||
|
*/
|
||||||
|
XSetWindowAttributes attrs;
|
||||||
|
Window shape_window;
|
||||||
|
Window client_window;
|
||||||
|
Region client_xregion;
|
||||||
|
GdkScreen *screen;
|
||||||
|
int screen_number;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Frame 0x%lx needs to incorporate client shape\n",
|
||||||
|
frame->xwindow);
|
||||||
|
|
||||||
|
screen = gtk_widget_get_screen (GTK_WIDGET (frames));
|
||||||
|
screen_number = gdk_x11_screen_get_screen_number (screen);
|
||||||
|
|
||||||
|
attrs.override_redirect = True;
|
||||||
|
|
||||||
|
shape_window = XCreateWindow (gdk_display,
|
||||||
|
RootWindow (gdk_display, screen_number),
|
||||||
|
-5000, -5000,
|
||||||
|
new_window_width,
|
||||||
|
new_window_height,
|
||||||
|
0,
|
||||||
|
CopyFromParent,
|
||||||
|
CopyFromParent,
|
||||||
|
CopyFromParent,
|
||||||
|
CWOverrideRedirect,
|
||||||
|
&attrs);
|
||||||
|
|
||||||
|
/* Copy the client's shape to the temporary shape_window */
|
||||||
|
client_window = meta_core_get_client_xwindow (gdk_display,
|
||||||
|
frame->xwindow);
|
||||||
|
|
||||||
|
XShapeCombineShape (gdk_display, shape_window, ShapeBounding,
|
||||||
|
fgeom.left_width,
|
||||||
|
fgeom.top_height,
|
||||||
|
client_window,
|
||||||
|
ShapeBounding,
|
||||||
|
ShapeSet);
|
||||||
|
|
||||||
|
/* Punch the client area out of the normal frame shape,
|
||||||
|
* then union it with the shape_window's existing shape
|
||||||
|
*/
|
||||||
|
client_xregion = XCreateRegion ();
|
||||||
|
|
||||||
|
xrect.x = fgeom.left_width;
|
||||||
|
xrect.y = fgeom.top_height;
|
||||||
|
xrect.width = new_window_width - fgeom.right_width - xrect.x;
|
||||||
|
xrect.height = new_window_height - fgeom.bottom_height - xrect.y;
|
||||||
|
|
||||||
|
XUnionRectWithRegion (&xrect, client_xregion, client_xregion);
|
||||||
|
|
||||||
|
XSubtractRegion (window_xregion, client_xregion, window_xregion);
|
||||||
|
|
||||||
|
XDestroyRegion (client_xregion);
|
||||||
|
|
||||||
|
XShapeCombineRegion (gdk_display, shape_window,
|
||||||
|
ShapeBounding, 0, 0, window_xregion, ShapeUnion);
|
||||||
|
|
||||||
|
/* Now copy shape_window shape to the real frame */
|
||||||
|
XShapeCombineShape (gdk_display, frame->xwindow, ShapeBounding,
|
||||||
|
0, 0,
|
||||||
|
shape_window,
|
||||||
|
ShapeBounding,
|
||||||
|
ShapeSet);
|
||||||
|
|
||||||
|
XDestroyWindow (gdk_display, shape_window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No shape on the client, so just do simple stuff */
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Frame 0x%lx has shaped corners\n",
|
||||||
|
frame->xwindow);
|
||||||
|
|
||||||
|
XShapeCombineRegion (gdk_display, frame->xwindow,
|
||||||
|
ShapeBounding, 0, 0, window_xregion, ShapeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->shape_applied = TRUE;
|
||||||
|
|
||||||
XDestroyRegion (window_xregion);
|
XDestroyRegion (window_xregion);
|
||||||
XDestroyRegion (corners_xregion);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,8 @@ struct _MetaUIFrame
|
|||||||
int text_height;
|
int text_height;
|
||||||
char *title; /* NULL once we have a layout */
|
char *title; /* NULL once we have a layout */
|
||||||
guint expose_delayed : 1;
|
guint expose_delayed : 1;
|
||||||
|
guint shape_applied : 1;
|
||||||
|
|
||||||
/* FIXME get rid of this, it can just be in the MetaFrames struct */
|
/* FIXME get rid of this, it can just be in the MetaFrames struct */
|
||||||
MetaFrameControl prelit_control;
|
MetaFrameControl prelit_control;
|
||||||
};
|
};
|
||||||
@ -127,7 +128,8 @@ void meta_frames_unflicker_bg (MetaFrames *frames,
|
|||||||
void meta_frames_apply_shapes (MetaFrames *frames,
|
void meta_frames_apply_shapes (MetaFrames *frames,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
int new_window_width,
|
int new_window_width,
|
||||||
int new_window_height);
|
int new_window_height,
|
||||||
|
gboolean window_has_shape);
|
||||||
|
|
||||||
void meta_frames_queue_draw (MetaFrames *frames,
|
void meta_frames_queue_draw (MetaFrames *frames,
|
||||||
Window xwindow);
|
Window xwindow);
|
||||||
|
@ -1028,7 +1028,12 @@ update_application_based (gboolean value)
|
|||||||
{
|
{
|
||||||
gboolean old = application_based;
|
gboolean old = application_based;
|
||||||
|
|
||||||
|
/* DISABLE application_based feature for now */
|
||||||
|
#if 0
|
||||||
application_based = value;
|
application_based = value;
|
||||||
|
#else
|
||||||
|
application_based = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
return old != application_based;
|
return old != application_based;
|
||||||
}
|
}
|
||||||
|
13
src/ui.c
13
src/ui.c
@ -238,12 +238,15 @@ meta_ui_reset_frame_bg (MetaUI *ui,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_ui_apply_frame_shape (MetaUI *ui,
|
meta_ui_apply_frame_shape (MetaUI *ui,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
int new_window_width,
|
int new_window_width,
|
||||||
int new_window_height)
|
int new_window_height,
|
||||||
|
gboolean window_has_shape)
|
||||||
{
|
{
|
||||||
meta_frames_apply_shapes (ui->frames, xwindow, new_window_width, new_window_height);
|
meta_frames_apply_shapes (ui->frames, xwindow,
|
||||||
|
new_window_width, new_window_height,
|
||||||
|
window_has_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
9
src/ui.h
9
src/ui.h
@ -73,10 +73,11 @@ void meta_ui_unflicker_frame_bg (MetaUI *ui,
|
|||||||
void meta_ui_reset_frame_bg (MetaUI *ui,
|
void meta_ui_reset_frame_bg (MetaUI *ui,
|
||||||
Window xwindow);
|
Window xwindow);
|
||||||
|
|
||||||
void meta_ui_apply_frame_shape (MetaUI *ui,
|
void meta_ui_apply_frame_shape (MetaUI *ui,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
int new_window_width,
|
int new_window_width,
|
||||||
int new_window_height);
|
int new_window_height,
|
||||||
|
gboolean window_has_shape);
|
||||||
|
|
||||||
void meta_ui_queue_frame_draw (MetaUI *ui,
|
void meta_ui_queue_frame_draw (MetaUI *ui,
|
||||||
Window xwindow);
|
Window xwindow);
|
||||||
|
@ -282,6 +282,8 @@ topic_name (MetaDebugTopic topic)
|
|||||||
return "GROUPS";
|
return "GROUPS";
|
||||||
case META_DEBUG_RESIZING:
|
case META_DEBUG_RESIZING:
|
||||||
return "RESIZING";
|
return "RESIZING";
|
||||||
|
case META_DEBUG_SHAPES:
|
||||||
|
return "SHAPES";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Window manager";
|
return "Window manager";
|
||||||
|
@ -65,7 +65,8 @@ typedef enum
|
|||||||
META_DEBUG_STARTUP = 1 << 15,
|
META_DEBUG_STARTUP = 1 << 15,
|
||||||
META_DEBUG_PREFS = 1 << 16,
|
META_DEBUG_PREFS = 1 << 16,
|
||||||
META_DEBUG_GROUPS = 1 << 17,
|
META_DEBUG_GROUPS = 1 << 17,
|
||||||
META_DEBUG_RESIZING = 1 << 18
|
META_DEBUG_RESIZING = 1 << 18,
|
||||||
|
META_DEBUG_SHAPES = 1 << 19
|
||||||
|
|
||||||
} MetaDebugTopic;
|
} MetaDebugTopic;
|
||||||
|
|
||||||
|
48
src/window.c
48
src/window.c
@ -41,6 +41,10 @@
|
|||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||||
@ -159,9 +163,11 @@ meta_window_new (MetaDisplay *display,
|
|||||||
GSList *tmp;
|
GSList *tmp;
|
||||||
MetaWorkspace *space;
|
MetaWorkspace *space;
|
||||||
gulong existing_wm_state;
|
gulong existing_wm_state;
|
||||||
|
gulong event_mask;
|
||||||
#define N_INITIAL_PROPS 10
|
#define N_INITIAL_PROPS 10
|
||||||
Atom initial_props[N_INITIAL_PROPS];
|
Atom initial_props[N_INITIAL_PROPS];
|
||||||
int i;
|
int i;
|
||||||
|
gboolean has_shape;
|
||||||
|
|
||||||
g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
|
g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
|
||||||
|
|
||||||
@ -241,11 +247,36 @@ meta_window_new (MetaDisplay *display,
|
|||||||
|
|
||||||
XAddToSaveSet (display->xdisplay, xwindow);
|
XAddToSaveSet (display->xdisplay, xwindow);
|
||||||
|
|
||||||
XSelectInput (display->xdisplay, xwindow,
|
event_mask =
|
||||||
PropertyChangeMask |
|
PropertyChangeMask | EnterWindowMask | LeaveWindowMask |
|
||||||
EnterWindowMask | LeaveWindowMask |
|
FocusChangeMask | ColormapChangeMask;
|
||||||
FocusChangeMask |
|
|
||||||
ColormapChangeMask);
|
XSelectInput (display->xdisplay, xwindow, event_mask);
|
||||||
|
|
||||||
|
has_shape = FALSE;
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
if (META_DISPLAY_HAS_SHAPE (display))
|
||||||
|
{
|
||||||
|
int x_bounding, y_bounding, x_clip, y_clip;
|
||||||
|
unsigned w_bounding, h_bounding, w_clip, h_clip;
|
||||||
|
int bounding_shaped, clip_shaped;
|
||||||
|
|
||||||
|
XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask);
|
||||||
|
|
||||||
|
XShapeQueryExtents (display->xdisplay, xwindow,
|
||||||
|
&bounding_shaped, &x_bounding, &y_bounding,
|
||||||
|
&w_bounding, &h_bounding,
|
||||||
|
&clip_shaped, &x_clip, &y_clip,
|
||||||
|
&w_clip, &h_clip);
|
||||||
|
|
||||||
|
has_shape = bounding_shaped != FALSE;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_SHAPES,
|
||||||
|
"Window has_shape = %d extents %d,%d %d x %d\n",
|
||||||
|
has_shape, x_bounding, y_bounding,
|
||||||
|
w_bounding, h_bounding);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get rid of any borders */
|
/* Get rid of any borders */
|
||||||
if (attrs.border_width != 0)
|
if (attrs.border_width != 0)
|
||||||
@ -311,6 +342,8 @@ meta_window_new (MetaDisplay *display,
|
|||||||
|
|
||||||
/* avoid tons of stack updates */
|
/* avoid tons of stack updates */
|
||||||
meta_stack_freeze (window->screen->stack);
|
meta_stack_freeze (window->screen->stack);
|
||||||
|
|
||||||
|
window->has_shape = has_shape;
|
||||||
|
|
||||||
/* Remember this rect is the actual window size */
|
/* Remember this rect is the actual window size */
|
||||||
window->rect.x = attrs.x;
|
window->rect.x = attrs.x;
|
||||||
@ -977,6 +1010,11 @@ meta_window_free (MetaWindow *window)
|
|||||||
XSelectInput (window->display->xdisplay,
|
XSelectInput (window->display->xdisplay,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
NoEventMask);
|
NoEventMask);
|
||||||
|
|
||||||
|
#ifdef HAVE_SHAPE
|
||||||
|
if (META_DISPLAY_HAS_SHAPE (window->display))
|
||||||
|
XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask);
|
||||||
|
#endif
|
||||||
|
|
||||||
meta_error_trap_pop (window->display, FALSE);
|
meta_error_trap_pop (window->display, FALSE);
|
||||||
|
|
||||||
|
@ -219,6 +219,9 @@ struct _MetaWindow
|
|||||||
guint using_net_wm_name : 1; /* vs. plain wm_name */
|
guint using_net_wm_name : 1; /* vs. plain wm_name */
|
||||||
guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */
|
guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */
|
||||||
|
|
||||||
|
/* has a shape mask */
|
||||||
|
guint has_shape : 1;
|
||||||
|
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
/* XSync update counter */
|
/* XSync update counter */
|
||||||
XSyncCounter update_counter;
|
XSyncCounter update_counter;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user