ksystemtray.cpp00001
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 }
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
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
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
00163 break;
00164 }
00165 }
00166
00167 void KSystemTray::mouseReleaseEvent( QMouseEvent * )
00168 {
00169 }
00170
00171
00172 void KSystemTray::contextMenuAboutToShow( KPopupMenu* )
00173 {
00174 }
00175
00176
00177
00178
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
00204
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
00232
00233
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
00244 bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
00245
00246
00247
00248
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;
00262 if( !info2.geometry().intersects( pw->geometry()))
00263 continue;
00264 if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
00265 continue;
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;
00271 pw->raise();
00272 KWin::activateWindow( pw->winId());
00273 return;
00274 }
00275 minimizeRestore( false );
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() );
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 { }
00332
00333 #include "ksystemtray.moc"
00334 #include "kdockwindow.moc"
|