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.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Aug 30 22:54:00 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003