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 "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>
00031
#include <kwinmodule.h>
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>
00039
#endif
00040
00041
#include <qapplication.h>
00042
00043
class KSystemTrayPrivate
00044 {
00045
public:
00046 KSystemTrayPrivate()
00047 {
00048 actionCollection = 0;
00049 }
00050
00051 ~KSystemTrayPrivate()
00052 {
00053
delete actionCollection;
00054 }
00055
00056
KActionCollection* actionCollection;
00057
bool on_all_desktops;
00058 };
00059
00060 KSystemTray::KSystemTray(
QWidget* parent,
const char* name )
00061 :
QLabel( parent, name, WType_TopLevel )
00062 {
00063
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00064
QXEmbed::initialize();
00065
#endif
00066
00067 d =
new KSystemTrayPrivate;
00068 d->actionCollection =
new KActionCollection(
this);
00069
00070
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00071
00072
00073
KWin::setSystemTrayWindowFor( winId(), parent?parent->topLevelWidget()->winId(): qt_xrootwin() );
00074 setBackgroundMode(X11ParentRelative);
00075 setBackgroundOrigin(WindowOrigin);
00076
#endif
00077
hasQuit = 0;
00078 menu =
new KPopupMenu(
this );
00079 menu->
insertTitle( kapp->miniIcon(), kapp->caption() );
00080 move( -1000, -1000 );
00081
KAction* quitAction =
KStdAction::quit(
this, SIGNAL(
quitSelected()), d->actionCollection);
00082
00083
if (parentWidget())
00084 {
00085 connect(quitAction, SIGNAL(activated()), parentWidget(), SLOT(close()));
00086
new KAction(i18n(
"Minimize"),
KShortcut(),
00087
this, SLOT( minimizeRestoreAction() ),
00088 d->actionCollection,
"minimizeRestore");
00089
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00090
KWin::WindowInfo info =
KWin::windowInfo( parentWidget()->winId());
00091 d->on_all_desktops = info.
onAllDesktops();
00092
#endif
00093
}
00094
else
00095 {
00096 connect(quitAction, SIGNAL(activated()), qApp, SLOT(closeAllWindows()));
00097 d->on_all_desktops =
false;
00098 }
00099 }
00100
00101 KSystemTray::~KSystemTray()
00102 {
00103
delete d;
00104 }
00105
00106
00107 void KSystemTray::showEvent(
QShowEvent * )
00108 {
00109
if ( !hasQuit ) {
00110 menu->insertSeparator();
00111
KAction* action = d->actionCollection->action(
"minimizeRestore");
00112
00113
if (action)
00114 {
00115 action->plug(menu);
00116 }
00117
00118 action = d->actionCollection->action(KStdAction::name(KStdAction::Quit));
00119
00120
if (action)
00121 {
00122 action->plug(menu);
00123 }
00124
00125 hasQuit = 1;
00126 }
00127 }
00128
00129
00130 void KSystemTray::enterEvent(
QEvent* e )
00131 {
00132 QLabel::enterEvent( e );
00133 }
00134
00135 KPopupMenu*
KSystemTray::contextMenu()
const
00136
{
00137
return menu;
00138 }
00139
00140
00141 void KSystemTray::mousePressEvent(
QMouseEvent *e )
00142 {
00143
if ( !rect().contains( e->pos() ) )
00144
return;
00145
00146
switch ( e->button() ) {
00147
case LeftButton:
00148
toggleActive();
00149
break;
00150
case MidButton:
00151
00152
case RightButton:
00153
if ( parentWidget() ) {
00154
KAction* action = d->actionCollection->action(
"minimizeRestore");
00155
if ( parentWidget()->isVisible() )
00156 action->setText( i18n(
"&Minimize") );
00157
else
00158 action->setText( i18n(
"&Restore") );
00159 }
00160
contextMenuAboutToShow( menu );
00161 menu->popup( e->globalPos() );
00162
break;
00163
default:
00164
00165
break;
00166 }
00167 }
00168
00169 void KSystemTray::mouseReleaseEvent(
QMouseEvent * )
00170 {
00171 }
00172
00173
00174 void KSystemTray::contextMenuAboutToShow(
KPopupMenu* )
00175 {
00176 }
00177
00178
00179
00180
00181
void KSystemTray::minimizeRestoreAction()
00182 {
00183
if ( parentWidget() ) {
00184
bool restore = !( parentWidget()->isVisible() );
00185 minimizeRestore( restore );
00186 }
00187 }
00188
00189 void KSystemTray::toggleActive()
00190 {
00191 activateOrHide();
00192 }
00193
00194 void KSystemTray::setActive()
00195 {
00196 minimizeRestore(
true );
00197 }
00198
00199 void KSystemTray::setInactive()
00200 {
00201 minimizeRestore(
false );
00202 }
00203
00204
00205
00206
00207
void KSystemTray::activateOrHide()
00208 {
00209
QWidget *pw = parentWidget();
00210
00211
if ( !pw )
00212
return;
00213
00214
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00215
KWin::WindowInfo info1 =
KWin::windowInfo( pw->winId(), NET::XAWMState | NET::WMState );
00216
00217
bool mapped = (info1.
mappingState() == NET::Visible) && !info1.
isMinimized();
00218
00219
00220
00221
00222
if( !mapped )
00223 minimizeRestore(
true );
00224
else
00225 {
00226
KWinModule module;
00227
for(
QValueList< WId >::ConstIterator it = module.
stackingOrder().fromLast();
00228 it != module.
stackingOrder().end() && (*it) != pw->winId();
00229 --it )
00230 {
00231
KWin::WindowInfo info2 =
KWin::windowInfo( *it,
00232 NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
00233
if( info2.
mappingState() != NET::Visible )
00234
continue;
00235
if( !info2.
geometry().intersects( pw->geometry()))
00236
continue;
00237
if( !info1.
hasState( NET::KeepAbove ) && info2.
hasState( NET::KeepAbove ))
00238
continue;
00239 NET::WindowType type = info2.
windowType( NET::NormalMask | NET::DesktopMask
00240 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
00241 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
00242
if( type == NET::Dock || type == NET::TopMenu )
00243
continue;
00244 pw->raise();
00245
KWin::activateWindow( pw->winId());
00246
return;
00247 }
00248 minimizeRestore(
false );
00249 }
00250
#endif
00251
}
00252
00253
void KSystemTray::minimizeRestore(
bool restore )
00254 {
00255
QWidget* pw = parentWidget();
00256
if( !pw )
00257
return;
00258
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00259
KWin::WindowInfo info =
KWin::windowInfo( pw->winId(), NET::WMGeometry | NET::WMDesktop );
00260
if ( restore )
00261 {
00262
00263
00264
if( d->on_all_desktops )
00265
KWin::setOnAllDesktops( pw->winId(),
true );
00266
else
00267
KWin::setOnDesktop( pw->winId(),
KWin::currentDesktop());
00268 pw->move( info.
geometry().topLeft() );
00269 pw->show();
00270 pw->raise();
00271
KWin::activateWindow( pw->winId() );
00272 }
else {
00273 d->on_all_desktops = info.
onAllDesktops();
00274 pw->hide();
00275 }
00276
#endif
00277
}
00278
00279 KActionCollection*
KSystemTray::actionCollection()
00280 {
00281
return d->actionCollection;
00282 }
00283
00284 QPixmap KSystemTray::loadIcon(
const QString &icon,
KInstance *instance )
00285 {
00286
KConfig *appCfg = kapp->config();
00287
KConfigGroupSaver configSaver(appCfg,
"System Tray");
00288
int iconWidth = appCfg->
readNumEntry(
"systrayIconWidth", 22);
00289
return instance->
iconLoader()->
loadIcon( icon, KIcon::Panel, iconWidth );
00290 }
00291
00292
void KSystemTray::virtual_hook(
int,
void* )
00293 { }
00294
00295
#include "ksystemtray.moc"
00296
#include "kdockwindow.moc"