Example #1
0
void Workspace::takeActivity( Client* c, int flags, bool handled )
    {
     // the 'if( c == active_client ) return;' optimization must not be done here
    if (!focusChangeEnabled() && ( c != active_client) )
        flags &= ~ActivityFocus;

    if ( !c )
        {
        focusToNull();
        return;
        }

    if( flags & ActivityFocus )
        {
        Client* modal = c->findModal();
        if( modal != NULL && modal != c )	
            {
            next_active_client = modal;
            if( !modal->isOnDesktop( c->desktop()))
                {
                modal->setDesktop( c->desktop());
                if( modal->desktop() != c->desktop()) // forced desktop
                    activateClient( modal );
                }
            // if the click was inside the window (i.e. handled is set),
            // but it has a modal, there's no need to use handled mode, because
            // the modal doesn't get the click anyway
            // raising of the original window needs to be still done
            if( flags & ActivityRaise )
                raiseClient( c );
            c = modal;
            handled = false;
            }
        cancelDelayFocus();
        }
    if ( !( flags & ActivityFocusForce ) && ( c->isTopMenu() || c->isDock() || c->isSplash()) )
        flags &= ~ActivityFocus; // toplevel menus and dock windows don't take focus if not forced
    if( c->isShade())
        {
        if( c->wantsInput() && ( flags & ActivityFocus ))
            {
            // client cannot accept focus, but at least the window should be active (window menu, et. al. )
            c->setActive( true );
            focusToNull();
            }
	if( c->wantsInput())
	    next_active_client = c;
        flags &= ~ActivityFocus;
        handled = false; // no point, can't get clicks
        }
    if( !c->isShown( true )) // shouldn't happen, call activateClient() if needed
        {
	next_active_client = c;
        kdWarning( 1212 ) << "takeActivity: not shown" << endl;
        return;
        }
    c->takeActivity( flags, handled, Allowed );
    if( !c->isOnScreen( active_screen ))
        active_screen = c->screen();
    }
Example #2
0
void Workspace::handleTakeActivity( Client* c, Time /*timestamp*/, int flags )
    {
    if( pending_take_activity != c ) // pending_take_activity is reset when doing restack or activation
        return;
    if(( flags & ActivityRaise ) != 0 )
        raiseClient( c );
    if(( flags & ActivityFocus ) != 0 && c->isShown( false ))
        c->takeFocus( Allowed );
    pending_take_activity = NULL;
    }
Example #3
0
void Workspace::raiseOrLowerClient( Client *c)
    {
    if (!c) return;
    Client* topmost = NULL;
// TODO    Q_ASSERT( block_stacking_updates == 0 );
    if ( most_recently_raised && stacking_order.contains( most_recently_raised ) &&
         most_recently_raised->isShown( true ) && c->isOnCurrentDesktop())
        topmost = most_recently_raised;
    else
        topmost = topClientOnDesktop( c->isOnAllDesktops() ? currentDesktop() : c->desktop(),
            options->separateScreenFocus ? c->screen() : -1 );

    if( c == topmost)
        lowerClient(c);
    else
        raiseClient(c);
    }
Example #4
0
void Workspace::raiseClient( Client* c, bool nogroup )
    {
    if ( !c )
        return;
    if( c->isTopMenu())
        return;

    c->cancelAutoRaise();

    StackingUpdatesBlocker blocker( this );

    if( !nogroup && c->isTransient())
        {
        ClientList wins = ensureStackingOrder( c->group()->members());
        foreach( Client* c2, wins )
            if( c2 != c )
                raiseClient( c2, true );
        }
Example #5
0
// deactivates 'c' and activates next client
bool Workspace::activateNextClient(Client* c)
{
    // if 'c' is not the active or the to-become active one, do nothing
    if (!(c == active_client || (should_get_focus.count() > 0 && c == should_get_focus.last())))
        return false;

    closeActivePopup();

    if (c != NULL) {
        if (c == active_client)
            setActiveClient(NULL, Allowed);
        should_get_focus.removeAll(c);
    }

    // if blocking focus, move focus to the desktop later if needed
    // in order to avoid flickering
    if (!focusChangeEnabled()) {
        focusToNull();
        return true;
    }

    if (!options->focusPolicyIsReasonable())
        return false;

    Client* get_focus = NULL;

    if (options->isNextFocusPrefersMouse()) {
        get_focus = clientUnderMouse(c ? c->screen() : activeScreen());
        if (get_focus && (get_focus == c || get_focus->isDesktop())) {
            // should rather not happen, but it cannot get the focus. rest of usability is tested above
            get_focus = 0;
        }
    }

    if (!get_focus) { // no suitable window under the mouse -> find sth. else

        // first try to pass the focus to the (former) active clients leader
        if (c  && (get_focus = c->transientFor()) && isUsableFocusCandidate(get_focus, c, options->isSeparateScreenFocus())) {
            raiseClient(get_focus);   // also raise - we don't know where it came from
        } else {
            // nope, ask the focus chain for the next candidate
            get_focus = NULL; // reset from the inline assignment above
            for (int i = focus_chain[ currentDesktop()].size() - 1; i >= 0; --i) {
                Client* ci = focus_chain[ currentDesktop()].at(i);
                if (isUsableFocusCandidate(ci, c, options->isSeparateScreenFocus())) {
                    get_focus = ci;
                    break; // we're done
                }
            }
        }
    }

    if (get_focus == NULL)   // last chance: focus the desktop
        get_focus = findDesktop(true, currentDesktop());

    if (get_focus != NULL)
        requestFocus(get_focus);
    else
        focusToNull();

    return true;

}