mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05: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>
|
||||
|
||||
* 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;
|
||||
}
|
||||
|
||||
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
|
||||
meta_core_get_frame_flags (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
|
@ -31,6 +31,9 @@ void meta_core_get_client_size (Display *xdisplay,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
Window meta_core_get_client_xwindow (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
|
||||
MetaFrameFlags meta_core_get_frame_flags (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
MetaFrameType meta_core_get_frame_type (Display *xdisplay,
|
||||
|
118
src/display.c
118
src/display.c
@ -45,6 +45,9 @@
|
||||
#ifdef HAVE_RANDR
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
#ifdef HAVE_SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#define USE_GDK_DISPLAY
|
||||
@ -490,6 +493,27 @@ meta_display_open (const char *name)
|
||||
meta_verbose ("Not compiled with Xsync support\n");
|
||||
#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;
|
||||
|
||||
#ifdef HAVE_GTK_MULTIHEAD
|
||||
@ -1190,6 +1214,56 @@ event_callback (XEvent *event,
|
||||
}
|
||||
#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)
|
||||
{
|
||||
case KeyPress:
|
||||
@ -1902,6 +1976,15 @@ event_get_modified_window (MetaDisplay *display,
|
||||
return None;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -2360,6 +2443,27 @@ meta_spew_event (MetaDisplay *display,
|
||||
}
|
||||
else
|
||||
#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)";
|
||||
extra = g_strdup_printf ("type: %d", event->xany.type);
|
||||
@ -3046,19 +3150,9 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
|
||||
meta_window_queue_move_resize (window);
|
||||
if (window->frame)
|
||||
{
|
||||
window->frame->need_reapply_frame_shape = TRUE;
|
||||
|
||||
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;
|
||||
|
@ -296,6 +296,13 @@ struct _MetaDisplay
|
||||
#else
|
||||
#define META_DISPLAY_HAS_XSYNC(display) FALSE
|
||||
#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);
|
||||
|
45
src/frame.c
45
src/frame.c
@ -58,6 +58,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
frame->current_cursor = 0;
|
||||
|
||||
frame->mapped = FALSE;
|
||||
frame->need_reapply_frame_shape = TRUE;
|
||||
|
||||
attrs.event_mask = EVENT_MASK;
|
||||
|
||||
@ -144,7 +145,9 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
frame->rect.height,
|
||||
frame->window->has_shape);
|
||||
frame->need_reapply_frame_shape = FALSE;
|
||||
|
||||
meta_display_ungrab (window->display);
|
||||
}
|
||||
@ -277,6 +280,20 @@ meta_frame_calc_geometry (MetaFrame *frame,
|
||||
*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
|
||||
meta_frame_sync_to_window (MetaFrame *frame,
|
||||
int resize_gravity,
|
||||
@ -284,7 +301,10 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
gboolean need_resize)
|
||||
{
|
||||
if (!(need_move || need_resize))
|
||||
return;
|
||||
{
|
||||
update_shape (frame);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Syncing frame geometry %d,%d %dx%d (SE: %d,%d)\n",
|
||||
@ -301,19 +321,18 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
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.
|
||||
*/
|
||||
|
||||
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
/* we need new shape if we're resized */
|
||||
frame->need_reapply_frame_shape = TRUE;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||
frame->xwindow,
|
||||
|
@ -57,6 +57,7 @@ struct _MetaFrame
|
||||
int bottom_height;
|
||||
|
||||
guint mapped : 1;
|
||||
guint need_reapply_frame_shape : 1;
|
||||
};
|
||||
|
||||
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->title = NULL;
|
||||
frame->expose_delayed = FALSE;
|
||||
frame->shape_applied = FALSE;
|
||||
frame->prelit_control = META_FRAME_CONTROL_NONE;
|
||||
|
||||
meta_core_grab_buttons (gdk_display, frame->xwindow);
|
||||
@ -664,7 +665,8 @@ void
|
||||
meta_frames_apply_shapes (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int new_window_width,
|
||||
int new_window_height)
|
||||
int new_window_height,
|
||||
gboolean window_has_shape)
|
||||
{
|
||||
#ifdef HAVE_SHAPE
|
||||
/* 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 ||
|
||||
fgeom.top_right_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,
|
||||
ShapeBounding, 0, 0, None, ShapeSet);
|
||||
if (frame->shape_applied)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
@ -804,11 +821,98 @@ meta_frames_apply_shapes (MetaFrames *frames,
|
||||
|
||||
XSubtractRegion (window_xregion, corners_xregion, window_xregion);
|
||||
|
||||
XShapeCombineRegion (gdk_display, frame->xwindow,
|
||||
ShapeBounding, 0, 0, window_xregion, ShapeSet);
|
||||
XDestroyRegion (corners_xregion);
|
||||
|
||||
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 (corners_xregion);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ struct _MetaUIFrame
|
||||
int text_height;
|
||||
char *title; /* NULL once we have a layout */
|
||||
guint expose_delayed : 1;
|
||||
guint shape_applied : 1;
|
||||
|
||||
/* FIXME get rid of this, it can just be in the MetaFrames struct */
|
||||
MetaFrameControl prelit_control;
|
||||
@ -127,7 +128,8 @@ void meta_frames_unflicker_bg (MetaFrames *frames,
|
||||
void meta_frames_apply_shapes (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int new_window_width,
|
||||
int new_window_height);
|
||||
int new_window_height,
|
||||
gboolean window_has_shape);
|
||||
|
||||
void meta_frames_queue_draw (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
|
@ -1028,7 +1028,12 @@ update_application_based (gboolean value)
|
||||
{
|
||||
gboolean old = application_based;
|
||||
|
||||
/* DISABLE application_based feature for now */
|
||||
#if 0
|
||||
application_based = value;
|
||||
#else
|
||||
application_based = FALSE;
|
||||
#endif
|
||||
|
||||
return old != application_based;
|
||||
}
|
||||
|
13
src/ui.c
13
src/ui.c
@ -238,12 +238,15 @@ meta_ui_reset_frame_bg (MetaUI *ui,
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_apply_frame_shape (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int new_window_width,
|
||||
int new_window_height)
|
||||
meta_ui_apply_frame_shape (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int new_window_width,
|
||||
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
|
||||
|
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,
|
||||
Window xwindow);
|
||||
|
||||
void meta_ui_apply_frame_shape (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int new_window_width,
|
||||
int new_window_height);
|
||||
void meta_ui_apply_frame_shape (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int new_window_width,
|
||||
int new_window_height,
|
||||
gboolean window_has_shape);
|
||||
|
||||
void meta_ui_queue_frame_draw (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
@ -282,6 +282,8 @@ topic_name (MetaDebugTopic topic)
|
||||
return "GROUPS";
|
||||
case META_DEBUG_RESIZING:
|
||||
return "RESIZING";
|
||||
case META_DEBUG_SHAPES:
|
||||
return "SHAPES";
|
||||
}
|
||||
|
||||
return "Window manager";
|
||||
|
@ -65,7 +65,8 @@ typedef enum
|
||||
META_DEBUG_STARTUP = 1 << 15,
|
||||
META_DEBUG_PREFS = 1 << 16,
|
||||
META_DEBUG_GROUPS = 1 << 17,
|
||||
META_DEBUG_RESIZING = 1 << 18
|
||||
META_DEBUG_RESIZING = 1 << 18,
|
||||
META_DEBUG_SHAPES = 1 << 19
|
||||
|
||||
} MetaDebugTopic;
|
||||
|
||||
|
48
src/window.c
48
src/window.c
@ -41,6 +41,10 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||
@ -159,9 +163,11 @@ meta_window_new (MetaDisplay *display,
|
||||
GSList *tmp;
|
||||
MetaWorkspace *space;
|
||||
gulong existing_wm_state;
|
||||
gulong event_mask;
|
||||
#define N_INITIAL_PROPS 10
|
||||
Atom initial_props[N_INITIAL_PROPS];
|
||||
int i;
|
||||
gboolean has_shape;
|
||||
|
||||
g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
|
||||
|
||||
@ -241,11 +247,36 @@ meta_window_new (MetaDisplay *display,
|
||||
|
||||
XAddToSaveSet (display->xdisplay, xwindow);
|
||||
|
||||
XSelectInput (display->xdisplay, xwindow,
|
||||
PropertyChangeMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
FocusChangeMask |
|
||||
ColormapChangeMask);
|
||||
event_mask =
|
||||
PropertyChangeMask | EnterWindowMask | LeaveWindowMask |
|
||||
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 */
|
||||
if (attrs.border_width != 0)
|
||||
@ -312,6 +343,8 @@ meta_window_new (MetaDisplay *display,
|
||||
/* avoid tons of stack updates */
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
|
||||
window->has_shape = has_shape;
|
||||
|
||||
/* Remember this rect is the actual window size */
|
||||
window->rect.x = attrs.x;
|
||||
window->rect.y = attrs.y;
|
||||
@ -978,6 +1011,11 @@ meta_window_free (MetaWindow *window)
|
||||
window->xwindow,
|
||||
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);
|
||||
|
||||
if (window->icon)
|
||||
|
@ -219,6 +219,9 @@ struct _MetaWindow
|
||||
guint using_net_wm_name : 1; /* vs. plain wm_name */
|
||||
guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */
|
||||
|
||||
/* has a shape mask */
|
||||
guint has_shape : 1;
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
/* XSync update counter */
|
||||
XSyncCounter update_counter;
|
||||
|
Loading…
Reference in New Issue
Block a user