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 }
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"