diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc index 315b42655..d96b64ca9 100644 --- a/kdesktop/lock/lockprocess.cc +++ b/kdesktop/lock/lockprocess.cc @@ -170,6 +170,8 @@ extern bool trinity_desktop_lock_use_sak; extern bool trinity_desktop_lock_hide_active_windows; extern bool trinity_desktop_lock_forced; +extern bool argb_visual; + extern TQXLibWindowList trinity_desktop_lock_hidden_window_list; bool trinity_desktop_lock_autohide_lockdlg = TRUE; @@ -236,17 +238,24 @@ LockProcess::LockProcess() setupSignals(); setupPipe(); + // 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(), winId(), kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); + kapp->installX11EventFilter(this); mForceContinualLockDisplayTimer = new TQTimer( this ); mHackDelayStartupTimer = new TQTimer( this ); mEnsureVRootWindowSecurityTimer = new TQTimer( this ); - // Try to get the root pixmap - if (!m_rootPixmap) m_rootPixmap = new KRootPixmap(this); - connect(m_rootPixmap, TQT_SIGNAL(backgroundUpdated(const TQPixmap &)), this, TQT_SLOT(slotPaintBackground(const TQPixmap &))); - m_rootPixmap->setCustomPainting(true); - m_rootPixmap->start(); + if (!argb_visual) { + // Try to get the root pixmap + if (!m_rootPixmap) m_rootPixmap = new KRootPixmap(this); + connect(m_rootPixmap, TQT_SIGNAL(backgroundUpdated(const TQPixmap &)), this, TQT_SLOT(slotPaintBackground(const TQPixmap &))); + m_rootPixmap->setCustomPainting(true); + m_rootPixmap->start(); + } // Get root window attributes XWindowAttributes rootAttr; @@ -973,8 +982,26 @@ void LockProcess::createSaverWindow() attrs.override_redirect = 1; hide(); - Window w = XCreateWindow( x11Display(), RootWindow( x11Display(), x11Screen()), - x(), y(), width(), height(), 0, x11Depth(), InputOutput, visual, flags, &attrs ); + + if (argb_visual) { + attrs.background_pixel = 0; + attrs.border_pixel = 0; + flags |= CWBackPixel; + flags |= CWBorderPixel; + if (!(flags & CWColormap)) { + XVisualInfo vinfo; + if (!XMatchVisualInfo( x11Display(), x11Screen(), 32, TrueColor, &vinfo )) { + printf("[ERROR] Unable to locate matching X11 Visual; this application will not function correctly!\n\r"); + } + else { + visual = vinfo.visual; + attrs.colormap = XCreateColormap( x11Display(), RootWindow( x11Display(), x11Screen()), visual, AllocNone ); + flags |= CWColormap; + } + } + } + + Window w = XCreateWindow( x11Display(), RootWindow( x11Display(), x11Screen()), x(), y(), width(), height(), 0, x11Depth(), InputOutput, visual, flags, &attrs ); create( w ); // Some xscreensaver hacks check for this property @@ -984,10 +1011,13 @@ void LockProcess::createSaverWindow() (unsigned char *) version, strlen(version)); XSetWindowAttributes attr; - attr.event_mask = KeyPressMask | ButtonPressMask | PointerMotionMask | - VisibilityChangeMask | ExposureMask; - XChangeWindowAttributes(tqt_xdisplay(), winId(), - CWEventMask, &attr); + attr.event_mask = KeyPressMask | ButtonPressMask | PointerMotionMask | VisibilityChangeMask | ExposureMask; + 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); // erase(); @@ -1079,7 +1109,12 @@ void LockProcess::desktopResized() XSync(tqt_xdisplay(), False); // Black out the background widget to hide ugly resize tiling artifacts - setBackgroundColor(black); + if (argb_visual) { + setErasePixmap(TQPixmap()); + } + else { + setBackgroundColor(black); + } erase(); // This slot needs to be able to execute very rapidly so as to prevent the user's desktop from ever @@ -1205,28 +1240,35 @@ void LockProcess::saveVRoot() // void LockProcess::setVRoot(Window win, Window vr) { - if (gVRoot) + if (gVRoot) { removeVRoot(gVRoot); + } unsigned long rw = RootWindowOfScreen(ScreenOfDisplay(tqt_xdisplay(), tqt_xscreen())); unsigned long vroot_data[1] = { vr }; - Window rootReturn, parentReturn, *children; + Window rootReturn; + Window parentReturn; + Window *children = NULL; unsigned int numChildren; Window top = win; while (1) { - XQueryTree(tqt_xdisplay(), top , &rootReturn, &parentReturn, - &children, &numChildren); - if (children) + if (XQueryTree(tqt_xdisplay(), top, &rootReturn, &parentReturn, &children, &numChildren) == 0) { + printf("[WARNING] XQueryTree() failed!\n\r"); fflush(stdout); + break; + } + if (children) { XFree((char *)children); + } if (parentReturn == rw) { break; - } else + } + else { top = parentReturn; + } } - XChangeProperty(tqt_xdisplay(), top, gXA_VROOT, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)vroot_data, 1); + XChangeProperty(tqt_xdisplay(), top, gXA_VROOT, XA_WINDOW, 32, PropModeReplace, (unsigned char *)vroot_data, 1); } //--------------------------------------------------------------------------- @@ -1367,11 +1409,16 @@ bool LockProcess::startSaver() } if (((!(trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced)) && (!trinity_desktop_lock_in_sec_dlg)) && mHackStartupEnabled) { - if (backingPixmap.isNull()) { - setBackgroundColor(black); + if (argb_visual) { + setErasePixmap(TQPixmap()); } else { - setBackgroundPixmap(backingPixmap); + if (backingPixmap.isNull()) { + setBackgroundColor(black); + } + else { + setBackgroundPixmap(backingPixmap); + } } setGeometry(0, 0, mRootWidth, mRootHeight); erase(); @@ -1510,13 +1557,19 @@ void LockProcess::repaintRootWindowIfNeeded() { if (trinity_desktop_lock_use_system_modal_dialogs) { if (!mHackProc.isRunning()) { - if (backingPixmap.isNull()) { - setBackgroundColor(black); - setGeometry(0, 0, mRootWidth, mRootHeight); + if (argb_visual) { + setErasePixmap(TQPixmap()); erase(); } else { - bitBlt(this, 0, 0, &backingPixmap); + if (backingPixmap.isNull()) { + setBackgroundColor(black); + setGeometry(0, 0, mRootWidth, mRootHeight); + erase(); + } + else { + bitBlt(this, 0, 0, &backingPixmap); + } } } if (currentDialog == NULL) { @@ -1537,11 +1590,16 @@ bool LockProcess::startHack() if (currentDialog || (!mDialogs.isEmpty())) { // no resuming with dialog visible or when not visible - if (backingPixmap.isNull()) { - setBackgroundColor(black); + if (argb_visual) { + setErasePixmap(TQPixmap()); } else { - setBackgroundPixmap(backingPixmap); + if (backingPixmap.isNull()) { + setBackgroundColor(black); + } + else { + setBackgroundPixmap(backingPixmap); + } } setGeometry(0, 0, mRootWidth, mRootHeight); erase(); @@ -1585,11 +1643,16 @@ bool LockProcess::startHack() { if (trinity_desktop_lock_use_system_modal_dialogs) { // Make sure we have a nice clean display to start with! - if (backingPixmap.isNull()) { - setBackgroundColor(black); + if (argb_visual) { + setErasePixmap(TQPixmap()); } else { - setBackgroundPixmap(backingPixmap); + if (backingPixmap.isNull()) { + setBackgroundColor(black); + } + else { + setBackgroundPixmap(backingPixmap); + } } setGeometry(0, 0, mRootWidth, mRootHeight); erase(); @@ -1620,18 +1683,31 @@ bool LockProcess::startHack() usleep(100); TQApplication::syncX(); if (!trinity_desktop_lock_use_system_modal_dialogs) { - if (backingPixmap.isNull()) { - setBackgroundColor(black); + if (argb_visual) { + setErasePixmap(TQPixmap()); } else { - setBackgroundPixmap(backingPixmap); + if (backingPixmap.isNull()) { + setBackgroundColor(black); + } + else { + setBackgroundPixmap(backingPixmap); + } } } - if (backingPixmap.isNull()) { - setGeometry(0, 0, mRootWidth, mRootHeight); + if (argb_visual) { + setErasePixmap(TQPixmap()); erase(); } - else bitBlt(this, 0, 0, &backingPixmap); + else { + if (backingPixmap.isNull()) { + setGeometry(0, 0, mRootWidth, mRootHeight); + erase(); + } + else { + bitBlt(this, 0, 0, &backingPixmap); + } + } if (trinity_desktop_lock_use_system_modal_dialogs) { ENABLE_CONTINUOUS_LOCKDLG_DISPLAY if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE); @@ -1669,18 +1745,30 @@ void LockProcess::hackExited(TDEProcess *) usleep(100); TQApplication::syncX(); if (!trinity_desktop_lock_use_system_modal_dialogs) { - if (backingPixmap.isNull()) { - setBackgroundColor(black); + if (argb_visual) { + setErasePixmap(TQPixmap()); } else { - setBackgroundPixmap(backingPixmap); + if (backingPixmap.isNull()) { + setBackgroundColor(black); + } + else { + setBackgroundPixmap(backingPixmap); + } } } - if (backingPixmap.isNull()) { - setGeometry(0, 0, mRootWidth, mRootHeight); - erase(); + if (argb_visual) { + setErasePixmap(TQPixmap()); + } + else { + if (backingPixmap.isNull()) { + setGeometry(0, 0, mRootWidth, mRootHeight); + erase(); + } + else { + bitBlt(this, 0, 0, &backingPixmap); + } } - else bitBlt(this, 0, 0, &backingPixmap); if (!mSuspended) { if (trinity_desktop_lock_use_system_modal_dialogs) { ENABLE_CONTINUOUS_LOCKDLG_DISPLAY @@ -1757,11 +1845,16 @@ void LockProcess::resume( bool force ) if( !force && (!mDialogs.isEmpty() || !mVisibility )) { // no resuming with dialog visible or when not visible if (trinity_desktop_lock_use_system_modal_dialogs) { - if (backingPixmap.isNull()) { - setBackgroundColor(black); + if (argb_visual) { + setErasePixmap(TQPixmap()); } else { - setBackgroundPixmap(backingPixmap); + if (backingPixmap.isNull()) { + setBackgroundColor(black); + } + else { + setBackgroundPixmap(backingPixmap); + } } setGeometry(0, 0, mRootWidth, mRootHeight); erase(); @@ -1949,6 +2042,13 @@ void LockProcess::slotForcePaintBackground() void LockProcess::slotPaintBackground(const TQPixmap &rpm) { + if (argb_visual) { + if (mEnsureScreenHiddenTimer) { + mEnsureScreenHiddenTimer->stop(); + } + return; + } + if (mEnsureScreenHiddenTimer) { mEnsureScreenHiddenTimer->stop(); } diff --git a/kdesktop/lock/main.cc b/kdesktop/lock/main.cc index 377080d23..017250a35 100644 --- a/kdesktop/lock/main.cc +++ b/kdesktop/lock/main.cc @@ -19,6 +19,8 @@ Boston, MA 02110-1301, USA. */ +#include + #include "lockprocess.h" #include "main.h" #include "kdesktopsettings.h" @@ -35,8 +37,19 @@ #include -#include -#include +#if defined(Q_WS_X11) && defined(HAVE_XRENDER) && TQT_VERSION >= 0x030300 +#define COMPOSITE +#endif + +#ifdef COMPOSITE +# include +# include +# include +# include +#else +# include +# include +#endif #define OPEN_TDMCONFIG_AND_SET_GROUP \ if( stat( KDE_CONFDIR "/tdm/tdmdistrc" , &st ) == 0) { \ @@ -64,6 +77,38 @@ bool signalled_blank; bool signalled_run; bool in_internal_mode = FALSE; +bool argb_visual = FALSE; + +static void sigusr1_handler(int) +{ + signalled_forcelock = TRUE; +} + +static void sigusr2_handler(int) +{ + signalled_dontlock = TRUE; +} + +static void sigusr3_handler(int) +{ + signalled_securedialog = TRUE; +} + +static void sigusr4_handler(int) +{ + signalled_blank = TRUE; +} + +static void sigusr5_handler(int) +{ + signalled_run = TRUE; +} + +static int trapXErrors(Display *, XErrorEvent *) +{ + return 0; +} + bool MyApp::x11EventFilter( XEvent *ev ) { if (ev->type == ButtonPress || ev->type == ButtonRelease || ev->type == MotionNotify) { @@ -119,6 +164,10 @@ bool MyApp::x11EventFilter( XEvent *ev ) XCreateWindowEvent create_event = ev->xcreatewindow; XWindowAttributes childAttr; Window childTransient; + + // XGetWindowAttributes may generate BadWindow errors, so make sure they are silently ignored + int (*oldHandler)(Display *, XErrorEvent *); + oldHandler = XSetErrorHandler(trapXErrors); if (XGetWindowAttributes(create_event.display, create_event.window, &childAttr) && XGetTransientForHint(create_event.display, create_event.window, &childTransient)) { if ((childAttr.override_redirect) && (childTransient)) { if (!trinity_desktop_lock_hidden_window_list.contains(create_event.window)) { @@ -128,6 +177,7 @@ bool MyApp::x11EventFilter( XEvent *ev ) XFlush(create_event.display); } } + XSetErrorHandler(oldHandler); } else if (ev->type == DestroyNotify) { XDestroyWindowEvent destroy_event = ev->xdestroywindow; @@ -171,36 +221,6 @@ void restore_hidden_override_redirect_windows() { } } -static void sigusr1_handler(int) -{ - signalled_forcelock = TRUE; -} - -static void sigusr2_handler(int) -{ - signalled_dontlock = TRUE; -} - -static void sigusr3_handler(int) -{ - signalled_securedialog = TRUE; -} - -static void sigusr4_handler(int) -{ - signalled_blank = TRUE; -} - -static void sigusr5_handler(int) -{ - signalled_run = TRUE; -} - -static int trapXErrors(Display *, XErrorEvent *) -{ - return 0; -} - // ----------------------------------------------------------------------------- int main( int argc, char **argv ) @@ -287,7 +307,16 @@ int main( int argc, char **argv ) } } +// FIXME +// Composite should be enabled where possible, however using ARGB visuals seems to cause problems +// with XScreenSaver hacks (they do not display). +// #ifdef COMPOSITE +// MyApp app(TDEApplication::openX11RGBADisplay()); +// argb_visual = app.isX11CompositionAvailable(); +// #else MyApp app; +// #endif + kdDebug() << "app " << kdesktop_screen_number << " " << starting_screen << " " << child << " " << child_sockets.count() << " " << parent_connection << endl; app.disableSessionManagement(); TDEGlobal::locale()->insertCatalogue("libdmctl"); diff --git a/kdesktop/lock/main.h b/kdesktop/lock/main.h index aabdbdc63..6caaa0898 100644 --- a/kdesktop/lock/main.h +++ b/kdesktop/lock/main.h @@ -28,6 +28,7 @@ class MyApp : public TDEApplication { Q_OBJECT public: MyApp() : TDEApplication(), lastTick( 0 ) {} + MyApp(Display *display, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0, bool allowStyles=true) : TDEApplication(display, visual, colormap, allowStyles), lastTick( 0 ) {} protected: bool x11EventFilter( XEvent * ); signals: