With windows that have are listed for the focus stealing prevention

workaround, don't make their user timestamp newer than the active window's
one (unless a real user activity takes place in them).
As they are belong to the active application and just fail to say so,
this makes sure they won't prevent that application from getting focus
by having newer timestamp. E.g. Alt+F2, typing URL, kio_uiserver dialog
shows (has workaround), SSL certificate dialog shows (shown by kdesktop),
and it wouldn't get focus, because kio_uiserver's timestamp would be later.

svn path=/trunk/kdebase/kwin/; revision=298357
This commit is contained in:
Luboš Luňák 2004-03-24 19:05:49 +00:00
parent 1c302cb000
commit 854e9cc05a
7 changed files with 44 additions and 8 deletions

View file

@ -278,6 +278,14 @@ void Workspace::activateClient( Client* c, bool force )
if( options->focusPolicyIsReasonable())
requestFocus( c, force );
// Don't update user time for clients that have focus stealing workaround.
// As they usually belong to the current active window but fail to provide
// this information, updating their user time would make the user time
// of the currently active window old, and reject further activation for it.
// E.g. typing URL in minicli which will show kio_uiserver dialog (with workaround),
// and then kdesktop shows dialog about SSL certificate.
// This needs also avoiding user creation time in Client::readUserTimeMapTimestamp().
if( !c->ignoreFocusStealing())
c->updateUserTime();
}
@ -445,7 +453,7 @@ bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in
kdDebug( 1212 ) << "Activation: No client active, allowing" << endl;
return true; // no active client -> always allow
}
if( options->ignoreFocusStealingClasses.contains(QString::fromLatin1(c->resourceClass())))
if( c->ignoreFocusStealing())
return true;
if( time == 0 ) // explicitly asked not to get focus
return false;
@ -472,7 +480,7 @@ bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in
}
// options->focusStealingPreventionLevel == 2 // normal
Time user_time = ac->userTime();
kdDebug( 1212 ) << "Activation, compared:" << time << ":" << user_time
kdDebug( 1212 ) << "Activation, compared:" << c << ":" << time << ":" << user_time
<< ":" << ( timestampCompare( time, user_time ) >= 0 ) << endl;
return timestampCompare( time, user_time ) >= 0; // time >= user_time
}
@ -498,7 +506,7 @@ bool Workspace::allowFullClientRaising( const Client* c )
kdDebug( 1212 ) << "Raising: No client active, allowing" << endl;
return true; // no active client -> always allow
}
if( options->ignoreFocusStealingClasses.contains(QString::fromLatin1(c->resourceClass())))
if( c->ignoreFocusStealing())
return true;
// TODO window urgency -> return true?
if( Client::belongToSameApplication( c, ac, true ))
@ -686,9 +694,12 @@ Time Client::readUserTimeMapTimestamp( const KStartupInfoData* asn_data,
// this check will be done in Workspace::allowClientActiovationTimestamp().
if( session && !session->fake )
return -1U;
if( ignoreFocusStealing() && act != NULL )
time = act->userTime();
else
time = readUserCreationTime();
}
kdDebug( 1212 ) << "User timestamp, final:" << time << endl;
kdDebug( 1212 ) << "User timestamp, final:" << this << ":" << time << endl;
return time;
}

View file

@ -124,6 +124,7 @@ Client::Client( Workspace *ws )
user_noborder = false;
not_obscured = false;
urgency = false;
ignore_focus_stealing = false;
Pdeletewindow = 0;
Ptakefocus = 0;

View file

@ -259,6 +259,7 @@ class Client : public QObject, public KDecorationDefines
void updateUserTime( Time time = CurrentTime );
Time userTime() const;
bool hasUserTimeSupport() const;
bool ignoreFocusStealing() const;
// does 'delete c;'
static void deleteClient( Client* c, allowed_t );
@ -445,6 +446,7 @@ private slots:
uint user_noborder : 1;
uint not_obscured : 1;
uint urgency : 1; // XWMHints, UrgencyHint
uint ignore_focus_stealing : 1; // don't apply focus stealing prevention to this client
void getWMHints();
void readIcons();
void getWindowProtocols();
@ -484,6 +486,7 @@ private slots:
int border_left, border_right, border_top, border_bottom;
QRegion _mask;
friend struct FetchNameInternalPredicate;
friend struct CheckIgnoreFocusStealingProcedure;
void show() { assert( false ); } // SELI remove after Client is no longer QWidget
void hide() { assert( false ); }
};
@ -824,6 +827,13 @@ inline bool Client::hasUserTimeSupport() const
return info->userTime() != -1U;
}
inline bool Client::ignoreFocusStealing() const
{
return ignore_focus_stealing;
}
KWIN_PROCEDURE( CheckIgnoreFocusStealingProcedure, cl->ignore_focus_stealing = options->checkIgnoreFocusStealing( cl ));
inline Window Client::moveResizeGrabWindow() const
{
return move_resize_grab_window;

View file

@ -103,6 +103,7 @@ bool Client::manage( Window w, bool isMapped )
XFree( classHint.res_name );
XFree( classHint.res_class );
}
ignore_focus_stealing = options->checkIgnoreFocusStealing( this );
detectNoBorder();
fetchName();

View file

@ -10,6 +10,7 @@ License. See the file "COPYING" for the exact licensing terms.
******************************************************************/
#include "options.h"
#include <qpalette.h>
#include <qpixmap.h>
#include <kapplication.h>
@ -18,6 +19,8 @@ License. See the file "COPYING" for the exact licensing terms.
#include <kglobalsettings.h>
#include <qtooltip.h>
#include "client.h"
namespace KWinInternal
{
@ -242,4 +245,9 @@ int Options::electricBorderDelay()
return electric_border_delay;
}
bool Options::checkIgnoreFocusStealing( const Client* c )
{
return ignoreFocusStealingClasses.contains(QString::fromLatin1(c->resourceClass()));
}
} // namespace

View file

@ -21,6 +21,8 @@ License. See the file "COPYING" for the exact licensing terms.
namespace KWinInternal
{
class Client;
class Options : public KDecorationOptions
{
public:
@ -184,8 +186,8 @@ class Options : public KDecorationOptions
* List of window classes to ignore PPosition size hint
*/
QStringList ignorePositionClasses;
// List of window classes for which not to use focus stealing prevention
QStringList ignoreFocusStealingClasses;
bool checkIgnoreFocusStealing( const Client* c );
WindowOperation operationTitlebarDblClick() { return OpTitlebarDblClick; }
@ -265,6 +267,8 @@ class Options : public KDecorationOptions
bool show_geometry_tip;
bool topmenus;
bool desktop_topmenu;
// List of window classes for which not to use focus stealing prevention
QStringList ignoreFocusStealingClasses;
};
extern Options* options;

View file

@ -734,6 +734,7 @@ void Workspace::slotReconfigure()
tab_box->reconfigure();
popupinfo->reconfigure();
readShortcuts();
forEachClient( CheckIgnoreFocusStealingProcedure());
if( mgr->reset( changed ))
{ // decorations need to be recreated