libkworkspace
kwindowlistmenu.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00093
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
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
00119
00120
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
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
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
00178 if ( i == 0 ) {
00179 if ( numberOfDesktops > 1 )
00180 addSeparator();
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
00205
00206
00207
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