void Application::announceActiveScreenChangedIfNeeded() { if (m_previousActiveScreen != activeScreen()) { m_previousActiveScreen = activeScreen(); Q_EMIT activeScreenChanged(m_previousActiveScreen); } }
// 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; }
void Blackbox::process_event(XEvent *e) { switch (e->type) { case MapRequest: { #ifdef DEBUG fprintf(stderr, "Blackbox::process_event(): MapRequest for 0x%lx\n", e->xmaprequest.window); #endif // DEBUG BlackboxWindow *win = findWindow(e->xmaprequest.window); if (win) { if ((!activeScreen() || activeScreen() == win->screen()) && (win->isTransient() || _resource.focusNewWindows())) win->activate(); } else { BScreen *screen = findScreen(e->xmaprequest.parent); if (! screen) { /* we got a map request for a window who's parent isn't root. this can happen in only one circumstance: a client window unmapped a managed window, and then remapped it somewhere between unmapping the client window and reparenting it to root. regardless of how it happens, we need to find the screen that the window is on */ XWindowAttributes wattrib; if (! XGetWindowAttributes(XDisplay(), e->xmaprequest.window, &wattrib)) { // failed to get the window attributes, perhaps the window has // now been destroyed? break; } screen = findScreen(wattrib.root); assert(screen != 0); // this should never happen } screen->addWindow(e->xmaprequest.window); } break; } case ConfigureRequest: { BlackboxWindow *win = findWindow(e->xconfigurerequest.window); if (win) { // a window wants to resize win->configureRequestEvent(&e->xconfigurerequest); break; } Slit *slit = dynamic_cast<Slit *>(findEventHandler(e->xconfigurerequest.parent)); if (slit) { // something in the slit wants to resize slit->configureRequestEvent(&e->xconfigurerequest); break; } /* handle configure requests for windows that have no EventHandlers by simply configuring them as requested. note: the event->window parameter points to the window being configured, and event->parent points to the window that received the event (in this case, the root window, since SubstructureRedirect has been selected). */ XWindowChanges xwc; xwc.x = e->xconfigurerequest.x; xwc.y = e->xconfigurerequest.y; xwc.width = e->xconfigurerequest.width; xwc.height = e->xconfigurerequest.height; xwc.border_width = e->xconfigurerequest.border_width; xwc.sibling = e->xconfigurerequest.above; xwc.stack_mode = e->xconfigurerequest.detail; XConfigureWindow(XDisplay(), e->xconfigurerequest.window, e->xconfigurerequest.value_mask, &xwc); break; } case FocusIn: { #ifdef FOCUS_DEBUG printf("FocusIn : window %8lx mode %s detail %s\n", e->xfocus.window, Mode[e->xfocus.mode], Detail[e->xfocus.detail]); #endif if (e->xfocus.mode == NotifyGrab || (e->xfocus.detail != NotifyNonlinearVirtual && e->xfocus.detail != NotifyVirtual)) { /* don't process FocusIns when: 1. they are the result of a grab 2. the new focus window isn't an ancestor or inferior of the old focus window (NotifyNonlinearVirtual and NotifyVirtual) */ break; } BlackboxWindow *win = findWindow(e->xfocus.window); if (!win || win->isFocused()) break; #ifdef FOCUS_DEBUG printf(" win %p got focus\n", win); #endif win->setFocused(true); setFocusedWindow(win); /* set the event window to None. when the FocusOut event handler calls this function recursively, it uses this as an indication that focus has moved to a known window. */ e->xfocus.window = None; break; } case FocusOut: { #ifdef FOCUS_DEBUG printf("FocusOut: window %8lx mode %s detail %s\n", e->xfocus.window, Mode[e->xfocus.mode], Detail[e->xfocus.detail]); #endif if (e->xfocus.mode == NotifyGrab || (e->xfocus.detail != NotifyNonlinearVirtual && e->xfocus.detail != NotifyVirtual)) { /* don't process FocusOuts when: 1. they are the result of a grab 2. the new focus window isn't an ancestor or inferior of the old focus window (NotifyNonlinearVirtual and NotifyNonlinearVirtual) */ break; } BlackboxWindow *win = findWindow(e->xfocus.window); if (!win || !win->isFocused()) break; bool lost_focus = true; // did the window really lose focus? bool no_focus = true; // did another window get focus? XSync(XDisplay(), False); XEvent event; if (XCheckIfEvent(XDisplay(), &event, scanForFocusIn, NULL)) { process_event(&event); if (event.xfocus.window == None) no_focus = false; } else { XWindowAttributes attr; Window w; int unused; XGetInputFocus(XDisplay(), &w, &unused); if (w != None && XGetWindowAttributes(XDisplay(), w, &attr) && attr.override_redirect) { #ifdef FOCUS_DEBUG printf(" focused moved to an override_redirect window\n"); #endif lost_focus = (e->xfocus.mode == NotifyNormal); } } if (lost_focus) { #ifdef FOCUS_DEBUG printf(" win %p lost focus\n", win); #endif win->setFocused(false); if (no_focus) { #ifdef FOCUS_DEBUG printf(" no window has focus\n"); #endif setFocusedWindow(0); } } break; } default: // Send the event through the default EventHandlers. bt::Application::process_event(e); break; } // switch }