From 854e9cc05a1d2abcf2f34b7483d4f06ba8e69650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Wed, 24 Mar 2004 19:05:49 +0000 Subject: [PATCH] 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 --- activation.cpp | 23 +++++++++++++++++------ client.cpp | 1 + client.h | 10 ++++++++++ manage.cpp | 1 + options.cpp | 8 ++++++++ options.h | 8 ++++++-- workspace.cpp | 1 + 7 files changed, 44 insertions(+), 8 deletions(-) diff --git a/activation.cpp b/activation.cpp index bb829c321a..067ed9ee7f 100644 --- a/activation.cpp +++ b/activation.cpp @@ -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; } diff --git a/client.cpp b/client.cpp index 57dfd0bb67..ecc73c5b8a 100644 --- a/client.cpp +++ b/client.cpp @@ -124,6 +124,7 @@ Client::Client( Workspace *ws ) user_noborder = false; not_obscured = false; urgency = false; + ignore_focus_stealing = false; Pdeletewindow = 0; Ptakefocus = 0; diff --git a/client.h b/client.h index d53f82d67c..cab6fe9072 100644 --- a/client.h +++ b/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 { diff --git a/manage.cpp b/manage.cpp index 5220f8139a..a978932ce7 100644 --- a/manage.cpp +++ b/manage.cpp @@ -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(); diff --git a/options.cpp b/options.cpp index e87124d83b..129daef6a6 100644 --- a/options.cpp +++ b/options.cpp @@ -10,6 +10,7 @@ License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #include "options.h" + #include #include #include @@ -18,6 +19,8 @@ License. See the file "COPYING" for the exact licensing terms. #include #include +#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 diff --git a/options.h b/options.h index 5cd88a3f61..4201128d65 100644 --- a/options.h +++ b/options.h @@ -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; diff --git a/workspace.cpp b/workspace.cpp index 65221c8b9c..8b72032b76 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -734,6 +734,7 @@ void Workspace::slotReconfigure() tab_box->reconfigure(); popupinfo->reconfigure(); readShortcuts(); + forEachClient( CheckIgnoreFocusStealingProcedure()); if( mgr->reset( changed )) { // decorations need to be recreated