Support for _NET_WM_SYNC_REQUEST, based on a patch
by Rayiner Hashem <gtg990h@mail.gatech.edu>. svn path=/trunk/KDE/kdebase/workspace/; revision=679986
This commit is contained in:
parent
8eac2caca5
commit
162d6ac7c9
12 changed files with 248 additions and 14 deletions
|
@ -92,6 +92,12 @@ Atoms::Atoms()
|
||||||
atoms[n] = &kde_net_wm_frame_strut;
|
atoms[n] = &kde_net_wm_frame_strut;
|
||||||
names[n++] = (char*) "_KDE_NET_WM_FRAME_STRUT";
|
names[n++] = (char*) "_KDE_NET_WM_FRAME_STRUT";
|
||||||
|
|
||||||
|
atoms[n] = &net_wm_sync_request_counter;
|
||||||
|
names[n++] = (char*) "_NET_WM_SYNC_REQUEST_COUNTER";
|
||||||
|
|
||||||
|
atoms[n] = &net_wm_sync_request;
|
||||||
|
names[n++] = (char*) "_NET_WM_SYNC_REQUEST";
|
||||||
|
|
||||||
assert( n <= max );
|
assert( n <= max );
|
||||||
|
|
||||||
XInternAtoms( display(), names, n, false, atoms_return );
|
XInternAtoms( display(), names, n, false, atoms_return );
|
||||||
|
|
2
atoms.h
2
atoms.h
|
@ -47,6 +47,8 @@ class Atoms
|
||||||
Atom xdnd_position;
|
Atom xdnd_position;
|
||||||
Atom net_frame_extents;
|
Atom net_frame_extents;
|
||||||
Atom kde_net_wm_frame_strut;
|
Atom kde_net_wm_frame_strut;
|
||||||
|
Atom net_wm_sync_request_counter;
|
||||||
|
Atom net_wm_sync_request;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
87
client.cpp
87
client.cpp
|
@ -36,6 +36,10 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
|
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
#include <X11/extensions/sync.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// put all externs before the namespace statement to allow the linker
|
// put all externs before the namespace statement to allow the linker
|
||||||
// to resolve them properly
|
// to resolve them properly
|
||||||
|
|
||||||
|
@ -91,6 +95,12 @@ Client::Client( Workspace *ws )
|
||||||
block_geometry_updates( 0 ),
|
block_geometry_updates( 0 ),
|
||||||
pending_geometry_update( PendingGeometryNone ),
|
pending_geometry_update( PendingGeometryNone ),
|
||||||
shade_geometry_change( false ),
|
shade_geometry_change( false ),
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
sync_counter( None ),
|
||||||
|
sync_alarm( None ),
|
||||||
|
#endif
|
||||||
|
sync_timeout( NULL ),
|
||||||
|
sync_resize_pending( false ),
|
||||||
border_left( 0 ),
|
border_left( 0 ),
|
||||||
border_right( 0 ),
|
border_right( 0 ),
|
||||||
border_top( 0 ),
|
border_top( 0 ),
|
||||||
|
@ -147,6 +157,9 @@ Client::Client( Workspace *ws )
|
||||||
|
|
||||||
geom = QRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0)
|
geom = QRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0)
|
||||||
client_size = QSize( 100, 100 );
|
client_size = QSize( 100, 100 );
|
||||||
|
#if defined(HAVE_XSYNC) || defined(HAVE_XDAMAGE)
|
||||||
|
ready_for_painting = false; // wait for first damage or sync reply
|
||||||
|
#endif
|
||||||
|
|
||||||
// SELI initialize xsizehints??
|
// SELI initialize xsizehints??
|
||||||
}
|
}
|
||||||
|
@ -156,6 +169,10 @@ Client::Client( Workspace *ws )
|
||||||
*/
|
*/
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
if( sync_alarm != None )
|
||||||
|
XSyncDestroyAlarm( display(), sync_alarm );
|
||||||
|
#endif
|
||||||
assert(!moveResizeMode);
|
assert(!moveResizeMode);
|
||||||
assert( client == None );
|
assert( client == None );
|
||||||
assert( wrapper == None );
|
assert( wrapper == None );
|
||||||
|
@ -1431,6 +1448,76 @@ void Client::getWindowProtocols()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::getSyncCounter()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
if( !Extensions::syncAvailable())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Atom retType;
|
||||||
|
unsigned long nItemRet;
|
||||||
|
unsigned long byteRet;
|
||||||
|
int formatRet;
|
||||||
|
unsigned char* propRet;
|
||||||
|
int ret = XGetWindowProperty( display(), window(), atoms->net_wm_sync_request_counter,
|
||||||
|
0, 1, false, XA_CARDINAL, &retType, &formatRet, &nItemRet, &byteRet, &propRet );
|
||||||
|
|
||||||
|
if( ret == Success && formatRet == 32 )
|
||||||
|
{
|
||||||
|
sync_counter = *(long*)propRet;
|
||||||
|
XSyncIntToValue( &sync_counter_value, 0 );
|
||||||
|
XSyncValue zero;
|
||||||
|
XSyncIntToValue( &zero, 0 );
|
||||||
|
XSyncSetCounter( display(), sync_counter, zero );
|
||||||
|
if( sync_alarm == None )
|
||||||
|
{
|
||||||
|
XSyncAlarmAttributes attrs;
|
||||||
|
attrs.trigger.counter = sync_counter;
|
||||||
|
attrs.trigger.value_type = XSyncRelative;
|
||||||
|
attrs.trigger.test_type = XSyncPositiveTransition;
|
||||||
|
XSyncIntToValue( &attrs.trigger.wait_value, 1 );
|
||||||
|
XSyncIntToValue( &attrs.delta, 1 );
|
||||||
|
sync_alarm = XSyncCreateAlarm( display(),
|
||||||
|
XSyncCACounter | XSyncCAValueType | XSyncCATestType | XSyncCADelta | XSyncCAValue,
|
||||||
|
&attrs );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the client a _NET_SYNC_REQUEST
|
||||||
|
void Client::sendSyncRequest()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
if( sync_counter == None )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// we increment before the notify so that after the notify
|
||||||
|
// syncCounterSerial will equal the value we are expecting
|
||||||
|
// in the acknowledgement
|
||||||
|
int overflow;
|
||||||
|
XSyncValue one;
|
||||||
|
XSyncIntToValue( &one, 1 );
|
||||||
|
#undef XSyncValueAdd // it causes a warning :-/
|
||||||
|
XSyncValueAdd( &sync_counter_value, sync_counter_value, one, &overflow );
|
||||||
|
|
||||||
|
// send the message to client
|
||||||
|
XEvent ev;
|
||||||
|
ev.xclient.type = ClientMessage;
|
||||||
|
ev.xclient.window = window();
|
||||||
|
ev.xclient.format = 32;
|
||||||
|
ev.xclient.message_type = atoms->wm_protocols;
|
||||||
|
ev.xclient.data.l[ 0 ] = atoms->net_wm_sync_request;
|
||||||
|
ev.xclient.data.l[ 1 ] = xTime();
|
||||||
|
ev.xclient.data.l[ 2 ] = XSyncValueLow32( sync_counter_value );
|
||||||
|
ev.xclient.data.l[ 3 ] = XSyncValueHigh32( sync_counter_value );
|
||||||
|
ev.xclient.data.l[ 4 ] = 0;
|
||||||
|
XSendEvent( display(), window(), False, NoEventMask, &ev );
|
||||||
|
XSync(display(),false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Client::wantsTabFocus() const
|
bool Client::wantsTabFocus() const
|
||||||
{
|
{
|
||||||
return ( isNormalWindow() || isDialog()) && wantsInput();
|
return ( isNormalWindow() || isDialog()) && wantsInput();
|
||||||
|
|
23
client.h
23
client.h
|
@ -12,6 +12,8 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#ifndef KWIN_CLIENT_H
|
#ifndef KWIN_CLIENT_H
|
||||||
#define KWIN_CLIENT_H
|
#define KWIN_CLIENT_H
|
||||||
|
|
||||||
|
#include <config-X11.h>
|
||||||
|
|
||||||
#include <qframe.h>
|
#include <qframe.h>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <netwm.h>
|
#include <netwm.h>
|
||||||
|
@ -30,6 +32,10 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
#include "toplevel.h"
|
#include "toplevel.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
#include <X11/extensions/sync.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
class QTimer;
|
class QTimer;
|
||||||
class K3Process;
|
class K3Process;
|
||||||
class KStartupInfoData;
|
class KStartupInfoData;
|
||||||
|
@ -84,6 +90,9 @@ class Client
|
||||||
|
|
||||||
bool windowEvent( XEvent* e );
|
bool windowEvent( XEvent* e );
|
||||||
virtual bool eventFilter( QObject* o, QEvent* e );
|
virtual bool eventFilter( QObject* o, QEvent* e );
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
void syncEvent( XSyncAlarmNotifyEvent* e );
|
||||||
|
#endif
|
||||||
|
|
||||||
bool manage( Window w, bool isMapped );
|
bool manage( Window w, bool isMapped );
|
||||||
void releaseWindow( bool on_shutdown = false );
|
void releaseWindow( bool on_shutdown = false );
|
||||||
|
@ -293,6 +302,9 @@ class Client
|
||||||
void leaveNotifyEvent( XCrossingEvent* e );
|
void leaveNotifyEvent( XCrossingEvent* e );
|
||||||
void focusInEvent( XFocusInEvent* e );
|
void focusInEvent( XFocusInEvent* e );
|
||||||
void focusOutEvent( XFocusOutEvent* e );
|
void focusOutEvent( XFocusOutEvent* e );
|
||||||
|
#ifdef HAVE_XDAMAGE
|
||||||
|
virtual void damageNotifyEvent( XDamageNotifyEvent* e );
|
||||||
|
#endif
|
||||||
|
|
||||||
bool buttonPressEvent( Window w, int button, int state, int x, int y, int x_root, int y_root );
|
bool buttonPressEvent( Window w, int button, int state, int x, int y, int x_root, int y_root );
|
||||||
bool buttonReleaseEvent( Window w, int button, int state, int x, int y, int x_root, int y_root );
|
bool buttonReleaseEvent( Window w, int button, int state, int x, int y, int x_root, int y_root );
|
||||||
|
@ -307,6 +319,7 @@ class Client
|
||||||
void pingTimeout();
|
void pingTimeout();
|
||||||
void processKillerExited();
|
void processKillerExited();
|
||||||
void demandAttentionKNotify();
|
void demandAttentionKNotify();
|
||||||
|
void syncTimeout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ICCCM 4.1.3.1, 4.1.4 , NETWM 2.5.1
|
// ICCCM 4.1.3.1, 4.1.4 , NETWM 2.5.1
|
||||||
|
@ -339,6 +352,8 @@ class Client
|
||||||
NETExtendedStrut strut() const;
|
NETExtendedStrut strut() const;
|
||||||
int checkShadeGeometry( int w, int h );
|
int checkShadeGeometry( int w, int h );
|
||||||
void blockGeometryUpdates( bool block );
|
void blockGeometryUpdates( bool block );
|
||||||
|
void getSyncCounter();
|
||||||
|
void sendSyncRequest();
|
||||||
|
|
||||||
bool startMoveResize();
|
bool startMoveResize();
|
||||||
void finishMoveResize( bool cancel );
|
void finishMoveResize( bool cancel );
|
||||||
|
@ -352,6 +367,7 @@ class Client
|
||||||
void ungrabButton( int mod );
|
void ungrabButton( int mod );
|
||||||
void resetMaximize();
|
void resetMaximize();
|
||||||
void resizeDecoration( const QSize& s );
|
void resizeDecoration( const QSize& s );
|
||||||
|
void performMoveResize();
|
||||||
|
|
||||||
void pingWindow();
|
void pingWindow();
|
||||||
void killProcess( bool ask, Time timestamp = CurrentTime );
|
void killProcess( bool ask, Time timestamp = CurrentTime );
|
||||||
|
@ -465,6 +481,13 @@ class Client
|
||||||
PendingGeometry_t pending_geometry_update;
|
PendingGeometry_t pending_geometry_update;
|
||||||
QRect geom_before_block;
|
QRect geom_before_block;
|
||||||
bool shade_geometry_change;
|
bool shade_geometry_change;
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
XSyncCounter sync_counter;
|
||||||
|
XSyncValue sync_counter_value;
|
||||||
|
XSyncAlarm sync_alarm;
|
||||||
|
#endif
|
||||||
|
QTimer* sync_timeout;
|
||||||
|
bool sync_resize_pending;
|
||||||
int border_left, border_right, border_top, border_bottom;
|
int border_left, border_right, border_top, border_bottom;
|
||||||
QRegion _mask;
|
QRegion _mask;
|
||||||
static bool check_active_modal; // see Client::checkActiveModal()
|
static bool check_active_modal; // see Client::checkActiveModal()
|
||||||
|
|
|
@ -284,6 +284,11 @@ void Workspace::performCompositing()
|
||||||
repaints_region |= c->repaints().translated( c->pos());
|
repaints_region |= c->repaints().translated( c->pos());
|
||||||
c->resetRepaints( c->rect());
|
c->resetRepaints( c->rect());
|
||||||
}
|
}
|
||||||
|
ToplevelList tmp = windows;
|
||||||
|
windows.clear();
|
||||||
|
foreach( Toplevel* c, tmp )
|
||||||
|
if( c->readyForPainting())
|
||||||
|
windows.append( c );
|
||||||
QRegion repaints = repaints_region;
|
QRegion repaints = repaints_region;
|
||||||
// clear all repaints, so that post-pass can add repaints for the next repaint
|
// clear all repaints, so that post-pass can add repaints for the next repaint
|
||||||
repaints_region = QRegion();
|
repaints_region = QRegion();
|
||||||
|
@ -445,6 +450,17 @@ void Toplevel::damageNotifyEvent( XDamageNotifyEvent* e )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::damageNotifyEvent( XDamageNotifyEvent* e )
|
||||||
|
{
|
||||||
|
Toplevel::damageNotifyEvent( e );
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
if( sync_counter == None ) // cannot detect complete redraw, consider done now
|
||||||
|
ready_for_painting = true;
|
||||||
|
#else
|
||||||
|
ready_for_painting = true; // no sync at all, consider done now
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Toplevel::addDamage( const QRect& r )
|
void Toplevel::addDamage( const QRect& r )
|
||||||
|
|
28
events.cpp
28
events.cpp
|
@ -478,6 +478,15 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
QTimer::singleShot( 0, this, SLOT( setupCompositing() ) );
|
QTimer::singleShot( 0, this, SLOT( setupCompositing() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( e->type == Extensions::syncAlarmNotifyEvent() && Extensions::syncAvailable())
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
foreach( Client* c, clients )
|
||||||
|
c->syncEvent( reinterpret_cast< XSyncAlarmNotifyEvent* >( e ));
|
||||||
|
foreach( Client* c, desktops )
|
||||||
|
c->syncEvent( reinterpret_cast< XSyncAlarmNotifyEvent* >( e ));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -909,6 +918,8 @@ void Client::propertyNotifyEvent( XPropertyEvent* e )
|
||||||
getWindowProtocols();
|
getWindowProtocols();
|
||||||
else if( e->atom == atoms->motif_wm_hints )
|
else if( e->atom == atoms->motif_wm_hints )
|
||||||
getMotifHints();
|
getMotifHints();
|
||||||
|
else if( e->atom == atoms->net_wm_sync_request_counter )
|
||||||
|
getSyncCounter();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1560,6 +1571,23 @@ void Client::keyPressEvent( uint key_code )
|
||||||
QCursor::setPos( pos );
|
QCursor::setPos( pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
void Client::syncEvent( XSyncAlarmNotifyEvent* e )
|
||||||
|
{
|
||||||
|
if( e->alarm == sync_alarm && XSyncValueEqual( e->counter_value, sync_counter_value ))
|
||||||
|
{
|
||||||
|
ready_for_painting = true;
|
||||||
|
if( isResize())
|
||||||
|
{
|
||||||
|
delete sync_timeout;
|
||||||
|
sync_timeout = NULL;
|
||||||
|
if( sync_resize_pending )
|
||||||
|
performMoveResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
// Unmanaged
|
// Unmanaged
|
||||||
// ****************************************
|
// ****************************************
|
||||||
|
|
59
geometry.cpp
59
geometry.cpp
|
@ -2368,6 +2368,8 @@ void Client::leaveMoveResize()
|
||||||
moveResizeMode = false;
|
moveResizeMode = false;
|
||||||
delete eater;
|
delete eater;
|
||||||
eater = 0;
|
eater = 0;
|
||||||
|
delete sync_timeout;
|
||||||
|
sync_timeout = NULL;
|
||||||
if( options->electricBorders() == Options::ElectricMoveOnly )
|
if( options->electricBorders() == Options::ElectricMoveOnly )
|
||||||
workspace()->reserveElectricBorderSwitching( false );
|
workspace()->reserveElectricBorderSwitching( false );
|
||||||
}
|
}
|
||||||
|
@ -2618,26 +2620,57 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
||||||
else
|
else
|
||||||
assert( false );
|
assert( false );
|
||||||
|
|
||||||
if( update )
|
if( isResize())
|
||||||
{
|
{
|
||||||
if( rules()->checkMoveResizeMode
|
if( sync_timeout != NULL )
|
||||||
( isResize() ? options->resizeMode : options->moveMode ) == Options::Opaque )
|
|
||||||
{
|
{
|
||||||
setGeometry( moveResizeGeom );
|
sync_resize_pending = true;
|
||||||
positionGeometryTip();
|
return;
|
||||||
}
|
}
|
||||||
else if( rules()->checkMoveResizeMode
|
|
||||||
( isResize() ? options->resizeMode : options->moveMode ) == Options::Transparent )
|
|
||||||
{
|
|
||||||
clearbound(); // it's necessary to move the geometry tip when there's no outline
|
|
||||||
positionGeometryTip(); // shown, otherwise it would cause repaint problems in case
|
|
||||||
drawbound( moveResizeGeom ); // they overlap; the paint event will come after this,
|
|
||||||
} // so the geometry tip will be painted above the outline
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( update )
|
||||||
|
performMoveResize();
|
||||||
if ( isMove() )
|
if ( isMove() )
|
||||||
workspace()->checkElectricBorder(globalPos, xTime());
|
workspace()->checkElectricBorder(globalPos, xTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::performMoveResize()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
if( isResize() && sync_counter != None )
|
||||||
|
{
|
||||||
|
sync_timeout = new QTimer( this );
|
||||||
|
connect( sync_timeout, SIGNAL( timeout()), SLOT( syncTimeout()));
|
||||||
|
sync_timeout->setSingleShot( true );
|
||||||
|
sync_timeout->start( 500 );
|
||||||
|
sendSyncRequest();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
sync_resize_pending = false;
|
||||||
|
if( rules()->checkMoveResizeMode
|
||||||
|
( isResize() ? options->resizeMode : options->moveMode ) == Options::Opaque )
|
||||||
|
{
|
||||||
|
setGeometry( moveResizeGeom );
|
||||||
|
positionGeometryTip();
|
||||||
|
}
|
||||||
|
else if( rules()->checkMoveResizeMode
|
||||||
|
( isResize() ? options->resizeMode : options->moveMode ) == Options::Transparent )
|
||||||
|
{
|
||||||
|
clearbound(); // it's necessary to move the geometry tip when there's no outline
|
||||||
|
positionGeometryTip(); // shown, otherwise it would cause repaint problems in case
|
||||||
|
drawbound( moveResizeGeom ); // they overlap; the paint event will come after this,
|
||||||
|
} // so the geometry tip will be painted above the outline
|
||||||
if( effects )
|
if( effects )
|
||||||
static_cast<EffectsHandlerImpl*>(effects)->windowUserMovedResized( effectWindow(), false, false );
|
static_cast<EffectsHandlerImpl*>(effects)->windowUserMovedResized( effectWindow(), false, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::syncTimeout()
|
||||||
|
{
|
||||||
|
sync_timeout->deleteLater();
|
||||||
|
sync_timeout = NULL;
|
||||||
|
if( sync_resize_pending )
|
||||||
|
performMoveResize();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -96,6 +96,7 @@ bool Client::manage( Window w, bool isMapped )
|
||||||
getWindowRole();
|
getWindowRole();
|
||||||
getWmClientLeader();
|
getWmClientLeader();
|
||||||
getWmClientMachine();
|
getWmClientMachine();
|
||||||
|
getSyncCounter();
|
||||||
// first only read the caption text, so that setupWindowRules() can use it for matching,
|
// first only read the caption text, so that setupWindowRules() can use it for matching,
|
||||||
// and only then really set the caption using setCaption(), which checks for duplicates etc.
|
// and only then really set the caption using setCaption(), which checks for duplicates etc.
|
||||||
// and also relies on rules already existing
|
// and also relies on rules already existing
|
||||||
|
@ -441,6 +442,9 @@ bool Client::manage( Window w, bool isMapped )
|
||||||
workspace()->restoreSessionStackingOrder( this );
|
workspace()->restoreSessionStackingOrder( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( compositing()) // sending ConfigureNotify is done when setting mapping state below,
|
||||||
|
sendSyncRequest(); // getting the first sync response means window is ready for compositing
|
||||||
|
|
||||||
if( isShown( true ) && !doNotShow )
|
if( isShown( true ) && !doNotShow )
|
||||||
{
|
{
|
||||||
if( isDialog())
|
if( isDialog())
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace KWin
|
||||||
Toplevel::Toplevel( Workspace* ws )
|
Toplevel::Toplevel( Workspace* ws )
|
||||||
: vis( NULL )
|
: vis( NULL )
|
||||||
, info( NULL )
|
, info( NULL )
|
||||||
|
, ready_for_painting( true )
|
||||||
, client( None )
|
, client( None )
|
||||||
, frame( None )
|
, frame( None )
|
||||||
, wspace( ws )
|
, wspace( ws )
|
||||||
|
@ -104,6 +105,7 @@ void Toplevel::copyToDeleted( Toplevel* c )
|
||||||
frame = c->frame;
|
frame = c->frame;
|
||||||
wspace = c->wspace;
|
wspace = c->wspace;
|
||||||
window_pix = c->window_pix;
|
window_pix = c->window_pix;
|
||||||
|
ready_for_painting = c->ready_for_painting;
|
||||||
#ifdef HAVE_XDAMAGE
|
#ifdef HAVE_XDAMAGE
|
||||||
damage_handle = None;
|
damage_handle = None;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,6 +85,7 @@ class Toplevel
|
||||||
static bool resourceMatch( const Toplevel* c1, const Toplevel* c2 );
|
static bool resourceMatch( const Toplevel* c1, const Toplevel* c2 );
|
||||||
|
|
||||||
Pixmap windowPixmap( bool allow_create = true ); // may return None (e.g. at a bad moment while resizing)
|
Pixmap windowPixmap( bool allow_create = true ); // may return None (e.g. at a bad moment while resizing)
|
||||||
|
bool readyForPainting() const; // true if the window has been already painted its contents
|
||||||
Visual* visual() const;
|
Visual* visual() const;
|
||||||
bool shape() const;
|
bool shape() const;
|
||||||
void setOpacity( double opacity );
|
void setOpacity( double opacity );
|
||||||
|
@ -111,7 +112,7 @@ class Toplevel
|
||||||
void detectShape( Window id );
|
void detectShape( Window id );
|
||||||
virtual void propertyNotifyEvent( XPropertyEvent* e );
|
virtual void propertyNotifyEvent( XPropertyEvent* e );
|
||||||
#ifdef HAVE_XDAMAGE
|
#ifdef HAVE_XDAMAGE
|
||||||
void damageNotifyEvent( XDamageNotifyEvent* e );
|
virtual void damageNotifyEvent( XDamageNotifyEvent* e );
|
||||||
#endif
|
#endif
|
||||||
Pixmap createWindowPixmap();
|
Pixmap createWindowPixmap();
|
||||||
void discardWindowPixmap();
|
void discardWindowPixmap();
|
||||||
|
@ -130,6 +131,7 @@ class Toplevel
|
||||||
Visual* vis;
|
Visual* vis;
|
||||||
int bit_depth;
|
int bit_depth;
|
||||||
NETWinInfo* info;
|
NETWinInfo* info;
|
||||||
|
bool ready_for_painting;
|
||||||
private:
|
private:
|
||||||
static QByteArray staticWindowRole(WId);
|
static QByteArray staticWindowRole(WId);
|
||||||
static QByteArray staticSessionId(WId);
|
static QByteArray staticSessionId(WId);
|
||||||
|
@ -219,6 +221,11 @@ inline QRect Toplevel::rect() const
|
||||||
return QRect( 0, 0, width(), height());
|
return QRect( 0, 0, width(), height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Toplevel::readyForPainting() const
|
||||||
|
{
|
||||||
|
return ready_for_painting;
|
||||||
|
}
|
||||||
|
|
||||||
inline Visual* Toplevel::visual() const
|
inline Visual* Toplevel::visual() const
|
||||||
{
|
{
|
||||||
return vis;
|
return vis;
|
||||||
|
|
22
utils.cpp
22
utils.cpp
|
@ -50,6 +50,9 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#ifdef HAVE_OPENGL
|
#ifdef HAVE_OPENGL
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
#include <X11/extensions/sync.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -74,6 +77,8 @@ int Extensions::composite_version = 0;
|
||||||
int Extensions::fixes_version = 0;
|
int Extensions::fixes_version = 0;
|
||||||
int Extensions::render_version = 0;
|
int Extensions::render_version = 0;
|
||||||
bool Extensions::has_glx = false;
|
bool Extensions::has_glx = false;
|
||||||
|
bool Extensions::has_sync = false;
|
||||||
|
int Extensions::sync_event_base = 0;
|
||||||
|
|
||||||
void Extensions::init()
|
void Extensions::init()
|
||||||
{
|
{
|
||||||
|
@ -131,6 +136,14 @@ void Extensions::init()
|
||||||
has_glx = false;
|
has_glx = false;
|
||||||
#ifdef HAVE_OPENGL
|
#ifdef HAVE_OPENGL
|
||||||
has_glx = glXQueryExtension( display(), &dummy, &dummy );
|
has_glx = glXQueryExtension( display(), &dummy, &dummy );
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
if( XSyncQueryExtension( display(), &sync_event_base, &dummy ))
|
||||||
|
{
|
||||||
|
int major = 0, minor = 0;
|
||||||
|
if( XSyncInitialize( display(), &major, &minor ))
|
||||||
|
has_sync = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
kDebug( 1212 ) << "Extensions: shape: 0x" << QString::number( shape_version, 16 )
|
kDebug( 1212 ) << "Extensions: shape: 0x" << QString::number( shape_version, 16 )
|
||||||
<< " composite: 0x" << QString::number( composite_version, 16 )
|
<< " composite: 0x" << QString::number( composite_version, 16 )
|
||||||
|
@ -190,6 +203,15 @@ bool Extensions::fixesRegionAvailable()
|
||||||
return fixes_version >= 0x30; // 3
|
return fixes_version >= 0x30; // 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Extensions::syncAlarmNotifyEvent()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XSYNC
|
||||||
|
return sync_event_base + XSyncAlarmNotify;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
|
void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
|
||||||
bool& minimize, bool& maximize, bool& close )
|
bool& minimize, bool& maximize, bool& close )
|
||||||
{
|
{
|
||||||
|
|
4
utils.h
4
utils.h
|
@ -143,6 +143,8 @@ class Extensions
|
||||||
static bool fixesAvailable() { return fixes_version > 0; }
|
static bool fixesAvailable() { return fixes_version > 0; }
|
||||||
static bool fixesRegionAvailable();
|
static bool fixesRegionAvailable();
|
||||||
static bool glxAvailable() { return has_glx; }
|
static bool glxAvailable() { return has_glx; }
|
||||||
|
static bool syncAvailable() { return has_sync; }
|
||||||
|
static int syncAlarmNotifyEvent();
|
||||||
private:
|
private:
|
||||||
static int shape_version;
|
static int shape_version;
|
||||||
static int shape_event_base;
|
static int shape_event_base;
|
||||||
|
@ -154,6 +156,8 @@ class Extensions
|
||||||
static int render_version;
|
static int render_version;
|
||||||
static int fixes_version;
|
static int fixes_version;
|
||||||
static bool has_glx;
|
static bool has_glx;
|
||||||
|
static bool has_sync;
|
||||||
|
static int sync_event_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
// compile with XShape older than 1.0
|
// compile with XShape older than 1.0
|
||||||
|
|
Loading…
Reference in a new issue