summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <[email protected]>2013-05-05 03:46:01 -0500
committerTimothy Pearson <[email protected]>2013-05-05 03:46:01 -0500
commit9804217b51b058fed43a060a746f543da044b2a5 (patch)
treeba646daf2376d2b39d4f6346a0e416f81f69d30f
parent2b6bc47289c47d4c5322ac25b688d0b3027a31d0 (diff)
downloadtdebase-9804217b51b058fed43a060a746f543da044b2a5.tar.gz
tdebase-9804217b51b058fed43a060a746f543da044b2a5.zip
Fix OpenGL screensaver background when ARGB mode is enabled
-rw-r--r--kdesktop/lock/lockprocess.cc32
-rw-r--r--kdesktop/lock/lockprocess.h1
-rw-r--r--twin/kompmgr/kompmgr.c137
3 files changed, 143 insertions, 27 deletions
diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc
index 33fd374aa..30c9e4dee 100644
--- a/kdesktop/lock/lockprocess.cc
+++ b/kdesktop/lock/lockprocess.cc
@@ -137,6 +137,10 @@ static Window gVRootData = 0;
static Atom gXA_VROOT;
static Atom gXA_SCREENSAVER_VERSION;
+Atom kde_wm_system_modal_notification = 0;
+Atom kde_wm_transparent_to_desktop = 0;
+Atom kde_wm_transparent_to_black = 0;
+
void print_trace()
{
#ifdef WITH_KDESKTOP_LOCK_BACKTRACE
@@ -234,7 +238,8 @@ LockProcess::LockProcess()
m_mousePrevY(0),
m_dialogPrevX(0),
m_dialogPrevY(0),
- m_maskWidget(NULL)
+ m_maskWidget(NULL),
+ m_saverRootWindow(0)
{
#ifdef KEEP_MOUSE_UNGRABBED
setNFlags(WX11DisableMove|WX11DisableClose|WX11DisableShade|WX11DisableMinimize|WX11DisableMaximize);
@@ -242,10 +247,10 @@ LockProcess::LockProcess()
setupSignals();
- // Signal that we want to be transparent to the desktop, not to windows behind us...
- Atom kde_wm_transparent_to_desktop;
+ // Set up atoms
+ kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False);
kde_wm_transparent_to_desktop = XInternAtom(tqt_xdisplay(), "_KDE_TRANSPARENT_TO_DESKTOP", False);
- XChangeProperty(tqt_xdisplay(), winId(), kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
+ kde_wm_transparent_to_black = XInternAtom(tqt_xdisplay(), "_KDE_TRANSPARENT_TO_BLACK", False);
kapp->installX11EventFilter(this);
@@ -923,8 +928,8 @@ void LockProcess::createSaverWindow()
XFree( info );
}
- Window w = XCreateWindow( x11Display(), RootWindow( x11Display(), x11Screen()), x(), y(), width(), height(), 0, x11Depth(), InputOutput, visual, flags, &attrs );
- create( w );
+ m_saverRootWindow = XCreateWindow( x11Display(), RootWindow( x11Display(), x11Screen()), x(), y(), width(), height(), 0, x11Depth(), InputOutput, visual, flags, &attrs );
+ create( m_saverRootWindow );
// Some xscreensaver hacks check for this property
const char *version = "KDE 2.0";
@@ -937,9 +942,7 @@ void LockProcess::createSaverWindow()
XChangeWindowAttributes(tqt_xdisplay(), winId(), CWEventMask, &attr);
// Signal that we want to be transparent to the desktop, not to windows behind us...
- Atom kde_wm_transparent_to_desktop;
- kde_wm_transparent_to_desktop = XInternAtom(tqt_xdisplay(), "_KDE_TRANSPARENT_TO_DESKTOP", False);
- XChangeProperty(tqt_xdisplay(), w, kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
+ XChangeProperty(tqt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
// erase();
@@ -1598,6 +1601,11 @@ bool LockProcess::startHack()
if (trinity_desktop_lock_use_system_modal_dialogs) {
// Make sure we have a nice clean display to start with!
if (argb_visual) {
+ // Signal that we want to be transparent to a black background...
+ if (m_saverRootWindow) {
+ XChangeProperty(tqt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_black, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
+ XClearArea(tqt_xdisplay(), m_saverRootWindow, 0, 0, 0, 0, True);
+ }
setTransparentBackgroundARGB();
}
else {
@@ -1712,6 +1720,10 @@ void LockProcess::hackExited(TDEProcess *)
}
}
if (argb_visual) {
+ if (m_saverRootWindow) {
+ XDeleteProperty(tqt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_black);
+ XClearArea(tqt_xdisplay(), m_saverRootWindow, 0, 0, 0, 0, True);
+ }
setTransparentBackgroundARGB();
}
else {
@@ -2346,8 +2358,6 @@ void LockProcess::msgBox( TQMessageBox::Icon type, const TQString &txt )
TQDialog box( 0, "messagebox", true, (trinity_desktop_lock_use_system_modal_dialogs?((WFlags)WStyle_StaysOnTop):((WFlags)WX11BypassWM)) );
if (trinity_desktop_lock_use_system_modal_dialogs) {
// Signal that we do not want any window controls to be shown at all
- Atom kde_wm_system_modal_notification;
- kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False);
XChangeProperty(tqt_xdisplay(), box.winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
}
box.setCaption(i18n("Authentication Subsystem Notice"));
diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h
index 5b9649893..23fe9912a 100644
--- a/kdesktop/lock/lockprocess.h
+++ b/kdesktop/lock/lockprocess.h
@@ -238,6 +238,7 @@ private:
int m_dialogPrevY;
TQWidget* m_maskWidget;
+ Window m_saverRootWindow;
ControlPipeHandlerObject* mControlPipeHandler;
TQEventLoopThread* mControlPipeHandlerThread;
diff --git a/twin/kompmgr/kompmgr.c b/twin/kompmgr/kompmgr.c
index 34ebb86e1..55c1bebd1 100644
--- a/twin/kompmgr/kompmgr.c
+++ b/twin/kompmgr/kompmgr.c
@@ -163,6 +163,9 @@ typedef struct _win {
/* setting whether a window will be transparent to the desktop or the windows below it */
Bool show_root_tile;
+
+ /* setting whether a window will be transparent to a black background or something else */
+ Bool show_black_background;
} win;
typedef struct _conv {
@@ -228,6 +231,7 @@ Atom dimAtom;
Atom deskChangeAtom;
Atom winTypeAtom;
Atom winTDETTDAtom;
+Atom winTDETTBAtom;
Atom winType[NUM_WINTYPES];
double winTypeOpacity[NUM_WINTYPES];
Bool winTypeShadow[NUM_WINTYPES];
@@ -1081,6 +1085,12 @@ static char *backgroundProps[] = {
0,
};
+static Bool
+determine_window_transparent_to_black(Display *dpy, Window w);
+
+static Bool
+determine_window_transparent_to_desktop(Display *dpy, Window w);
+
static Picture
root_tile (Display *dpy)
{
@@ -1596,7 +1606,18 @@ paint_all (Display *dpy, XserverRegion region)
background pixmap entirely here is the place to do it; simply
draw the new background onto rootBuffer before continuing! */
if (w->isInFade == False) {
- if (w->show_root_tile == True) {
+ // HACK
+ // For an unknown reason the PropertyNotify event handler is not
+ // fired when either the show_black_background or show_root_tile
+ // control atoms are changed. This works around the problem but
+ // causes an unquantified, likely relatively low, performance loss.
+ w->show_black_background = determine_window_transparent_to_black(dpy, w->id);
+ if (w->show_black_background == True) {
+ XRenderComposite (dpy, PictOpSrc, blackPicture, None, rootBuffer,
+ x, y, x, y,
+ x, y, wid, hei);
+ }
+ else if (w->show_root_tile == True) {
XRenderComposite (dpy, PictOpSrc, rootTile, None, rootBuffer,
x, y, x, y,
x, y, wid, hei);
@@ -1807,8 +1828,9 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
win *w = find_win (dpy, id);
Drawable back;
- if (!w)
+ if (!w) {
return;
+ }
w->a.map_state = IsViewable;
@@ -1817,6 +1839,8 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
/* This needs to be here since we don't get PropertyNotify when unmapped */
w->opacity = get_opacity_prop (dpy, w, OPAQUE);
+ w->show_root_tile = determine_window_transparent_to_desktop(dpy, id);
+ w->show_black_background = determine_window_transparent_to_black(dpy, id);
determine_mode (dpy, w);
w->windowType = determine_wintype (dpy, w->id, w->id);
@@ -1846,8 +1870,9 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
#endif
w->a_prev = w->a;
- if (fade && winTypeFade[w->windowType])
+ if (fade && winTypeFade[w->windowType]) {
set_fade (dpy, w, 0, get_opacity_prop(dpy, w, OPAQUE)*1.0/OPAQUE, fade_in_step, 0, False, True, True, True);
+ }
}
static void
@@ -2175,6 +2200,28 @@ get_window_transparent_to_desktop(Display * dpy, Window w)
return False;
}
+static Bool
+get_window_transparent_to_black(Display * dpy, Window w)
+{
+ Atom actual;
+ int format;
+ unsigned long n, left;
+
+ unsigned char *data;
+ int result = XGetWindowProperty (dpy, w, winTDETTBAtom, 0L, 1L, False,
+ XA_ATOM, &actual, &format,
+ &n, &left, &data);
+
+ if (result == Success && data != None && format == 32 )
+ {
+ Atom a;
+ a = *(long*)data;
+ XFree ( (void *) data);
+ return True;
+ }
+ return False;
+}
+
static void
determine_mode(Display *dpy, win *w)
{
@@ -2235,8 +2282,9 @@ determine_window_transparent_to_desktop (Display *dpy, Window w)
Bool type;
type = get_window_transparent_to_desktop (dpy, w);
- if (type == True)
+ if (type == True) {
return True;
+ }
if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
&nchildren))
@@ -2260,6 +2308,41 @@ determine_window_transparent_to_desktop (Display *dpy, Window w)
return False;
}
+static Bool
+determine_window_transparent_to_black (Display *dpy, Window w)
+{
+ Window root_return, parent_return;
+ Window *children = NULL;
+ unsigned int nchildren, i;
+ Bool type;
+
+ type = get_window_transparent_to_black (dpy, w);
+ if (type == True) {
+ return True;
+ }
+
+ if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
+ &nchildren))
+ {
+ /* XQueryTree failed. */
+ if (children)
+ XFree ((void *)children);
+ return False;
+ }
+
+ for (i = 0;i < nchildren;i++)
+ {
+ type = determine_window_transparent_to_black (dpy, children[i]);
+ if (type == True)
+ return True;
+ }
+
+ if (children)
+ XFree ((void *)children);
+
+ return False;
+}
+
static void
add_win (Display *dpy, Window id, Window prev)
{
@@ -2330,6 +2413,7 @@ add_win (Display *dpy, Window id, Window prev)
new->shadowSize = 100;
new->decoHash = 0;
new->show_root_tile = determine_window_transparent_to_desktop(dpy, id);
+ new->show_black_background = determine_window_transparent_to_black(dpy, id);
new->windowType = determine_wintype (dpy, new->id, new->id);
if ((new->windowType < 0) || (new->windowType > NUM_WINTYPES)) new->windowType = WINTYPE_NORMAL;
@@ -3400,6 +3484,7 @@ main (int argc, char **argv)
deskChangeAtom = XInternAtom (dpy, DESKCHANGE_PROP, False);
winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", False);
winTDETTDAtom = XInternAtom (dpy, "_KDE_TRANSPARENT_TO_DESKTOP", False);
+ winTDETTBAtom = XInternAtom (dpy, "_KDE_TRANSPARENT_TO_BLACK", False);
winType[WINTYPE_DESKTOP] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
winType[WINTYPE_DOCK] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
winType[WINTYPE_TOOLBAR] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
@@ -3464,8 +3549,9 @@ main (int argc, char **argv)
allDamage = None;
clipChanged = True;
XGrabServer (dpy);
- if (autoRedirect)
+ if (autoRedirect) {
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectAutomatic);
+ }
else
{
int dummy;
@@ -3489,8 +3575,9 @@ main (int argc, char **argv)
XUngrabServer (dpy);
ufd.fd = ConnectionNumber (dpy);
ufd.events = POLLIN;
- if (!autoRedirect)
+ if (!autoRedirect) {
paint_all (dpy, None);
+ }
/* Under no circumstances should these two lines EVER be moved earlier in main() than this point */
atexit(delete_pid_file);
@@ -3500,8 +3587,9 @@ main (int argc, char **argv)
{
/* dump_wins (); */
do {
- if (autoRedirect)
+ if (autoRedirect) {
XFlush (dpy);
+ }
if (!QLength (dpy))
{
if (poll (&ufd, 1, fade_timeout()) == 0)
@@ -3512,8 +3600,9 @@ main (int argc, char **argv)
}
XNextEvent (dpy, &ev);
- if ((ev.type & 0x7f) != KeymapNotify)
+ if ((ev.type & 0x7f) != KeymapNotify) {
discard_ignore (dpy, ev.xany.serial);
+ }
#if DEBUG_EVENTS
printf ("event %10.10s serial 0x%08x window 0x%08x\n",
ev_name(&ev), ev_serial (&ev), ev_window (&ev));
@@ -3711,14 +3800,30 @@ main (int argc, char **argv)
w->extents = win_extents (dpy, w);
}
}
- }
- else if (ev.xproperty.atom == deskChangeAtom)
- {
- /*just set global variable*/
- unsigned int tmp = get_deskchange_prop(dpy, ev.xproperty.window);
- printf("desk change, state:%d\n",tmp);
- }
- break;
+ }
+ else if (ev.xproperty.atom == deskChangeAtom)
+ {
+ /*just set global variable*/
+ unsigned int tmp = get_deskchange_prop(dpy, ev.xproperty.window);
+ printf("desk change, state:%d\n",tmp);
+ }
+ else if (ev.xproperty.atom == winTDETTDAtom)
+ {
+ win * w = find_win(dpy, ev.xproperty.window);
+ if (w)
+ {
+ w->show_root_tile = determine_window_transparent_to_desktop(dpy, ev.xproperty.window);
+ }
+ }
+ else if (ev.xproperty.atom == winTDETTBAtom)
+ {
+ win * w = find_win(dpy, ev.xproperty.window);
+ if (w)
+ {
+ w->show_black_background = determine_window_transparent_to_black(dpy, ev.xproperty.window);
+ }
+ }
+ break;
default:
if (ev.type == damage_event + XDamageNotify)
{