• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkworkspace

kwindowlistmenu.cpp

Go to the documentation of this file.
00001 /*****************************************************************
00002 
00003 Copyright (c) 2000 Matthias Elter <elter@kde.org>
00004                    Matthias Ettrich <ettrich@kde.org>
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a copy
00007 of this software and associated documentation files (the "Software"), to deal
00008 in the Software without restriction, including without limitation the rights
00009 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, subject to the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00019 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00020 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 
00023 ******************************************************************/
00024 
00025 #include "kwindowlistmenu.h"
00026 
00027 #include <QtCore/QBool>
00028 
00029 #include <QtGui/QApplication>
00030 #include <QtGui/QDesktopWidget>
00031 #include <QtGui/QPainter>
00032 #include <QtGui/QX11Info>
00033 
00034 #include <QtDBus/QtDBus>
00035 #include <klocale.h>
00036 #include <kstringhandler.h>
00037 #include <kstyle.h>
00038 #include <kwindowsystem.h>
00039 #include <netwm.h>
00040 
00041 #undef Bool
00042 #include "kwindowlistmenu.moc"
00043 #include "kwin_interface.h"
00044 
00045 static bool compareKWinWindowInfo( KWindowInfo* firstInfo, KWindowInfo* secondInfo )
00046 {
00047   QString firstTitle, secondTitle;
00048 
00049   if ( firstInfo )
00050     firstTitle = firstInfo->visibleNameWithState().toLower();
00051 
00052   if ( secondInfo )
00053     secondTitle = secondInfo->visibleNameWithState().toLower();
00054 
00055   return firstTitle.compare( secondTitle ) >= 0;
00056 }
00057 
00058 class KWindowListMenu::Private
00059 {
00060 };
00061 
00062 KWindowListMenu::KWindowListMenu( QWidget *parent )
00063   : KMenu( parent ), d( new Private )
00064 {
00065 }
00066 
00067 KWindowListMenu::~KWindowListMenu()
00068 {
00069   delete d;
00070 }
00071 
00072 static bool standaloneDialog( const KWindowInfo* info, const QList<KWindowInfo*>& list )
00073 {
00074   WId group = info->groupLeader();
00075 
00076   if ( group == 0 )
00077     return info->transientFor() == QX11Info::appRootWindow();
00078 
00079   foreach ( KWindowInfo* info, list )
00080     if ( info->groupLeader() == group )
00081       return false;
00082 
00083   return true;
00084 }
00085 
00086 void KWindowListMenu::init()
00087 {
00088   int numberOfDesktops = KWindowSystem::numberOfDesktops();
00089   int currentDesktop = KWindowSystem::currentDesktop();
00090   WId activeWindow = KWindowSystem::activeWindow();
00091 
00092   // Make sure the popup is not too wide, otherwise clicking in the middle of kdesktop
00093   // wouldn't leave any place for the popup, and release would activate some menu entry.
00094   int maxwidth = qApp->desktop()->screenGeometry( this ).width() / 2 - 100;
00095 
00096   clear();
00097 
00098   QAction* unclutter = addAction( i18n("Unclutter Windows"),
00099                               this, SLOT( slotUnclutterWindows() ) );
00100   QAction* cascade = addAction( i18n("Cascade Windows"),
00101                             this, SLOT( slotCascadeWindows() ) );
00102 
00103   // if we only have one desktop we won't be showing titles, so put a separator in
00104   if ( numberOfDesktops == 1 )
00105     addSeparator();
00106 
00107   QList<KWindowInfo> windows;
00108   foreach ( WId id, KWindowSystem::windows() )
00109     windows.append( KWindowSystem::windowInfo( id, NET::WMDesktop ) );
00110 
00111   bool showAllDesktopsGroup = ( numberOfDesktops > 1 );
00112 
00113   int i = 0;
00114   for ( int j = 1; j <= numberOfDesktops + (showAllDesktopsGroup ? 1 : 0); j++ ) {
00115     bool onAllDesktops = ( j > numberOfDesktops );
00116     int items = 0;
00117 
00118     // KDE4 porting - huh? didn't know you could set an item checked before it's created?
00119     //if (!activeWindow && d == cd)
00120         //setItemChecked(1000 + d, true);
00121 
00122     QList<KWindowInfo*> list;
00123 
00124     foreach (const KWindowInfo &wi, windows) {
00125       if ( (wi.desktop() == j) || (onAllDesktops && wi.onAllDesktops())
00126            || (!showAllDesktopsGroup && wi.onAllDesktops()) ) {
00127         list.append( new KWindowInfo( wi.win(),
00128                          NET::WMVisibleName | NET::WMState | NET::XAWMState | NET::WMWindowType,
00129                          NET::WM2GroupLeader | NET::WM2TransientFor ) );
00130       }
00131     }
00132 
00133     qStableSort( list.begin(), list.end(), compareKWinWindowInfo );
00134 
00135     foreach ( KWindowInfo* info, list ) {
00136       ++i;
00137       QString itemText = fontMetrics().elidedText(info->visibleNameWithState(), Qt::ElideMiddle, maxwidth);
00138 
00139       NET::WindowType windowType = info->windowType( NET::NormalMask | NET::DesktopMask
00140           | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00141           | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00142 
00143       if ( (windowType == NET::Normal || windowType == NET::Unknown
00144               || (windowType == NET::Dialog && standaloneDialog( info, list )))
00145               && !(info->state() & NET::SkipTaskbar) ) {
00146 
00147         QPixmap pm = KWindowSystem::icon( info->win(), 16, 16, true );
00148         items++;
00149 
00150         // ok, we have items on this desktop, let's show the title
00151         if ( items == 1 && numberOfDesktops > 1 ) {
00152           if( !onAllDesktops )
00153               addTitle( KWindowSystem::desktopName( j ) );
00154           else
00155               addTitle( i18n( "On All Desktops" ) );
00156         }
00157 
00158         // Avoid creating unwanted accelerators.
00159         itemText.replace( '&', QLatin1String( "&&" ));
00160 
00161         QAction* action = addAction( pm, itemText, this, SLOT( slotForceActiveWindow() ) );
00162         action->setData( (int)info->win() );
00163 
00164         if ( info->win() == activeWindow )
00165           action->setChecked( true );
00166       }
00167     }
00168 
00169     if ( j == currentDesktop ) {
00170       unclutter->setEnabled( items > 0 );
00171       cascade->setEnabled( items > 0 );
00172     }
00173 
00174     qDeleteAll( list );
00175   }
00176 
00177   // no windows?
00178   if ( i == 0 ) {
00179     if ( numberOfDesktops > 1 )
00180       addSeparator(); // because we don't have any titles, nor a separator
00181 
00182     addAction( i18n( "No Windows" ) )->setEnabled( false );
00183   }
00184 }
00185 
00186 void KWindowListMenu::slotForceActiveWindow()
00187 {
00188     QAction* window = qobject_cast<QAction*>(sender());
00189     if (!window || !window->data().canConvert(QVariant::Int))
00190         return;
00191 
00192     KWindowSystem::forceActiveWindow(window->data().toInt());
00193 }
00194 
00195 void KWindowListMenu::slotSetCurrentDesktop()
00196 {
00197     QAction* window = qobject_cast<QAction*>(sender());
00198     if (!window || !window->data().canConvert(QVariant::Int))
00199         return;
00200 
00201     KWindowSystem::setCurrentDesktop(window->data().toInt());
00202 }
00203 
00204 // This popup is much more useful from keyboard if it has the active
00205 // window active by default - however, QPopupMenu tries hard to resist.
00206 // QPopupMenu::popup() resets the active item, so this needs to be
00207 // called after popup().
00208 void KWindowListMenu::selectActiveWindow()
00209 {
00210     foreach (QAction* action, actions())
00211         if (action->isChecked()) {
00212             setActiveAction(action);
00213             break;
00214         }
00215 }
00216 
00217 void KWindowListMenu::slotUnclutterWindows()
00218 {
00219     org::kde::KWin kwin("org.kde.kwin", "/KWin", QDBusConnection::sessionBus());
00220     kwin.unclutterDesktop();
00221 }
00222 
00223 void KWindowListMenu::slotCascadeWindows()
00224 {
00225     org::kde::KWin kwin("org.kde.kwin", "/KWin", QDBusConnection::sessionBus());
00226     kwin.cascadeDesktop();
00227 }
00228 

libkworkspace

Skip menu "libkworkspace"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal