Exemplo n.º 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();
    }
Exemplo n.º 2
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( focusChangeEnabled())
        {
        if ( options->focusPolicyIsReasonable())
            { // search the focus_chain for a client to transfer focus to,
              // first try to transfer focus to the first suitable window in the group
            Client* get_focus = NULL;
            const ClientList windows = ( c != NULL ? c->group()->members() : ClientList());
	    for ( int i = focus_chain[ currentDesktop() ].size() - 1;
                  i >= 0;
                  --i )
                {
                Client* ci = focus_chain[ currentDesktop() ].at( i );
                if( c == ci || !ci->isShown( false )
                    || !ci->isOnCurrentDesktop())
                    continue;
                if( options->separateScreenFocus )
                    {
                    if( c != NULL && !ci->isOnScreen( c->screen()))
                        continue;
                    if( c == NULL && !ci->isOnScreen( activeScreen()))
                        continue;
                    }
                if( windows.contains( ci ))
                    {
                    get_focus = ci;
                    break;
                    }
                if( get_focus == NULL )
                    get_focus = ci;
                }
            if( get_focus == NULL )
                get_focus = findDesktop( true, currentDesktop());
            if( get_focus != NULL )
                requestFocus( get_focus );
            else
                focusToNull();
            }
            else
                return false;
        }
    else
        // if blocking focus, move focus to the desktop later if needed
        // in order to avoid flickering
        focusToNull();
    return true;
    }
Exemplo n.º 3
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.remove( c );
        }
    if( focusChangeEnabled())
        {
        if ( options->focusPolicyIsReasonable())
            { // search the focus_chain for a client to transfer focus to
              // if 'c' is transient, transfer focus to the first suitable mainwindow
            Client* get_focus = NULL;
            const ClientList mainwindows = ( c != NULL ? c->mainClients() : ClientList());
            for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
                 it != focus_chain[currentDesktop()].end();
                 --it )
                {
                if( !(*it)->isShown( false ) || !(*it)->isOnCurrentDesktop())
                    continue;
                if( options->separateScreenFocus )
                    {
                    if( c != NULL && !(*it)->isOnScreen( c->screen()))
                        continue;
                    if( c == NULL && !(*it)->isOnScreen( activeScreen()))
                        continue;
                    }
                if( mainwindows.contains( *it ))
                    {
                    get_focus = *it;
                    break;
                    }
                if( get_focus == NULL )
                    get_focus = *it;
                }
            if( get_focus == NULL )
                get_focus = findDesktop( true, currentDesktop());
            if( get_focus != NULL )
                {
                requestFocus( get_focus );
                }
            else
                focusToNull();
            }
            else
                return false;
        }
    else
        // if blocking focus, move focus to the desktop later if needed
        // in order to avoid flickering
        focusToNull();
    return true;
    }
Exemplo n.º 4
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;

}