Browse Source

Add composition manager detection and support to Trinity

This adds the methods required to make transparent widgets via alpha blending a reality
An additional widget class may be coming shortly


git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1246265 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
tags/v3.5.13
tpearson 8 years ago
parent
commit
47ee068d2c
5 changed files with 316 additions and 7 deletions
  1. 6
    0
      CMakeLists.txt
  2. 3
    0
      config.h.cmake
  3. 9
    1
      kdecore/CMakeLists.txt
  4. 211
    4
      kdecore/kapplication.cpp
  5. 87
    2
      kdecore/kapplication.h

+ 6
- 0
CMakeLists.txt View File

@@ -548,6 +548,12 @@ if( XRENDER_FOUND )
set( HAVE_XRENDER 1 )
endif( XRENDER_FOUND )

##### check for xcomposite #########################

pkg_search_module( XCOMPOSITE xcomposite )
if( XCOMPOSITE_FOUND )
set( HAVE_XCOMPOSITE 1 )
endif( XCOMPOSITE_FOUND )

##### check for libxml-2.0 ######################


+ 3
- 0
config.h.cmake View File

@@ -665,6 +665,9 @@
/* Defined if your system has XRender support */
#cmakedefine HAVE_XRENDER 1

/* Defined if your system has XComposite support */
#cmakedefine HAVE_XCOMPOSITE 1

/* Define to 1 if you have the `_getpty' function. */
#cmakedefine HAVE__GETPTY 1


+ 9
- 1
kdecore/CMakeLists.txt View File

@@ -129,7 +129,7 @@ tde_add_library( ${target} SHARED AUTOMOC
SOURCES ${${target}_SRCS}
VERSION 4.2.0
EMBED kdecorenetwork-static
LINK ltdlc-static ${KDESVGICONS} DCOP-shared kdefx-shared ${ZLIB_LIBRARIES} ${LIBIDN_LIBRARIES} ICE SM
LINK ltdlc-static ${KDESVGICONS} DCOP-shared kdefx-shared ${ZLIB_LIBRARIES} ${LIBIDN_LIBRARIES} ${XCOMPOSITE_LIBRARIES} ICE SM
DEPENDENCIES dcopidl dcopidl2cpp
DESTINATION ${LIB_INSTALL_DIR}
)
@@ -199,3 +199,11 @@ tde_add_executable(kgrantpty SETUID
SOURCES kgrantpty.c
DESTINATION ${BIN_INSTALL_DIR}
)

##### kdetcompmgr #################################

tde_add_executable( kdetcompmgr
SOURCES kdetcompmgr.cpp
LINK kdecore-shared
DESTINATION ${BIN_INSTALL_DIR}
)

+ 211
- 4
kdecore/kapplication.cpp View File

@@ -125,6 +125,11 @@

#ifdef Q_WS_X11
#include <X11/Xlib.h>
#ifdef COMPOSITE
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xcomposite.h>
#include <dlfcn.h>
#endif
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/SM/SMlib.h>
@@ -175,6 +180,18 @@ static Atom atom_NetSupported;
static Atom kde_xdnd_drop;
#endif

#ifdef Q_WS_X11
static int composite_event, composite_error, composite_opcode;
static bool x11_composite_error_generated;
static int x11_error(Display *dpy, XErrorEvent *ev) {
if (ev->request_code == composite_opcode && ev->minor_code == X_CompositeRedirectSubwindows)
{
x11_composite_error_generated = true;
return 0;
}
}
#endif

// duplicated from patched Qt, so that there won't be unresolved symbols if Qt gets
// replaced by unpatched one
KDECORE_EXPORT bool qt_qclipboard_bailout_hack = false;
@@ -602,6 +619,7 @@ KApplication::KApplication( int& argc, char** argv, const TQCString& rAppName,
TQApplication( argc, argv, GUIenabled ), KInstance(rAppName),
#ifdef Q_WS_X11
display(0L),
argb_visual(false),
#endif
d (new KApplicationPrivate())
{
@@ -622,11 +640,11 @@ KApplication::KApplication( int& argc, char** argv, const TQCString& rAppName,
}

KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
TRUE ), // Qt4 requires that there always be a GUI
TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), TRUE ), // Qt4 requires that there always be a GUI
KInstance( KCmdLineArgs::about),
#ifdef Q_WS_X11
display(0L),
argb_visual(false),
#endif
d (new KApplicationPrivate)
{
@@ -648,9 +666,11 @@ KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
bool allowStyles ) :
TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
visual, colormap ),
visual?visual:getX11RGBAVisual(dpy), colormap?colormap:getX11RGBAColormap(dpy) ),
KInstance( KCmdLineArgs::about), display(0L), d (new KApplicationPrivate)
{
if ((visual) && (colormap))
getX11RGBAInformation(dpy);
aIconPixmap.pm.icon = 0L;
aIconPixmap.pm.miniIcon = 0L;
read_app_startup_id();
@@ -665,9 +685,11 @@ KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap
KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
bool allowStyles, KInstance * _instance ) :
TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
visual, colormap ),
visual?visual:getX11RGBAVisual(dpy), colormap?colormap:getX11RGBAColormap(dpy) ),
KInstance( _instance ), display(0L), d (new KApplicationPrivate)
{
if ((visual) && (colormap))
getX11RGBAInformation(dpy);
aIconPixmap.pm.icon = 0L;
aIconPixmap.pm.miniIcon = 0L;
read_app_startup_id();
@@ -684,6 +706,7 @@ KApplication::KApplication( bool allowStyles, bool GUIenabled, KInstance* _insta
TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
GUIenabled ),
KInstance( _instance ),
argb_visual(false),
#ifdef Q_WS_X11
display(0L),
#endif
@@ -708,6 +731,7 @@ KApplication::KApplication(Display *display, int& argc, char** argv, const TQCSt
bool allowStyles, bool GUIenabled ) :
TQApplication( display ), KInstance(rAppName),
display(0L),
argb_visual(false),
d (new KApplicationPrivate())
{
aIconPixmap.pm.icon = 0L;
@@ -1718,7 +1742,190 @@ public:
};
#endif

#if defined(Q_WS_X11) && defined(COMPOSITE)
bool KApplication::isCompositionManagerAvailable() {
KConfigGroup pConfig (KGlobal::config(), "General");
return pConfig.readBoolEntry("compositingManagerAvailable", false);

return false;
}

bool KApplication::detectCompositionManagerAvailable(bool force_available) {
bool compositing_manager_available;
if (force_available) {
compositing_manager_available = true;
}
else {
// See if compositing has been enabled
KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
char *displayname = 0;
if ( qtargs->isSet("display"))
displayname = qtargs->getOption( "display" ).data();
Display *dpy = XOpenDisplay( displayname );
x11_composite_error_generated = false;
compositing_manager_available = false;
XSetErrorHandler(x11_error);
if (!XQueryExtension (dpy, COMPOSITE_NAME, &composite_opcode, &composite_event, &composite_error)) {
XSetErrorHandler(NULL);
compositing_manager_available = false;
}
else {
Window root_window = XDefaultRootWindow(dpy);
XCompositeRedirectSubwindows(dpy, root_window, CompositeRedirectManual);
XSync(dpy, false);
if (x11_composite_error_generated == true) {
compositing_manager_available = true;
}
else {
XCompositeUnredirectSubwindows(dpy, root_window, CompositeRedirectManual);
compositing_manager_available = false;
}
XSetErrorHandler(NULL);
XCloseDisplay(dpy);
}
}
KConfigGroup pConfig (KGlobal::config(), "General");
bool cmanager_enabled = pConfig.readBoolEntry("compositingManagerAvailable", false);
if (cmanager_enabled != compositing_manager_available) {
pConfig.writeEntry("compositingManagerAvailable", compositing_manager_available, true, true);
}
pConfig.sync();

return compositing_manager_available;
}

Display* KApplication::openX11RGBADisplay() {
KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
char *displayname = 0;
if ( qtargs->isSet("display"))
displayname = qtargs->getOption( "display" ).data();
Display *dpy = XOpenDisplay( displayname );
return dpy;
}

Qt::HANDLE KApplication::getX11RGBAVisual(Display *dpy) {
getX11RGBAInformation(dpy);
return argb_x11_visual;
}

Qt::HANDLE KApplication::getX11RGBAColormap(Display *dpy) {
getX11RGBAInformation(dpy);
return argb_x11_colormap;
}

bool KApplication::isX11CompositionAvailable() {
return argb_visual & isCompositionManagerAvailable();
}

void KApplication::getX11RGBAInformation(Display *dpy) {
if ( !dpy ) {
argb_visual = false;
return;
}
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;
}
}
}
if( argb_visual ) {
argb_x11_visual = Qt::HANDLE( visual );
argb_x11_colormap = Qt::HANDLE( colormap );
argb_visual = true;
return;
}
argb_visual = false;
return;
}

KApplication KApplication::KARGBApplicationObject( bool allowStyles ) {
KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
bool argb_visual_available = false;
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_available = true;
break;
}
}
}
if( argb_visual_available ) {
return KApplication( dpy, Qt::HANDLE( visual ), Qt::HANDLE( colormap ), allowStyles );
}
else {
return KApplication(allowStyles, true);
}
}
#else
Qt::HANDLE KApplication::getX11RGBAVisual(char *display) {
return 0;
}

Qt::HANDLE KApplication::getX11RGBAColormap(char *display) {
return 0;
}

bool KApplication::isX11CompositionAvailable() {
return false;
}

KApplication KApplication::KARGBApplication( bool allowStyles ) {
return KApplication::KApplication(allowStyles, true);
}
#endif

static bool kapp_block_user_input = false;


+ 87
- 2
kdecore/kapplication.h View File

@@ -48,6 +48,8 @@ class KSessionManaged;
class KStyle;
class KURL;

#define COMPOSITE // [FIXME] Autodetect composition support

#define kapp KApplication::kApplication()

class KApplicationPrivate;
@@ -113,6 +115,10 @@ public:
* This constructor takes aboutData and command line
* arguments from KCmdLineArgs.
*
* If ARGB (transparent) widgets are to be used in your application,
* please use KARGBApplication(new object name) or
* KARGBApplication(new object name, allow_styles) instead of KApplication(...).
*
* @param allowStyles Set to false to disable the loading on plugin based
* styles. This is only useful to applications that do not display a GUI
* normally. If you do create an application with @p allowStyles set to false
@@ -860,15 +866,88 @@ public:
*/
TQString checkRecoverFile( const TQString& pFilename, bool& bRecover ) const;

#ifdef Q_WS_X11
#if defined(Q_WS_X11) && defined(COMPOSITE)
/**
* @internal
* Get the X11 display
* @return the X11 Display
*/
Display *getDisplay() { return display; }
Display *getDisplay() { return display; }

/**
* @internal
* Gets X11 composition information
*/
void getX11RGBAInformation(Display *dpy);

/**
* Gets the availability of a composition manager such as kompmgr
* Note that at least one application must have called detectCompositionManagerAvailable
* while the current X display was active in order for this method to return valid results.
* @see detectCompositionManagerAvailable()
* @return whether the composition manager is enabled
*/
static bool isCompositionManagerAvailable();

/**
* Detects the availability of a composition manager such as kompmgr
* Note that calling this method will probably cause the screen to flicker.
* @see isCompositionManagerAvailable()
* @param force_available If set, force TDE to assume a composition manager is available
* @return whether the composition manager is enabled
*/
bool detectCompositionManagerAvailable(bool force_available=false);

/**
* @internal
* Opens an X11 display and returns the handle to it
* @return the X11 display handle
*/
Display *openX11RGBADisplay();
#endif

/**
* @internal
* Creates a default KApplication with transparency support
* (if available)
*/
static KApplication KARGBApplicationObject( bool allowStyles=true );

#define KARGBApplication(objectname, ...) const KApplication &__kapplication_internal_app = KApplication::KARGBApplicationObject(__VA_ARGS__); KApplication &objectname = const_cast<KApplication&>(__kapplication_internal_app);

/**
* Returns the X11 display visual
*
* @return A pointer to the X11 display visual
*/
Qt::HANDLE getX11RGBAVisual(Display *dpy);

/**
* Returns the X11 display colormap
*
* @return An X11 display colormap object
*/
Qt::HANDLE getX11RGBAColormap(Display *dpy);

/**
* Returns whether or not X11 composition is available
*
* You must first call getX11RGBAInformation()
*
* Note that getX11RGBAInformation() has already
* been called if you used the default KApplication
* constructor.
*
* Additionally, at least one application must have called
* detectCompositionManagerAvailable while the current X
* display was active in order for this method to return
* valid results.
*
* @return true if composition is available
*/
bool isX11CompositionAvailable();

/**
* Enables style plugins.
*
* This is useful only to applications that normally
@@ -1201,6 +1280,12 @@ private:
void dcopClientPostInit();
void initUrlActionRestrictions();

bool argb_visual;
#if defined(Q_WS_X11) && defined(COMPOSITE)
Qt::HANDLE argb_x11_visual;
Qt::HANDLE argb_x11_colormap;
#endif

public:
/**
* @internal

Loading…
Cancel
Save