diff options
author | Havoc Pennington <hp@pobox.com> | 2002-08-06 04:11:23 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2002-08-06 04:11:23 +0000 |
commit | 00dcef82e32456c6202f2ebb509ce411b5825eb8 (patch) | |
tree | 6595ec8a2ede066e71620e8013947daf379ad15b /src/effects.c | |
parent | f15e959634f57513088143e81491ab9deacbeee9 (diff) | |
download | metacity-00dcef82e32456c6202f2ebb509ce411b5825eb8.tar.gz |
disable animation when shading windows, just doesn't really convey the
2002-07-28 Havoc Pennington <hp@pobox.com>
* src/window.c (meta_window_shade): disable animation when shading
windows, just doesn't really convey the idea anyway.
* src/effects.c: Move to using a shaped window instead of
IncludeInferiors to do the animations, looks a lot better
because we don't have to grab the server.
* src/window.c (meta_window_change_workspace): remove bogus
assertion that was causing a crash
(meta_window_new): auto-fullscreen huge undecorated windows.
* src/keybindings.c (switch_to_workspace): use
meta_window_change_workspace() to avoid same bug in cut-and-paste
code from there
Diffstat (limited to 'src/effects.c')
-rw-r--r-- | src/effects.c | 140 |
1 files changed, 128 insertions, 12 deletions
diff --git a/src/effects.c b/src/effects.c index e486edbe..4b73e4d5 100644 --- a/src/effects.c +++ b/src/effects.c @@ -19,10 +19,23 @@ * 02111-1307, USA. */ +#include <config.h> #include "effects.h" #include "display.h" #include "ui.h" +#ifdef HAVE_SHAPE +#include <X11/extensions/shape.h> +#endif + +typedef enum +{ + META_ANIMATION_DRAW_ROOT, + META_ANIMATION_WINDOW_WIREFRAME, + META_ANIMATION_WINDOW_OPAQUE + +} MetaAnimationStyle; + typedef struct { MetaScreen *screen; @@ -41,11 +54,14 @@ typedef struct /* used instead of the global flag, since * we don't want to change midstream. */ - gboolean use_opaque; + MetaAnimationStyle style; - /* For wireframe */ + /* For wireframe drawn on root window */ GC gc; + /* For wireframe window */ + Window wireframe_xwindow; + /* For opaque */ MetaImageWindow *image_window; GdkPixbuf *orig_pixbuf; @@ -54,6 +70,61 @@ typedef struct } BoxAnimationContext; +static void +update_wireframe_window (MetaDisplay *display, + Window xwindow, + const MetaRectangle *rect) +{ + XMoveResizeWindow (display->xdisplay, + xwindow, + rect->x, rect->y, + rect->width, rect->height); + +#ifdef HAVE_SHAPE + +#define OUTLINE_WIDTH 3 + + if (rect->width > OUTLINE_WIDTH * 2 && + rect->height > OUTLINE_WIDTH * 2) + { + XRectangle xrect; + Region inner_xregion; + Region outer_xregion; + + inner_xregion = XCreateRegion (); + outer_xregion = XCreateRegion (); + + xrect.x = 0; + xrect.y = 0; + xrect.width = rect->width; + xrect.height = rect->height; + + XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion); + + xrect.x += OUTLINE_WIDTH; + xrect.y += OUTLINE_WIDTH; + xrect.width -= OUTLINE_WIDTH * 2; + xrect.height -= OUTLINE_WIDTH * 2; + + XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion); + + XSubtractRegion (outer_xregion, inner_xregion, outer_xregion); + + XShapeCombineRegion (display->xdisplay, xwindow, + ShapeBounding, 0, 0, outer_xregion, ShapeSet); + + XDestroyRegion (outer_xregion); + XDestroyRegion (inner_xregion); + } + else + { + /* Unset the shape */ + XShapeCombineMask (display->xdisplay, xwindow, + ShapeBounding, 0, 0, None, ShapeSet); + } +#endif +} + static gboolean effects_draw_box_animation_timeout (BoxAnimationContext *context) { @@ -64,7 +135,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context) if (!context->first_time) { - if (!context->use_opaque) + if (context->style == META_ANIMATION_DRAW_ROOT) { /* Restore the previously drawn background */ XDrawRectangle (context->screen->display->xdisplay, @@ -94,18 +165,23 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context) if (elapsed > context->millisecs_duration) { /* All done */ - if (context->use_opaque) + if (context->style == META_ANIMATION_WINDOW_OPAQUE) { g_object_unref (G_OBJECT (context->orig_pixbuf)); meta_image_window_free (context->image_window); } - else + else if (context->style == META_ANIMATION_DRAW_ROOT) { meta_display_ungrab (context->screen->display); meta_ui_pop_delay_exposes (context->screen->ui); XFreeGC (context->screen->display->xdisplay, context->gc); } + else if (context->style == META_ANIMATION_WINDOW_WIREFRAME) + { + XDestroyWindow (context->screen->display->xdisplay, + context->wireframe_xwindow); + } g_free (context); return FALSE; @@ -130,7 +206,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context) context->last_rect = draw_rect; - if (context->use_opaque) + if (context->style == META_ANIMATION_WINDOW_OPAQUE) { GdkPixbuf *scaled; @@ -174,7 +250,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context) g_object_unref (G_OBJECT (scaled)); } } - else + else if (context->style == META_ANIMATION_DRAW_ROOT) { /* Draw the rectangle */ XDrawRectangle (context->screen->display->xdisplay, @@ -183,6 +259,12 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context) draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height); } + else if (context->style == META_ANIMATION_WINDOW_WIREFRAME) + { + update_wireframe_window (context->screen->display, + context->wireframe_xwindow, + &draw_rect); + } /* kick changes onto the server */ XFlush (context->screen->display->xdisplay); @@ -198,7 +280,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context) * and unmapping of windows that's going on. */ -static gboolean use_opaque_animations = FALSE; +static MetaAnimationStyle animation_style = META_ANIMATION_WINDOW_WIREFRAME; void meta_effects_draw_box_animation (MetaScreen *screen, @@ -225,9 +307,14 @@ meta_effects_draw_box_animation (MetaScreen *screen, context->end_rect = *destination_rect; context->anim_type = anim_type; - context->use_opaque = use_opaque_animations; + context->style = animation_style; - if (context->use_opaque) +#ifndef HAVE_SHAPE + if (context->style == META_ANIMATION_WINDOW_WIREFRAME) + context->style = META_ANIMATION_DRAW_ROOT; +#endif + + if (context->style == META_ANIMATION_WINDOW_OPAQUE) { GdkPixbuf *pix; @@ -242,7 +329,7 @@ meta_effects_draw_box_animation (MetaScreen *screen, if (pix == NULL) { /* Fall back to wireframe */ - context->use_opaque = FALSE; + context->style = META_ANIMATION_WINDOW_WIREFRAME; } else { @@ -258,7 +345,36 @@ meta_effects_draw_box_animation (MetaScreen *screen, } /* Not an else, so that fallback works */ - if (!context->use_opaque) + if (context->style == META_ANIMATION_WINDOW_WIREFRAME) + { + XSetWindowAttributes attrs; + + attrs.override_redirect = True; + attrs.background_pixel = BlackPixel (screen->display->xdisplay, + screen->number); + + context->wireframe_xwindow = XCreateWindow (screen->display->xdisplay, + screen->xroot, + initial_rect->x, + initial_rect->y, + initial_rect->width, + initial_rect->height, + 0, + CopyFromParent, + CopyFromParent, + CopyFromParent, + CWOverrideRedirect | CWBackPixel, + &attrs); + + update_wireframe_window (screen->display, + context->wireframe_xwindow, + initial_rect); + + XMapWindow (screen->display->xdisplay, + context->wireframe_xwindow); + } + + if (context->style == META_ANIMATION_DRAW_ROOT) { XGCValues gc_values; |