[Xfce4-commits] r26691 - xfwm4/branches/xfce_4_4/src

Olivier Fourdan olivier at xfce.org
Thu Mar 20 23:38:35 CET 2008


Author: olivier
Date: 2008-03-20 22:38:35 +0000 (Thu, 20 Mar 2008)
New Revision: 26691

Modified:
   xfwm4/branches/xfce_4_4/src/compositor.c
   xfwm4/branches/xfce_4_4/src/display.h
   xfwm4/branches/xfce_4_4/src/screen.h
Log:
Backport overlay and compositor support from trunk (Bug #3849)

Modified: xfwm4/branches/xfce_4_4/src/compositor.c
===================================================================
--- xfwm4/branches/xfce_4_4/src/compositor.c	2008-03-19 23:15:50 UTC (rev 26690)
+++ xfwm4/branches/xfce_4_4/src/compositor.c	2008-03-20 22:38:35 UTC (rev 26691)
@@ -16,12 +16,12 @@
 
         xcompmgr - (c) 2003 Keith Packard
         metacity - (c) 2003, 2004 Red Hat, Inc.
-        xfwm4    - (c) 2005-2006 Olivier Fourdan
+        xfwm4    - (c) 2005-2008 Olivier Fourdan
 
 */
 
 #ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
 #endif
 
 #include <X11/Xlib.h>
@@ -70,9 +70,10 @@
 #define WIN_NO_SHADOW(cw)               ((cw->c) && \
                                            (FLAG_TEST (cw->c->flags, CLIENT_FLAG_FULLSCREEN | CLIENT_FLAG_BELOW) || \
                                               (cw->c->type & (WINDOW_DOCK | WINDOW_DESKTOP))))
+#define WIN_IS_DOCK(cw)                 (WIN_HAS_CLIENT(cw) && (cw->c->type & WINDOW_DOCK))
 #define WIN_IS_OVERRIDE(cw)             (cw->attr.override_redirect)
 #define WIN_IS_ARGB(cw)                 (cw->argb)
-#define WIN_IS_OPAQUE(cw)               (((cw->opacity == NET_WM_OPAQUE) && !WIN_IS_ARGB(cw)) || (cw->screen_info->overlays))
+#define WIN_IS_OPAQUE(cw)               (((cw->opacity == NET_WM_OPAQUE) && !WIN_IS_ARGB(cw)) || (cw->screen_info->wins_unredirected))
 #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) && \
@@ -549,7 +550,7 @@
         return (None);
     }
 
-    shadowPixmap = XCreatePixmap (display_info->dpy, screen_info->xroot,
+    shadowPixmap = XCreatePixmap (display_info->dpy, screen_info->output,
                                 shadowImage->width, shadowImage->height, 8);
     if (shadowPixmap == None)
     {
@@ -602,7 +603,7 @@
     g_return_val_if_fail (render_format != NULL , None);
 
     pixmap = XCreatePixmap (display_info->dpy,
-                            screen_info->xroot, 1, 1, argb ? 32 : 8);
+                            screen_info->output, 1, 1, argb ? 32 : 8);
     g_return_val_if_fail (pixmap != None, None);
 
     pa.repeat = TRUE;
@@ -814,7 +815,7 @@
 #endif
     if (!pixmap)
     {
-        pixmap = XCreatePixmap (dpy, screen_info->xroot, 1, 1,
+        pixmap = XCreatePixmap (dpy, screen_info->output, 1, 1,
                                 DefaultDepth (dpy, screen_info->screen));
         g_return_val_if_fail (pixmap != None, None);
         fill = TRUE;
@@ -866,7 +867,7 @@
     g_return_val_if_fail (format != NULL, None);
 
     rootPixmap = XCreatePixmap (display_info->dpy,
-                                screen_info->xroot,
+                                screen_info->output,
                                 screen_width, screen_height, depth);
     g_return_val_if_fail (rootPixmap != None, None);
 
@@ -919,21 +920,21 @@
 
     /*
        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 (!(screen_info->overlays) &&
-         ((screen_info->params->show_popup_shadow &&
+    if ((screen_info->params->show_popup_shadow &&
               WIN_IS_OVERRIDE(cw) &&
+              !WIN_IS_FULLSCREEN(cw) &&
               !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw))) ||
           (screen_info->params->show_frame_shadow &&
               !WIN_IS_OVERRIDE(cw) &&
               !WIN_NO_SHADOW(cw) &&
-              (WIN_HAS_FRAME(cw) || !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw))))))
+              !WIN_IS_DOCK(cw) &&
+              (WIN_HAS_FRAME(cw) || !(WIN_IS_ARGB(cw) || WIN_IS_SHAPED(cw)))))
     {
         XRectangle sr;
 
@@ -1083,7 +1084,7 @@
         XCompositeUnredirectWindow (display_info->dpy, cw->id, display_info->composite_mode);
         XSync (display_info->dpy, FALSE);
 
-        TRACE ("Window 0x%lx unredirected, overlays is %i", cw->id, screen_info->overlays);
+        TRACE ("Window 0x%lx unredirected, wins_unredirected is %i", cw->id, screen_info->wins_unredirected);
     }
 }
 
@@ -1124,11 +1125,11 @@
                                          * screen_info->params->frame_opacity
                                          / (NET_WM_OPAQUE * 100.0);
 
-                cw->alphaBorderPict = solid_picture (screen_info, 
-                                                     FALSE, 
-                                                     frame_opacity, 
-                                                     0.0, /* red   */ 
-                                                     0.0, /* green */ 
+                cw->alphaBorderPict = solid_picture (screen_info,
+                                                     FALSE,
+                                                     frame_opacity,
+                                                     0.0, /* red   */
+                                                     0.0, /* green */
                                                      0.0  /* blue  */);
             }
 
@@ -1226,7 +1227,6 @@
     gint screen_width;
     gint screen_height;
     gint screen_number;
-    Window xroot;
     CWindow *cw;
 
     TRACE ("entering paint_all");
@@ -1237,7 +1237,6 @@
     screen_width = screen_info->width;
     screen_height = screen_info->height;
     screen_number = screen_info->screen;
-    xroot = screen_info->xroot;
 
     /* Create root buffer if not done yet */
     if (screen_info->rootBuffer == None)
@@ -1355,9 +1354,9 @@
             if ((cw->opacity != NET_WM_OPAQUE) && !(cw->alphaPict))
             {
                 cw->alphaPict = solid_picture (screen_info, FALSE,
-                                               (double) cw->opacity / NET_WM_OPAQUE,  
-                                               0.0, /* red   */ 
-                                               0.0, /* green */ 
+                                               (double) cw->opacity / NET_WM_OPAQUE,
+                                               0.0, /* red   */
+                                               0.0, /* green */
                                                0.0  /* blue  */);
             }
             XFixesIntersectRegion (dpy, cw->borderClip, cw->borderClip, cw->borderSize);
@@ -1755,28 +1754,43 @@
 map_win (CWindow *cw)
 {
     ScreenInfo *screen_info;
+    DisplayInfo *display_info;
 
     g_return_if_fail (cw != NULL);
-    TRACE ("entering map_win 0x%lx", cw->id);
+    TRACE ("entering map_win 0x%lx\n", cw->id);
 
-    cw->viewable = TRUE;
-    cw->damaged = FALSE;
+    screen_info = cw->screen_info;
+    display_info = screen_info->display_info;
 
-    screen_info = cw->screen_info;
     if (!WIN_IS_REDIRECTED(cw))
     {
-        screen_info->overlays++;
-        TRACE ("Mapping unredirected window 0x%lx, overlays increased to %i", cw->id, screen_info->overlays);
+        /* To be safe, we count only the fullscreen overlays */
+        if (WIN_IS_FULLSCREEN(cw) && WIN_IS_VIEWABLE (cw))
+        {
+            screen_info->wins_unredirected++;
+        }
+#if HAVE_OVERLAYS
+        if ((screen_info->wins_unredirected == 1) && (display_info->have_overlays))
+        {
+            TRACE ("Unmapping overlay window");
+            XUnmapWindow (myScreenGetXDisplay (screen_info), screen_info->overlay);
+        }
+#endif /* HAVE_OVERLAYS */
+        TRACE ("Mapping unredirected window 0x%lx, wins_unredirected increased to %i", cw->id, screen_info->wins_unredirected);
         return;
     }
+
+    cw->viewable = TRUE;
+    cw->damaged = FALSE;
+
     if (!screen_info->params->unredirect_overlays)
     {
-        TRACE ("Not unredirecting overlays");
+        TRACE ("Not unredirecting wins_unredirected");
         return;
     }
 
     /* Check for new windows to un-redirect. */
-    if (WIN_IS_FULLSCREEN(cw) && WIN_HAS_DAMAGE(cw) && WIN_IS_OVERRIDE(cw) &&
+    if ((WIN_IS_FULLSCREEN(cw) || (screen_info->wins_unredirected > 0)) && WIN_HAS_DAMAGE(cw) && WIN_IS_OVERRIDE(cw) &&
         WIN_IS_NATIVE_OPAQUE(cw) && WIN_IS_REDIRECTED(cw) && !WIN_IS_SHAPED(cw))
     {
         CWindow *top;
@@ -1797,31 +1811,37 @@
 unmap_win (CWindow *cw)
 {
     ScreenInfo *screen_info;
+    DisplayInfo *display_info;
 
     g_return_if_fail (cw != NULL);
     TRACE ("entering unmap_win 0x%lx", cw->id);
 
     screen_info = cw->screen_info;
-    if (!WIN_IS_REDIRECTED(cw) && (screen_info->overlays > 0))
-    {
-        screen_info->overlays--;
-        TRACE ("Unmapped window 0x%lx, overlays decreased to %i", cw->id, screen_info->overlays);
-    }
+    display_info = screen_info->display_info;
 
-    if (!screen_info->overlays)
+    if (!WIN_IS_REDIRECTED(cw) && WIN_IS_FULLSCREEN(cw) && (screen_info->wins_unredirected > 0))
     {
-        /* Repaint immediately if that was the last unredirected window */
-
-        if (!WIN_IS_REDIRECTED(cw))
+        screen_info->wins_unredirected--;
+        TRACE ("Unmapped window 0x%lx, wins_unredirected decreased to %i", cw->id, screen_info->wins_unredirected);
+        if (!screen_info->wins_unredirected)
         {
+            /* Restore the overlay if that was the last unredirected window */
+#if HAVE_OVERLAYS
+            if (display_info->have_overlays)
+            {
+                TRACE ("Remapping overlay window");
+                XMapWindow (myScreenGetXDisplay (screen_info), screen_info->overlay);
+            }
+#endif /* HAVE_OVERLAYS */
             damage_screen (screen_info);
             repair_screen (screen_info);
-        }
-        else if (WIN_IS_VISIBLE(cw))
-        {
-            damage_win (cw);
-        }
+       }
     }
+    else if (WIN_IS_VISIBLE(cw))
+    {
+        damage_win (cw);
+    }
+
     cw->viewable = FALSE;
     cw->damaged = FALSE;
     free_win_data (cw, FALSE);
@@ -1925,7 +1945,11 @@
     new->shaped = is_shaped (display_info, id);
     new->viewable = (new->attr.map_state == IsViewable);
 
-    if ((new->attr.class != InputOnly) && (id != screen_info->xroot))
+    if ((new->attr.class != InputOnly)
+#if HAVE_OVERLAYS
+         && ((!display_info->have_overlays) || (id != screen_info->overlay))
+#endif
+         && (id != screen_info->output))
     {
         new->damage = XDamageCreate (display_info->dpy, id, XDamageReportNonEmpty);
     }
@@ -2122,7 +2146,10 @@
     {
         ScreenInfo *screen_info;
 
-        unmap_win (cw);
+        if (WIN_IS_VIEWABLE (cw))
+        {
+            unmap_win (cw);
+        }
         screen_info = cw->screen_info;
         screen_info->cwindows = g_list_remove (screen_info->cwindows, (gconstpointer) cw);
 
@@ -2184,7 +2211,7 @@
             ScreenInfo *screen_info = myDisplayGetScreenFromRoot (display_info, ev->window);
             if ((screen_info) && (screen_info->rootTile))
             {
-                XClearArea (display_info->dpy, screen_info->xroot, 0, 0, 0, 0, TRUE);
+                XClearArea (display_info->dpy, screen_info->output, 0, 0, 0, 0, TRUE);
                 XRenderFreePicture (display_info->dpy, screen_info->rootTile);
                 screen_info->rootTile = None;
                 add_repair (display_info);
@@ -2413,7 +2440,10 @@
     cw = find_cwindow_in_display (display_info, ev->window);
     if (cw)
     {
-        unmap_win (cw);
+        if (WIN_IS_VIEWABLE (cw))
+        {
+            unmap_win (cw);
+        }
     }
 }
 
@@ -2650,10 +2680,11 @@
 compositorInitDisplay (DisplayInfo *display_info)
 {
 #ifdef HAVE_COMPOSITOR
-#if HAVE_NAME_WINDOW_PIXMAP
     int composite_major, composite_minor;
-#endif
 
+    composite_major = 0;
+    composite_minor = 0;
+
     if (!XCompositeQueryExtension (display_info->dpy,
                                 &display_info->composite_event_base,
                                 &display_info->composite_error_base))
@@ -2666,9 +2697,11 @@
     else
     {
         display_info->have_composite = TRUE;
+        XCompositeQueryVersion (display_info->dpy, &composite_major, &composite_minor);
 #if DEBUG
         g_print ("composite event base: %i\n", display_info->composite_event_base);
         g_print ("composite error base: %i\n", display_info->composite_error_base);
+        g_print ("composite version: %i.%i\n", composite_major, composite_minor);
 #endif
     }
 
@@ -2705,7 +2738,7 @@
 #if DEBUG
         g_print ("fixes event base: %i\n", display_info->fixes_event_base);
         g_print ("fixes error base: %i\n", display_info->fixes_error_base);
-#endif
+#endif /* DEBUG */
     }
 
     display_info->compositor_idle_id = 0;
@@ -2723,12 +2756,15 @@
 
     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
+#else  /* HAVE_NAME_WINDOW_PIXMAP */
     display_info->have_name_window_pixmap = FALSE;
-#endif
+#endif /* HAVE_NAME_WINDOW_PIXMAP */
 
+#if HAVE_OVERLAYS
+    display_info->have_overlays = ((composite_major > 0) || (composite_minor >= 3));
+#endif /* HAVE_OVERLAYS */
+
 #else /* HAVE_COMPOSITOR */
     display_info->enable_compositor = FALSE;
 #endif /* HAVE_COMPOSITOR */
@@ -2792,8 +2828,38 @@
         return FALSE;
     }
 
+    screen_info->output = screen_info->xroot;
+#if HAVE_OVERLAYS
+    if (display_info->have_overlays)
+    {
+        screen_info->overlay = XCompositeGetOverlayWindow (display_info->dpy, screen_info->xroot);
+        if (screen_info->overlay != None)
+        {
+            XSetWindowAttributes attributes;
+
+            screen_info->root_overlay = XCreateWindow (display_info->dpy, screen_info->overlay,
+                                                       0, 0, screen_info->width, screen_info->height, 0, screen_info->depth,
+                                                       InputOutput, screen_info->visual, 0, &attributes);
+            XMapWindow (display_info->dpy, screen_info->root_overlay);
+            XRaiseWindow (display_info->dpy, screen_info->overlay);
+            XShapeCombineRectangles (display_info->dpy, screen_info->overlay,
+                                     ShapeInput, 0, 0, NULL, 0, ShapeSet, Unsorted);
+            XShapeCombineRectangles (display_info->dpy, screen_info->root_overlay,
+                                     ShapeInput, 0, 0, NULL, 0, ShapeSet, Unsorted);
+            screen_info->output = screen_info->root_overlay;
+            TRACE ("Overlay enabled");
+        }
+        else
+        {
+            /* Something is wrong with overlay support */
+            TRACE ("Cannot get root window overlay, overlay support disabled");
+            display_info->have_overlays = FALSE;
+        }
+    }
+#endif /* HAVE_OVERLAYS */
+
     pa.subwindow_mode = IncludeInferiors;
-    screen_info->rootPicture = XRenderCreatePicture (display_info->dpy, screen_info->xroot,
+    screen_info->rootPicture = XRenderCreatePicture (display_info->dpy, screen_info->output,
                                                      visual_format, CPSubwindowMode, &pa);
 
     if (screen_info->rootPicture == None)
@@ -2807,19 +2873,19 @@
     presum_gaussian (screen_info);
     screen_info->rootBuffer = None;
     /* Change following argb values to play with shadow colors */
-    screen_info->blackPicture = solid_picture (screen_info, 
-                                               TRUE, 
-                                               1.0, /* alpha */ 
-                                               0.0, /* red   */ 
-                                               0.0, /* green */ 
+    screen_info->blackPicture = solid_picture (screen_info,
+                                               TRUE,
+                                               1.0, /* alpha */
+                                               0.0, /* red   */
+                                               0.0, /* green */
                                                0.0  /* blue  */);
     screen_info->rootTile = None;
     screen_info->allDamage = None;
     screen_info->cwindows = NULL;
     screen_info->compositor_active = TRUE;
-    screen_info->overlays = 0;
+    screen_info->wins_unredirected = 0;
 
-    XClearArea (display_info->dpy, screen_info->xroot, 0, 0, 0, 0, TRUE);
+    XClearArea (display_info->dpy, screen_info->output, 0, 0, 0, 0, TRUE);
     compositorSetCMSelection (screen_info, screen_info->xfwm4_win);
     TRACE ("Manual compositing enabled");
 
@@ -2864,6 +2930,17 @@
     screen_info->cwindows = NULL;
     TRACE ("Compositor: removed %i window(s) remaining", i);
 
+#if HAVE_OVERLAYS
+    if (display_info->have_overlays)
+    {
+        XDestroyWindow (display_info->dpy, screen_info->root_overlay);
+        screen_info->root_overlay = None;
+
+        XCompositeReleaseOverlayWindow (display_info->dpy, screen_info->overlay);
+        screen_info->overlay = None;
+    }
+#endif /* HAVE_OVERLAYS */
+
     if (screen_info->rootPicture)
     {
         XRenderFreePicture (display_info->dpy, screen_info->rootPicture);
@@ -2894,7 +2971,7 @@
     }
 
     screen_info->gaussianSize = -1;
-    screen_info->overlays = 0;
+    screen_info->wins_unredirected = 0;
 
     XCompositeUnredirectSubwindows (display_info->dpy, screen_info->xroot,
                                     display_info->composite_mode);

Modified: xfwm4/branches/xfce_4_4/src/display.h
===================================================================
--- xfwm4/branches/xfce_4_4/src/display.h	2008-03-19 23:15:50 UTC (rev 26690)
+++ xfwm4/branches/xfce_4_4/src/display.h	2008-03-20 22:38:35 UTC (rev 26691)
@@ -48,6 +48,11 @@
 #define HAVE_NAME_WINDOW_PIXMAP 1
 #endif /* HAVE_NAME_WINDOW_PIXMAP */
 #endif /* COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2 */
+#if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 3
+#ifndef HAVE_OVERLAYS
+#define HAVE_OVERLAYS 1
+#endif /* HAVE_OVERLAYS */
+#endif /* COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 3 */
 #endif /* HAVE_COMPOSITOR */
 
 #include <gtk/gtk.h>
@@ -286,6 +291,10 @@
     gboolean have_name_window_pixmap;
 #endif /* HAVE_NAME_WINDOW_PIXMAP */
 
+#if HAVE_OVERLAYS
+    gboolean have_overlays;
+#endif /* HAVE_OVERLAYS */
+
 #endif /* HAVE_COMPOSITOR */
 };
 
@@ -331,7 +340,7 @@
 Time                     myDisplayUpdateCurrentTime             (DisplayInfo *,
                                                                  XEvent *);
 Time                     myDisplayGetCurrentTime                (DisplayInfo *);
-Time                     myDisplayGetTime                       (DisplayInfo *, 
+Time                     myDisplayGetTime                       (DisplayInfo *,
                                                                  Time);
 Time                     myDisplayGetLastUserTime               (DisplayInfo *);
 void                     myDisplaySetLastUserTime               (DisplayInfo *,

Modified: xfwm4/branches/xfce_4_4/src/screen.h
===================================================================
--- xfwm4/branches/xfce_4_4/src/screen.h	2008-03-19 23:15:50 UTC (rev 26690)
+++ xfwm4/branches/xfce_4_4/src/screen.h	2008-03-20 22:38:35 UTC (rev 26691)
@@ -133,8 +133,14 @@
 #endif
 
 #ifdef HAVE_COMPOSITOR
+#if HAVE_OVERLAYS
+    Window overlay;
+    Window root_overlay;
+#endif
     GList *cwindows;
+    Window output;
 
+
     gaussian_conv *gaussianMap;
     gint gaussianSize;
     guchar *shadowCorner;
@@ -146,7 +152,7 @@
     Picture rootTile;
     XserverRegion allDamage;
 
-    guint overlays;
+    guint wins_unredirected;
     gboolean compositor_active;
     gboolean clipChanged;
 #endif /* HAVE_COMPOSITOR */



More information about the Xfce4-commits mailing list