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