From afb2c168c783226ad1b97f0b1423def304ae1de9 Mon Sep 17 00:00:00 2001 From: tpearson Date: Sun, 28 Aug 2011 23:40:58 +0000 Subject: [PATCH] Add ability to "punch through" to desktop for transparency in kompmgr Activate Konsole ARGB mode by default when kompmgr is running git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1249953 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- konsole/konsole/konsole.cpp | 8 ++++ konsole/konsole/main.cpp | 57 +---------------------------- kwin/kompmgr/kompmgr.c | 73 +++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 55 deletions(-) diff --git a/konsole/konsole/konsole.cpp b/konsole/konsole/konsole.cpp index e47236e63..973e17abe 100644 --- a/konsole/konsole/konsole.cpp +++ b/konsole/konsole/konsole.cpp @@ -144,6 +144,9 @@ Time to start a requirement list. #include #include "printsettings.h" +#include +#include + #define KONSOLEDEBUG kdDebug(1211) #define POPUP_NEW_SESSION_ID 121 @@ -344,6 +347,11 @@ Konsole::Konsole(const char* name, int histon, bool menubaron, bool tabbaron, bo // connect(kapp, TQT_SIGNAL(kdisplayFontChanged()), this, TQT_SLOT(slotFontChanged())); kapp->dcopClient()->setDefaultObject( "konsole" ); + + // 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(qt_xdisplay(), "_KDE_TRANSPARENT_TO_DESKTOP", False); + XChangeProperty(qt_xdisplay(), winId(), kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); } diff --git a/konsole/konsole/main.cpp b/konsole/konsole/main.cpp index d37a43be3..1d0fdbb48 100644 --- a/konsole/konsole/main.cpp +++ b/konsole/konsole/main.cpp @@ -75,9 +75,6 @@ static KCmdLineOptions options[] = { "noframe", I18N_NOOP("Do not display frame"), 0 }, { "noscrollbar", I18N_NOOP("Do not display scrollbar"), 0 }, { "noxft", I18N_NOOP("Do not use Xft (anti-aliasing)"), 0 }, -#ifdef COMPOSITE - { "real-transparency", I18N_NOOP("Enable experimental support for real transparency"), 0 }, -#endif { "vt_sz CCxLL", I18N_NOOP("Terminal size in columns x lines"), 0 }, { "noresize", I18N_NOOP("Terminal size is fixed"), 0 }, { "type ", I18N_NOOP("Start with given session type"), 0 }, @@ -252,58 +249,8 @@ extern "C" int KDE_EXPORT kdemain(int argc, char* argv[]) KApplication* a = NULL; #ifdef COMPOSITE - if ( args->isSet("real-transparency")) { - char *display = 0; - if ( qtargs->isSet("display")) - display = qtargs->getOption( "display" ).data(); - - Display *dpy = XOpenDisplay( display ); - if ( !dpy ) { - kdError() << "cannot connect to X server " << display << endl; - exit( 1 ); - } - - int screen = DefaultScreen( dpy ); - Colormap colormap = 0; - Visual *visual = 0; - int event_base, error_base; - - if ( XRenderQueryExtension( dpy, &event_base, &error_base ) ) { - int nvi; - XVisualInfo templ; - templ.screen = screen; - templ.depth = 32; - templ.c_class = TrueColor; - XVisualInfo *xvi = XGetVisualInfo( dpy, VisualScreenMask | VisualDepthMask - | VisualClassMask, &templ, &nvi ); - - for ( int i = 0; i < nvi; i++ ) { - XRenderPictFormat *format = XRenderFindVisualFormat( dpy, xvi[i].visual ); - if ( format->type == PictTypeDirect && format->direct.alphaMask ) { - visual = xvi[i].visual; - colormap = XCreateColormap( dpy, RootWindow( dpy, screen ), visual, AllocNone ); - kdDebug() << "found visual with alpha support" << endl; - argb_visual = true; - break; - } - } - } - // The TQApplication ctor used is normally intended for applications not using Qt - // as the primary toolkit (e.g. Motif apps also using Qt), with some slightly - // unpleasant side effects (e.g. #83974). This code checks if qt-copy patch #0078 - // is applied, which allows turning this off. - bool* qt_no_foreign_hack = static_cast< bool* >( dlsym( RTLD_DEFAULT, "qt_no_foreign_hack" )); - if( qt_no_foreign_hack ) - *qt_no_foreign_hack = true; - // else argb_visual = false ... ? *shrug* - - if( argb_visual ) - a = new KApplication( dpy, Qt::HANDLE( visual ), Qt::HANDLE( colormap ) ); - else - XCloseDisplay( dpy ); - } - if( a == NULL ) - a = new KApplication; + a = new KApplication(KApplication::openX11RGBADisplay()); + argb_visual = a->isX11CompositionAvailable(); #else KApplication* a = new KApplication; #endif diff --git a/kwin/kompmgr/kompmgr.c b/kwin/kompmgr/kompmgr.c index 910622d73..ad0d469a0 100644 --- a/kwin/kompmgr/kompmgr.c +++ b/kwin/kompmgr/kompmgr.c @@ -129,6 +129,9 @@ typedef struct _win { /* for drawing translucent windows */ XserverRegion borderClip; struct _win *prev_trans; + + /* setting whether a window will be transparent to the desktop or the windows below it */ + Bool show_root_tile; } win; typedef struct _conv { @@ -198,6 +201,7 @@ Atom winUtilAtom; Atom winSplashAtom; Atom winDialogAtom; Atom winNormalAtom; +Atom winTDETTDAtom; /* opacity property name; sometime soon I'll write up an EWMH spec for it */ #define OPACITY_PROP "_KDE_WM_WINDOW_OPACITY" @@ -1463,6 +1467,17 @@ paint_all (Display *dpy, XserverRegion region) hei = w->a.height; #endif set_ignore (dpy, NextRequest (dpy)); + /* Here we redraw the background of the transparent window if we want + to do anything special (i.e. anything other than showing the + windows and desktop prestacked behind of the window). + For example, if you want to blur the background or show another + background pixmap entirely here is the place to do it; simply + draw the new background onto rootBuffer before continuing! */ + if (w->show_root_tile == True) { + XRenderComposite (dpy, PictOpSrc, rootTile, None, rootBuffer, + x, y, x, y, + x, y, wid, hei); + } XRenderComposite (dpy, PictOpOver, w->picture, w->alphaPict, rootBuffer, 0, 0, 0, 0, x, y, wid, hei); @@ -1865,6 +1880,28 @@ damage_tqshape(Display *dpy, win *w, XRectangle *tqshape_damage) } #endif +static Bool +get_window_transparent_to_desktop(Display * dpy, Window w) +{ + Atom actual; + int format; + unsigned long n, left; + + unsigned char *data; + int result = XGetWindowProperty (dpy, w, winTDETTDAtom, 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; +} + /* determine mode for window all in one place. Future might check for menu flag and other cool things */ @@ -1942,6 +1979,40 @@ determine_mode(Display *dpy, win *w) } } +static Bool +determine_window_transparent_to_desktop (Display *dpy, Window w) +{ + Window root_return, parent_return; + Window *children = NULL; + unsigned int nchildren, i; + Bool type; + + type = get_window_transparent_to_desktop (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 winNormalAtom; + } + + for (i = 0;i < nchildren;i++) + { + type = determine_window_transparent_to_desktop (dpy, children[i]); + if (type == True) + return True; + } + + if (children) + XFree ((void *)children); + + return False; +} + static Atom determine_wintype (Display *dpy, Window w) { @@ -2031,6 +2102,7 @@ add_win (Display *dpy, Window id, Window prev) new->opacity = OPAQUE; new->shadowSize = 100; new->decoHash = 0; + new->show_root_tile = determine_window_transparent_to_desktop(dpy, id); new->borderClip = None; new->prev_trans = 0; @@ -2873,6 +2945,7 @@ main (int argc, char **argv) winSplashAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False); winDialogAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); winNormalAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False); + winTDETTDAtom = XInternAtom (dpy, "_KDE_TRANSPARENT_TO_DESKTOP", False); pa.subwindow_mode = IncludeInferiors;