deactivates 'window' and activates next window
| 431 | |
| 432 | // deactivates 'window' and activates next window |
| 433 | void Workspace::activateNextWindow(Window *window) |
| 434 | { |
| 435 | if (m_activeWindow != window) { |
| 436 | return; |
| 437 | } |
| 438 | |
| 439 | closeActivePopup(); |
| 440 | |
| 441 | Window *focusCandidate = nullptr; |
| 442 | |
| 443 | if (options->focusPolicyIsReasonable()) { |
| 444 | LogicalOutput *output = window ? window->output() : workspace()->activeOutput(); |
| 445 | VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop(output); |
| 446 | |
| 447 | if (!focusCandidate && showingDesktop()) { |
| 448 | focusCandidate = findDesktop(desktop, output); // to not break the state |
| 449 | } |
| 450 | |
| 451 | if (!focusCandidate && options->isNextFocusPrefersMouse()) { |
| 452 | focusCandidate = windowUnderMouse(output); |
| 453 | if (focusCandidate && (focusCandidate == window || focusCandidate->isDesktop())) { |
| 454 | // should rather not happen, but it cannot get the focus. rest of usability is tested above |
| 455 | focusCandidate = nullptr; |
| 456 | } |
| 457 | } |
| 458 | |
| 459 | if (!focusCandidate) { // no suitable window under the mouse -> find sth. else |
| 460 | // first try to pass the focus to the (former) active clients leader |
| 461 | if (window && window->isTransient()) { |
| 462 | auto leaders = window->mainWindows(); |
| 463 | if (leaders.count() == 1 && m_focusChain->isUsableFocusCandidate(leaders.at(0), window)) { |
| 464 | focusCandidate = leaders.at(0); |
| 465 | raiseWindow(focusCandidate); // also raise - we don't know where it came from |
| 466 | } |
| 467 | } |
| 468 | if (!focusCandidate) { |
| 469 | // nope, ask the focus chain for the next candidate |
| 470 | focusCandidate = m_focusChain->nextForDesktop(window, desktop); |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | if (focusCandidate == nullptr) { // last chance: focus the desktop |
| 475 | focusCandidate = findDesktop(desktop, output); |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | if (focusCandidate) { |
| 480 | if (requestFocus(focusCandidate)) { |
| 481 | return; |
| 482 | } |
| 483 | } |
| 484 | |
| 485 | resetFocus(); |
| 486 | } |
| 487 | |
| 488 | void Workspace::switchToOutput(LogicalOutput *output) |
| 489 | { |