kdeui
ksystemtray.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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;
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
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
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
00164 break;
00165 }
00166 }
00167
00168 void KSystemTray::mouseReleaseEvent( QMouseEvent * )
00169 {
00170 }
00171
00172
00173 void KSystemTray::contextMenuAboutToShow( KPopupMenu* )
00174 {
00175 }
00176
00177
00178
00179
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
00205
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
00233
00234
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
00245 bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
00246
00247
00248
00249
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;
00263 if( !info2.geometry().intersects( pw->geometry()))
00264 continue;
00265 if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
00266 continue;
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;
00272 pw->raise();
00273 KWin::activateWindow( pw->winId());
00274 return;
00275 }
00276 minimizeRestore( false );
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() );
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 { }
00333
00334 #include "ksystemtray.moc"
00335 #include "kdockwindow.moc"