Author: olivier Date: 2006-06-14 09:27:23 +0000 (Wed, 14 Jun 2006) New Revision: 22096
Modified: xfwm4/trunk/src/client.c xfwm4/trunk/src/compositor.c xfwm4/trunk/src/display.c xfwm4/trunk/src/display.h xfwm4/trunk/src/events.c xfwm4/trunk/src/hints.h xfwm4/trunk/src/screen.h xfwm4/trunk/src/startup_notification.c Log: Finish rework of the compositor, which should fix quite few bugs and improve performance (by discarding damages of covered windows, for example), unredirecting fullscreen overrides seems to work fine which gives a huge performance boost on fullscreen games, fixes translucent xscreensaver window, rework the NET_ACTIVE_WINDOW message handling to improve focus passing (see this thread on the ML http://foo-projects.org/pipermail/xfce4-dev/2006-June/020471.html) Modified: xfwm4/trunk/src/client.c =================================================================== --- xfwm4/trunk/src/client.c 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/client.c 2006-06-14 09:27:23 UTC (rev 22096) @@ -1420,6 +1420,7 @@ if (getNetWMUserTime (display_info, c->window, &c->user_time)) { FLAG_SET (c->flags, CLIENT_FLAG_HAS_USER_TIME); + myDisplaySetLastUserTime (display_info, c->user_time); } } Modified: xfwm4/trunk/src/compositor.c =================================================================== --- xfwm4/trunk/src/compositor.c 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/compositor.c 2006-06-14 09:27:23 UTC (rev 22096) @@ -68,16 +68,19 @@ !FLAG_TEST (cw->c->flags, CLIENT_FLAG_FULLSCREEN)) #define WIN_IS_OVERRIDE(cw) (cw->c == NULL) #define WIN_IS_ARGB(cw) (cw->argb) -#define WIN_IS_OPAQUE(cw) ((cw->opacity == NET_WM_OPAQUE) && !WIN_IS_ARGB(cw)) +#define WIN_IS_OPAQUE(cw) (((cw->opacity == NET_WM_OPAQUE) && !WIN_IS_ARGB(cw)) || (cw->screen_info->overlays)) +#define WIN_IS_NATIVE_OPAQUE(cw) ((cw->native_opacity) && !WIN_IS_ARGB(cw)) #define WIN_IS_FULLSCREEN(cw) ((cw->attr.x == 0) && \ (cw->attr.y == 0) && \ (cw->attr.width == gdk_screen_get_width (cw->screen_info->gscr)) && \ (cw->attr.height == gdk_screen_get_height (cw->screen_info->gscr))) #define WIN_IS_SHAPED(cw) ((!WIN_IS_OVERRIDE(cw) && FLAG_TEST (cw->c->flags, CLIENT_FLAG_HAS_SHAPE)) || \ (WIN_IS_OVERRIDE(cw) && (cw->shaped))) -#define WIN_IS_VISIBLE(cw) ((cw->damaged) && (cw->viewable)) +#define WIN_IS_VISIBLE(cw) ((cw->viewable) && (cw->damage)) +#define WIN_IS_DAMAGED(cw) (cw->damaged) +#define WIN_IS_REDIRECTED(cw) (cw->redirected) -/* #define IDLE_REPAINT */ +#define USE_IDLE_REPAINT typedef struct _CWindow CWindow; struct _CWindow @@ -93,6 +96,7 @@ gboolean redirected; gboolean argb; gboolean skipped; + gboolean native_opacity; Damage damage; #if HAVE_NAME_WINDOW_PIXMAP @@ -115,7 +119,6 @@ gint shadow_height; guint opacity; - guint ignore_unmap; }; static CWindow* @@ -311,7 +314,7 @@ TRACE ("entering presum_gaussian"); map = screen_info->gaussianMap; - screen_info->gsize = map->size; + screen_info->gaussianSize = map->size; center = map->size / 2; if (screen_info->shadowCorner) @@ -323,50 +326,50 @@ g_free (screen_info->shadowTop); } - screen_info->shadowCorner = (guchar *) (g_malloc ((screen_info->gsize + 1) - * (screen_info->gsize + 1) * 26)); - screen_info->shadowTop = (guchar *) (g_malloc ((screen_info->gsize + 1) * 26)); + screen_info->shadowCorner = (guchar *) (g_malloc ((screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) * 26)); + screen_info->shadowTop = (guchar *) (g_malloc ((screen_info->gaussianSize + 1) * 26)); - for (x = 0; x <= screen_info->gsize; x++) + for (x = 0; x <= screen_info->gaussianSize; x++) { - screen_info->shadowTop[25 * (screen_info->gsize + 1) + x] = + screen_info->shadowTop[25 * (screen_info->gaussianSize + 1) + x] = sum_gaussian (map, 1, x - center, center, - screen_info->gsize * 2, - screen_info->gsize * 2); + screen_info->gaussianSize * 2, + screen_info->gaussianSize * 2); for(opacity = 0; opacity < 25; opacity++) { - screen_info->shadowTop[opacity * (screen_info->gsize + 1) + x] = - screen_info->shadowTop[25 * (screen_info->gsize + 1) + x] * opacity / 25; + screen_info->shadowTop[opacity * (screen_info->gaussianSize + 1) + x] = + screen_info->shadowTop[25 * (screen_info->gaussianSize + 1) + x] * opacity / 25; } for(y = 0; y <= x; y++) { - screen_info->shadowCorner[25 * (screen_info->gsize + 1) - * (screen_info->gsize + 1) - + y * (screen_info->gsize + 1) + x] + screen_info->shadowCorner[25 * (screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) + + y * (screen_info->gaussianSize + 1) + x] = sum_gaussian (map, 1, x - center, y - center, - screen_info->gsize * 2, - screen_info->gsize * 2); - screen_info->shadowCorner[25 * (screen_info->gsize + 1) - * (screen_info->gsize + 1) - + x * (screen_info->gsize + 1) + y] - = screen_info->shadowCorner[25 * (screen_info->gsize + 1) - * (screen_info->gsize + 1) - + y * (screen_info->gsize + 1) + x]; + screen_info->gaussianSize * 2, + screen_info->gaussianSize * 2); + screen_info->shadowCorner[25 * (screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) + + x * (screen_info->gaussianSize + 1) + y] + = screen_info->shadowCorner[25 * (screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) + + y * (screen_info->gaussianSize + 1) + x]; for(opacity = 0; opacity < 25; opacity++) { - screen_info->shadowCorner[opacity * (screen_info->gsize + 1) - * (screen_info->gsize + 1) - + y * (screen_info->gsize + 1) + x] - = screen_info->shadowCorner[opacity * (screen_info->gsize + 1) - * (screen_info->gsize + 1) - + x * (screen_info->gsize + 1) + y] - = screen_info->shadowCorner[25 * (screen_info->gsize + 1) - * (screen_info->gsize + 1) - + y * (screen_info->gsize + 1) + x] * opacity / 25; + screen_info->shadowCorner[opacity * (screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) + + y * (screen_info->gaussianSize + 1) + x] + = screen_info->shadowCorner[opacity * (screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) + + x * (screen_info->gaussianSize + 1) + y] + = screen_info->shadowCorner[25 * (screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) + + y * (screen_info->gaussianSize + 1) + x] * opacity / 25; } } } @@ -378,7 +381,7 @@ XImage *ximage; guchar *data; guchar d; - gint gsize; + gint gaussianSize; gint ylimit, xlimit; gint swidth; gint sheight; @@ -390,10 +393,10 @@ g_return_val_if_fail (screen_info != NULL, NULL); TRACE ("entering make_shadow"); - gsize = screen_info->gaussianMap->size; - swidth = width + gsize - screen_info->params->shadow_delta_width - screen_info->params->shadow_delta_x; - sheight = height + gsize - screen_info->params->shadow_delta_height - screen_info->params->shadow_delta_y; - center = gsize / 2; + gaussianSize = screen_info->gaussianMap->size; + swidth = width + gaussianSize - screen_info->params->shadow_delta_width - screen_info->params->shadow_delta_x; + sheight = height + gaussianSize - screen_info->params->shadow_delta_height - screen_info->params->shadow_delta_y; + center = gaussianSize / 2; opacity_int = (gint) (opacity * 25); if ((swidth < 1) || (sheight < 1)) @@ -418,9 +421,9 @@ * Build the gaussian in sections */ - if (screen_info->gsize > 0) + if (screen_info->gaussianSize > 0) { - d = screen_info->shadowTop[opacity_int * (screen_info->gsize + 1) + screen_info->gsize]; + d = screen_info->shadowTop[opacity_int * (screen_info->gaussianSize + 1) + screen_info->gaussianSize]; } else { @@ -432,12 +435,12 @@ * corners */ - ylimit = gsize; + ylimit = gaussianSize; if (ylimit > sheight / 2) { ylimit = (sheight + 1) / 2; } - xlimit = gsize; + xlimit = gaussianSize; if (xlimit > swidth / 2) { xlimit = (swidth + 1) / 2; @@ -446,11 +449,11 @@ { for (x = 0; x < xlimit; x++) { - if ((xlimit == screen_info->gsize) && (ylimit == screen_info->gsize)) + if ((xlimit == screen_info->gaussianSize) && (ylimit == screen_info->gaussianSize)) { - d = screen_info->shadowCorner[opacity_int * (screen_info->gsize + 1) - * (screen_info->gsize + 1) - + y * (screen_info->gsize + 1) + x]; + d = screen_info->shadowCorner[opacity_int * (screen_info->gaussianSize + 1) + * (screen_info->gaussianSize + 1) + + y * (screen_info->gaussianSize + 1) + x]; } else { @@ -469,21 +472,21 @@ * top/bottom */ - x_diff = swidth - (gsize * 2); + x_diff = swidth - (gaussianSize * 2); if (x_diff > 0 && ylimit > 0) { for (y = 0; y < ylimit; y++) { - if (ylimit == screen_info->gsize) + if (ylimit == screen_info->gaussianSize) { - d = screen_info->shadowTop[opacity_int * (screen_info->gsize + 1) + y]; + d = screen_info->shadowTop[opacity_int * (screen_info->gaussianSize + 1) + y]; } else { d = sum_gaussian (screen_info->gaussianMap, opacity, center, y - center, width, height); } - memset (&data[y * swidth + gsize], d, x_diff); - memset (&data[(sheight - y - 1) * swidth + gsize], d, x_diff); + memset (&data[y * swidth + gaussianSize], d, x_diff); + memset (&data[(sheight - y - 1) * swidth + gaussianSize], d, x_diff); } } @@ -493,15 +496,15 @@ for (x = 0; x < xlimit; x++) { - if (xlimit == screen_info->gsize) + if (xlimit == screen_info->gaussianSize) { - d = screen_info->shadowTop[opacity_int * (screen_info->gsize + 1) + x]; + d = screen_info->shadowTop[opacity_int * (screen_info->gaussianSize + 1) + x]; } else { d = sum_gaussian (screen_info->gaussianMap, opacity, x - center, center, width, height); } - for (y = gsize; y < sheight - gsize; y++) + for (y = gaussianSize; y < sheight - gaussianSize; y++) { data[y * swidth + x] = d; data[y * swidth + (swidth - x - 1)] = d; @@ -813,15 +816,20 @@ /* We apply a shadow to the window if: - + - There is no overlay (ie unredirected windows) - It's a window with a frame and the user asked for shadows under regular windows, - it's an override redirect window that is not shaped, not an argb and the user asked for shadows on so called "popup" windows. */ - if ((WIN_IS_OVERRIDE(cw) && !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw)) && screen_info->params->show_popup_shadow) || - (!WIN_IS_OVERRIDE(cw) && (WIN_HAS_FRAME(cw) || !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw))) && screen_info->params->show_frame_shadow)) + if (!(screen_info->overlays) && + (WIN_IS_OVERRIDE(cw) && + !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw)) && + screen_info->params->show_popup_shadow) || + (!WIN_IS_OVERRIDE(cw) && + (WIN_HAS_FRAME(cw) || !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw))) && + screen_info->params->show_frame_shadow)) { XRectangle sr; @@ -958,7 +966,7 @@ g_return_if_fail (cw != NULL); TRACE ("entering unredirect_win"); - if (cw->redirected) + if (WIN_IS_REDIRECTED(cw)) { screen_info = cw->screen_info; display_info = screen_info->display_info; @@ -966,15 +974,15 @@ #if HAVE_NAME_WINDOW_PIXMAP if (cw->name_window_pixmap) { - XFreePixmap (myScreenGetXDisplay (cw->screen_info), cw->name_window_pixmap); + XFreePixmap (display_info->dpy, cw->name_window_pixmap); cw->name_window_pixmap = None; } #endif + screen_info->overlays++; cw->redirected = FALSE; XCompositeUnredirectWindow (display_info->dpy, cw->id, display_info->composite_mode); - - /* Unredirect will cause an unmap notify, ignore it */ - cw->ignore_unmap++; + + TRACE ("Window 0x%lx unredirected"); } } @@ -1086,7 +1094,7 @@ index = screen_info->cwindows; cw = (CWindow *) index->data; - if (WIN_IS_FULLSCREEN(cw) && WIN_IS_VISIBLE(cw) && WIN_IS_OVERRIDE(cw) && WIN_IS_OPAQUE(cw) && (cw->redirected)) + if (WIN_IS_FULLSCREEN(cw) && WIN_IS_VISIBLE(cw) && WIN_IS_OVERRIDE(cw) && WIN_IS_NATIVE_OPAQUE(cw) && WIN_IS_REDIRECTED(cw)) { TRACE ("Toplevel window 0x%lx is fullscreen, unredirecting", cw->id); unredirect_win (cw); @@ -1117,13 +1125,13 @@ cw = (CWindow *) index->data; TRACE ("painting forward 0x%lx", cw->id); - if (!WIN_IS_VISIBLE(cw)) + if (!WIN_IS_VISIBLE(cw) || !WIN_IS_DAMAGED(cw) || !WIN_IS_REDIRECTED(cw)) { TRACE ("skipped, not damaged or not viewable 0x%lx", cw->id); cw->skipped = TRUE; continue; } - + if ((cw->attr.x + cw->attr.width < 1) || (cw->attr.y + cw->attr.height < 1) || (cw->attr.x >= screen_width) || (cw->attr.y >= screen_height)) { @@ -1246,7 +1254,7 @@ } } -#ifdef IDLE_REPAINT +#ifdef USE_IDLE_REPAINT static void remove_timeouts (DisplayInfo *display_info) { @@ -1262,7 +1270,7 @@ display_info->compositor_timeout_id = 0; } } -#endif /* IDLE_REPAINT */ +#endif /* USE_IDLE_REPAINT */ static void repair_display (DisplayInfo *display_info) @@ -1278,16 +1286,16 @@ return; } -#ifdef IDLE_REPAINT +#ifdef USE_IDLE_REPAINT remove_timeouts (display_info); -#endif /* IDLE_REPAINT */ +#endif /* USE_IDLE_REPAINT */ for (screens = display_info->screens; screens; screens = g_slist_next (screens)) { repair_screen ((ScreenInfo *) screens->data); } } -#ifdef IDLE_REPAINT +#ifdef USE_IDLE_REPAINT static gboolean compositor_idle_cb (gpointer data) { @@ -1310,12 +1318,12 @@ return FALSE; } -#endif /* IDLE_REPAINT */ +#endif /* USE_IDLE_REPAINT */ static void add_repair (DisplayInfo *display_info) { -#ifdef IDLE_REPAINT +#ifdef USE_IDLE_REPAINT if (display_info->compositor_idle_id != 0) { return; @@ -1331,7 +1339,7 @@ display_info->compositor_timeout_id = g_timeout_add (50 /* ms */, compositor_timeout_cb, display_info); -#endif /* IDLE_REPAINT */ +#endif /* USE_IDLE_REPAINT */ } static void @@ -1475,32 +1483,28 @@ for (index = screen_info->cwindows; index; index = g_list_next (index)) { CWindow *cw2 = (CWindow *) index->data; - if (cw2 == cw) { break; } - else if (WIN_IS_OPAQUE(cw2) && WIN_IS_VISIBLE (cw2)) + else if (WIN_IS_OPAQUE(cw2) && WIN_IS_VISIBLE(cw2)) { - if ((cw2->clientSize) && (screen_info->params->frame_opacity < 100)) + if (!WIN_IS_REDIRECTED(cw2)) { - TRACE ("Subtract client region of 0x%lx (%i, %i) %ix%i from 0x%lx", - cw2->id, cw2->attr.x, cw2->attr.y, cw2->attr.width, cw2->attr.height, cw->id); + XFixesDestroyRegion (myScreenGetXDisplay (cw->screen_info), parts); + cw->damaged = FALSE; + return; + } + else if ((cw2->clientSize) && (screen_info->params->frame_opacity < 100)) + { XFixesSubtractRegion (myScreenGetXDisplay (screen_info), parts, parts, cw2->clientSize); } else if (cw2->borderSize) { - TRACE ("Subtract border region of 0x%lx (%i, %i) %ix%i from 0x%lx", - cw2->id, cw2->attr.x, cw2->attr.y, cw2->attr.width, cw2->attr.height, cw->id); XFixesSubtractRegion (myScreenGetXDisplay (screen_info), parts, parts, cw2->borderSize); } - else - { - TRACE ("Nothing to substract of 0x%lx (%i, %i) %ix%i from 0x%lx", - cw2->id, cw2->attr.x, cw2->attr.y, cw2->attr.width, cw2->attr.height, cw->id); - } } } @@ -1611,8 +1615,14 @@ cw->viewable = TRUE; cw->damaged = FALSE; + screen_info = cw->screen_info; - add_repair (cw->screen_info->display_info); + if (!(cw->redirected)) + { + screen_info->overlays++; + } + + add_repair (screen_info->display_info); } static void @@ -1623,17 +1633,15 @@ g_return_if_fail (cw != NULL); TRACE ("entering unmap_win 0x%lx", cw->id); - if (cw->ignore_unmap > 0) - { - TRACE ("Ignore unmap of unredirected 0x%lx", cw->id); - cw->ignore_unmap--; - return; - } - cw->damaged = FALSE; screen_info = cw->screen_info; cw->viewable = FALSE; + if (!(cw->redirected) && (screen_info->overlays > 0)) + { + screen_info->overlays--; + } + if (cw->extents != None) { add_damage (screen_info, cw->extents); @@ -1657,15 +1665,21 @@ display_info = screen_info->display_info; c = cw->c; + cw->native_opacity = FALSE; if (c) { cw->opacity = c->opacity; + cw->native_opacity = WIN_IS_OPAQUE(cw); } + else if (getOpacity (display_info, cw->id, &cw->opacity)) + { + cw->native_opacity = WIN_IS_OPAQUE(cw); + } else { cw->opacity = (double) (screen_info->params->popup_opacity / 100.0) * NET_WM_OPAQUE; + cw->native_opacity = TRUE; } - getOpacity (display_info, cw->id, &cw->opacity); } static void @@ -1686,7 +1700,7 @@ TRACE ("An error occured getting window attributes, 0x%lx not added", id); return; } - + if (c) { screen_info = c->screen_info; @@ -1751,7 +1765,6 @@ new->clientSize = None; new->extents = None; new->shadow = None; - new->ignore_unmap = 0; new->shadow_dx = 0; new->shadow_dy = 0; new->shadow_width = 0; @@ -1851,7 +1864,7 @@ cw->extents = None; } - if ((cw->attr.width != width) || (cw->attr.height != height)) + if ((cw->attr.width != width) || (cw->attr.height != height) || (cw->attr.border_width != bw)) { #if HAVE_NAME_WINDOW_PIXMAP if (cw->name_window_pixmap) @@ -1859,12 +1872,12 @@ XFreePixmap (myScreenGetXDisplay (cw->screen_info), cw->name_window_pixmap); cw->name_window_pixmap = None; } -#endif if (cw->picture) { XRenderFreePicture (myScreenGetXDisplay (cw->screen_info), cw->picture); cw->picture = None; } +#endif if (cw->shadow) { @@ -1932,7 +1945,7 @@ TRACE ("entering compositorHandleDamage for 0x%lx", ev->drawable); cw = find_cwindow_in_display (display_info, ev->drawable); - if ((cw) && (cw->redirected)) + if ((cw) && WIN_IS_REDIRECTED(cw)) { repair_win (cw); add_repair (display_info); @@ -1996,6 +2009,7 @@ cw->opacity = NET_WM_OPAQUE; } set_win_opacity (cw, cw->opacity); + cw->native_opacity = WIN_IS_OPAQUE(cw); /* Transset changes the property on the frame, not the client window. We need to check and update the client "opacity" @@ -2180,6 +2194,50 @@ } static void +compositorHandleMapNotify (DisplayInfo *display_info, XMapEvent *ev) +{ + CWindow *cw; + + g_return_if_fail (display_info != NULL); + g_return_if_fail (ev != NULL); + TRACE ("entering compositorHandleUnmapNotify for 0x%lx", ev->window); + + if (!(display_info->enable_compositor)) + { + TRACE ("compositor disabled"); + return; + } + + cw = find_cwindow_in_display (display_info, ev->window); + if (cw) + { + map_win (cw); + } +} + +static void +compositorHandleUnmapNotify (DisplayInfo *display_info, XUnmapEvent *ev) +{ + CWindow *cw; + + g_return_if_fail (display_info != NULL); + g_return_if_fail (ev != NULL); + TRACE ("entering compositorHandleUnmapNotify for 0x%lx", ev->window); + + if (!(display_info->enable_compositor)) + { + TRACE ("compositor disabled"); + return; + } + + cw = find_cwindow_in_display (display_info, ev->window); + if (cw) + { + unmap_win (cw); + } +} + +static void compositorHandleShapeNotify (DisplayInfo *display_info, XShapeEvent *ev) { CWindow *cw; @@ -2216,6 +2274,26 @@ #endif /* HAVE_COMPOSITOR */ +static gboolean +compositorIsUsable (DisplayInfo *display_info) +{ +#ifdef HAVE_COMPOSITOR + if (!display_info->enable_compositor) + { + TRACE ("compositor disabled"); + return FALSE; + } + else if (display_info->composite_mode != CompositeRedirectManual) + { + TRACE ("compositor not set to manual redirect mode"); + return FALSE; + } + return TRUE; +#else + return FALSE; +#endif /* HAVE_COMPOSITOR */ +} + void compositorWindowSetOpacity (DisplayInfo *display_info, Window id, guint opacity) { @@ -2226,9 +2304,8 @@ g_return_if_fail (id != None); TRACE ("entering compositorSetOpacity for 0x%lx", id); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return; } @@ -2250,9 +2327,8 @@ g_return_if_fail (id != None); TRACE ("entering compositorMapWindow for 0x%lx", id); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return; } @@ -2277,9 +2353,8 @@ g_return_if_fail (id != None); TRACE ("entering compositorUnmapWindow for 0x%lx", id); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return; } @@ -2301,9 +2376,8 @@ g_return_if_fail (id != None); TRACE ("entering compositorAddWindow for 0x%lx", id); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return; } @@ -2336,9 +2410,8 @@ g_return_if_fail (id != None); TRACE ("entering compositorRemoveWindow: 0x%lx", id); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return; } @@ -2359,13 +2432,11 @@ g_return_if_fail (ev != NULL); TRACE ("entering compositorHandleEvent"); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return; } - - if (ev->type == CreateNotify) + else if (ev->type == CreateNotify) { compositorHandleCreateNotify (display_info, (XCreateWindowEvent *) ev); } @@ -2393,6 +2464,14 @@ { compositorHandlePropertyNotify (display_info, (XPropertyEvent *) ev); } + else if (ev->type == MapNotify) + { + compositorHandleMapNotify (display_info, (XMapEvent *) ev); + } + else if (ev->type == UnmapNotify) + { + compositorHandleUnmapNotify (display_info, (XUnmapEvent *) ev); + } else if (ev->type == (display_info->damage_event_base + XDamageNotify)) { compositorHandleDamage (display_info, (XDamageNotifyEvent *) ev); @@ -2401,9 +2480,9 @@ { compositorHandleShapeNotify (display_info, (XShapeEvent *) ev); } -#ifndef IDLE_REPAINT +#ifndef USE_IDLE_REPAINT repair_display (display_info); -#endif /* IDLE_REPAINT */ +#endif /* USE_IDLE_REPAINT */ #endif /* HAVE_COMPOSITOR */ } @@ -2417,9 +2496,8 @@ g_return_val_if_fail (display_info != NULL, FALSE); TRACE ("entering compositorCheckDamageEvent"); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return FALSE; } @@ -2436,6 +2514,7 @@ compositorInitDisplay (DisplayInfo *display_info) { #ifdef HAVE_COMPOSITOR + int composite_major, composite_minor; if (!XCompositeQueryExtension (display_info->dpy, &display_info->composite_event_base, @@ -2504,6 +2583,12 @@ } display_info->composite_mode = 0; +#if HAVE_NAME_WINDOW_PIXMAP + XCompositeQueryVersion (display_info->dpy, &composite_major, &composite_minor); + display_info->have_name_window_pixmap = ((composite_major > 0) || (composite_minor >= 2)); +#else + display_info->have_name_window_pixmap = FALSE; +#endif #else /* HAVE_COMPOSITOR */ display_info->enable_compositor = FALSE; @@ -2518,10 +2603,11 @@ g_return_if_fail (display_info != NULL); TRACE ("entering compositorInitDisplay"); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { return; } + repair_display (display_info); #endif /* HAVE_COMPOSITOR */ } @@ -2558,9 +2644,9 @@ display_info = screen_info->display_info; screen_info->compositor_active = FALSE; - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - return FALSE; + return; } gdk_error_trap_push (); @@ -2598,7 +2684,7 @@ return FALSE; } - screen_info->gsize = -1; + screen_info->gaussianSize = -1; screen_info->gaussianMap = make_gaussian_map(SHADOW_RADIUS); presum_gaussian (screen_info); screen_info->rootBuffer = None; @@ -2607,6 +2693,7 @@ screen_info->allDamage = None; screen_info->cwindows = NULL; screen_info->compositor_active = TRUE; + screen_info->overlays = 0; XClearArea (myScreenGetXDisplay (screen_info), screen_info->xroot, 0, 0, 0, 0, TRUE); @@ -2628,16 +2715,11 @@ TRACE ("entering compositorUnmanageScreen"); display_info = screen_info->display_info; - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { return; } - if (!(screen_info->compositor_active)) - { - return; - } - i = 0; for (index = screen_info->cwindows; index; index = g_list_next (index)) { @@ -2678,7 +2760,7 @@ screen_info->gaussianMap = NULL; } - screen_info->gsize = -1; + screen_info->gaussianSize = -1; XCompositeUnredirectSubwindows (display_info->dpy, screen_info->xroot, display_info->composite_mode); #endif /* HAVE_COMPOSITOR */ } @@ -2693,16 +2775,11 @@ TRACE ("entering compositorRepairScreen"); display_info = screen_info->display_info; - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { return; } - if (!(screen_info->compositor_active)) - { - return; - } - repair_screen (screen_info); #endif /* HAVE_COMPOSITOR */ } @@ -2717,6 +2794,11 @@ TRACE ("entering compositorUpdateScreenSize"); display_info = screen_info->display_info; + if (!compositorIsUsable (display_info)) + { + return; + } + if (screen_info->rootBuffer) { XRenderFreePicture (display_info->dpy, screen_info->rootBuffer); @@ -2737,16 +2819,11 @@ TRACE ("entering compositorRepairScreen"); display_info = screen_info->display_info; - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { return; } - if (!(screen_info->compositor_active)) - { - return; - } - for (index = screen_info->cwindows; index; index = g_list_next (index)) { CWindow *cw2 = (CWindow *) index->data; @@ -2767,9 +2844,8 @@ g_return_if_fail (id != None); TRACE ("entering compositorDamageWindow: 0x%lx", id); - if (!(display_info->enable_compositor)) + if (!compositorIsUsable (display_info)) { - TRACE ("compositor disabled"); return; } Modified: xfwm4/trunk/src/display.c =================================================================== --- xfwm4/trunk/src/display.c 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/display.c 2006-06-14 09:27:23 UTC (rev 22096) @@ -650,6 +650,28 @@ return (Time) display->current_time; } +Time myDisplayGetLastUserTime (DisplayInfo *); +void myDisplaySetLastUserTime (DisplayInfo *, + Time); +Time +myDisplayGetLastUserTime (DisplayInfo *display) +{ + g_return_val_if_fail (display != NULL, (Time) CurrentTime); + + return (Time) display->last_user_time; +} + +void +myDisplaySetLastUserTime (DisplayInfo *display, Time timestamp) +{ + g_return_if_fail (display != NULL); + + if (TIMESTAMP_IS_BEFORE(display->last_user_time, timestamp)) + { + display->last_user_time = timestamp; + } +} + static gdouble get_time(void) { Modified: xfwm4/trunk/src/display.h =================================================================== --- xfwm4/trunk/src/display.h 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/display.h 2006-06-14 09:27:23 UTC (rev 22096) @@ -64,6 +64,17 @@ #define WINDOW 1 #define FRAME 2 +/* + * The following macro is taken straight from metacity, + * if that needs some explanation, please refer to metacity's + * display.h source where it is explaned + */ +#define TIMESTAMP_IS_BEFORE_REAL(time1, time2) ((((time1) < (time2)) && ((time2) - (time1) < ((guint32)-1)/2 )) || \ + (((time1) > (time2)) && ((time1) - (time2) > ((guint32)-1)/2 ))) +#define TIMESTAMP_IS_BEFORE(time1, time2) ((time1) == 0 || \ + (TIMESTAMP_IS_BEFORE_REAL(time1, time2) && \ + (time2) != 0)) + enum { COMPOSITING_MANAGER = 0, @@ -200,6 +211,7 @@ gchar* hostname; Time current_time; + Time last_user_time; gboolean enable_compositor; #ifdef HAVE_RENDER @@ -271,6 +283,9 @@ Time myDisplayUpdateCurentTime (DisplayInfo *, XEvent *); Time myDisplayGetCurrentTime (DisplayInfo *); +Time myDisplayGetLastUserTime (DisplayInfo *); +void myDisplaySetLastUserTime (DisplayInfo *, + Time); gboolean myDisplayTestXrender (DisplayInfo *, gdouble); Modified: xfwm4/trunk/src/events.c =================================================================== --- xfwm4/trunk/src/events.c 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/events.c 2006-06-14 09:27:23 UTC (rev 22096) @@ -366,7 +366,6 @@ { screen_info = c->screen_info; key = getKeyPressed (screen_info, ev); - c->user_time = myDisplayGetCurrentTime (display_info); mode = c->win_state & WIN_STATE_MAXIMIZED; switch (key) @@ -783,7 +782,6 @@ state = ev->state & MODIFIER_MASK; win = ev->subwindow; screen_info = c->screen_info; - c->user_time = myDisplayGetCurrentTime (display_info); if ((ev->button == Button1) && (screen_info->params->easy_click) && (state == screen_info->params->easy_click)) { @@ -1129,12 +1127,7 @@ { FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_MAP_PENDING); } - compositorMapWindow (display_info, c->frame); } - else if (myDisplayGetScreenFromRoot (display_info, ev->event)) - { - compositorMapWindow (display_info, ev->window); - } } static void @@ -1178,7 +1171,6 @@ screen_info = c->screen_info; clientPassFocus (screen_info, c, c); - compositorUnmapWindow (display_info, c->frame); /* * ICCCM spec states that a client wishing to switch @@ -1207,10 +1199,6 @@ clientUnframe (c, FALSE); } } - else - { - compositorUnmapWindow (display_info, ev->window); - } } static gboolean @@ -1820,6 +1808,7 @@ TRACE ("client \"%s\" (0x%lx) has received a net_wm_user_time notify", c->name, c->window); if (getNetWMUserTime (display_info, c->window, &c->user_time)) { + myDisplaySetLastUserTime (display_info, c->user_time); FLAG_SET (c->flags, CLIENT_FLAG_HAS_USER_TIME); } } @@ -1976,12 +1965,11 @@ TRACE ("client \"%s\" (0x%lx) has received a net_active_window event", c->name, c->window); if (ev->data.l[0] != 0) { - Time current = myDisplayGetCurrentTime (screen_info->display_info); + Time current = myDisplayGetLastUserTime (screen_info->display_info); Time ev_time = (Time) ev->data.l[1]; - /* We are simply ignoring XServer time wraparound here */ TRACE ("Time of event received is %u, current XServer time is %u", (unsigned int) ev_time, (unsigned int) current); - if ((screen_info->params->prevent_focus_stealing) && (ev_time != (Time) 0) && (ev_time < current)) + if ((screen_info->params->prevent_focus_stealing) && (ev_time != (Time) 0) && TIMESTAMP_IS_BEFORE(ev_time, current)) { FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); clientSetNetState (c); Modified: xfwm4/trunk/src/hints.h =================================================================== --- xfwm4/trunk/src/hints.h 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/hints.h 2006-06-14 09:27:23 UTC (rev 22096) @@ -112,9 +112,10 @@ #define NET_WM_OPAQUE 0xffffffff /* Convenient macro */ -#define HINTS_ACCEPT_INPUT(wmhints) (!(wmhints) || \ - ((wmhints) && !(wmhints->flags & InputHint)) || \ +#define HINTS_ACCEPT_INPUT(wmhints) (!(wmhints) || \ + ((wmhints) && !(wmhints->flags & InputHint)) || \ ((wmhints) && (wmhints->flags & InputHint) && (wmhints->input))) + typedef struct { unsigned long orientation; Modified: xfwm4/trunk/src/screen.h =================================================================== --- xfwm4/trunk/src/screen.h 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/screen.h 2006-06-14 09:27:23 UTC (rev 22096) @@ -131,21 +131,21 @@ #endif #ifdef HAVE_COMPOSITOR - gboolean compositor_active; - GList *cwindows; gaussian_conv *gaussianMap; - gint gsize; + gint gaussianSize; guchar *shadowCorner; guchar *shadowTop; - Picture rootPicture; Picture rootBuffer; Picture blackPicture; Picture rootTile; XserverRegion allDamage; + + guint overlays; + gboolean compositor_active; gboolean clipChanged; #endif /* HAVE_COMPOSITOR */ }; Modified: xfwm4/trunk/src/startup_notification.c =================================================================== --- xfwm4/trunk/src/startup_notification.c 2006-06-14 09:00:01 UTC (rev 22095) +++ xfwm4/trunk/src/startup_notification.c 2006-06-14 09:27:23 UTC (rev 22096) @@ -38,6 +38,7 @@ #include <gtk/gtk.h> #include <libxfce4util/libxfce4util.h> +#include "display.h" #include "screen.h" #include "client.h" @@ -284,9 +285,10 @@ /* Set initial time */ timestamp = sn_startup_sequence_get_timestamp (sequence); TRACE ("Given startup time: %u", (unsigned int) timestamp); - if (timestamp > c->user_time) + if ((c->user_time == (Time) 0) || TIMESTAMP_IS_BEFORE(c->user_time, timestamp)) { c->user_time = timestamp; + myDisplaySetLastUserTime (screen_info->display_info, c->user_time); } FLAG_SET (c->flags, CLIENT_FLAG_HAS_STARTUP_TIME); _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits