Beispiel #1
0
// basically the same like allowClientActivation(), this time allowing
// a window to be fully raised upon its own request (XRaiseWindow),
// if refused, it will be raised only on top of windows belonging
// to the same application
bool Workspace::allowFullClientRaising(const Client* c, Time time)
{
    int level = c->rules()->checkFSP(options->focusStealingPreventionLevel());
    if (session_saving && level <= 2) { // <= normal
        return true;
    }
    Client* ac = mostRecentlyActivatedClient();
    if (level == 0)   // none
        return true;
    if (level == 4)   // extreme
        return false;
    if (ac == NULL || ac->isDesktop()) {
        kDebug(1212) << "Raising: No client active, allowing";
        return true; // no active client -> always allow
    }
    // TODO window urgency  -> return true?
    if (Client::belongToSameApplication(c, ac, true)) {
        kDebug(1212) << "Raising: Belongs to active application";
        return true;
    }
    if (level == 3)   // high
        return false;
    Time user_time = ac->userTime();
    kDebug(1212) << "Raising, compared:" << time << ":" << user_time
                 << ":" << (timestampCompare(time, user_time) >= 0) << endl;
    return timestampCompare(time, user_time) >= 0;   // time >= user_time
}
Beispiel #2
0
// focus_in -> the window got FocusIn event
// ignore_desktop - call comes from _NET_ACTIVE_WINDOW message, don't refuse just because of window
//     is on a different desktop
bool Workspace::allowClientActivation(const Client* c, Time time, bool focus_in, bool ignore_desktop)
{
    // options->focusStealingPreventionLevel :
    // 0 - none    - old KWin behaviour, new windows always get focus
    // 1 - low     - focus stealing prevention is applied normally, when unsure, activation is allowed
    // 2 - normal  - focus stealing prevention is applied normally, when unsure, activation is not allowed,
    //              this is the default
    // 3 - high    - new window gets focus only if it belongs to the active application,
    //              or when no window is currently active
    // 4 - extreme - no window gets focus without user intervention
    if (time == -1U)
        time = c->userTime();
    int level = c->rules()->checkFSP(options->focusStealingPreventionLevel());
    if (session_saving && level <= 2) { // <= normal
        return true;
    }
    Client* ac = mostRecentlyActivatedClient();
    if (focus_in) {
        if (should_get_focus.contains(const_cast< Client* >(c)))
            return true; // FocusIn was result of KWin's action
        // Before getting FocusIn, the active Client already
        // got FocusOut, and therefore got deactivated.
        ac = last_active_client;
    }
    if (time == 0)   // explicitly asked not to get focus
        return false;
    if (level == 0)   // none
        return true;
    if (level == 4)   // extreme
        return false;
    if (!ignore_desktop && !c->isOnCurrentDesktop())
        return false; // allow only with level == 0
    if (ac == NULL || ac->isDesktop()) {
        kDebug(1212) << "Activation: No client active, allowing";
        return true; // no active client -> always allow
    }
    // TODO window urgency  -> return true?
    if (Client::belongToSameApplication(c, ac, true)) {
        kDebug(1212) << "Activation: Belongs to active application";
        return true;
    }
    if (level == 3)   // high
        return false;
    if (time == -1U) {  // no time known
        kDebug(1212) << "Activation: No timestamp at all";
        if (level == 1)   // low
            return true;
        // no timestamp at all, don't activate - because there's also creation timestamp
        // done on CreateNotify, this case should happen only in case application
        // maps again already used window, i.e. this won't happen after app startup
        return false;
    }
    // level == 2 // normal
    Time user_time = ac->userTime();
    kDebug(1212) << "Activation, compared:" << c << ":" << time << ":" << user_time
                 << ":" << (timestampCompare(time, user_time) >= 0) << endl;
    return timestampCompare(time, user_time) >= 0;   // time >= user_time
}
Beispiel #3
0
void Group::startupIdChanged()
{
    KStartupInfoId asn_id;
    KStartupInfoData asn_data;
    bool asn_valid = workspace()->checkStartupNotification(leader_wid, asn_id, asn_data);
    if (!asn_valid)
        return;
    if (asn_id.timestamp() != 0 && user_time != -1U
            && timestampCompare(asn_id.timestamp(), user_time) > 0) {
        user_time = asn_id.timestamp();
    } else if (asn_data.timestamp() != -1U && user_time != -1U
              && timestampCompare(asn_data.timestamp(), user_time) > 0) {
        user_time = asn_data.timestamp();
    }
}
Beispiel #4
0
void Group::updateUserTime( Time time )
    { // copy of Client::updateUserTime
    if( time == CurrentTime )
        time = GET_QT_X_TIME();
    if( time != -1U
        && ( user_time == CurrentTime
            || timestampCompare( time, user_time ) > 0 )) // time > user_time
        user_time = time;
    }
Beispiel #5
0
/*!
  Updates the user time (time of last action in the active window).
  This is called inside  kwin for every action with the window
  that qualifies for user interaction (clicking on it, activate it
  externally, etc.).
 */
void Client::updateUserTime( Time time )
    { // copied in Group::updateUserTime
    if( time == CurrentTime )
        time = xTime();
    if( time != -1U
        && ( user_time == CurrentTime
            || timestampCompare( time, user_time ) > 0 )) // time > user_time
        user_time = time;
    group()->updateUserTime( user_time );
    }
Beispiel #6
0
Time Client::userTime() const
    {
    Time time = user_time;
    if( time == 0 ) // doesn't want focus after showing
        return 0;
    assert( group() != NULL );
    if( time == -1U
         || ( group()->userTime() != -1U
                 && timestampCompare( group()->userTime(), time ) > 0 ))
        time = group()->userTime();
    return time;
    }
Beispiel #7
0
/*!
  Updates the user time (time of last action in the active window).
  This is called inside  kwin for every action with the window
  that qualifies for user interaction (clicking on it, activate it
  externally, etc.).
 */
void Client::updateUserTime(Time time)
{
    // copied in Group::updateUserTime
    if (time == CurrentTime)
        time = xTime();
    if (time != -1U
            && (user_time == CurrentTime
                || timestampCompare(time, user_time) > 0)) {    // time > user_time
        user_time = time;
        shade_below = NULL; // do not hover re-shade a window after it got interaction
    }
    group()->updateUserTime(user_time);
}
Beispiel #8
0
Time Client::readUserTimeMapTimestamp( const TDEStartupInfoId* asn_id, const TDEStartupInfoData* asn_data,
    bool session ) const
    {
    Time time = info->userTime();
//    kdDebug( 1212 ) << "User timestamp, initial:" << time << endl;
    // newer ASN timestamp always replaces user timestamp, unless user timestamp is 0
    // helps e.g. with konqy reusing
    if( asn_data != NULL && time != 0 )
        {
        // prefer timestamp from ASN id (timestamp from data is obsolete way)
        if( asn_id->timestamp() != 0
            && ( time == -1U || timestampCompare( asn_id->timestamp(), time ) > 0 ))
            {
            time = asn_id->timestamp();
            }
        else if( asn_data->timestamp() != -1U
            && ( time == -1U || timestampCompare( asn_data->timestamp(), time ) > 0 ))
            {
            time = asn_data->timestamp();
            }
        }
//    kdDebug( 1212 ) << "User timestamp, ASN:" << time << endl;
    if( time == -1U )
        { // The window doesn't have any timestamp.
      // If it's the first window for its application
      // (i.e. there's no other window from the same app),
      // use the _TDE_NET_WM_USER_CREATION_TIME trick.
      // Otherwise, refuse activation of a window
      // from already running application if this application
      // is not the active one (unless focus stealing prevention is turned off).
        Client* act = workspace()->mostRecentlyActivatedClient();
        if( act != NULL && !belongToSameApplication( act, this, true ))
            {
            bool first_window = true;
            if( isTransient())
                {
                if( act->hasTransient( this, true ))
                    ; // is transient for currently active window, even though it's not
                      // the same app (e.g. kcookiejar dialog) -> allow activation
                else if( groupTransient() &&
                    findClientInList( mainClients(), SameApplicationActiveHackPredicate( this )) == NULL )
                    ; // standalone transient
                else
                    first_window = false;
                }
            else
                {
                if( workspace()->findClient( SameApplicationActiveHackPredicate( this )))
                    first_window = false;
                }
            // don't refuse if focus stealing prevention is turned off
            if( !first_window && rules()->checkFSP( options->focusStealingPreventionLevel ) > 0 )
                {
//                kdDebug( 1212 ) << "User timestamp, already exists:" << 0 << endl;
                return 0; // refuse activation
                }
            }
        // Creation time would just mess things up during session startup,
        // as possibly many apps are started up at the same time.
        // If there's no active window yet, no timestamp will be needed,
        // as plain Workspace::allowClientActivation() will return true
        // in such case. And if there's already active window,
        // it's better not to activate the new one.
        // Unless it was the active window at the time
        // of session saving and there was no user interaction yet,
        // this check will be done in manage().
        if( session )
            return -1U;
        if( ignoreFocusStealing() && act != NULL )
            time = act->userTime();
        else
            time = readUserCreationTime();
        }
//    kdDebug( 1212 ) << "User timestamp, final:" << this << ":" << time << endl;
    return time;
    }