| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 <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 // helper class
    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 } // namespace
    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     // Make sure the popup is not too wide, otherwise clicking in the middle of kdesktop
    00113     // wouldn't leave any place for the popup, and release would activate some menu entry.
    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     // if we only have one desktop we won't be showing titles, so put a separator in
    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                 // ok, we have items on this desktop, let's show the title
    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                 // Avoid creating unwanted accelerators.
    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     // no windows?
    00195     if (i == 0)
    00196     {
    00197         if (nd > 1)
    00198         {
    00199             // because we don't have any titles, nor a separator
    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         ; // do nothing
    00211     else if (id > 1000)
    00212         KWin::setCurrentDesktop(id - 1000);
    00213     else if ( id >= 0 )
    00214     KWin::forceActiveWindow(map[id]);
    00215 }
    00216
    00217 // This popup is much more useful from keyboard if it has the active
    00218 // window active by default - however, QPopupMenu tries hard to resist.
    00219 // QPopupMenu::popup() resets the active item, so this needs to be
    00220 // called after popup().
    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

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:24 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003