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:
parent
1c302cb000
commit
854e9cc05a
7 changed files with 44 additions and 8 deletions
|
@ -278,7 +278,15 @@ void Workspace::activateClient( Client* c, bool force )
|
|||
if( options->focusPolicyIsReasonable())
|
||||
requestFocus( c, force );
|
||||
|
||||
c->updateUserTime();
|
||||
// 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;
|
||||
time = readUserCreationTime();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ Client::Client( Workspace *ws )
|
|||
user_noborder = false;
|
||||
not_obscured = false;
|
||||
urgency = false;
|
||||
ignore_focus_stealing = false;
|
||||
|
||||
Pdeletewindow = 0;
|
||||
Ptakefocus = 0;
|
||||
|
|
10
client.h
10
client.h
|
@ -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 ); }
|
||||
};
|
||||
|
@ -823,6 +826,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
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -734,6 +734,7 @@ void Workspace::slotReconfigure()
|
|||
tab_box->reconfigure();
|
||||
popupinfo->reconfigure();
|
||||
readShortcuts();
|
||||
forEachClient( CheckIgnoreFocusStealingProcedure());
|
||||
|
||||
if( mgr->reset( changed ))
|
||||
{ // decorations need to be recreated
|
||||
|
|
Loading…
Reference in a new issue