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

# 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 "kmessagebox.h"
    00024 #include "kshortcut.h"
    00025 #include "ksystemtray.h"
    00026 #include "kpopupmenu.h"
    00027 #include "kapplication.h"
    00028 #include "klocale.h"
    00029 #include "kaboutdata.h"
    00030
    00031 #ifdef Q_WS_X11
    00032 #include <kwin.h>
    00033 #include <kwinmodule.h>
    00034 #include <qxembed.h>
    00035 #endif
    00036
    00037 #include <kiconloader.h>
    00038 #include <kconfig.h>
    00039
    00040 #include <qapplication.h>
    00041
    00042 class KSystemTrayPrivate
    00043 {
    00044 public:
    00045     KSystemTrayPrivate()
    00046     {
    00047         actionCollection = 0;
    00048     }
    00049
    00050     ~KSystemTrayPrivate()
    00051     {
    00052         delete actionCollection;
    00053     }
    00054
    00055     KActionCollection* actionCollection;
    00056     bool on_all_desktops; // valid only when the parent widget was hidden
    00057 };
    00058
    00059 KSystemTray::KSystemTray( QWidget* parent, const char* name )
    00060     : QLabel( parent, name, WType_TopLevel )
    00061 {
    00062 #ifdef Q_WS_X11
    00063     QXEmbed::initialize();
    00064 #endif
    00065
    00066     d = new KSystemTrayPrivate;
    00067     d->actionCollection = new KActionCollection(this);
    00068
    00069 #ifdef Q_WS_X11
    00070     KWin::setSystemTrayWindowFor( winId(), parent?parent->topLevelWidget()->winId(): qt_xrootwin() );
    00071 #endif
    00072     setBackgroundMode(X11ParentRelative);
    00073     setBackgroundOrigin(WindowOrigin);
    00074     hasQuit = 0;
    00075     menu = new KPopupMenu( this );
    00076     menu->insertTitle( kapp->miniIcon(), kapp->caption() );
    00077     move( -1000, -1000 );
    00078     KStdAction::quit(this, SLOT(maybeQuit()), d->actionCollection);
    00079
    00080     if (parentWidget())
    00081     {
    00082         new KAction(i18n("Minimize"), KShortcut(),
    00083                     this, SLOT( minimizeRestoreAction() ),
    00084                     d->actionCollection, "minimizeRestore");
    00085 #ifdef Q_WS_X11
    00086     KWin::WindowInfo info = KWin::windowInfo( parentWidget()->winId());
    00087     d->on_all_desktops = info.onAllDesktops();
    00088 #else
    00089     d->on_all_desktops = false;
    00090 #endif
    00091     }
    00092     else
    00093     {
    00094         d->on_all_desktops = false;
    00095     }
    00096     setCaption( KGlobal::instance()->aboutData()->programName());
    00097 }
    00098
    00099 KSystemTray::~KSystemTray()
    00100 {
    00101     delete d;
    00102 }
    00103
    00104
    00105 void KSystemTray::showEvent( QShowEvent * )
    00106 {
    00107     if ( !hasQuit ) {
    00108     menu->insertSeparator();
    00109         KAction* action = d->actionCollection->action("minimizeRestore");
    00110
    00111         if (action)
    00112         {
    00113             action->plug(menu);
    00114         }
    00115
    00116         action = d->actionCollection->action(KStdAction::name(KStdAction::Quit));
    00117
    00118         if (action)
    00119         {
    00120             action->plug(menu);
    00121         }
    00122
    00123     hasQuit = 1;
    00124     }
    00125 }
    00126
    00127 // KDE4 remove
    00128 void KSystemTray::enterEvent( QEvent* e )
    00129 {
    00130     QLabel::enterEvent( e );
    00131 }
    00132
    00133 KPopupMenu* KSystemTray::contextMenu() const
    00134 {
    00135     return menu;
    00136 }
    00137
    00138
    00139 void KSystemTray::mousePressEvent( QMouseEvent *e )
    00140 {
    00141     if ( !rect().contains( e->pos() ) )
    00142     return;
    00143
    00144     switch ( e->button() ) {
    00145     case LeftButton:
    00146         toggleActive();
    00147     break;
    00148     case MidButton:
    00149     // fall through
    00150     case RightButton:
    00151     if ( parentWidget() ) {
    00152             KAction* action = d->actionCollection->action("minimizeRestore");
    00153         if ( parentWidget()->isVisible() )
    00154         action->setText( i18n("&Minimize") );
    00155         else
    00156         action->setText( i18n("&Restore") );
    00157     }
    00158     contextMenuAboutToShow( menu );
    00159     menu->popup( e->globalPos() );
    00160     break;
    00161     default:
    00162     // nothing
    00163     break;
    00164     }
    00165 }
    00166
    00167 void KSystemTray::mouseReleaseEvent( QMouseEvent * )
    00168 {
    00169 }
    00170
    00171
    00172 void KSystemTray::contextMenuAboutToShow( KPopupMenu* )
    00173 {
    00174 }
    00175
    00176 // called from the popup menu - always do what the menu entry says,
    00177 // i.e. if the window is shown, no matter if active or not, the menu
    00178 // entry is "minimize", otherwise it's "restore"
    00179 void KSystemTray::minimizeRestoreAction()
    00180 {
    00181     if ( parentWidget() ) {
    00182         bool restore = !( parentWidget()->isVisible() );
    00183     minimizeRestore( restore );
    00184     }
    00185 }
    00186
    00187 void KSystemTray::maybeQuit()
    00188 {
    00189     QString query = i18n("<qt>Are you sure you want to quit <b>%1</b>?</qt>")
    00190                         .arg(kapp->caption());
    00191     if (KMessageBox::warningContinueCancel(this, query,
    00192                                      i18n("Confirm Quit From System Tray"),
    00193                                      KStdGuiItem::quit(),
    00194                                      QString("systemtrayquit%1")
    00195                                             .arg(kapp->caption())) !=
    00196         KMessageBox::Continue)
    00197     {
    00198         return;
    00199     }
    00200
    00201     emit quitSelected();
    00202
    00203     // KDE4: stop closing the parent widget? it results in complex application code
    00204     //       instead make applications connect to the quitSelected() signal
    00205
    00206     if (parentWidget())
    00207     {
    00208         parentWidget()->close();
    00209     }
    00210     else
    00211     {
    00212         qApp->closeAllWindows();
    00213     }
    00214 }
    00215
    00216 void KSystemTray::toggleActive()
    00217 {
    00218     activateOrHide();
    00219 }
    00220
    00221 void KSystemTray::setActive()
    00222 {
    00223     minimizeRestore( true );
    00224 }
    00225
    00226 void KSystemTray::setInactive()
    00227 {
    00228     minimizeRestore( false );
    00229 }
    00230
    00231 // called when left-clicking the tray icon
    00232 // if the window is not the active one, show it if needed, and activate it
    00233 // (just like taskbar); otherwise hide it
    00234 void KSystemTray::activateOrHide()
    00235 {
    00236     QWidget *pw = parentWidget();
    00237
    00238     if ( !pw )
    00239     return;
    00240
    00241 #ifdef Q_WS_X11
    00242     KWin::WindowInfo info1 = KWin::windowInfo( pw->winId(), NET::XAWMState | NET::WMState );
    00243     // mapped = visible (but possibly obscured)
    00244     bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
    00245 //    - not mapped -> show, raise, focus
    00246 //    - mapped
    00247 //        - obscured -> raise, focus
    00248 //        - not obscured -> hide
    00249     if( !mapped )
    00250         minimizeRestore( true );
    00251     else
    00252     {
    00253         KWinModule module;
    00254         for( QValueList< WId >::ConstIterator it = module.stackingOrder().fromLast();
    00255              it != module.stackingOrder().end() && (*it) != pw->winId();
    00256              --it )
    00257         {
    00258             KWin::WindowInfo info2 = KWin::windowInfo( *it,
    00259                 NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
    00260             if( info2.mappingState() != NET::Visible )
    00261                 continue; // not visible on current desktop -> ignore
    00262             if( !info2.geometry().intersects( pw->geometry()))
    00263                 continue; // not obscuring the window -> ignore
    00264             if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
    00265                 continue; // obscured by window kept above -> ignore
    00266             NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask
    00267                 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
    00268                 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
    00269             if( type == NET::Dock || type == NET::TopMenu )
    00270                 continue; // obscured by dock or topmenu -> ignore
    00271             pw->raise();
    00272             KWin::activateWindow( pw->winId());
    00273             return;
    00274         }
    00275         minimizeRestore( false ); // hide
    00276     }
    00277 #endif
    00278 }
    00279
    00280 void KSystemTray::minimizeRestore( bool restore )
    00281 {
    00282     QWidget* pw = parentWidget();
    00283     if( !pw )
    00284     return;
    00285 #ifdef Q_WS_X11
    00286     KWin::WindowInfo info = KWin::windowInfo( pw->winId(), NET::WMGeometry | NET::WMDesktop );
    00287     if ( restore )
    00288     {
    00289     if( d->on_all_desktops )
    00290         KWin::setOnAllDesktops( pw->winId(), true );
    00291     else
    00292         KWin::setCurrentDesktop( info.desktop() );
    00293         pw->move( info.geometry().topLeft() ); // avoid placement policies
    00294         pw->show();
    00295         pw->raise();
    00296     KWin::activateWindow( pw->winId() );
    00297     } else {
    00298     d->on_all_desktops = info.onAllDesktops();
    00299     pw->hide();
    00300     }
    00301 #endif
    00302 }
    00303
    00304 KActionCollection* KSystemTray::actionCollection()
    00305 {
    00306     return d->actionCollection;
    00307 }
    00308
    00309 QPixmap KSystemTray::loadIcon( const QString &icon, KInstance *instance )
    00310 {
    00311     KConfig *appCfg = kapp->config();
    00312     KConfigGroupSaver configSaver(appCfg, "System Tray");
    00313     int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
    00314     return instance->iconLoader()->loadIcon( icon, KIcon::Panel, iconWidth );
    00315 }
    00316
    00317 void KSystemTray::setPixmap( const QPixmap& p )
    00318 {
    00319     QLabel::setPixmap( p );
    00320 #ifdef Q_WS_X11
    00321     KWin::setIcons( winId(), p, QPixmap());
    00322 #endif
    00323 }
    00324
    00325 void KSystemTray::setCaption( const QString& s )
    00326 {
    00327     QLabel::setCaption( s );
    00328 }
    00329
    00330 void KSystemTray::virtual_hook( int, void* )
    00331 { /*BASE::virtual_hook( id, data );*/ }
    00332
    00333 #include "ksystemtray.moc"
    00334 #include "kdockwindow.moc"

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:23 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003