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; }
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; }
// 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; }
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; }
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; }
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 }
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 }
void KWM::activate(Window w){ if (desktop(w) != currentDesktop()) switchToDesktop(desktop(w)); if (isIconified(w)) setIconify(w, FALSE); raise(w); activateInternal(w); }
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 }
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); }
// 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; }
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; }