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 "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"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 14 00:10:16 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003