Beispiel #1
0
Client *FocusChain::nextForDesktop(Client *reference, uint desktop) const
{
    DesktopChains::const_iterator it = m_desktopFocusChains.find(desktop);
    if (it == m_desktopFocusChains.end()) {
        return NULL;
    }
    const QList<Client*> &chain = it.value();
    for (int i = chain.size() - 1; i >= 0; --i) {
        Client* client = chain.at(i);
        if (isUsableFocusCandidate(client, reference)) {
            return client;
        }
    }
    return NULL;
}
Beispiel #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 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;

}