Fix OpenGL screensaver background when ARGB mode is enabled

(cherry picked from commit 9804217b51)
v3.5.13-sru
Timothy Pearson 11 years ago committed by Slávek Banko
parent a8fe98ad75
commit 807a5445ca

@ -137,6 +137,10 @@ static Window gVRootData = 0;
static Atom gXA_VROOT; static Atom gXA_VROOT;
static Atom gXA_SCREENSAVER_VERSION; 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() void print_trace()
{ {
#ifdef WITH_KDESKTOP_LOCK_BACKTRACE #ifdef WITH_KDESKTOP_LOCK_BACKTRACE
@ -234,7 +238,8 @@ LockProcess::LockProcess()
m_mousePrevY(0), m_mousePrevY(0),
m_dialogPrevX(0), m_dialogPrevX(0),
m_dialogPrevY(0), m_dialogPrevY(0),
m_maskWidget(NULL) m_maskWidget(NULL),
m_saverRootWindow(0)
{ {
#ifdef KEEP_MOUSE_UNGRABBED #ifdef KEEP_MOUSE_UNGRABBED
setNFlags(WX11DisableMove|WX11DisableClose|WX11DisableShade|WX11DisableMinimize|WX11DisableMaximize); setNFlags(WX11DisableMove|WX11DisableClose|WX11DisableShade|WX11DisableMinimize|WX11DisableMaximize);
@ -243,10 +248,10 @@ LockProcess::LockProcess()
setupSignals(); setupSignals();
setupPipe(); setupPipe();
// Signal that we want to be transparent to the desktop, not to windows behind us... // Set up atoms
Atom kde_wm_transparent_to_desktop; kde_wm_system_modal_notification = XInternAtom(qt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False);
kde_wm_transparent_to_desktop = XInternAtom(qt_xdisplay(), "_KDE_TRANSPARENT_TO_DESKTOP", False); kde_wm_transparent_to_desktop = XInternAtom(qt_xdisplay(), "_KDE_TRANSPARENT_TO_DESKTOP", False);
XChangeProperty(qt_xdisplay(), winId(), kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); kde_wm_transparent_to_black = XInternAtom(qt_xdisplay(), "_KDE_TRANSPARENT_TO_BLACK", False);
kapp->installX11EventFilter(this); kapp->installX11EventFilter(this);
@ -1041,8 +1046,8 @@ void LockProcess::createSaverWindow()
XFree( info ); XFree( info );
} }
Window w = XCreateWindow( x11Display(), RootWindow( x11Display(), x11Screen()), x(), y(), width(), height(), 0, x11Depth(), InputOutput, visual, flags, &attrs ); m_saverRootWindow = XCreateWindow( x11Display(), RootWindow( x11Display(), x11Screen()), x(), y(), width(), height(), 0, x11Depth(), InputOutput, visual, flags, &attrs );
create( w ); create( m_saverRootWindow );
// Some xscreensaver hacks check for this property // Some xscreensaver hacks check for this property
const char *version = "KDE 2.0"; const char *version = "KDE 2.0";
@ -1055,9 +1060,7 @@ void LockProcess::createSaverWindow()
XChangeWindowAttributes(qt_xdisplay(), winId(), CWEventMask, &attr); XChangeWindowAttributes(qt_xdisplay(), winId(), CWEventMask, &attr);
// Signal that we want to be transparent to the desktop, not to windows behind us... // Signal that we want to be transparent to the desktop, not to windows behind us...
Atom kde_wm_transparent_to_desktop; XChangeProperty(qt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
kde_wm_transparent_to_desktop = XInternAtom(qt_xdisplay(), "_KDE_TRANSPARENT_TO_DESKTOP", False);
XChangeProperty(qt_xdisplay(), w, kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
// erase(); // erase();
@ -1716,6 +1719,11 @@ bool LockProcess::startHack()
if (trinity_desktop_lock_use_system_modal_dialogs) { if (trinity_desktop_lock_use_system_modal_dialogs) {
// Make sure we have a nice clean display to start with! // Make sure we have a nice clean display to start with!
if (argb_visual) { if (argb_visual) {
// Signal that we want to be transparent to a black background...
if (m_saverRootWindow) {
XChangeProperty(qt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_black, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
XClearArea(qt_xdisplay(), m_saverRootWindow, 0, 0, 0, 0, True);
}
setTransparentBackgroundARGB(); setTransparentBackgroundARGB();
} }
else { else {
@ -1830,6 +1838,10 @@ void LockProcess::hackExited(KProcess *)
} }
} }
if (argb_visual) { if (argb_visual) {
if (m_saverRootWindow) {
XDeleteProperty(qt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_black);
XClearArea(qt_xdisplay(), m_saverRootWindow, 0, 0, 0, 0, True);
}
setTransparentBackgroundARGB(); setTransparentBackgroundARGB();
} }
else { else {
@ -2463,8 +2475,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)) ); 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) { if (trinity_desktop_lock_use_system_modal_dialogs) {
// Signal that we do not want any window controls to be shown at all // 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(qt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False);
XChangeProperty(qt_xdisplay(), box.winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); XChangeProperty(qt_xdisplay(), box.winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
} }
box.setCaption(i18n("Authentication Subsystem Notice")); box.setCaption(i18n("Authentication Subsystem Notice"));

@ -216,6 +216,7 @@ private:
int m_dialogPrevY; int m_dialogPrevY;
TQWidget* m_maskWidget; TQWidget* m_maskWidget;
Window m_saverRootWindow;
}; };
#endif #endif

@ -163,6 +163,9 @@ typedef struct _win {
/* setting whether a window will be transparent to the desktop or the windows below it */ /* setting whether a window will be transparent to the desktop or the windows below it */
Bool show_root_tile; Bool show_root_tile;
/* setting whether a window will be transparent to a black background or something else */
Bool show_black_background;
} win; } win;
typedef struct _conv { typedef struct _conv {
@ -228,6 +231,7 @@ Atom dimAtom;
Atom deskChangeAtom; Atom deskChangeAtom;
Atom winTypeAtom; Atom winTypeAtom;
Atom winTDETTDAtom; Atom winTDETTDAtom;
Atom winTDETTBAtom;
Atom winType[NUM_WINTYPES]; Atom winType[NUM_WINTYPES];
double winTypeOpacity[NUM_WINTYPES]; double winTypeOpacity[NUM_WINTYPES];
Bool winTypeShadow[NUM_WINTYPES]; Bool winTypeShadow[NUM_WINTYPES];
@ -1038,6 +1042,12 @@ static char *backgroundProps[] = {
0, 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 static Picture
root_tile (Display *dpy) root_tile (Display *dpy)
{ {
@ -1554,7 +1564,18 @@ paint_all (Display *dpy, XserverRegion region)
background pixmap entirely here is the place to do it; simply background pixmap entirely here is the place to do it; simply
draw the new background onto rootBuffer before continuing! */ draw the new background onto rootBuffer before continuing! */
if (w->isInFade == False) { 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, XRenderComposite (dpy, PictOpSrc, rootTile, None, rootBuffer,
x, y, x, y, x, y, x, y,
x, y, wid, hei); x, y, wid, hei);
@ -1765,8 +1786,9 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
win *w = find_win (dpy, id); win *w = find_win (dpy, id);
Drawable back; Drawable back;
if (!w) if (!w) {
return; return;
}
w->a.map_state = IsViewable; w->a.map_state = IsViewable;
@ -1775,6 +1797,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 */ /* This needs to be here since we don't get PropertyNotify when unmapped */
w->opacity = get_opacity_prop (dpy, w, OPAQUE); 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); determine_mode (dpy, w);
w->windowType = determine_wintype (dpy, w->id, w->id); w->windowType = determine_wintype (dpy, w->id, w->id);
@ -1804,8 +1828,9 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
#endif #endif
w->a_prev = w->a; 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); set_fade (dpy, w, 0, get_opacity_prop(dpy, w, OPAQUE)*1.0/OPAQUE, fade_in_step, 0, False, True, True, True);
}
} }
static void static void
@ -2133,6 +2158,28 @@ get_window_transparent_to_desktop(Display * dpy, Window w)
return False; 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 static void
determine_mode(Display *dpy, win *w) determine_mode(Display *dpy, win *w)
{ {
@ -2193,8 +2240,9 @@ determine_window_transparent_to_desktop (Display *dpy, Window w)
Bool type; Bool type;
type = get_window_transparent_to_desktop (dpy, w); type = get_window_transparent_to_desktop (dpy, w);
if (type == True) if (type == True) {
return True; return True;
}
if (!XQueryTree (dpy, w, &root_return, &parent_return, &children, if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
&nchildren)) &nchildren))
@ -2218,6 +2266,41 @@ determine_window_transparent_to_desktop (Display *dpy, Window w)
return False; 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 static void
add_win (Display *dpy, Window id, Window prev) add_win (Display *dpy, Window id, Window prev)
{ {
@ -2288,6 +2371,7 @@ add_win (Display *dpy, Window id, Window prev)
new->shadowSize = 100; new->shadowSize = 100;
new->decoHash = 0; new->decoHash = 0;
new->show_root_tile = determine_window_transparent_to_desktop(dpy, id); 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); new->windowType = determine_wintype (dpy, new->id, new->id);
if ((new->windowType < 0) || (new->windowType > NUM_WINTYPES)) new->windowType = WINTYPE_NORMAL; if ((new->windowType < 0) || (new->windowType > NUM_WINTYPES)) new->windowType = WINTYPE_NORMAL;
@ -3350,6 +3434,7 @@ main (int argc, char **argv)
deskChangeAtom = XInternAtom (dpy, DESKCHANGE_PROP, False); deskChangeAtom = XInternAtom (dpy, DESKCHANGE_PROP, False);
winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", False); winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", False);
winTDETTDAtom = XInternAtom (dpy, "_KDE_TRANSPARENT_TO_DESKTOP", 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_DESKTOP] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
winType[WINTYPE_DOCK] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); winType[WINTYPE_DOCK] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
winType[WINTYPE_TOOLBAR] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False); winType[WINTYPE_TOOLBAR] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
@ -3414,8 +3499,9 @@ main (int argc, char **argv)
allDamage = None; allDamage = None;
clipChanged = True; clipChanged = True;
XGrabServer (dpy); XGrabServer (dpy);
if (autoRedirect) if (autoRedirect) {
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectAutomatic); XCompositeRedirectSubwindows (dpy, root, CompositeRedirectAutomatic);
}
else else
{ {
int dummy; int dummy;
@ -3439,8 +3525,9 @@ main (int argc, char **argv)
XUngrabServer (dpy); XUngrabServer (dpy);
ufd.fd = ConnectionNumber (dpy); ufd.fd = ConnectionNumber (dpy);
ufd.events = POLLIN; ufd.events = POLLIN;
if (!autoRedirect) if (!autoRedirect) {
paint_all (dpy, None); paint_all (dpy, None);
}
/* Under no circumstances should these two lines EVER be moved earlier in main() than this point */ /* Under no circumstances should these two lines EVER be moved earlier in main() than this point */
atexit(delete_pid_file); atexit(delete_pid_file);
@ -3450,8 +3537,9 @@ main (int argc, char **argv)
{ {
/* dump_wins (); */ /* dump_wins (); */
do { do {
if (autoRedirect) if (autoRedirect) {
XFlush (dpy); XFlush (dpy);
}
if (!QLength (dpy)) if (!QLength (dpy))
{ {
if (poll (&ufd, 1, fade_timeout()) == 0) if (poll (&ufd, 1, fade_timeout()) == 0)
@ -3462,8 +3550,9 @@ main (int argc, char **argv)
} }
XNextEvent (dpy, &ev); XNextEvent (dpy, &ev);
if ((ev.type & 0x7f) != KeymapNotify) if ((ev.type & 0x7f) != KeymapNotify) {
discard_ignore (dpy, ev.xany.serial); discard_ignore (dpy, ev.xany.serial);
}
#if DEBUG_EVENTS #if DEBUG_EVENTS
printf ("event %10.10s serial 0x%08x window 0x%08x\n", printf ("event %10.10s serial 0x%08x window 0x%08x\n",
ev_name(&ev), ev_serial (&ev), ev_window (&ev)); ev_name(&ev), ev_serial (&ev), ev_window (&ev));
@ -3661,14 +3750,30 @@ main (int argc, char **argv)
w->extents = win_extents (dpy, w); w->extents = win_extents (dpy, w);
} }
} }
} }
else if (ev.xproperty.atom == deskChangeAtom) else if (ev.xproperty.atom == deskChangeAtom)
{ {
/*just set global variable*/ /*just set global variable*/
unsigned int tmp = get_deskchange_prop(dpy, ev.xproperty.window); unsigned int tmp = get_deskchange_prop(dpy, ev.xproperty.window);
printf("desk change, state:%d\n",tmp); printf("desk change, state:%d\n",tmp);
} }
break; 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: default:
if (ev.type == damage_event + XDamageNotify) if (ev.type == damage_event + XDamageNotify)
{ {

Loading…
Cancel
Save