Check that getting compositing pixmap of a window succeeded.
It may fail (or "fail") if the window is not mapped or if the geometry doesn't match, both of which may happen due to the asynchronous nature of X. svn path=/branches/work/kwin_composite/; revision=637741
This commit is contained in:
parent
e81db7c1b5
commit
e61ecff9b9
8 changed files with 39 additions and 17 deletions
|
@ -458,8 +458,8 @@ void Client::updateShape()
|
|||
else
|
||||
XShapeCombineMask( display(), frameId(), ShapeBounding, 0, 0,
|
||||
None, ShapeSet);
|
||||
if( compositing() )
|
||||
discardWindowPixmap();
|
||||
if( compositing())
|
||||
addDamageFull();
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
// workaround for #19644 - shaped windows shouldn't have decoration
|
||||
|
@ -496,8 +496,8 @@ void Client::setMask( const QRegion& reg, int mode )
|
|||
xrects, rects.count(), ShapeSet, mode );
|
||||
delete[] xrects;
|
||||
}
|
||||
if( compositing() )
|
||||
discardWindowPixmap();
|
||||
if( compositing())
|
||||
addDamageFull();
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <stdio.h>
|
||||
|
||||
#include <QMenu>
|
||||
#include <kxerrorhandler.h>
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
|
@ -367,11 +368,26 @@ void Toplevel::discardWindowPixmap()
|
|||
window_pix = None;
|
||||
}
|
||||
|
||||
Pixmap Toplevel::createWindowPixmap() const
|
||||
Pixmap Toplevel::createWindowPixmap()
|
||||
{
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
assert( compositing());
|
||||
return XCompositeNameWindowPixmap( display(), frameId());
|
||||
grabXServer();
|
||||
KXErrorHandler err;
|
||||
window_pix = XCompositeNameWindowPixmap( display(), frameId());
|
||||
// check that the received pixmap is valid and actually matches what we
|
||||
// know about the window (i.e. size)
|
||||
XWindowAttributes attrs;
|
||||
if( !XGetWindowAttributes( display(), frameId(), &attrs ))
|
||||
window_pix = None;
|
||||
if( err.error( false ))
|
||||
window_pix = None;
|
||||
if( attrs.width != width() || attrs.height != height() || attrs.map_state != IsViewable )
|
||||
window_pix = None;
|
||||
ungrabXServer();
|
||||
if( window_pix == None )
|
||||
kDebug( 1212 ) << "Creating window pixmap failed: " << this << endl;
|
||||
return window_pix;
|
||||
#else
|
||||
return None;
|
||||
#endif
|
||||
|
|
|
@ -1633,8 +1633,7 @@ bool Unmanaged::windowEvent( XEvent* e )
|
|||
if( e->type == Extensions::shapeNotifyEvent() )
|
||||
{
|
||||
detectShape( window());
|
||||
if( compositing() )
|
||||
discardWindowPixmap();
|
||||
addDamageFull();
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
}
|
||||
|
@ -1666,9 +1665,9 @@ void Unmanaged::configureNotifyEvent( XConfigureEvent* e )
|
|||
return;
|
||||
workspace()->addRepaint( geometry()); // damage old area
|
||||
geom = newgeom;
|
||||
discardWindowPixmap();
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
discardWindowPixmap();
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
|
|
|
@ -48,6 +48,8 @@ void SceneBasic::paint( QRegion, ToplevelList windows )
|
|||
if( !r.isEmpty())
|
||||
{
|
||||
Pixmap pix = (*it)->windowPixmap();
|
||||
if( pix == None )
|
||||
continue;
|
||||
XCopyArea( display(), pix, composite_pixmap, gc,
|
||||
qMax( 0, -(*it)->x()), qMax( 0, -(*it)->y()), r.width(), r.height(), r.x(), r.y());
|
||||
}
|
||||
|
|
|
@ -851,14 +851,14 @@ void SceneOpenGL::Window::findTextureTarget()
|
|||
}
|
||||
|
||||
// Bind the window pixmap to an OpenGL texture.
|
||||
void SceneOpenGL::Window::bindTexture()
|
||||
bool SceneOpenGL::Window::bindTexture()
|
||||
{
|
||||
if( texture != 0 && toplevel->damage().isEmpty()
|
||||
&& !options->glAlwaysRebind ) // interestingly with some gfx cards always rebinding is faster
|
||||
{
|
||||
// texture doesn't need updating, just bind it
|
||||
glBindTexture( texture_target, texture );
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if( !toplevel->damage().isEmpty())
|
||||
texture_has_valid_mipmaps = false;
|
||||
|
@ -868,11 +868,13 @@ void SceneOpenGL::Window::bindTexture()
|
|||
{
|
||||
kDebug( 1212 ) << "No framebuffer configuration for depth " << toplevel->depth()
|
||||
<< "; not binding window" << endl;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Get the pixmap with the window contents
|
||||
Pixmap pix = toplevel->windowPixmap();
|
||||
if( pix == None )
|
||||
return false;
|
||||
// HACK
|
||||
// When a window uses ARGB visual and has a decoration, the decoration
|
||||
// does use ARGB visual. When converting such window to a texture
|
||||
|
@ -1029,9 +1031,9 @@ void SceneOpenGL::Window::bindTexture()
|
|||
// by GLXPixmap in the tfp case or not needed at all in non-tfp cases)
|
||||
if( copy_buffer )
|
||||
XFreePixmap( display(), pix );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QRegion SceneOpenGL::Window::optimizeBindDamage( const QRegion& reg, int limit )
|
||||
{
|
||||
if( reg.rects().count() <= 1 )
|
||||
|
@ -1141,7 +1143,8 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
|
|||
region &= shape();
|
||||
if( region.isEmpty())
|
||||
return;
|
||||
bindTexture();
|
||||
if( !bindTexture())
|
||||
return;
|
||||
glPushMatrix();
|
||||
// set texture filter
|
||||
if( options->smoothScale != 0 ) // default to yes
|
||||
|
|
|
@ -94,7 +94,7 @@ class SceneOpenGL::Window
|
|||
virtual void performPaint( int mask, QRegion region, WindowPaintData data );
|
||||
virtual void prepareForPainting();
|
||||
void findTextureTarget();
|
||||
void bindTexture();
|
||||
bool bindTexture();
|
||||
void enableTexture();
|
||||
void disableTexture();
|
||||
void discardTexture();
|
||||
|
|
|
@ -325,6 +325,8 @@ Picture SceneXrender::Window::picture()
|
|||
{
|
||||
// Get the pixmap with the window contents.
|
||||
Pixmap pix = toplevel->windowPixmap();
|
||||
if( pix == None )
|
||||
return None;
|
||||
// HACK the same alpha clear hack like with opengl, see there
|
||||
Client* c = dynamic_cast< Client* >( toplevel );
|
||||
bool alpha_clear = c != NULL && c->hasAlpha() && !c->noBorder();
|
||||
|
|
|
@ -78,7 +78,7 @@ class Toplevel
|
|||
pid_t pid() const;
|
||||
static bool resourceMatch( const Toplevel* c1, const Toplevel* c2 );
|
||||
|
||||
Pixmap windowPixmap( bool allow_create = true ); // for use with compositing
|
||||
Pixmap windowPixmap( bool allow_create = true ); // may return None (e.g. at a bad moment while resizing)
|
||||
Visual* visual() const;
|
||||
bool shape() const;
|
||||
void setOpacity( double opacity );
|
||||
|
@ -102,7 +102,7 @@ class Toplevel
|
|||
void detectShape( Window id );
|
||||
virtual void propertyNotifyEvent( XPropertyEvent* e );
|
||||
void damageNotifyEvent( XDamageNotifyEvent* e );
|
||||
Pixmap createWindowPixmap() const;
|
||||
Pixmap createWindowPixmap();
|
||||
void discardWindowPixmap();
|
||||
void addDamage( const QRect& r );
|
||||
void addDamage( int x, int y, int w, int h );
|
||||
|
|
Loading…
Reference in a new issue