• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

kwindowlistmenu.cpp

Go to the documentation of this file.
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 static QCString kwinName() {
00049     QCString appname;
00050     int screen_number = DefaultScreen(qt_xdisplay());
00051     if (screen_number == 0)
00052         appname = "kwin";
00053     else
00054         appname.sprintf("kwin-screen-%d", screen_number);
00055     return appname;
00056 }
00057 
00058 // helper class
00059 namespace
00060 {
00061 class NameSortedInfoList : public QPtrList<KWin::WindowInfo>
00062 {
00063 public:
00064     NameSortedInfoList() { setAutoDelete(true); }
00065     ~NameSortedInfoList() {}
00066 
00067 private:
00068     int compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 );
00069 };
00070 
00071 int NameSortedInfoList::compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 )
00072 {
00073     KWin::WindowInfo *i1 = static_cast<KWin::WindowInfo *>(s1);
00074     KWin::WindowInfo *i2 = static_cast<KWin::WindowInfo *>(s2);
00075     QString title1, title2;
00076     if (i1)
00077         title1 = i1->visibleNameWithState().lower();
00078     if (i2)
00079         title2 = i2->visibleNameWithState().lower();
00080     return title1.compare(title2);
00081 }
00082 
00083 } // namespace
00084 
00085 KWindowListMenu::KWindowListMenu(QWidget *parent, const char *name)
00086   : KPopupMenu(parent, name)
00087 {
00088     kwin_module = new KWinModule(this);
00089 
00090     connect(this, SIGNAL(activated(int)), SLOT(slotExec(int)));
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     int nd = kwin_module->numberOfDesktops();
00119     int cd = kwin_module->currentDesktop();
00120     WId active_window = kwin_module->activeWindow();
00121 
00122     // Make sure the popup is not too wide, otherwise clicking in the middle of kdesktop
00123     // wouldn't leave any place for the popup, and release would activate some menu entry.    
00124     int maxwidth = kapp->desktop()->screenGeometry( this ).width() / 2 - 100;
00125 
00126     clear();
00127     map.clear();
00128 
00129     int unclutter = insertItem( i18n("Unclutter Windows"),
00130                                 this, SLOT( slotUnclutterWindows() ) );
00131     int cascade = insertItem( i18n("Cascade Windows"),
00132                               this, SLOT( slotCascadeWindows() ) );
00133 
00134     // if we only have one desktop we won't be showing titles, so put a separator in
00135     if (nd == 1)
00136     {
00137         insertSeparator();
00138     }
00139 
00140 
00141     QValueList<KWin::WindowInfo> windows;
00142     for (QValueList<WId>::ConstIterator it = kwin_module->windows().begin();
00143          it != kwin_module->windows().end(); ++it) {
00144          windows.append( KWin::windowInfo( *it, NET::WMDesktop ));
00145     }
00146     bool show_all_desktops_group = ( nd > 1 );
00147     for (d = 1; d <= nd + (show_all_desktops_group ? 1 : 0); d++) {
00148         bool on_all_desktops = ( d > nd );
00149     int items = 0;
00150 
00151     if (!active_window && d == cd)
00152         setItemChecked(1000 + d, true);
00153 
00154         NameSortedInfoList list;
00155         list.setAutoDelete(true);
00156 
00157     for (QValueList<KWin::WindowInfo>::ConstIterator it = windows.begin();
00158              it != windows.end(); ++it) {
00159         if (((*it).desktop() == d) || (on_all_desktops && (*it).onAllDesktops())
00160                 || (!show_all_desktops_group && (*it).onAllDesktops())) {
00161             list.inSort(new KWin::WindowInfo( (*it).win(),
00162                     NET::WMVisibleName | NET::WMState | NET::XAWMState | NET::WMWindowType,
00163                     NET::WM2GroupLeader | NET::WM2TransientFor ));
00164             }
00165         }
00166 
00167         for (KWin::WindowInfo* info = list.first(); info; info = list.next(), ++i)
00168         {
00169             QString itemText = KStringHandler::cPixelSqueeze(info->visibleNameWithState(), fontMetrics(), maxwidth);
00170             NET::WindowType windowType = info->windowType( NET::NormalMask | NET::DesktopMask
00171                 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00172                 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00173             if ( (windowType == NET::Normal || windowType == NET::Unknown
00174                     || (windowType == NET::Dialog && standaloneDialog( info, list )))
00175                 && !(info->state() & NET::SkipTaskbar) ) {
00176                 QPixmap pm = KWin::icon(info->win(), 16, 16, true );
00177                 items++;
00178 
00179                 // ok, we have items on this desktop, let's show the title
00180                 if ( items == 1 && nd > 1 )
00181                 {
00182                     if( !on_all_desktops )
00183                         insertTitle(kwin_module->desktopName( d ), 1000 + d);
00184                     else
00185                         insertTitle(i18n("On All Desktops"), 2000 );
00186                 }
00187 
00188                 // Avoid creating unwanted accelerators.
00189                 itemText.replace('&', QString::fromLatin1("&&"));
00190                 insertItem( pm, itemText, i);
00191                 map.insert(i, info->win());
00192                 if (info->win() == active_window)
00193                     setItemChecked(i, true);
00194             }
00195         }
00196 
00197         if (d == cd)
00198         {
00199             setItemEnabled(unclutter, items > 0);
00200             setItemEnabled(cascade, items > 0);
00201         }
00202     }
00203 
00204     // no windows?
00205     if (i == 0)
00206     {
00207         if (nd > 1)
00208         {
00209             // because we don't have any titles, nor a separator
00210             insertSeparator();
00211         }
00212 
00213         setItemEnabled(insertItem(i18n("No Windows")), false);
00214     }
00215 }
00216 
00217 void KWindowListMenu::slotExec(int id)
00218 {
00219     if (id == 2000)
00220         ; // do nothing
00221     else if (id > 1000)
00222         KWin::setCurrentDesktop(id - 1000);
00223     else if ( id >= 0 )
00224     KWin::forceActiveWindow(map[id]);
00225 }
00226 
00227 // This popup is much more useful from keyboard if it has the active
00228 // window active by default - however, QPopupMenu tries hard to resist.
00229 // QPopupMenu::popup() resets the active item, so this needs to be
00230 // called after popup().
00231 void KWindowListMenu::selectActiveWindow()
00232 {
00233     for( unsigned int i = 0;
00234          i < count();
00235          ++i )
00236         if( isItemChecked( idAt( i )))
00237             {
00238             setActiveItem( i );
00239             break;
00240             }
00241 }
00242 
00243 void KWindowListMenu::slotUnclutterWindows()
00244 {
00245     kapp->dcopClient()->send(kwinName(), "KWinInterface", "unclutterDesktop()", "");
00246 }
00247 
00248 void KWindowListMenu::slotCascadeWindows()
00249 {
00250     kapp->dcopClient()->send(kwinName(), "KWinInterface", "cascadeDesktop()", "");
00251 }
00252 
00253 void KWindowListMenu::virtual_hook( int id, void* data )
00254 { KPopupMenu::virtual_hook( id, data ); }
00255 
00256 #endif // Q_WS_X11
00257 

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal