kdeui Library API Documentation

kwindowlistmenu.cpp

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 "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> // schroder
00032 #include <kwinmodule.h> // schroder
00033 #endif
00034 
00035 #include <klocale.h>
00036 #include <kstringhandler.h>
00037 
00038 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00039 //#ifndef Q_WS_QWS //FIXME
00040 #include <netwm.h> // schroder
00041 #endif
00042 #include <kapplication.h>
00043 #include <kstyle.h>
00044 #include <dcopclient.h>
00045 #include <qtimer.h>
00046 
00047 #undef Bool
00048 #include "kwindowlistmenu.h"
00049 #include "kwindowlistmenu.moc"
00050 
00051 // helper class
00052 namespace
00053 {
00054 class NameSortedInfoList : public QPtrList<KWin::WindowInfo>
00055 {
00056 public:
00057     NameSortedInfoList() { setAutoDelete(true); };
00058     ~NameSortedInfoList() {};
00059 
00060 private:
00061     int compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 );
00062 };
00063 
00064 int NameSortedInfoList::compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 )
00065 {
00066 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00067 //#ifndef Q_WS_QWS //FIXME
00068     KWin::WindowInfo *i1 = static_cast<KWin::WindowInfo *>(s1);
00069     KWin::WindowInfo *i2 = static_cast<KWin::WindowInfo *>(s2);
00070     QString title1, title2;
00071     if (i1)
00072         title1 = i1->visibleNameWithState().lower();
00073     if (i2)
00074         title2 = i2->visibleNameWithState().lower();
00075     return title1.compare(title2);
00076 #endif
00077 }
00078 
00079 } // namespace
00080 
00081 KWindowListMenu::KWindowListMenu(QWidget *parent, const char *name)
00082   : KPopupMenu(parent, name)
00083 {
00084 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00085 //#ifndef Q_WS_QWS //FIXME
00086     kwin_module = new KWinModule(this);
00087 #endif
00088 
00089     connect(this, SIGNAL(activated(int)), SLOT(slotExec(int)));
00090     connect(this, SIGNAL(aboutToShow()), SLOT(startActivateCurrentWindow()));
00091 }
00092 
00093 KWindowListMenu::~KWindowListMenu()
00094 {
00095 
00096 }
00097 
00098 static bool standaloneDialog( const KWin::WindowInfo* info, const NameSortedInfoList& list )
00099 {
00100     WId group = info->groupLeader();
00101     if( group == 0 )
00102     {
00103         return info->transientFor() == qt_xrootwin();
00104     }
00105     for( QPtrListIterator< KWin::WindowInfo > it( list );
00106          it.current() != NULL;
00107          ++it )
00108         if( (*it)->groupLeader() == group )
00109             return false;
00110     return true;
00111 }
00112 
00113 void KWindowListMenu::init()
00114 {
00115     int i, d;
00116     i = 0;
00117 
00118 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00119 //#ifndef Q_WS_QWS //FIXME
00120     int nd = kwin_module->numberOfDesktops();
00121     int cd = kwin_module->currentDesktop();
00122     WId active_window = kwin_module->activeWindow();
00123 
00124     clear();
00125     map.clear();
00126 
00127     int unclutter = insertItem( i18n("Unclutter Windows"),
00128                                 this, SLOT( slotUnclutterWindows() ) );
00129     int cascade = insertItem( i18n("Cascade Windows"),
00130                               this, SLOT( slotCascadeWindows() ) );
00131 
00132     // if we only have one desktop we won't be showing titles, so put a separator in
00133     if (nd == 1)
00134     {
00135         insertSeparator();
00136     }
00137 
00138 
00139     QValueList<KWin::WindowInfo> windows;
00140     for (QValueList<WId>::ConstIterator it = kwin_module->windows().begin();
00141          it != kwin_module->windows().end(); ++it) {
00142          windows.append( KWin::windowInfo( *it, NET::WMDesktop ));
00143     }
00144     bool show_all_desktops_group = ( nd > 1 );
00145     for (d = 1; d <= nd + (show_all_desktops_group ? 1 : 0); d++) {
00146         bool on_all_desktops = ( d > nd );
00147     int items = 0;
00148 
00149     if (!active_window && d == cd)
00150         setItemChecked(1000 + d, true);
00151 
00152         NameSortedInfoList list;
00153         list.setAutoDelete(true);
00154 
00155     for (QValueList<KWin::WindowInfo>::ConstIterator it = windows.begin();
00156              it != windows.end(); ++it) {
00157         if (((*it).desktop() == d) || (on_all_desktops && (*it).onAllDesktops())
00158                 || (!show_all_desktops_group && (*it).onAllDesktops())) {
00159             list.inSort(new KWin::WindowInfo( (*it).win(),
00160                     NET::WMVisibleName | NET::WMState | NET::XAWMState | NET::WMWindowType,
00161                     NET::WM2GroupLeader | NET::WM2TransientFor ));
00162             }
00163         }
00164 
00165         for (KWin::WindowInfo* info = list.first(); info!=0; info = list.next(), i++)
00166         {
00167             QString itemText = KStringHandler::cEmSqueeze(info->visibleNameWithState(), fontMetrics(), 40);
00168             NET::WindowType windowType = info->windowType( NET::NormalMask | NET::DesktopMask
00169                 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00170                 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00171             if ( (windowType == NET::Normal || windowType == NET::Unknown
00172                     || (windowType == NET::Dialog && standaloneDialog( info, list )))
00173                 && !(info->state() & NET::SkipTaskbar) ) {
00174                 QPixmap pm = KWin::icon(info->win(), 16, 16, true );
00175                 items++;
00176 
00177                 // ok, we have items on this desktop, let's show the title
00178                 if ( items == 1 && nd > 1 )
00179                 {
00180                     if( !on_all_desktops )
00181                         insertTitle(kwin_module->desktopName( d ), 1000 + d);
00182                     else
00183                         insertTitle(i18n("On All Desktops"), 2000 );
00184                 }
00185 
00186                 // Avoid creating unwanted accelerators.
00187                 itemText.replace("&", "&&");
00188                 insertItem( pm, itemText, i);
00189                 map.insert(i, info->win());
00190                 if (info->win() == active_window)
00191                     setItemChecked(i, true);
00192             }
00193         }
00194 
00195         if (d == cd)
00196         {
00197             setItemEnabled(unclutter, items > 0);
00198             setItemEnabled(cascade, items > 0);
00199         }
00200     }
00201 
00202     // no windows?
00203     if (i == 0)
00204     {
00205         if (nd > 1)
00206         {
00207             // because we don't have any titles, nor a separator
00208             insertSeparator();
00209         }
00210 
00211         setItemEnabled(insertItem(i18n("No windows")), false);
00212     }
00213 #endif
00214 
00215     adjustSize();
00216 }
00217 
00218 void KWindowListMenu::slotExec(int id)
00219 {
00220 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00221 //#ifndef Q_WS_QWS //FIXME
00222     if (id == 2000)
00223         ; // do nothing
00224     else if (id > 1000)
00225         KWin::setCurrentDesktop(id - 1000);
00226     else if ( id >= 0 )
00227     KWin::forceActiveWindow(map[id]);
00228 #endif
00229 }
00230 
00231 // This popup is much more useful from keyboard if it has the active
00232 // window active by default - however, QPopupMenu tries hard to resist.
00233 // QPopupMenu::popup() resets the active item, and after being shown,
00234 // the cursor is outside of the popup, causing leave notify, which cases
00235 // mouse move event, which causes reseting the active item again :(
00236 void KWindowListMenu::startActivateCurrentWindow()
00237 {
00238     QTimer::singleShot( 0, this, SLOT( activateCurrentWindow()));
00239 }
00240 
00241 void KWindowListMenu::activateCurrentWindow()
00242 {
00243     for( unsigned int i = 0;
00244          i < count();
00245          ++i )
00246         if( isItemChecked( idAt( i )))
00247             {
00248             setActiveItem( i );
00249             break;
00250             }
00251 }
00252 
00253 void KWindowListMenu::slotUnclutterWindows()
00254 {
00255     kapp->dcopClient()->send("kwin", "KWinInterface", "unclutterDesktop()", "");
00256 }
00257 
00258 void KWindowListMenu::slotCascadeWindows()
00259 {
00260     kapp->dcopClient()->send("kwin", "KWinInterface", "cascadeDesktop()", "");
00261 }
00262 
00263 void KWindowListMenu::virtual_hook( int id, void* data )
00264 { KPopupMenu::virtual_hook( id, data ); }
00265 
00266 #endif
00267 
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Feb 4 12:34:21 2004 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2003