summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Holmes <iain@src.gnome.org>2007-11-27 19:02:21 +0000
committerIain Holmes <iain@src.gnome.org>2007-11-27 19:02:21 +0000
commitc9eb152824e3e4cab441ce66d798aabcacd42326 (patch)
treef0d9debb1f478118123955aa49d54ff7c2429e85
parent1eb77288db72ba929c4e61a58e647379b8782859 (diff)
downloadmetacity-c9eb152824e3e4cab441ce66d798aabcacd42326.tar.gz
Properly revert the compositor changes
svn path=/branches/iains-blingtastic-bucket-o-bling/; revision=3445
-rw-r--r--src/compositor.c362
1 files changed, 112 insertions, 250 deletions
diff --git a/src/compositor.c b/src/compositor.c
index 82a916fb..87001808 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -47,11 +47,13 @@
#define USE_IDLE_REPAINT 1
-typedef enum _WindowDrawMode
+typedef enum _MetaCompWindowType
{
- WINDOW_SOLID,
- WINDOW_ARGB
-} WindowDrawMode;
+ META_COMP_WINDOW_NORMAL,
+ META_COMP_WINDOW_DND,
+ META_COMP_WINDOW_DESKTOP,
+ META_COMP_WINDOW_DOCK
+} MetaCompWindowType;
struct _MetaCompositor
{
@@ -62,8 +64,6 @@ struct _MetaCompositor
Atom atom_net_wm_window_opacity;
Atom atom_net_wm_window_type_dnd;
- gboolean damages_pending;
-
#ifdef USE_IDLE_REPAINT
guint repaint_id;
#endif
@@ -96,8 +96,6 @@ typedef struct _MetaCompScreen
guint overlays;
gboolean compositor_active;
gboolean clip_changed;
-
- GList *dock_windows;
} MetaCompScreen;
typedef struct _MetaCompWindow
@@ -117,11 +115,12 @@ typedef struct _MetaCompWindow
Pixmap shaded_back_pixmap;
#endif
- WindowDrawMode mode;
+ int mode;
gboolean damaged;
gboolean shaped;
- gboolean dnd;
+
+ MetaCompWindowType type;
Damage damage;
Picture picture;
@@ -144,6 +143,9 @@ typedef struct _MetaCompWindow
#define OPAQUE 0xffffffff
+#define WINDOW_SOLID 0
+#define WINDOW_ARGB 1
+
#define SHADOW_RADIUS 6.0
#define SHADOW_OFFSET_X (SHADOW_RADIUS * -3 / 2)
#define SHADOW_OFFSET_Y (SHADOW_RADIUS * -5 / 4)
@@ -152,13 +154,6 @@ typedef struct _MetaCompWindow
#define TRANS_OPACITY 0.75
-#define WIN_IS_ARGB(win) (win->mode == WINDOW_ARGB)
-#define WIN_IS_OPAQUE(win) ((win->opacity == (guint) OPAQUE) && !WIN_IS_ARGB(win))
-#define WIN_IS_VIEWABLE(win) (win->viewable)
-#define WIN_HAS_DAMAGE(win) (win->damage)
-#define WIN_IS_VISIBLE(win) (WIN_IS_VIEWABLE(win) && WIN_HAS_DAMAGE(win))
-#define WIN_IS_DAMAGED(win) (win->damaged)
-
/* Gaussian stuff for creating the shadows */
static double
gaussian (double r,
@@ -713,7 +708,7 @@ window_has_shadow (MetaCompWindow *cw)
}
/* Don't put shadow around DND icon windows */
- if (cw->dnd)
+ if (cw->type == META_COMP_WINDOW_DND)
return FALSE;
if (cw->mode != WINDOW_ARGB)
@@ -858,72 +853,6 @@ get_window_picture (MetaCompWindow *cw)
return None;
}
-/* Dock shadows are only drawn on the desktop...
- Here's how that all works. When a window is added in add_win, if it is
- a Dock window, it gets added to a list. In phase 2 of the compositing
- function, this list is walked before the main list. The shadows are then
- drawn on the same clip region as the root window was drawn. This means
- that in the compositing function, when we come to the dock windows in
- phase 3, we do not need to redraw their shadows. The end goal of all this
- is that all(*) windows are drawn over the dock shadows.
-
- (*) There is one caveat: Desktop windows. These are pretending to be the
- root window, so we draw over them as well. This is done by copying the
- overall region before subtracting the desktop area and then using this
- copy to base where we draw the dock shadows on */
-static void
-paint_dock_shadows (MetaScreen *screen,
- Picture root_buffer,
- XserverRegion region)
-{
- MetaDisplay *display = screen->display;
- Display *xdisplay = display->xdisplay;
- MetaCompScreen *info = screen->compositor_data;
- GList *d;
-
- for (d = info->dock_windows; d; d = d->next)
- {
- MetaCompWindow *cw = d->data;
- XserverRegion shadow_clip;
-
- if (cw->shadow)
- {
- shadow_clip = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesIntersectRegion (xdisplay, shadow_clip,
- cw->border_clip, region);
-
- XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
- shadow_clip);
-
- XRenderComposite (xdisplay, PictOpOver, info->black_picture,
- cw->shadow, root_buffer,
- 0, 0, 0, 0,
- cw->attrs.x + cw->shadow_dx,
- cw->attrs.y + cw->shadow_dy,
- cw->shadow_width, cw->shadow_height);
- XFixesDestroyRegion (xdisplay, shadow_clip);
- }
- }
-}
-
-/* How compositing works:
- The desktop is drawn in 3 phases, with some subphases.
- Phase 1: The window list is walked from depthwise (so top windows first)
- drawing all the opaque windows.
- 1.1: Once a window is drawn its region is removed from the overall region
- This new region is recorded for drawing the shadows on later.
- Phase 2: Once the window list has been walked, the root window is drawn
- Because all the opaque windows regions have been removed from the
- overall region, the root window is only drawn on the bits in between
- windows
- Phase 3: The window list is walked from the bottom to the top
- 3.1: The window's shadow is drawn, clipped to the region saved in
- phase 1.1
- 3.2: The translucent windows are then drawn as well.
-
- This is the general idea. However there are a few tweaks and tricks in it.
- See comments above and below about the dock shadow
-*/
static void
paint_windows (MetaScreen *screen,
GList *windows,
@@ -933,11 +862,11 @@ paint_windows (MetaScreen *screen,
MetaDisplay *display = screen->display;
MetaCompScreen *info = screen->compositor_data;
Display *xdisplay = display->xdisplay;
- GList *index, *last = NULL;
+ GList *index;
int screen_width, screen_height, screen_number;
Window xroot;
MetaCompWindow *cw;
- XserverRegion paint_region, desktop_region;
+ XserverRegion paint_region;
screen_width = screen->rect.width;
screen_height = screen->rect.height;
@@ -959,8 +888,6 @@ paint_windows (MetaScreen *screen,
XFixesCopyRegion (xdisplay, paint_region, region);
}
- desktop_region = None;
-
/*
* Painting from top to bottom, reducing the clipping area at
* each iteration. Only the opaque windows are painted 1st.
@@ -968,9 +895,9 @@ paint_windows (MetaScreen *screen,
for (index = windows; index; index = index->next)
{
cw = (MetaCompWindow *) index->data;
- if (!WIN_IS_DAMAGED (cw) || !WIN_IS_VISIBLE (cw))
+ if (!cw->damaged)
{
- cw->skipped = TRUE;
+ /* Not damaged */
continue;
}
@@ -978,7 +905,7 @@ paint_windows (MetaScreen *screen,
(cw->attrs.y + cw->attrs.height < 1) ||
(cw->attrs.x >= screen_width) || (cw->attrs.y >= screen_height))
{
- cw->skipped = TRUE;
+ /* Off screen */
continue;
}
@@ -1008,7 +935,7 @@ paint_windows (MetaScreen *screen,
if (cw->extents == None)
cw->extents = win_extents (cw);
- if (WIN_IS_OPAQUE (cw))
+ if (cw->mode == WINDOW_SOLID)
{
int x, y, wid, hei;
@@ -1029,16 +956,6 @@ paint_windows (MetaScreen *screen,
XRenderComposite (xdisplay, PictOpSrc, cw->picture,
None, root_buffer, 0, 0, 0, 0,
x, y, wid, hei);
-
- /* Here we copy paint_region before we subtract the desktop
- border_size region so we can draw the dock shadows over the
- same area that we drew the desktop window */
- if (cw->type == META_COMP_WINDOW_DESKTOP)
- {
- desktop_region = XFixesCreateRegion (xdisplay, 0, 0);
- XFixesCopyRegion (xdisplay, desktop_region, paint_region);
- }
-
XFixesSubtractRegion (xdisplay, paint_region,
paint_region, cw->border_size);
}
@@ -1048,86 +965,71 @@ paint_windows (MetaScreen *screen,
cw->border_clip = XFixesCreateRegion (xdisplay, 0, 0);
XFixesCopyRegion (xdisplay, cw->border_clip, paint_region);
}
-
- cw->skipped = FALSE;
- last = index;
}
XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0, paint_region);
paint_root (screen, root_buffer);
- /* We draw the dock shadows on the same region that we drew the
- desktop. If there was no desktop window then desktop_region will still
- be None, and so we use the paint_region as that was where we drew
- the root window. We cannot use paint_region if there was a desktop window
- because the desktop window covers the root window and so paint_region
- will be empty */
- paint_dock_shadows (screen, root_buffer,
- desktop_region == None ? paint_region : desktop_region);
-
- if (desktop_region)
- XFixesDestroyRegion (xdisplay, desktop_region);
-
/*
* Painting from bottom to top, translucent windows and shadows are painted
*/
- for (index = last; index; index = index->prev)
+ for (index = g_list_last (windows); index; index = index->prev)
{
cw = (MetaCompWindow *) index->data;
-
- if (cw->skipped)
- continue;
-
- if (cw->shadow && cw->type != META_COMP_WINDOW_DOCK)
- {
- XserverRegion shadow_clip;
-
- shadow_clip = XFixesCreateRegion (xdisplay, NULL, 0);
- XFixesSubtractRegion (xdisplay, shadow_clip, cw->border_clip,
- cw->border_size);
- XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
- shadow_clip);
-
- XRenderComposite (xdisplay, PictOpOver, info->black_picture,
- cw->shadow, root_buffer,
- 0, 0, 0, 0,
- cw->attrs.x + cw->shadow_dx,
- cw->attrs.y + cw->shadow_dy,
- cw->shadow_width, cw->shadow_height);
- if (shadow_clip)
- XFixesDestroyRegion (xdisplay, shadow_clip);
- }
- if ((cw->opacity != (guint) OPAQUE) && !(cw->alpha_pict))
- {
- cw->alpha_pict = solid_picture (display, screen, FALSE,
- (double) cw->opacity / OPAQUE,
- 0, 0, 0);
- }
-
- XFixesIntersectRegion (xdisplay, cw->border_clip, cw->border_clip,
- cw->border_size);
- XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
- cw->border_clip);
- if (cw->mode == WINDOW_ARGB)
+ if (cw->picture)
{
- int x, y, wid, hei;
+ if (cw->shadow)
+ {
+ XserverRegion shadow_clip;
+
+ shadow_clip = XFixesCreateRegion (xdisplay, NULL, 0);
+ XFixesSubtractRegion (xdisplay, shadow_clip, cw->border_clip,
+ cw->border_size);
+ XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
+ shadow_clip);
+
+ XRenderComposite (xdisplay, PictOpOver, info->black_picture,
+ cw->shadow, root_buffer,
+ 0, 0, 0, 0,
+ cw->attrs.x + cw->shadow_dx,
+ cw->attrs.y + cw->shadow_dy,
+ cw->shadow_width, cw->shadow_height);
+ if (shadow_clip)
+ XFixesDestroyRegion (xdisplay, shadow_clip);
+ }
+
+ if ((cw->opacity != (guint) OPAQUE) && !(cw->alpha_pict))
+ {
+ cw->alpha_pict = solid_picture (display, screen, FALSE,
+ (double) cw->opacity / OPAQUE,
+ 0, 0, 0);
+ }
+
+ XFixesIntersectRegion (xdisplay, cw->border_clip, cw->border_clip,
+ cw->border_size);
+ XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0,
+ cw->border_clip);
+ if (cw->mode == WINDOW_ARGB)
+ {
+ int x, y, wid, hei;
#ifdef HAVE_NAME_WINDOW_PIXMAP
- x = cw->attrs.x;
- y = cw->attrs.y;
- wid = cw->attrs.width + cw->attrs.border_width * 2;
- hei = cw->attrs.height + cw->attrs.border_width * 2;
+ x = cw->attrs.x;
+ y = cw->attrs.y;
+ wid = cw->attrs.width + cw->attrs.border_width * 2;
+ hei = cw->attrs.height + cw->attrs.border_width * 2;
#else
- x = cw->attrs.x + cw->attrs.border_width;
- y = cw->attrs.y + cw->attrs.border_height;
- wid = cw->attrs.width;
- hei = cw->attrs.height;
+ x = cw->attrs.x + cw->attrs.border_width;
+ y = cw->attrs.y + cw->attrs.border_height;
+ wid = cw->attrs.width;
+ hei = cw->attrs.height;
#endif
-
- XRenderComposite (xdisplay, PictOpOver, cw->picture,
- cw->alpha_pict, root_buffer, 0, 0, 0, 0,
- x, y, wid, hei);
- }
+
+ XRenderComposite (xdisplay, PictOpOver, cw->picture,
+ cw->alpha_pict, root_buffer, 0, 0, 0, 0,
+ x, y, wid, hei);
+ }
+ }
if (cw->border_clip)
{
@@ -1183,8 +1085,7 @@ static void
repair_display (MetaDisplay *display)
{
GSList *screens;
-
- meta_error_trap_push (display);
+
#ifdef USE_IDLE_REPAINT
if (display->compositor->repaint_id > 0)
{
@@ -1195,8 +1096,6 @@ repair_display (MetaDisplay *display)
for (screens = display->screens; screens; screens = screens->next)
repair_screen ((MetaScreen *) screens->data);
-
- meta_error_trap_pop (display, FALSE);
}
#ifdef USE_IDLE_REPAINT
@@ -1226,34 +1125,6 @@ add_repair (MetaDisplay *display)
#endif
static void
-fix_region (MetaCompWindow *cw,
- XserverRegion region)
-{
- GList *index;
- MetaScreen *screen = cw->screen;
- MetaCompScreen *info = screen->compositor_data;
- MetaDisplay *display = screen->display;
-
- /* Exclude opaque windows in front of the given area */
- for (index = info->windows; index; index = index->next)
- {
- MetaCompWindow *cw2 = (MetaCompWindow *) index->data;
- if (cw2 == cw)
- break;
- else if (WIN_IS_OPAQUE (cw2) && WIN_IS_VISIBLE (cw2))
- {
- /* Make sure the window's areas are up to date ... */
- if (cw2->border_size == None)
- cw2->border_size = border_size (cw2);
-
- if (cw2->border_size)
- XFixesSubtractRegion (display->xdisplay, region,
- region, cw2->border_size);
- }
- }
-}
-
-static void
add_damage (MetaScreen *screen,
XserverRegion damage)
{
@@ -1312,14 +1183,10 @@ repair_win (MetaCompWindow *cw)
cw->attrs.y + cw->attrs.border_width);
}
- if (parts)
- {
- fix_region (cw, parts);
- add_damage (screen, parts);
- cw->damaged = TRUE;
- }
-
meta_error_trap_pop (display, FALSE);
+
+ add_damage (screen, parts);
+ cw->damaged = TRUE;
}
static void
@@ -1428,7 +1295,6 @@ map_win (MetaDisplay *display,
cw->attrs.map_state = IsViewable;
cw->damaged = FALSE;
- cw->viewable = TRUE;
}
static void
@@ -1446,7 +1312,6 @@ unmap_win (MetaDisplay *display,
cw->attrs.map_state = IsUnmapped;
cw->damaged = FALSE;
- cw->viewable = FALSE;
if (cw->extents != None)
{
@@ -1494,7 +1359,6 @@ determine_mode (MetaDisplay *display,
damage = XFixesCreateRegion (display->xdisplay, NULL, 0);
XFixesCopyRegion (display->xdisplay, damage, cw->extents);
- fix_region (cw, damage);
add_damage (screen, damage);
}
}
@@ -1524,9 +1388,10 @@ get_window_type (MetaDisplay *display,
{
MetaCompositor *compositor = display->compositor;
int n_atoms;
- Atom *atoms;
+ Atom *atoms, type_atom;
int i;
+ type_atom = None;
n_atoms = 0;
atoms = NULL;
@@ -1536,11 +1401,31 @@ get_window_type (MetaDisplay *display,
for (i = 0; i < n_atoms; i++)
{
- if (atoms[i] == compositor->atom_net_wm_window_type_dnd)
- cw->dnd = TRUE;
- else
- cw->dnd = FALSE;
+ if (atoms[i] == compositor->atom_net_wm_window_type_dnd ||
+ atoms[i] == display->atom_net_wm_window_type_desktop ||
+ atoms[i] == display->atom_net_wm_window_type_dock ||
+ atoms[i] == display->atom_net_wm_window_type_toolbar ||
+ atoms[i] == display->atom_net_wm_window_type_menu ||
+ atoms[i] == display->atom_net_wm_window_type_dialog ||
+ atoms[i] == display->atom_net_wm_window_type_normal ||
+ atoms[i] == display->atom_net_wm_window_type_utility ||
+ atoms[i] == display->atom_net_wm_window_type_splash)
+ {
+ type_atom = atoms[i];
+ break;
+ }
}
+
+ meta_XFree (atoms);
+
+ if (type_atom == compositor->atom_net_wm_window_type_dnd)
+ cw->type = META_COMP_WINDOW_DND;
+ else if (type_atom == display->atom_net_wm_window_type_desktop)
+ cw->type = META_COMP_WINDOW_DESKTOP;
+ else if (type_atom == display->atom_net_wm_window_type_dock)
+ cw->type = META_COMP_WINDOW_DOCK;
+ else
+ cw->type = META_COMP_WINDOW_NORMAL;
}
/* Must be called with an error trap in place */
@@ -1573,12 +1458,6 @@ add_win (MetaScreen *screen,
}
get_window_type (display, cw);
- if (cw->type == META_COMP_WINDOW_DOCK)
- {
- info->dock_windows = g_list_append (info->dock_windows, cw);
- g_print ("Added %p to dock list\n", cw);
- }
-
/* If Metacity has decided not to manage this window then the input events
won't have been set on the window */
event_mask = cw->attrs.your_event_mask | PropertyChangeMask;
@@ -1593,7 +1472,6 @@ add_win (MetaScreen *screen,
cw->damaged = FALSE;
cw->shaped = is_shaped (display, xwindow);
- cw->viewable = (cw->attrs.map_state == IsViewable);
if (cw->attrs.class == InputOnly)
cw->damage = None;
@@ -1621,7 +1499,7 @@ add_win (MetaScreen *screen,
info->windows = g_list_prepend (info->windows, cw);
g_hash_table_insert (info->windows_by_xid, (gpointer) xwindow, cw);
- if (WIN_IS_VIEWABLE (cw))
+ if (cw->attrs.map_state == IsViewable)
map_win (display, screen, xwindow);
}
@@ -1710,8 +1588,7 @@ resize_win (MetaCompWindow *cw,
int width,
int height,
int border_width,
- gboolean override_redirect,
- gboolean shape_notify)
+ gboolean override_redirect)
{
MetaScreen *screen;
MetaDisplay *display;
@@ -1730,7 +1607,7 @@ resize_win (MetaCompWindow *cw,
cw->attrs.x = x;
cw->attrs.y = y;
- if (cw->attrs.width != width || cw->attrs.height != height || shape_notify)
+ if (cw->attrs.width != width || cw->attrs.height != height)
{
#ifdef HAVE_NAME_WINDOW_PIXMAP
if (cw->shaded_back_pixmap)
@@ -1775,17 +1652,11 @@ resize_win (MetaCompWindow *cw,
if (damage)
{
- cw->extents = win_extents (cw);
+ XserverRegion extents = win_extents (cw);
+
+ XFixesUnionRegion (display->xdisplay, damage, damage, extents);
+ XFixesDestroyRegion (display->xdisplay, extents);
- XFixesUnionRegion (display->xdisplay, damage, damage, cw->extents);
-
- if (shape_notify)
- {
- XFixesDestroyRegion (display->xdisplay, cw->extents);
- cw->extents = None;
- }
-
- fix_region (cw, damage);
add_damage (screen, damage);
}
@@ -1837,7 +1708,7 @@ process_configure_notify (MetaCompositor *compositor,
{
restack_win (cw, event->above);
resize_win (cw, event->x, event->y, event->width, event->height,
- event->border_width, event->override_redirect, FALSE);
+ event->border_width, event->override_redirect);
}
else
{
@@ -2049,10 +1920,9 @@ process_damage (MetaCompositor *compositor,
return;
repair_win (cw);
- compositor->damages_pending = event->more;
#ifdef USE_IDLE_REPAINT
- if (!compositor->damages_pending)
+ if (event->more == FALSE)
add_repair (compositor->display);
#endif
}
@@ -2074,7 +1944,7 @@ process_shape (MetaCompositor *compositor,
resize_win (cw, cw->attrs.x, cw->attrs.y,
event->width + event->x, event->height + event->y,
- cw->attrs.border_width, cw->attrs.override_redirect, TRUE);
+ cw->attrs.border_width, cw->attrs.override_redirect);
if (event->shaped && !cw->shaped)
cw->shaped = TRUE;
@@ -2105,8 +1975,6 @@ meta_compositor_new (MetaDisplay *display)
compositor->atom_net_wm_window_opacity = atoms[2];
compositor->atom_net_wm_window_type_dnd = atoms[3];
- compositor->damages_pending = FALSE;
-
#ifdef USE_IDLE_REPAINT
g_print ("Using idle repaint\n");
compositor->repaint_id = 0;
@@ -2172,8 +2040,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
info = g_new0 (MetaCompScreen, 1);
info->screen = screen;
- info->dock_windows = NULL;
-
+
visual_format = XRenderFindVisualFormat (display->xdisplay,
DefaultVisual (display->xdisplay,
screen->number));
@@ -2248,10 +2115,6 @@ meta_compositor_unmanage_screen (MetaCompositor *compositor,
XRenderFreePicture (display->xdisplay, info->black_picture);
g_free (info->gaussian_map);
- g_free (info->shadow_corner);
- g_free (info->shadow_top);
-
- g_list_free (info->dock_windows);
XCompositeUnredirectSubwindows (display->xdisplay, screen->xroot,
CompositeRedirectManual);
@@ -2380,12 +2243,11 @@ meta_compositor_process_event (MetaCompositor *compositor,
break;
}
+ meta_error_trap_pop (compositor->display, FALSE);
#ifndef USE_IDLE_REPAINT
- if (compositor->damages_pending)
- repair_display (compositor->display);
+ repair_display (compositor->display);
#endif
- meta_error_trap_pop (compositor->display, FALSE);
return;
#endif
}