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 info = KWin::windowInfo( pw->winId() );
00234     // mapped = visible (but possibly obscured)
00235     bool mapped = (info.mappingState() != NET::Withdrawn);
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 info = KWin::windowInfo( *it, NET::WMGeometry | NET::XAWMState );
00250             if( info.mappingState() == NET::Visible && info.geometry().intersects( pw->geometry()))
00251             {
00252                 pw->raise();
00253                 KWin::activateWindow( pw->winId());
00254                 return;
00255             }
00256         }
00257         minimizeRestore( false ); // hide
00258     }
00259 #endif
00260 }
00261 
00262 void KSystemTray::minimizeRestore( bool restore )
00263 {
00264     QWidget* pw = parentWidget();
00265     if( !pw )
00266     return;
00267 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00268     KWin::WindowInfo info = KWin::windowInfo( pw->winId(), NET::WMGeometry | NET::WMDesktop );
00269     if ( restore )
00270     {
00271 //#ifndef Q_WS_QWS //FIXME
00272 //#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00273     if( d->on_all_desktops )
00274         KWin::setOnAllDesktops( pw->winId(), true );
00275     else
00276         KWin::setOnDesktop( pw->winId(), KWin::currentDesktop());
00277         pw->move( info.geometry().topLeft() ); // avoid placement policies
00278         pw->show();
00279         pw->raise();
00280     KWin::activateWindow( pw->winId() );
00281     } else {
00282     d->on_all_desktops = info.onAllDesktops();
00283     pw->hide();
00284     }
00285 #endif
00286 }
00287 
00288 KActionCollection* KSystemTray::actionCollection()
00289 {
00290     return d->actionCollection;
00291 }
00292     
00293 QPixmap KSystemTray::loadIcon( const QString &icon, KInstance *instance )
00294 {
00295     KConfig *appCfg = kapp->config();
00296     KConfigGroupSaver configSaver(appCfg, "System Tray");
00297     int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
00298     return instance->iconLoader()->loadIcon( icon, KIcon::Panel, iconWidth );
00299 }
00300 
00301 void KSystemTray::virtual_hook( int, void* )
00302 { /*BASE::virtual_hook( id, data );*/ }
00303 
00304 #include "ksystemtray.moc"
00305 #include "kdockwindow.moc"
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:20 2004 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2003