diff options
-rw-r--r-- | src/core/frame.c | 24 | ||||
-rw-r--r-- | src/ui/frames.c | 56 | ||||
-rw-r--r-- | src/ui/frames.h | 1 |
3 files changed, 77 insertions, 4 deletions
diff --git a/src/core/frame.c b/src/core/frame.c index 3c0ef935..4b0b112f 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -28,6 +28,7 @@ #include "bell.h" #include "errors.h" #include "keybindings.h" +#include "prefs.h" #ifdef HAVE_RENDER #include <X11/extensions/Xrender.h> @@ -42,6 +43,25 @@ FocusChangeMask | \ ColormapChangeMask) +static gboolean update_shape (MetaFrame *frame); + +static void +prefs_changed_callback (MetaPreference preference, + gpointer data) +{ + MetaFrame *frame = (MetaFrame *) data; + + switch (preference) + { + case META_PREF_COMPOSITING_MANAGER: + frame->need_reapply_frame_shape = TRUE; + update_shape (frame); + break; + default: + break; + } +} + void meta_window_ensure_frame (MetaWindow *window) { @@ -167,6 +187,8 @@ meta_window_ensure_frame (MetaWindow *window) frame->need_reapply_frame_shape = FALSE; meta_display_ungrab (window->display); + + meta_prefs_add_listener (prefs_changed_callback, frame); } void @@ -182,6 +204,8 @@ meta_window_destroy_frame (MetaWindow *window) frame = window->frame; + meta_prefs_remove_listener (prefs_changed_callback, frame); + meta_frame_calc_borders (frame, &borders); meta_bell_notify_frame_destroy (frame); diff --git a/src/ui/frames.c b/src/ui/frames.c index 1ea60bbc..8fcdd9fa 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -686,6 +686,7 @@ meta_frames_manage_window (MetaFrames *frames, frame->title = NULL; frame->expose_delayed = FALSE; frame->shape_applied = FALSE; + frame->dest_kind = ShapeBounding; frame->prelit_control = META_FRAME_CONTROL_NONE; meta_core_grab_buttons (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow); @@ -1055,6 +1056,20 @@ get_client_region (MetaFrameGeometry *fgeom, return cairo_region_create_rectangle (&rect); } +static cairo_region_t * +get_frame_region (int window_width, + int window_height) +{ + cairo_rectangle_int_t rect; + + rect.x = 0; + rect.y = 0; + rect.width = window_width; + rect.height = window_height; + + return cairo_region_create_rectangle (&rect); +} + void meta_frames_apply_shapes (MetaFrames *frames, Window xwindow, @@ -1068,6 +1083,8 @@ meta_frames_apply_shapes (MetaFrames *frames, MetaFrameGeometry fgeom; cairo_region_t *window_region; Display *display; + gboolean compositing_manager; + int dest_kind; frame = meta_frames_lookup_window (frames, xwindow); g_return_if_fail (frame != NULL); @@ -1090,6 +1107,8 @@ meta_frames_apply_shapes (MetaFrames *frames, XShapeCombineMask (display, frame->xwindow, ShapeBounding, 0, 0, None, ShapeSet); + XShapeCombineMask (display, frame->xwindow, + ShapeClip, 0, 0, None, ShapeSet); frame->shape_applied = FALSE; } else @@ -1102,6 +1121,18 @@ meta_frames_apply_shapes (MetaFrames *frames, return; /* nothing to do */ } + compositing_manager = meta_prefs_get_compositing_manager (); + + dest_kind = ShapeClip; + if (!compositing_manager) + dest_kind = ShapeBounding; + + if (frame->dest_kind != dest_kind) + { + XShapeCombineMask (display, frame->xwindow, + frame->dest_kind, 0, 0, None, ShapeSet); + } + window_region = get_visible_region (frames, frame, &fgeom, @@ -1119,7 +1150,9 @@ meta_frames_apply_shapes (MetaFrames *frames, XSetWindowAttributes attrs; Window shape_window; Window client_window; + cairo_region_t *frame_region; cairo_region_t *client_region; + cairo_region_t *tmp_region; GdkScreen *screen; int screen_number; @@ -1159,16 +1192,22 @@ meta_frames_apply_shapes (MetaFrames *frames, /* Punch the client area out of the normal frame shape, * then union it with the shape_window's existing shape */ + frame_region = get_frame_region (new_window_width, + new_window_height); client_region = get_client_region (&fgeom, new_window_width, new_window_height); - cairo_region_subtract (window_region, client_region); + tmp_region = compositing_manager ? frame_region : window_region; + + cairo_region_subtract (tmp_region, client_region); cairo_region_destroy (client_region); apply_cairo_region_to_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window, - window_region, ShapeBounding, ShapeUnion); + tmp_region, ShapeBounding, ShapeUnion); + + cairo_region_destroy (frame_region); /* Now copy shape_window shape to the real frame */ XShapeCombineShape (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, ShapeBounding, @@ -1178,6 +1217,13 @@ meta_frames_apply_shapes (MetaFrames *frames, ShapeSet); XDestroyWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window); + + if (compositing_manager) + { + apply_cairo_region_to_window (display, + frame->xwindow, window_region, + dest_kind, ShapeSet); + } } else { @@ -1187,10 +1233,12 @@ meta_frames_apply_shapes (MetaFrames *frames, "Frame 0x%lx has shaped corners\n", frame->xwindow); - apply_cairo_region_to_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, - window_region, ShapeBounding, ShapeSet); + apply_cairo_region_to_window (display, + frame->xwindow, window_region, + dest_kind, ShapeSet); } + frame->dest_kind = dest_kind; frame->shape_applied = TRUE; cairo_region_destroy (window_region); diff --git a/src/ui/frames.h b/src/ui/frames.h index cde51e60..5019aaad 100644 --- a/src/ui/frames.h +++ b/src/ui/frames.h @@ -83,6 +83,7 @@ struct _MetaUIFrame char *title; /* NULL once we have a layout */ guint expose_delayed : 1; guint shape_applied : 1; + int dest_kind; /* FIXME get rid of this, it can just be in the MetaFrames struct */ MetaFrameControl prelit_control; |