summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-09-02 02:53:23 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-09-02 02:53:23 +0000
commitc0455ff674ad53b854239cb77bd8209d7303f3af (patch)
treef8ec895deb3e53543e3f1b43c28be328f7831930
parent291eb697d16574d229c819334204250ab5616077 (diff)
downloadtdebase-c0455ff674ad53b854239cb77bd8209d7303f3af.tar.gz
tdebase-c0455ff674ad53b854239cb77bd8209d7303f3af.zip
Work around ATI fglrx XDamage bug that was causing kompmgr to not draw new popup windows
Clean up kompmgr a bit and attempt to smooth out the window fades git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1250856 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
-rw-r--r--kwin/kompmgr/kompmgr.c125
1 files changed, 106 insertions, 19 deletions
diff --git a/kwin/kompmgr/kompmgr.c b/kwin/kompmgr/kompmgr.c
index 1cbae52eb..96b74bc52 100644
--- a/kwin/kompmgr/kompmgr.c
+++ b/kwin/kompmgr/kompmgr.c
@@ -38,6 +38,7 @@
* Added ability to write PID of process to home directory 08/14/2011
* Added SIGUSR2 handler to reload settings [Prevent flicker on settings change] 08/14/2011
* Added SIGTERM handler to clean up stale PID files on exit 08/14/2011
+ * Added hack to work around ATI fglrx XDamage event generation bugs [WORK_AROUND_FGLRX] 09/01/2011
*
* TODO:
* http://patchwork.freedesktop.org/patch/1053/ [Fix window mapping with re-used window ids]
@@ -72,6 +73,8 @@ check baghira.sf.net for more infos
#define CAN_DO_USABLE 1
+#define WORK_AROUND_FGLRX 1
+
#define _TOPHEIGHT_(x) ((x >> 24) & 0xff)
#define _RIGHTWIDTH_(x) ((x >> 16) & 0xff)
#define _BOTTOMHEIGHT_(x) ((x >> 8) & 0xff)
@@ -122,6 +125,7 @@ typedef struct _win {
unsigned int shadowSize;
Atom windowType;
unsigned long damage_sequence; /* sequence when damage was created */
+ int destroyed;
Bool shapable; /* this will allow window managers to exclude windows if just the deco is shaped*/
Bool shaped;
XRectangle shape_bounds;
@@ -980,7 +984,7 @@ find_win (Display *dpy, Window id)
win *w;
for (w = list; w; w = w->next)
- if (w->id == id)
+ if ((!w->destroyed) && (w->id == id))
return w;
return 0;
}
@@ -1530,6 +1534,8 @@ add_damage (Display *dpy, XserverRegion damage)
allDamage = damage;
}
+static void damage_win (Display *dpy, XDamageNotifyEvent *de);
+
static void
repair_win (Display *dpy, win *w)
{
@@ -1574,17 +1580,45 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
if (!w)
return;
+
w->a.map_state = IsViewable;
/* This needs to be here or else we lose transparency messages */
XSelectInput (dpy, id, PropertyChangeMask);
+ /* This needs to be here since we don't get PropertyNotify when unmapped */
+ w->opacity = get_opacity_prop (dpy, w, OPAQUE);
+ determine_mode (dpy, w);
+
#if CAN_DO_USABLE
w->damage_bounds.x = w->damage_bounds.y = 0;
w->damage_bounds.width = w->damage_bounds.height = 0;
#endif
w->damaged = 0;
+#if HAS_NAME_WINDOW_PIXMAP
+ /* If the window was previously mapped and its pixmap still exists, it
+ is out of date now, so force us to reacquire it. (If the window
+ re-maps before the unmap fade-out finished) */
+ if (w->pixmap)
+ {
+ XFreePixmap (dpy, w->pixmap);
+ w->pixmap = None;
+ }
+#endif
+
+#if WORK_AROUND_FGLRX
+ XserverRegion extents = win_extents (dpy, w);
+ XDamageNotifyEvent de;
+ de.drawable = w->id;
+ de.area.x = 0;
+ de.area.y = 0;
+ de.area.width = w->a.width + w->a.border_width * 2;
+ de.area.height = w->a.height + w->a.border_width * 2;
+ damage_win(dpy, &de);
+ XFixesDestroyRegion (dpy, extents);
+#endif
+
if ((fade && fadeWindows) || (fade && fadeMenuWindows && w->windowType == winMenuAtom))
set_fade (dpy, w, 0, get_opacity_prop(dpy, w, OPAQUE)*1.0/OPAQUE, fade_in_step, 0, False, True, True, True);
}
@@ -2066,7 +2100,7 @@ add_win (Display *dpy, Window id, Window prev)
if (prev)
{
for (p = &list; *p; p = &(*p)->next)
- if ((*p)->id == prev)
+ if ((*p)->id == prev && !(*p)->destroyed)
break;
}
else
@@ -2114,6 +2148,7 @@ add_win (Display *dpy, Window id, Window prev)
new->shadow_width = 0;
new->shadow_height = 0;
new->opacity = OPAQUE;
+ new->destroyed = False;
new->shadowSize = 100;
new->decoHash = 0;
new->show_root_tile = determine_window_transparent_to_desktop(dpy, id);
@@ -2123,15 +2158,12 @@ add_win (Display *dpy, Window id, Window prev)
XShapeSelectInput( dpy, id, ShapeNotifyMask );
- /* moved mode setting to one place */
- new->opacity = get_opacity_prop (dpy, new, OPAQUE);
new->shadowSize = get_shadow_prop (dpy, new);
new->shapable = get_shapable_prop(dpy, new);
new->decoHash = get_decoHash_prop(dpy, new);
tmp = get_dim_prop(dpy, new);
new->dimPicture = (tmp < OPAQUE) ? solid_picture (dpy, True, (double)tmp/OPAQUE, 0.1, 0.1, 0.1) : None;
new->windowType = determine_wintype (dpy, new->id);
- determine_mode (dpy, new);
new->next = *p;
*p = new;
@@ -2161,7 +2193,7 @@ restack_win (Display *dpy, win *w, Window new_above)
/* rehook */
for (prev = &list; *prev; prev = &(*prev)->next)
{
- if ((*prev)->id == new_above)
+ if ((!(*prev)->destroyed) && ((*prev)->id == new_above))
break;
}
w->next = *prev;
@@ -2190,6 +2222,7 @@ configure_win (Display *dpy, XConfigureEvent *ce)
}
return;
}
+
#if CAN_DO_USABLE
if (w->usable)
#endif
@@ -2202,7 +2235,9 @@ configure_win (Display *dpy, XConfigureEvent *ce)
w->shape_bounds.y -= w->a.y;
w->a.x = ce->x;
w->a.y = ce->y;
- if (w->a.width != ce->width || w->a.height != ce->height)
+ /* Only destroy the pixmap if the window is mapped */
+ if (w->a.map_state != IsUnmapped &&
+ (w->a.width != ce->width || w->a.height != ce->height))
{
#if HAS_NAME_WINDOW_PIXMAP
if (w->pixmap)
@@ -2227,7 +2262,7 @@ configure_win (Display *dpy, XConfigureEvent *ce)
w->a.border_width = ce->border_width;
w->a.override_redirect = ce->override_redirect;
restack_win (dpy, w, ce->above);
- if (damage)
+ if (w->a.map_state != IsUnmapped && damage)
{
XserverRegion extents = win_extents (dpy, w);
XFixesUnionRegion (dpy, damage, damage, extents);
@@ -2242,7 +2277,8 @@ configure_win (Display *dpy, XConfigureEvent *ce)
w->shape_bounds.height = w->a.height;
}
- clipChanged = True;
+ if (w->a.map_state != IsUnmapped)
+ clipChanged = True;
}
static void
@@ -2268,7 +2304,7 @@ finish_destroy_win (Display *dpy, Window id, Bool gone)
win **prev, *w;
for (prev = &list; (w = *prev); prev = &w->next)
- if (w->id == id)
+ if (w->id == id && w->destroyed)
{
if (!gone)
finish_unmap_win (dpy, w);
@@ -2318,6 +2354,7 @@ static void
destroy_win (Display *dpy, Window id, Bool gone, Bool fade)
{
win *w = find_win (dpy, id);
+ if (w) w->destroyed = True;
#if HAS_NAME_WINDOW_PIXMAP
if ((w && w->pixmap && fade && fadeWindows) || (w && w->pixmap && fade && fadeWindows && w->windowType == winMenuAtom))
set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, destroy_callback, gone, False, True, True);
@@ -2351,10 +2388,16 @@ destroy_win (Display *dpy, Window id, Bool gone, Bool fade)
static void
damage_win (Display *dpy, XDamageNotifyEvent *de)
{
- win *w = find_win (dpy, de->drawable);
+ win *w = find_win (dpy, de->drawable);
if (!w)
return;
+
+#if WORK_AROUND_FGLRX
+ if (w->a.map_state != IsViewable)
+ return;
+#endif
+
#if CAN_DO_USABLE
if (!w->usable)
{
@@ -2380,7 +2423,8 @@ damage_win (Display *dpy, XDamageNotifyEvent *de)
w->damage_bounds.height = de->area.y + de->area.height - w->damage_bounds.y;
}
#if 0
- printf ("unusable damage %d, %d: %d x %d bounds %d, %d: %d x %d\n",
+ printf ("unusable damage [%d] %d, %d: %d x %d bounds %d, %d: %d x %d\n",
+ de->drawable,
de->area.x,
de->area.y,
de->area.width,
@@ -2865,16 +2909,55 @@ usage (char *program)
exit (1);
}
-static void
-give_me_a_name(void)
+static Bool
+register_cm (void)
{
- Window w;
+ Window w;
+ Atom a;
+ static char net_wm_cm[] = "_NET_WM_CM_Sxx";
+
+ snprintf (net_wm_cm, sizeof (net_wm_cm), "_NET_WM_CM_S%d", scr);
+ a = XInternAtom (dpy, net_wm_cm, False);
- w = XCreateSimpleWindow (dpy, RootWindow(dpy, 0), 0, 0, 1, 1, 0, None,
+/* w = XGetSelectionOwner (dpy, a);
+ if (w != None)
+ {
+ XTextProperty tp;
+ char **strs;
+ int count;
+ Atom winNameAtom = XInternAtom (dpy, "_NET_WM_NAME", False);
+
+ if (!XGetTextProperty (dpy, w, &tp, winNameAtom) &&
+ !XGetTextProperty (dpy, w, &tp, XA_WM_NAME))
+ {
+ fprintf (stderr,
+ "Another composite manager is already running (0x%lx)\n",
+ (unsigned long) w);
+ return False;
+ }
+ if (XmbTextPropertyToTextList (dpy, &tp, &strs, &count) == Success)
+ {
+ fprintf (stderr,
+ "Another composite manager is already running (%s)\n",
+ strs[0]);
+
+ XFreeStringList (strs);
+ }
+
+ XFree (tp.value);
+
+ return False;
+ }*/
+
+ w = XCreateSimpleWindow (dpy, RootWindow (dpy, scr), 0, 0, 1, 1, 0, None,
None);
- Xutf8SetWMProperties(dpy, w, "kcompmgr", "kcompmgr", NULL, 0, NULL, NULL,
+ Xutf8SetWMProperties(dpy, w, "kcompmgr", "kcompmgr", NULL, 0, NULL, NULL,
NULL);
-}
+
+ XSetSelectionOwner (dpy, a, w, 0);
+
+ return True;
+}
int
main (int argc, char **argv)
@@ -3042,7 +3125,11 @@ main (int argc, char **argv)
fprintf(stderr, "Started\n");
- give_me_a_name();
+ register_cm();
+ if (!register_cm())
+ {
+ exit (1);
+ }
/* get atoms */
shadowAtom = XInternAtom (dpy, SHADOW_PROP, False);