Пример #1
0
void Workspace::setCurrentScreen(int new_screen)
{
    if (new_screen < 0 || new_screen >= numScreens())
        return;
    if (!options->focusPolicyIsReasonable())
        return;
    closeActivePopup();
    Client* get_focus = NULL;
    for (int i = focus_chain[ currentDesktop()].count() - 1;
            i >= 0;
            --i) {
        Client* ci = focus_chain[ currentDesktop()].at(i);
        if (!ci->isShown(false) || !ci->isOnCurrentDesktop() || !ci->isOnCurrentActivity())
            continue;
        if (!ci->screen() == new_screen)
            continue;
        get_focus = ci;
        break;
    }
    if (get_focus == NULL)
        get_focus = findDesktop(true, currentDesktop());
    if (get_focus != NULL && get_focus != mostRecentlyActivatedClient())
        requestFocus(get_focus);
    active_screen = new_screen;
}
Пример #2
0
void Workspace::setCurrentScreen( int new_screen )
    {
    if (new_screen < 0 || new_screen > numScreens())
        return;
    if ( !options->focusPolicyIsReasonable())
        return;
    closeActivePopup();
    Client* get_focus = NULL;
    for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
         it != focus_chain[currentDesktop()].end();
         --it )
        {
        if( !(*it)->isShown( false ) || !(*it)->isOnCurrentDesktop())
            continue;
        if( !(*it)->screen() == new_screen )
            continue;
        get_focus = *it;
        break;
        }
    if( get_focus == NULL )
        get_focus = findDesktop( true, currentDesktop());
    if( get_focus != NULL && get_focus != mostRecentlyActivatedClient())
        requestFocus( get_focus );
    active_screen = new_screen;
    }
Пример #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.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;
    }
Пример #4
0
bool KWindowSystemPrivate::mapViewport()
{
// compiz claims support even though it doesn't use virtual desktops :(
//    if( isSupported( NET::DesktopViewport ) && !isSupported( NET::NumberOfDesktops ))

// this test is duplicated in KWindowSystem::mapViewport()
    if( isSupported( NET::DesktopViewport ) && numberOfDesktops( true ) <= 1
        && ( desktopGeometry( currentDesktop( true )).width > QApplication::desktop()->width()
            || desktopGeometry( currentDesktop( true )).height > QApplication::desktop()->height()))
        return true;
    return false;
}
Пример #5
0
int KWM::desktop(Window w){
  static Atom a = 0;
  if (!a)
    a = XInternAtom(qt_xdisplay(), "KWM_WIN_DESKTOP", False);
  if (isSticky(w))
      return currentDesktop();
  long result = 1;
  if (!getSimpleProperty(w, a, result) || result <= 0){
    result = currentDesktop();
    moveToDesktop(w, (int) result);
    kwm_error = TRUE; // restore error
  }
  return (int) result;
}
Пример #6
0
void bringToFront(QWidget *widget, bool)
{
	Q_ASSERT(widget);
	QWidget* w = widget->window();

#ifdef Q_WS_X11
	// If we're not on the current desktop, do the hide/show trick
	long dsk, curr_dsk;
	Window win = w->winId();
	if(desktopOfWindow(&win, &dsk) && currentDesktop(&curr_dsk)) {
		if((dsk != curr_dsk) && (dsk != -1)) {  // second condition for sticky windows
			w->hide();
		}
	}

	// FIXME: multi-desktop hacks for Win and Mac required
#endif

	if(w->isMaximized())
		w->showMaximized();
	else
		w->showNormal();

	//if(grabFocus)
	//	w->setActiveWindow();
	w->raise();
	w->activateWindow();

#ifdef Q_WS_WIN
	// TODO: unify with AdvancedWidget::bringToFront()
	ForceForegroundWindow(w->winId());
#endif
}
Пример #7
0
bool KRootPixmap::eventFilter(QObject *, QEvent *event)
{
    // Initialise after the first show or paint event on the managed widget.
    if(!m_bInit && ((event->type() == QEvent::Show) || (event->type() == QEvent::Paint)))
    {
        m_bInit = true;
        m_Desk = currentDesktop();
    }

    if(!m_bActive)
        return false;

    switch(event->type())
    {
        case QEvent::Resize:
        case QEvent::Move:
            m_pTimer->start(100, true);
            break;

        case QEvent::Paint:
            m_pTimer->start(0, true);
            break;

        case QEvent::Reparent:
            d->toplevel->removeEventFilter(this);
            d->toplevel = m_pWidget->topLevelWidget();
            d->toplevel->installEventFilter(this);
            break;

        default:
            break;
    }

    return false; // always continue processing
}
Пример #8
0
void KWM::activate(Window w){
  if (desktop(w) != currentDesktop())
    switchToDesktop(desktop(w));
  if (isIconified(w))
    setIconify(w, FALSE);
  raise(w);
  activateInternal(w);
}
Пример #9
0
void KRootPixmap::repaint(bool force)
{
    QPoint p1 = m_pWidget->mapToGlobal(m_pWidget->rect().topLeft());
    QPoint p2 = m_pWidget->mapToGlobal(m_pWidget->rect().bottomRight());
    if(!force && (m_Rect == QRect(p1, p2)))
        return;

    // Due to northwest bit gravity, we don't need to do anything if the
    // bottom right corner of the widget is moved inward.
    // That said, konsole clears the background when it is resized, so
    // we have to reset the background pixmap.
    if((p1 == m_Rect.topLeft()) && (m_pWidget->width() < m_Rect.width()) && (m_pWidget->height() < m_Rect.height()))
    {
        m_Rect = QRect(p1, p2);
        updateBackground(m_pPixmap);
        return;
    }
    m_Rect = QRect(p1, p2);
#ifdef Q_WS_X11
    m_Desk = KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop();
    if(m_Desk == NET::OnAllDesktops)
        m_Desk = currentDesktop();

    // KSharedPixmap will correctly generate a tile for us.
    m_pPixmap->loadFromShared(pixmapName(m_Desk), m_Rect);
#else
    m_Desk = currentDesktop();
    // !x11 note: tile is not generated!
    // TODO: pixmapName() is a nonsense now!
    m_pPixmap->load(pixmapName(m_Desk));
    if(!m_pPixmap->isNull())
    {
        m_pPixmap->resize(m_Rect.size());
        slotDone(true);
    }
#endif
}
Пример #10
0
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);
    }
Пример #11
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;
    }
Пример #12
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;

}
Пример #13
0
bool KWindowSystemPrivate::x11Event( XEvent * ev )
{
    KWindowSystem* s_q = KWindowSystem::self();

#ifdef HAVE_XFIXES
    if ( ev->type == xfixesEventBase + XFixesSelectionNotify && ev->xany.window == winId() ) {
        XFixesSelectionNotifyEvent *event = reinterpret_cast<XFixesSelectionNotifyEvent*>(ev);
        bool haveOwner = event->owner != None;
        if (compositingEnabled != haveOwner) {
            compositingEnabled = haveOwner;
            emit s_q->compositingChanged( compositingEnabled );
        }
        return true;
    }
#endif

    if ( ev->xany.window == QX11Info::appRootWindow() ) {
        int old_current_desktop = currentDesktop();
        WId old_active_window = activeWindow();
        int old_number_of_desktops = numberOfDesktops();
        bool old_showing_desktop = showingDesktop();
        unsigned long m[ 5 ];
	NETRootInfo::event( ev, m, 5 );

	if (( m[ PROTOCOLS ] & CurrentDesktop ) && currentDesktop() != old_current_desktop )
	    emit s_q->currentDesktopChanged( currentDesktop() );
	if (( m[ PROTOCOLS ] & DesktopViewport ) && mapViewport() && currentDesktop() != old_current_desktop )
	    emit s_q->currentDesktopChanged( currentDesktop() );
	if (( m[ PROTOCOLS ] & ActiveWindow ) && activeWindow() != old_active_window )
	    emit s_q->activeWindowChanged( activeWindow() );
	if ( m[ PROTOCOLS ] & DesktopNames )
	    emit s_q->desktopNamesChanged();
	if (( m[ PROTOCOLS ] & NumberOfDesktops ) && numberOfDesktops() != old_number_of_desktops )
	    emit s_q->numberOfDesktopsChanged( numberOfDesktops() );
	if (( m[ PROTOCOLS ] & DesktopGeometry ) && mapViewport() && numberOfDesktops() != old_number_of_desktops )
	    emit s_q->numberOfDesktopsChanged( numberOfDesktops() );
	if ( m[ PROTOCOLS ] & WorkArea )
	    emit s_q->workAreaChanged();
	if ( m[ PROTOCOLS ] & ClientListStacking ) {
	    updateStackingOrder();
	    emit s_q->stackingOrderChanged();
	}
        if(( m[ PROTOCOLS2 ] & WM2ShowingDesktop ) && showingDesktop() != old_showing_desktop ) {
	    emit s_q->showingDesktopChanged( showingDesktop());
        }
    } else  if ( windows.contains( ev->xany.window ) ){
	NETWinInfo ni( QX11Info::display(), ev->xany.window, QX11Info::appRootWindow(), 0 );
        unsigned long dirty[ 2 ];
	ni.event( ev, dirty, 2 );
	if ( ev->type ==PropertyNotify ) {
            if( ev->xproperty.atom == XA_WM_HINTS )
	        dirty[ NETWinInfo::PROTOCOLS ] |= NET::WMIcon; // support for old icons
            else if( ev->xproperty.atom == XA_WM_NAME )
                dirty[ NETWinInfo::PROTOCOLS ] |= NET::WMName; // support for old name
            else if( ev->xproperty.atom == XA_WM_ICON_NAME )
                dirty[ NETWinInfo::PROTOCOLS ] |= NET::WMIconName; // support for old iconic name
        }
        if( mapViewport() && ( dirty[ NETWinInfo::PROTOCOLS ] & (NET::WMState | NET::WMGeometry) )) {
	    /* geometry change -> possible viewport change
	     * state change -> possible NET::Sticky change
	     */
            dirty[ NETWinInfo::PROTOCOLS ] |= NET::WMDesktop;
	}
	if ( (dirty[ NETWinInfo::PROTOCOLS ] & NET::WMStrut) != 0 ) {
            removeStrutWindow( ev->xany.window );
            if ( !possibleStrutWindows.contains( ev->xany.window ) )
        	possibleStrutWindows.append( ev->xany.window );
	}
	if ( dirty[ NETWinInfo::PROTOCOLS ] || dirty[ NETWinInfo::PROTOCOLS2 ] ) {
	    emit s_q->windowChanged( ev->xany.window );
	    emit s_q->windowChanged( ev->xany.window, dirty );
	    emit s_q->windowChanged( ev->xany.window, dirty[ NETWinInfo::PROTOCOLS ] );
	    if ( (dirty[ NETWinInfo::PROTOCOLS ] & NET::WMStrut) != 0 )
		emit s_q->strutChanged();
	}
    }

    return false;
}