From c1d1b6289fc4d8c58c44f7b5cf532ff983b2d562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Fri, 9 Jan 2004 17:35:21 +0000 Subject: [PATCH] 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 --- activation.cpp | 6 +++--- client.cpp | 9 +++++++++ geometry.cpp | 4 ++-- workspace.cpp | 13 ++++++++----- workspace.h | 6 ++---- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/activation.cpp b/activation.cpp index f9b6eac738..f2b06a3293 100644 --- a/activation.cpp +++ b/activation.cpp @@ -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 ) ) { diff --git a/client.cpp b/client.cpp index 79fa4ff5e4..62ac79730f 100644 --- a/client.cpp +++ b/client.cpp @@ -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 ); diff --git a/geometry.cpp b/geometry.cpp index f52fbc08b4..3025df68e5 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -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; } /*! diff --git a/workspace.cpp b/workspace.cpp index 671f40a8e0..e8ebad7a06 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -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()) diff --git a/workspace.h b/workspace.h index f7eebe443c..3b0da8d77d 100644 --- a/workspace.h +++ b/workspace.h @@ -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;