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> // schroder
00031 #include <kwinmodule.h> // schroder
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> // schroder
00039 #endif
00040 
00041 #include <qapplication.h>
00042 
00043 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00044 #include <X11/Xlib.h> // schroder
00045 #ifndef KDE_USE_FINAL
00046 const int XFocusOut = FocusOut;
00047 const int XFocusIn = FocusIn;
00048 #endif
00049 #undef FocusOut
00050 #undef FocusIn
00051 #undef KeyPress
00052 #undef KeyRelease
00053 
00054 extern Time qt_x_time;
00055 #endif // Q_WS_X11 && ! K_WS_QTONLY
00056 
00057 class KSystemTrayPrivate
00058 {
00059 public:
00060     KSystemTrayPrivate()
00061     {
00062         actionCollection = 0;
00063     }
00064 
00065     ~KSystemTrayPrivate()
00066     {
00067         delete actionCollection;
00068     }
00069 
00070     KActionCollection* actionCollection;
00071     bool on_all_desktops; // valid only when the parent widget was hidden
00072 };
00073 
00074 KSystemTray::KSystemTray( QWidget* parent, const char* name )
00075     : QLabel( parent, name, WType_TopLevel )
00076 {
00077 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00078     QXEmbed::initialize();
00079 #endif
00080     
00081     d = new KSystemTrayPrivate;
00082     d->actionCollection = new KActionCollection(this);
00083 
00084 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00085 //#ifndef Q_WS_QWS
00086     // FIXME(E): Talk with QWS
00087     KWin::setSystemTrayWindowFor( winId(), parent?parent->topLevelWidget()->winId(): qt_xrootwin() );
00088     setBackgroundMode(X11ParentRelative);
00089     setBackgroundOrigin(WindowOrigin);
00090 #endif
00091     hasQuit = 0;
00092     menu = new KPopupMenu( this );
00093     menu->insertTitle( kapp->miniIcon(), kapp->caption() );
00094     move( -1000, -1000 );
00095     KAction* quitAction = KStdAction::quit(this, SIGNAL(quitSelected()), d->actionCollection);
00096 
00097     if (parentWidget())
00098     {
00099         connect(quitAction, SIGNAL(activated()), parentWidget(), SLOT(close()));
00100         new KAction(i18n("Minimize"), KShortcut(),
00101                     this, SLOT( minimizeRestoreAction() ),
00102                     d->actionCollection, "minimizeRestore");
00103 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00104     KWin::WindowInfo info = KWin::windowInfo( parentWidget()->winId());
00105     d->on_all_desktops = info.onAllDesktops();
00106 #endif
00107     }
00108     else
00109     {
00110         connect(quitAction, SIGNAL(activated()), qApp, SLOT(closeAllWindows()));
00111     d->on_all_desktops = false;
00112     }
00113 }
00114 
00115 KSystemTray::~KSystemTray()
00116 {
00117     delete d;
00118 }
00119 
00120 
00121 void KSystemTray::showEvent( QShowEvent * )
00122 {
00123     if ( !hasQuit ) {
00124     menu->insertSeparator();
00125         KAction* action = d->actionCollection->action("minimizeRestore");
00126 
00127         if (action)
00128         {
00129             action->plug(menu);
00130         }
00131 
00132         action = d->actionCollection->action(KStdAction::name(KStdAction::Quit));
00133 
00134         if (action)
00135         {
00136             action->plug(menu);
00137         }
00138 
00139     hasQuit = 1;
00140     }
00141 }
00142 
00143 // KDE4 remove
00144 void KSystemTray::enterEvent( QEvent* e )
00145 {
00146 #if QT_VERSION < 0x030200
00147 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00148 //#ifndef Q_WS_QWS
00149     // FIXME(E): Implement for Qt Embedded
00150     if ( !qApp->focusWidget() ) {
00151     XEvent ev;
00152     memset(&ev, 0, sizeof(ev));
00153     ev.xfocus.display = qt_xdisplay();
00154     ev.xfocus.type = XFocusIn;
00155     ev.xfocus.window = winId();
00156     ev.xfocus.mode = NotifyNormal;
00157     ev.xfocus.detail = NotifyAncestor;
00158     Time time = qt_x_time;
00159     qt_x_time = 1;
00160     qApp->x11ProcessEvent( &ev );
00161     qt_x_time = time;
00162     }
00163 #endif
00164 #endif
00165     QLabel::enterEvent( e );
00166 }
00167 
00168 KPopupMenu* KSystemTray::contextMenu() const
00169 {
00170     return menu;
00171 }
00172 
00173 
00174 void KSystemTray::mousePressEvent( QMouseEvent *e )
00175 {
00176     if ( !rect().contains( e->pos() ) )
00177     return;
00178 
00179     switch ( e->button() ) {
00180     case LeftButton:
00181         activateOrHide();
00182     break;
00183     case MidButton:
00184     // fall through
00185     case RightButton:
00186     if ( parentWidget() ) {
00187             KAction* action = d->actionCollection->action("minimizeRestore");
00188         if ( parentWidget()->isVisible() )
00189         action->setText( i18n("&Minimize") );
00190         else
00191         action->setText( i18n("&Restore") );
00192     }
00193     contextMenuAboutToShow( menu );
00194     menu->popup( e->globalPos() );
00195     break;
00196     default:
00197     // nothing
00198     break;
00199     }
00200 }
00201 
00202 void KSystemTray::mouseReleaseEvent( QMouseEvent * )
00203 {
00204 }
00205 
00206 
00207 void KSystemTray::contextMenuAboutToShow( KPopupMenu* )
00208 {
00209 }
00210 
00211 // called from the popup menu - always do what the menu entry says,
00212 // i.e. if the window is shown, no matter if active or not, the menu
00213 // entry is "minimize", otherwise it's "restore"
00214 void KSystemTray::minimizeRestoreAction()
00215 {
00216     if ( parentWidget() ) {
00217         bool restore = !( parentWidget()->isVisible() );
00218     minimizeRestore( restore );
00219     }
00220 }
00221 
00222 // called when left-clicking the tray icon
00223 // if the window is not the active one, show it if needed, and activate it
00224 // (just like taskbar); otherwise hide it
00225 void KSystemTray::activateOrHide()
00226 {
00227     QWidget *pw = parentWidget();
00228 
00229     if ( !pw )
00230     return;
00231 
00232 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00233     KWin::WindowInfo info1 = KWin::windowInfo( pw->winId(), NET::XAWMState | NET::WMState );
00234     // mapped = visible (but possibly obscured)
00235     bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
00236 //    - not mapped -> show, raise, focus
00237 //    - mapped
00238 //        - obscured -> raise, focus
00239 //        - not obscured -> hide
00240     if( !mapped )
00241         minimizeRestore( true );
00242     else
00243     {
00244         KWinModule module;
00245         for( QValueList< WId >::ConstIterator it = module.stackingOrder().fromLast();
00246              it != module.stackingOrder().end() && (*it) != pw->winId();
00247              --it )
00248         {
00249             KWin::WindowInfo info2 = KWin::windowInfo( *it,
00250                 NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
00251             if( info2.mappingState() != NET::Visible )
00252                 continue; // not visible on current desktop -> ignore
00253             if( !info2.geometry().intersects( pw->geometry()))
00254                 continue; // not obscuring the window -> ignore
00255             if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
00256                 continue; // obscured by window kept above -> ignore
00257             NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask
00258                 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00259                 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00260             if( type == NET::Dock || type == NET::TopMenu )
00261                 continue; // obscured by dock or topmenu -> ignore
00262             pw->raise();
00263             KWin::activateWindow( pw->winId());
00264             return;
00265         }
00266         minimizeRestore( false ); // hide
00267     }
00268 #endif
00269 }
00270 
00271 void KSystemTray::minimizeRestore( bool restore )
00272 {
00273     QWidget* pw = parentWidget();
00274     if( !pw )
00275     return;
00276 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00277     KWin::WindowInfo info = KWin::windowInfo( pw->winId(), NET::WMGeometry | NET::WMDesktop );
00278     if ( restore )
00279     {
00280 //#ifndef Q_WS_QWS //FIXME
00281 //#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00282     if( d->on_all_desktops )
00283         KWin::setOnAllDesktops( pw->winId(), true );
00284     else
00285         KWin::setOnDesktop( pw->winId(), KWin::currentDesktop());
00286         pw->move( info.geometry().topLeft() ); // avoid placement policies
00287         pw->show();
00288         pw->raise();
00289     KWin::activateWindow( pw->winId() );
00290     } else {
00291     d->on_all_desktops = info.onAllDesktops();
00292     pw->hide();
00293     }
00294 #endif
00295 }
00296 
00297 KActionCollection* KSystemTray::actionCollection()
00298 {
00299     return d->actionCollection;
00300 }
00301     
00302 QPixmap KSystemTray::loadIcon( const QString &icon, KInstance *instance )
00303 {
00304     KConfig *appCfg = kapp->config();
00305     KConfigGroupSaver configSaver(appCfg, "System Tray");
00306     int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
00307     return instance->iconLoader()->loadIcon( icon, KIcon::Panel, iconWidth );
00308 }
00309 
00310 void KSystemTray::virtual_hook( int, void* )
00311 { /*BASE::virtual_hook( id, data );*/ }
00312 
00313 #include "ksystemtray.moc"
00314 #include "kdockwindow.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun May 16 22:02:10 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003