kdeui Library API Documentation

ksystemtray.cpp

00001 /* This file is part of the KDE libraries
00002 
00003     Copyright (C) 1999 Matthias Ettrich (ettrich@kde.org)
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018     Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #include "config.h"
00022 #include "kaction.h"
00023 #include "kshortcut.h"
00024 #include "ksystemtray.h"
00025 #include "kpopupmenu.h"
00026 #include "kapplication.h"
00027 #include "klocale.h"
00028 
00029 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00030 #include <kwin.h> 
00031 #include <kwinmodule.h> 
00032 #endif
00033 
00034 #include <kiconloader.h>
00035 #include <kconfig.h>
00036 
00037 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00038 #include <qxembed.h> 
00039 #endif
00040 
00041 #include <qapplication.h>
00042 
00043 class KSystemTrayPrivate
00044 {
00045 public:
00046     KSystemTrayPrivate()
00047     {
00048         actionCollection = 0;
00049     }
00050 
00051     ~KSystemTrayPrivate()
00052     {
00053         delete actionCollection;
00054     }
00055 
00056     KActionCollection* actionCollection;
00057     bool on_all_desktops; // valid only when the parent widget was hidden
00058 };
00059 
00060 KSystemTray::KSystemTray( QWidget* parent, const char* name )
00061     : QLabel( parent, name, WType_TopLevel )
00062 {
00063 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00064     QXEmbed::initialize();
00065 #endif
00066     
00067     d = new KSystemTrayPrivate;
00068     d->actionCollection = new KActionCollection(this);
00069 
00070 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00071 //#ifndef Q_WS_QWS
00072     // FIXME(E): Talk with QWS
00073     KWin::setSystemTrayWindowFor( winId(), parent?parent->topLevelWidget()->winId(): qt_xrootwin() );
00074     setBackgroundMode(X11ParentRelative);
00075     setBackgroundOrigin(WindowOrigin);
00076 #endif
00077     hasQuit = 0;
00078     menu = new KPopupMenu( this );
00079     menu->insertTitle( kapp->miniIcon(), kapp->caption() );
00080     move( -1000, -1000 );
00081     KAction* quitAction = KStdAction::quit(this, SIGNAL(quitSelected()), d->actionCollection);
00082 
00083     if (parentWidget())
00084     {
00085         connect(quitAction, SIGNAL(activated()), parentWidget(), SLOT(close()));
00086         new KAction(i18n("Minimize"), KShortcut(),
00087                     this, SLOT( minimizeRestoreAction() ),
00088                     d->actionCollection, "minimizeRestore");
00089 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00090     KWin::WindowInfo info = KWin::windowInfo( parentWidget()->winId());
00091     d->on_all_desktops = info.onAllDesktops();
00092 #endif
00093     }
00094     else
00095     {
00096         connect(quitAction, SIGNAL(activated()), qApp, SLOT(closeAllWindows()));
00097     d->on_all_desktops = false;
00098     }
00099 }
00100 
00101 KSystemTray::~KSystemTray()
00102 {
00103     delete d;
00104 }
00105 
00106 
00107 void KSystemTray::showEvent( QShowEvent * )
00108 {
00109     if ( !hasQuit ) {
00110     menu->insertSeparator();
00111         KAction* action = d->actionCollection->action("minimizeRestore");
00112 
00113         if (action)
00114         {
00115             action->plug(menu);
00116         }
00117 
00118         action = d->actionCollection->action(KStdAction::name(KStdAction::Quit));
00119 
00120         if (action)
00121         {
00122             action->plug(menu);
00123         }
00124 
00125     hasQuit = 1;
00126     }
00127 }
00128 
00129 // KDE4 remove
00130 void KSystemTray::enterEvent( QEvent* e )
00131 {
00132     QLabel::enterEvent( e );
00133 }
00134 
00135 KPopupMenu* KSystemTray::contextMenu() const
00136 {
00137     return menu;
00138 }
00139 
00140 
00141 void KSystemTray::mousePressEvent( QMouseEvent *e )
00142 {
00143     if ( !rect().contains( e->pos() ) )
00144     return;
00145 
00146     switch ( e->button() ) {
00147     case LeftButton:
00148         toggleActive();
00149     break;
00150     case MidButton:
00151     // fall through
00152     case RightButton:
00153     if ( parentWidget() ) {
00154             KAction* action = d->actionCollection->action("minimizeRestore");
00155         if ( parentWidget()->isVisible() )
00156         action->setText( i18n("&Minimize") );
00157         else
00158         action->setText( i18n("&Restore") );
00159     }
00160     contextMenuAboutToShow( menu );
00161     menu->popup( e->globalPos() );
00162     break;
00163     default:
00164     // nothing
00165     break;
00166     }
00167 }
00168 
00169 void KSystemTray::mouseReleaseEvent( QMouseEvent * )
00170 {
00171 }
00172 
00173 
00174 void KSystemTray::contextMenuAboutToShow( KPopupMenu* )
00175 {
00176 }
00177 
00178 // called from the popup menu - always do what the menu entry says,
00179 // i.e. if the window is shown, no matter if active or not, the menu
00180 // entry is "minimize", otherwise it's "restore"
00181 void KSystemTray::minimizeRestoreAction()
00182 {
00183     if ( parentWidget() ) {
00184         bool restore = !( parentWidget()->isVisible() );
00185     minimizeRestore( restore );
00186     }
00187 }
00188 
00189 void KSystemTray::toggleActive()
00190 {
00191     activateOrHide();
00192 }
00193 
00194 void KSystemTray::setActive()
00195 {
00196     minimizeRestore( true );
00197 }
00198 
00199 void KSystemTray::setInactive()
00200 {
00201     minimizeRestore( false );
00202 }
00203 
00204 // called when left-clicking the tray icon
00205 // if the window is not the active one, show it if needed, and activate it
00206 // (just like taskbar); otherwise hide it
00207 void KSystemTray::activateOrHide()
00208 {
00209     QWidget *pw = parentWidget();
00210 
00211     if ( !pw )
00212     return;
00213 
00214 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00215     KWin::WindowInfo info1 = KWin::windowInfo( pw->winId(), NET::XAWMState | NET::WMState );
00216     // mapped = visible (but possibly obscured)
00217     bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
00218 //    - not mapped -> show, raise, focus
00219 //    - mapped
00220 //        - obscured -> raise, focus
00221 //        - not obscured -> hide
00222     if( !mapped )
00223         minimizeRestore( true );
00224     else
00225     {
00226         KWinModule module;
00227         for( QValueList< WId >::ConstIterator it = module.stackingOrder().fromLast();
00228              it != module.stackingOrder().end() && (*it) != pw->winId();
00229              --it )
00230         {
00231             KWin::WindowInfo info2 = KWin::windowInfo( *it,
00232                 NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
00233             if( info2.mappingState() != NET::Visible )
00234                 continue; // not visible on current desktop -> ignore
00235             if( !info2.geometry().intersects( pw->geometry()))
00236                 continue; // not obscuring the window -> ignore
00237             if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
00238                 continue; // obscured by window kept above -> ignore
00239             NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask
00240                 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00241                 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00242             if( type == NET::Dock || type == NET::TopMenu )
00243                 continue; // obscured by dock or topmenu -> ignore
00244             pw->raise();
00245             KWin::activateWindow( pw->winId());
00246             return;
00247         }
00248         minimizeRestore( false ); // hide
00249     }
00250 #endif
00251 }
00252 
00253 void KSystemTray::minimizeRestore( bool restore )
00254 {
00255     QWidget* pw = parentWidget();
00256     if( !pw )
00257     return;
00258 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00259     KWin::WindowInfo info = KWin::windowInfo( pw->winId(), NET::WMGeometry | NET::WMDesktop );
00260     if ( restore )
00261     {
00262 //#ifndef Q_WS_QWS //FIXME
00263 //#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00264     if( d->on_all_desktops )
00265         KWin::setOnAllDesktops( pw->winId(), true );
00266     else
00267         KWin::setOnDesktop( pw->winId(), KWin::currentDesktop());
00268         pw->move( info.geometry().topLeft() ); // avoid placement policies
00269         pw->show();
00270         pw->raise();
00271     KWin::activateWindow( pw->winId() );
00272     } else {
00273     d->on_all_desktops = info.onAllDesktops();
00274     pw->hide();
00275     }
00276 #endif
00277 }
00278 
00279 KActionCollection* KSystemTray::actionCollection()
00280 {
00281     return d->actionCollection;
00282 }
00283     
00284 QPixmap KSystemTray::loadIcon( const QString &icon, KInstance *instance )
00285 {
00286     KConfig *appCfg = kapp->config();
00287     KConfigGroupSaver configSaver(appCfg, "System Tray");
00288     int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
00289     return instance->iconLoader()->loadIcon( icon, KIcon::Panel, iconWidth );
00290 }
00291 
00292 void KSystemTray::virtual_hook( int, void* )
00293 { /*BASE::virtual_hook( id, data );*/ }
00294 
00295 #include "ksystemtray.moc"
00296 #include "kdockwindow.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Feb 18 15:10:19 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003