Make sure there aren't two windows given focus with the same X timestamp,

because if one timestamp is reused for activating window A and then
immediatelly window B, and A will want to set focus to one
of its subwindows after receiving WM_TAKE_FOCUS, and will lag a bit,
it will actually set the focus after B, and will win. Fixes #71704.

If somebody still gets the warning, I'd be interested in the backtrace.

svn path=/trunk/kdebase/kwin/; revision=278208
This commit is contained in:
Luboš Luňák 2004-01-09 17:35:21 +00:00
parent dac6116169
commit c1d1b6289f
5 changed files with 24 additions and 14 deletions

View file

@ -266,7 +266,9 @@ void Workspace::activateClient( Client* c, bool force )
raiseClient( c );
if (!c->isOnDesktop(currentDesktop()) )
{
++block_focus;
setCurrentDesktop( c->desktop() );
--block_focus;
// popupinfo->showInfo( desktopName(currentDesktop()) ); // AK - not sure
}
if( c->isMinimized())
@ -339,8 +341,6 @@ void Workspace::requestFocus( Client* c, bool force )
\a c may already be destroyed
*/
extern bool block_focus; // SELI
void Workspace::clientHidden( Client* c )
{
assert( !c->isShown( true ) || !c->isOnCurrentDesktop());
@ -353,7 +353,7 @@ void Workspace::clientHidden( Client* c )
if( c == active_client )
setActiveClient( NULL, Allowed );
should_get_focus.remove( c );
if( !block_focus )
if( focusChangeEnabled())
{
if ( c->wantsTabFocus() && focus_chain.contains( c ) )
{

View file

@ -1098,6 +1098,15 @@ void Client::takeFocus( bool force, allowed_t )
if ( !force && ( isTopMenu() || isDock() || isSplash()) )
return; // toplevel menus and dock windows don't take focus if not forced
#ifndef NDEBUG
static Time previous_focus_timestamp;
if( previous_focus_timestamp == qt_x_time )
{
kdWarning( 1212 ) << "Repeated use of the same X timestamp for focus" << endl;
kdDebug( 1212 ) << kdBacktrace() << endl;
}
previous_focus_timestamp = qt_x_time;
#endif
if ( input )
{
XSetInputFocus( qt_xdisplay(), window(), RevertToPointerRoot, qt_x_time );

View file

@ -302,9 +302,9 @@ void Workspace::setClientIsMoving( Client *c )
// window while still moving the first one.
movingClient = c;
if (movingClient)
setFocusChangeEnabled( false );
++block_focus;
else
setFocusChangeEnabled( true );
--block_focus;
}
/*!

View file

@ -49,8 +49,6 @@ namespace KWinInternal
extern int screen_number;
bool block_focus = FALSE;
static Window null_focus_window = 0;
Workspace *Workspace::_self = 0;
@ -78,7 +76,7 @@ Workspace::Workspace( bool restore )
control_grab (false),
tab_grab (false),
mouse_emulation (false),
focus_change (true),
block_focus (0),
tab_box (0),
popupinfo (0),
popup (0),
@ -289,6 +287,8 @@ void Workspace::init()
active_client = NULL;
rootInfo->setActiveWindow( None );
focusToNull();
if( !kapp->isSessionRestored())
++block_focus; // because it will be set below
char nm[ 100 ];
sprintf( nm, "_KDE_TOPMENU_OWNER_S%d", DefaultScreen( qt_xdisplay()));
@ -352,7 +352,10 @@ void Workspace::init()
Client* new_active_client = NULL;
if( !kapp->isSessionRestored())
{
--block_focus;
new_active_client = findClient( WindowMatchPredicate( client_info.activeWindow()));
}
if( new_active_client == NULL
&& activeClient() == NULL && should_get_focus.count() == 0 ) // no client activated in manage()
{
@ -946,7 +949,7 @@ bool Workspace::setCurrentDesktop( int new_desktop )
if( popup )
popup->close();
block_focus = TRUE;
++block_focus;
// TODO Q_ASSERT( block_stacking_updates == 0 ); // make sure stacking_order is up to date
StackingUpdatesBlocker blocker( this );
@ -982,7 +985,7 @@ bool Workspace::setCurrentDesktop( int new_desktop )
}
// restore the focus on this desktop
block_focus = FALSE;
--block_focus;
Client* c = 0;
if ( options->focusPolicyIsReasonable())

View file

@ -117,12 +117,10 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
void gotFocusIn( const Client* );
bool fakeRequestedActivity( Client* c );
void unfakeActivity( Client* c );
bool focusChangeEnabled() { return block_focus == 0; }
void updateColormap();
void setFocusChangeEnabled(bool b) { focus_change = b; }
bool focusChangeEnabled() { return focus_change; }
/**
* Indicates that the client c is being moved around by the user.
*/
@ -445,7 +443,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
bool mouse_emulation;
unsigned int mouse_emulation_state;
WId mouse_emulation_window;
bool focus_change;
int block_focus;
TabBox* tab_box;
PopupInfo* popupinfo;