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 <qglobal.h>
00026
00027
#ifdef Q_WS_X11
00028
00029
#include "config.h"
00030
#include <qpainter.h>
00031
#include <qvaluelist.h>
00032
00033
#include <kwin.h>
00034
#include <kwinmodule.h>
00035
00036
#include <klocale.h>
00037
#include <kstringhandler.h>
00038
00039
#include <netwm.h>
00040
#include <kapplication.h>
00041
#include <kstyle.h>
00042
#include <dcopclient.h>
00043
00044
#undef Bool
00045
#include "kwindowlistmenu.h"
00046
#include "kwindowlistmenu.moc"
00047
00048
00049
namespace
00050
{
00051
class NameSortedInfoList :
public QPtrList<KWin::WindowInfo>
00052 {
00053
public:
00054 NameSortedInfoList() { setAutoDelete(
true); };
00055 ~NameSortedInfoList() {};
00056
00057
private:
00058
int compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 );
00059 };
00060
00061
int NameSortedInfoList::compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 )
00062 {
00063 KWin::WindowInfo *i1 = static_cast<KWin::WindowInfo *>(s1);
00064 KWin::WindowInfo *i2 = static_cast<KWin::WindowInfo *>(s2);
00065
QString title1, title2;
00066
if (i1)
00067 title1 = i1->visibleNameWithState().lower();
00068
if (i2)
00069 title2 = i2->visibleNameWithState().lower();
00070
return title1.compare(title2);
00071 }
00072
00073 }
00074
00075 KWindowListMenu::KWindowListMenu(
QWidget *parent,
const char *name)
00076 :
KPopupMenu(parent,
name)
00077 {
00078 kwin_module =
new KWinModule(
this);
00079
00080 connect(
this, SIGNAL(activated(
int)), SLOT(slotExec(
int)));
00081 }
00082
00083 KWindowListMenu::~KWindowListMenu()
00084 {
00085
00086 }
00087
00088
static bool standaloneDialog(
const KWin::WindowInfo* info,
const NameSortedInfoList& list )
00089 {
00090 WId group = info->groupLeader();
00091
if( group == 0 )
00092 {
00093
return info->transientFor() == qt_xrootwin();
00094 }
00095
for(
QPtrListIterator< KWin::WindowInfo > it( list );
00096 it.current() != NULL;
00097 ++it )
00098
if( (*it)->groupLeader() == group )
00099
return false;
00100
return true;
00101 }
00102
00103
void KWindowListMenu::init()
00104 {
00105
int i, d;
00106 i = 0;
00107
00108
int nd = kwin_module->numberOfDesktops();
00109
int cd = kwin_module->currentDesktop();
00110 WId active_window = kwin_module->activeWindow();
00111
00112
00113
00114
int maxwidth = kapp->desktop()->screenGeometry(
this ).width() / 2 - 100;
00115
00116
clear();
00117 map.clear();
00118
00119
int unclutter = insertItem( i18n(
"Unclutter Windows"),
00120
this, SLOT( slotUnclutterWindows() ) );
00121
int cascade = insertItem( i18n(
"Cascade Windows"),
00122
this, SLOT( slotCascadeWindows() ) );
00123
00124
00125
if (nd == 1)
00126 {
00127 insertSeparator();
00128 }
00129
00130
00131
QValueList<KWin::WindowInfo> windows;
00132
for (
QValueList<WId>::ConstIterator it = kwin_module->windows().begin();
00133 it != kwin_module->windows().end(); ++it) {
00134 windows.append( KWin::windowInfo( *it, NET::WMDesktop ));
00135 }
00136
bool show_all_desktops_group = ( nd > 1 );
00137
for (d = 1; d <= nd + (show_all_desktops_group ? 1 : 0); d++) {
00138
bool on_all_desktops = ( d > nd );
00139
int items = 0;
00140
00141
if (!active_window && d == cd)
00142 setItemChecked(1000 + d,
true);
00143
00144 NameSortedInfoList list;
00145 list.setAutoDelete(
true);
00146
00147
for (
QValueList<KWin::WindowInfo>::ConstIterator it = windows.begin();
00148 it != windows.end(); ++it) {
00149
if (((*it).desktop() == d) || (on_all_desktops && (*it).onAllDesktops())
00150 || (!show_all_desktops_group && (*it).onAllDesktops())) {
00151 list.inSort(
new KWin::WindowInfo( (*it).win(),
00152 NET::WMVisibleName | NET::WMState | NET::XAWMState | NET::WMWindowType,
00153 NET::WM2GroupLeader | NET::WM2TransientFor ));
00154 }
00155 }
00156
00157
for (KWin::WindowInfo* info = list.first(); info; info = list.next(), ++i)
00158 {
00159
QString itemText =
KStringHandler::cPixelSqueeze(info->visibleNameWithState(), fontMetrics(), maxwidth);
00160
NET::WindowType windowType = info->windowType( NET::NormalMask | NET::DesktopMask
00161 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00162 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00163
if ( (windowType == NET::Normal || windowType == NET::Unknown
00164 || (windowType == NET::Dialog && standaloneDialog( info, list )))
00165 && !(info->state() & NET::SkipTaskbar) ) {
00166
QPixmap pm = KWin::icon(info->win(), 16, 16,
true );
00167 items++;
00168
00169
00170
if ( items == 1 && nd > 1 )
00171 {
00172
if( !on_all_desktops )
00173 insertTitle(kwin_module->desktopName( d ), 1000 + d);
00174
else
00175 insertTitle(i18n(
"On All Desktops"), 2000 );
00176 }
00177
00178
00179 itemText.replace(
'&', QString::fromLatin1(
"&&"));
00180 insertItem( pm, itemText, i);
00181 map.insert(i, info->win());
00182
if (info->win() == active_window)
00183 setItemChecked(i,
true);
00184 }
00185 }
00186
00187
if (d == cd)
00188 {
00189 setItemEnabled(unclutter, items > 0);
00190 setItemEnabled(cascade, items > 0);
00191 }
00192 }
00193
00194
00195
if (i == 0)
00196 {
00197
if (nd > 1)
00198 {
00199
00200 insertSeparator();
00201 }
00202
00203 setItemEnabled(insertItem(i18n(
"No Windows")),
false);
00204 }
00205 }
00206
00207
void KWindowListMenu::slotExec(
int id)
00208 {
00209
if (
id == 2000)
00210 ;
00211
else if (
id > 1000)
00212 KWin::setCurrentDesktop(
id - 1000);
00213
else if (
id >= 0 )
00214 KWin::forceActiveWindow(map[
id]);
00215 }
00216
00217
00218
00219
00220
00221
void KWindowListMenu::selectActiveWindow()
00222 {
00223
for(
unsigned int i = 0;
00224 i < count();
00225 ++i )
00226
if( isItemChecked( idAt( i )))
00227 {
00228 setActiveItem( i );
00229
break;
00230 }
00231 }
00232
00233
void KWindowListMenu::slotUnclutterWindows()
00234 {
00235 kapp->dcopClient()->send(
"kwin",
"KWinInterface",
"unclutterDesktop()",
"");
00236 }
00237
00238
void KWindowListMenu::slotCascadeWindows()
00239 {
00240 kapp->dcopClient()->send(
"kwin",
"KWinInterface",
"cascadeDesktop()",
"");
00241 }
00242
00243
void KWindowListMenu::virtual_hook(
int id,
void* data )
00244 { KPopupMenu::virtual_hook(
id, data ); }
00245
00246
#endif // Q_WS_X11
00247