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
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00044
#include <X11/Xlib.h>
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;
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
00086
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
00144 void KSystemTray::enterEvent(
QEvent* e )
00145 {
00146
#if QT_VERSION < 0x030200
00147
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00148
00149
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
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
00198
break;
00199 }
00200 }
00201
00202 void KSystemTray::mouseReleaseEvent(
QMouseEvent * )
00203 {
00204 }
00205
00206
00207 void KSystemTray::contextMenuAboutToShow(
KPopupMenu* )
00208 {
00209 }
00210
00211
00212
00213
00214
void KSystemTray::minimizeRestoreAction()
00215 {
00216
if ( parentWidget() ) {
00217
bool restore = !( parentWidget()->isVisible() );
00218 minimizeRestore( restore );
00219 }
00220 }
00221
00222
00223
00224
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
00235
bool mapped = (info1.
mappingState() == NET::Visible) && !info1.
isMinimized();
00236
00237
00238
00239
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;
00253
if( !info2.
geometry().
intersects( pw->
geometry()))
00254
continue;
00255
if( !info1.
hasState( NET::KeepAbove ) && info2.
hasState( NET::KeepAbove ))
00256
continue;
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;
00262 pw->
raise();
00263
KWin::activateWindow( pw->
winId());
00264
return;
00265 }
00266 minimizeRestore(
false );
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
00281
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() );
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 { }
00312
00313
#include "ksystemtray.moc"
00314
#include "kdockwindow.moc"