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