示例#1
0
void
Application::announceActiveScreenChangedIfNeeded()
{
    if (m_previousActiveScreen != activeScreen()) {
        m_previousActiveScreen = activeScreen();
        Q_EMIT activeScreenChanged(m_previousActiveScreen);
    }
}
示例#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( 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;
    }
示例#3
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.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;
    }
示例#4
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;

}
示例#5
0
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
}