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

kdeui

ksystemtray.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, 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     setAlignment( alignment() | Qt::AlignVCenter | Qt::AlignHCenter );
00098 }
00099 
00100 KSystemTray::~KSystemTray()
00101 {
00102     delete d;
00103 }
00104 
00105 
00106 void KSystemTray::showEvent( QShowEvent * )
00107 {
00108     if ( !hasQuit ) {
00109     menu->insertSeparator();
00110         KAction* action = d->actionCollection->action("minimizeRestore");
00111 
00112         if (action)
00113         {
00114             action->plug(menu);
00115         }
00116 
00117         action = d->actionCollection->action(KStdAction::name(KStdAction::Quit));
00118 
00119         if (action)
00120         {
00121             action->plug(menu);
00122         }
00123 
00124     hasQuit = 1;
00125     }
00126 }
00127 
00128 // KDE4 remove
00129 void KSystemTray::enterEvent( QEvent* e )
00130 {
00131     QLabel::enterEvent( e );
00132 }
00133 
00134 KPopupMenu* KSystemTray::contextMenu() const
00135 {
00136     return menu;
00137 }
00138 
00139 
00140 void KSystemTray::mousePressEvent( QMouseEvent *e )
00141 {
00142     if ( !rect().contains( e->pos() ) )
00143     return;
00144 
00145     switch ( e->button() ) {
00146     case LeftButton:
00147         toggleActive();
00148     break;
00149     case MidButton:
00150     // fall through
00151     case RightButton:
00152     if ( parentWidget() ) {
00153             KAction* action = d->actionCollection->action("minimizeRestore");
00154         if ( parentWidget()->isVisible() )
00155         action->setText( i18n("&Minimize") );
00156         else
00157         action->setText( i18n("&Restore") );
00158     }
00159     contextMenuAboutToShow( menu );
00160     menu->popup( e->globalPos() );
00161     break;
00162     default:
00163     // nothing
00164     break;
00165     }
00166 }
00167 
00168 void KSystemTray::mouseReleaseEvent( QMouseEvent * )
00169 {
00170 }
00171 
00172 
00173 void KSystemTray::contextMenuAboutToShow( KPopupMenu* )
00174 {
00175 }
00176 
00177 // called from the popup menu - always do what the menu entry says,
00178 // i.e. if the window is shown, no matter if active or not, the menu
00179 // entry is "minimize", otherwise it's "restore"
00180 void KSystemTray::minimizeRestoreAction()
00181 {
00182     if ( parentWidget() ) {
00183         bool restore = !( parentWidget()->isVisible() );
00184     minimizeRestore( restore );
00185     }
00186 }
00187 
00188 void KSystemTray::maybeQuit()
00189 {
00190     QString query = i18n("<qt>Are you sure you want to quit <b>%1</b>?</qt>")
00191                         .arg(kapp->caption());
00192     if (KMessageBox::warningContinueCancel(this, query,
00193                                      i18n("Confirm Quit From System Tray"),
00194                                      KStdGuiItem::quit(),
00195                                      QString("systemtrayquit%1")
00196                                             .arg(kapp->caption())) !=
00197         KMessageBox::Continue)
00198     {
00199         return;
00200     }
00201 
00202     emit quitSelected();
00203 
00204     // KDE4: stop closing the parent widget? it results in complex application code
00205     //       instead make applications connect to the quitSelected() signal
00206 
00207     if (parentWidget())
00208     {
00209         parentWidget()->close();
00210     }
00211     else
00212     {
00213         qApp->closeAllWindows();
00214     }
00215 }
00216 
00217 void KSystemTray::toggleActive()
00218 {
00219     activateOrHide();
00220 }
00221 
00222 void KSystemTray::setActive()
00223 {
00224     minimizeRestore( true );
00225 }
00226 
00227 void KSystemTray::setInactive()
00228 {
00229     minimizeRestore( false );
00230 }
00231 
00232 // called when left-clicking the tray icon
00233 // if the window is not the active one, show it if needed, and activate it
00234 // (just like taskbar); otherwise hide it
00235 void KSystemTray::activateOrHide()
00236 {
00237     QWidget *pw = parentWidget();
00238 
00239     if ( !pw )
00240     return;
00241 
00242 #ifdef Q_WS_X11
00243     KWin::WindowInfo info1 = KWin::windowInfo( pw->winId(), NET::XAWMState | NET::WMState );
00244     // mapped = visible (but possibly obscured)
00245     bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
00246 //    - not mapped -> show, raise, focus
00247 //    - mapped
00248 //        - obscured -> raise, focus
00249 //        - not obscured -> hide
00250     if( !mapped )
00251         minimizeRestore( true );
00252     else
00253     {
00254         KWinModule module;
00255         for( QValueList< WId >::ConstIterator it = module.stackingOrder().fromLast();
00256              it != module.stackingOrder().end() && (*it) != pw->winId();
00257              --it )
00258         {
00259             KWin::WindowInfo info2 = KWin::windowInfo( *it,
00260                 NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
00261             if( info2.mappingState() != NET::Visible )
00262                 continue; // not visible on current desktop -> ignore
00263             if( !info2.geometry().intersects( pw->geometry()))
00264                 continue; // not obscuring the window -> ignore
00265             if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
00266                 continue; // obscured by window kept above -> ignore
00267             NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask
00268                 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00269                 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00270             if( type == NET::Dock || type == NET::TopMenu )
00271                 continue; // obscured by dock or topmenu -> ignore
00272             pw->raise();
00273             KWin::activateWindow( pw->winId());
00274             return;
00275         }
00276         minimizeRestore( false ); // hide
00277     }
00278 #endif
00279 }
00280 
00281 void KSystemTray::minimizeRestore( bool restore )
00282 {
00283     QWidget* pw = parentWidget();
00284     if( !pw )
00285     return;
00286 #ifdef Q_WS_X11
00287     KWin::WindowInfo info = KWin::windowInfo( pw->winId(), NET::WMGeometry | NET::WMDesktop );
00288     if ( restore )
00289     {
00290     if( d->on_all_desktops )
00291         KWin::setOnAllDesktops( pw->winId(), true );
00292     else
00293         KWin::setCurrentDesktop( info.desktop() );
00294         pw->move( info.geometry().topLeft() ); // avoid placement policies
00295         pw->show();
00296         pw->raise();
00297     KWin::activateWindow( pw->winId() );
00298     } else {
00299     d->on_all_desktops = info.onAllDesktops();
00300     pw->hide();
00301     }
00302 #endif
00303 }
00304 
00305 KActionCollection* KSystemTray::actionCollection()
00306 {
00307     return d->actionCollection;
00308 }
00309     
00310 QPixmap KSystemTray::loadIcon( const QString &icon, KInstance *instance )
00311 {
00312     KConfig *appCfg = kapp->config();
00313     KConfigGroupSaver configSaver(appCfg, "System Tray");
00314     int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
00315     return instance->iconLoader()->loadIcon( icon, KIcon::Panel, iconWidth );
00316 }
00317 
00318 void KSystemTray::setPixmap( const QPixmap& p )
00319 {
00320     QLabel::setPixmap( p );
00321 #ifdef Q_WS_X11
00322     KWin::setIcons( winId(), p, QPixmap());
00323 #endif
00324 }
00325 
00326 void KSystemTray::setCaption( const QString& s )
00327 {
00328     QLabel::setCaption( s );
00329 }
00330 
00331 void KSystemTray::virtual_hook( int, void* )
00332 { /*BASE::virtual_hook( id, data );*/ }
00333 
00334 #include "ksystemtray.moc"
00335 #include "kdockwindow.moc"

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