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(); }
// 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; }
// 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; }
// 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; }