ksystemtray.cpp
/* This file is part of the KDE libraries
Copyright (C) 1999 Matthias Ettrich (ettrich@kde.org)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "kaction.h"
#include "kmessagebox.h"
#include "kshortcut.h"
#include "ksystemtray.h"
#include "kpopupmenu.h"
#include "kapplication.h"
#include "klocale.h"
#include "kaboutdata.h"
#ifdef Q_WS_X11
#include <kwin.h>
#include <kwinmodule.h>
#include <qxembed.h>
#endif
#include <kiconloader.h>
#include <kconfig.h>
#include <qapplication.h>
class KSystemTrayPrivate
{
public:
KSystemTrayPrivate()
{
actionCollection = 0;
}
~KSystemTrayPrivate()
{
delete actionCollection;
}
KActionCollection* actionCollection;
bool on_all_desktops; // valid only when the parent widget was hidden
};
KSystemTray::KSystemTray( QWidget* parent, const char* name )
: QLabel( parent, name, WType_TopLevel )
{
#ifdef Q_WS_X11
QXEmbed::initialize();
#endif
d = new KSystemTrayPrivate;
d->actionCollection = new KActionCollection(this);
#ifdef Q_WS_X11
KWin::setSystemTrayWindowFor( winId(), parent?parent->topLevelWidget()->winId(): qt_xrootwin() );
#endif
setBackgroundMode(X11ParentRelative);
setBackgroundOrigin(WindowOrigin);
hasQuit = 0;
menu = new KPopupMenu( this );
menu->insertTitle( kapp->miniIcon(), kapp->caption() );
move( -1000, -1000 );
KStdAction::quit(this, SLOT(maybeQuit()), d->actionCollection);
if (parentWidget())
{
new KAction(i18n("Minimize"), KShortcut(),
this, SLOT( minimizeRestoreAction() ),
d->actionCollection, "minimizeRestore");
#ifdef Q_WS_X11
KWin::WindowInfo info = KWin::windowInfo( parentWidget()->winId());
d->on_all_desktops = info.onAllDesktops();
#else
d->on_all_desktops = false;
#endif
}
else
{
d->on_all_desktops = false;
}
setCaption( KGlobal::instance()->aboutData()->programName());
setAlignment( alignment() | Qt::AlignVCenter | Qt::AlignHCenter );
}
KSystemTray::~KSystemTray()
{
delete d;
}
void KSystemTray::showEvent( QShowEvent * )
{
if ( !hasQuit ) {
menu->insertSeparator();
KAction* action = d->actionCollection->action("minimizeRestore");
if (action)
{
action->plug(menu);
}
action = d->actionCollection->action(KStdAction::name(KStdAction::Quit));
if (action)
{
action->plug(menu);
}
hasQuit = 1;
}
}
// KDE4 remove
void KSystemTray::enterEvent( QEvent* e )
{
QLabel::enterEvent( e );
}
KPopupMenu* KSystemTray::contextMenu() const
{
return menu;
}
void KSystemTray::mousePressEvent( QMouseEvent *e )
{
if ( !rect().contains( e->pos() ) )
return;
switch ( e->button() ) {
case LeftButton:
toggleActive();
break;
case MidButton:
// fall through
case RightButton:
if ( parentWidget() ) {
KAction* action = d->actionCollection->action("minimizeRestore");
if ( parentWidget()->isVisible() )
action->setText( i18n("&Minimize") );
else
action->setText( i18n("&Restore") );
}
contextMenuAboutToShow( menu );
menu->popup( e->globalPos() );
break;
default:
// nothing
break;
}
}
void KSystemTray::mouseReleaseEvent( QMouseEvent * )
{
}
void KSystemTray::contextMenuAboutToShow( KPopupMenu* )
{
}
// called from the popup menu - always do what the menu entry says,
// i.e. if the window is shown, no matter if active or not, the menu
// entry is "minimize", otherwise it's "restore"
void KSystemTray::minimizeRestoreAction()
{
if ( parentWidget() ) {
bool restore = !( parentWidget()->isVisible() );
minimizeRestore( restore );
}
}
void KSystemTray::maybeQuit()
{
QString query = i18n("<qt>Are you sure you want to quit <b>%1</b>?</qt>")
.arg(kapp->caption());
if (KMessageBox::warningContinueCancel(this, query,
i18n("Confirm Quit From System Tray"),
KStdGuiItem::quit(),
QString("systemtrayquit%1")
.arg(kapp->caption())) !=
KMessageBox::Continue)
{
return;
}
emit quitSelected();
// KDE4: stop closing the parent widget? it results in complex application code
// instead make applications connect to the quitSelected() signal
if (parentWidget())
{
parentWidget()->close();
}
else
{
qApp->closeAllWindows();
}
}
void KSystemTray::toggleActive()
{
activateOrHide();
}
void KSystemTray::setActive()
{
minimizeRestore( true );
}
void KSystemTray::setInactive()
{
minimizeRestore( false );
}
// called when left-clicking the tray icon
// if the window is not the active one, show it if needed, and activate it
// (just like taskbar); otherwise hide it
void KSystemTray::activateOrHide()
{
QWidget *pw = parentWidget();
if ( !pw )
return;
#ifdef Q_WS_X11
KWin::WindowInfo info1 = KWin::windowInfo( pw->winId(), NET::XAWMState | NET::WMState );
// mapped = visible (but possibly obscured)
bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
// - not mapped -> show, raise, focus
// - mapped
// - obscured -> raise, focus
// - not obscured -> hide
if( !mapped )
minimizeRestore( true );
else
{
KWinModule module;
for( QValueList< WId >::ConstIterator it = module.stackingOrder().fromLast();
it != module.stackingOrder().end() && (*it) != pw->winId();
--it )
{
KWin::WindowInfo info2 = KWin::windowInfo( *it,
NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
if( info2.mappingState() != NET::Visible )
continue; // not visible on current desktop -> ignore
if( !info2.geometry().intersects( pw->geometry()))
continue; // not obscuring the window -> ignore
if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
continue; // obscured by window kept above -> ignore
NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask
| NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
| NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
if( type == NET::Dock || type == NET::TopMenu )
continue; // obscured by dock or topmenu -> ignore
pw->raise();
KWin::activateWindow( pw->winId());
return;
}
minimizeRestore( false ); // hide
}
#endif
}
void KSystemTray::minimizeRestore( bool restore )
{
QWidget* pw = parentWidget();
if( !pw )
return;
#ifdef Q_WS_X11
KWin::WindowInfo info = KWin::windowInfo( pw->winId(), NET::WMGeometry | NET::WMDesktop );
if ( restore )
{
if( d->on_all_desktops )
KWin::setOnAllDesktops( pw->winId(), true );
else
KWin::setCurrentDesktop( info.desktop() );
pw->move( info.geometry().topLeft() ); // avoid placement policies
pw->show();
pw->raise();
KWin::activateWindow( pw->winId() );
} else {
d->on_all_desktops = info.onAllDesktops();
pw->hide();
}
#endif
}
KActionCollection* KSystemTray::actionCollection()
{
return d->actionCollection;
}
QPixmap KSystemTray::loadIcon( const QString &icon, KInstance *instance )
{
KConfig *appCfg = kapp->config();
KConfigGroupSaver configSaver(appCfg, "System Tray");
int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
return instance->iconLoader()->loadIcon( icon, KIcon::Panel, iconWidth );
}
void KSystemTray::setPixmap( const QPixmap& p )
{
QLabel::setPixmap( p );
#ifdef Q_WS_X11
KWin::setIcons( winId(), p, QPixmap());
#endif
}
void KSystemTray::setCaption( const QString& s )
{
QLabel::setCaption( s );
}
void KSystemTray::virtual_hook( int, void* )
{ /*BASE::virtual_hook( id, data );*/ }
#include "ksystemtray.moc"
#include "kdockwindow.moc"
KWin::WindowInfo
KWin::WindowInfo::mappingState
NET::MappingState mappingState() const
KSystemTray::setInactive
void setInactive()
Hides the window associated with this system tray icon, regardless of its current state...
Definition: ksystemtray.cpp:227
KSystemTray::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *)
Reimplemented to provide the standard show/raise behavior for the parentWidget() and the context menu...
Definition: ksystemtray.cpp:168
KActionCollection
A managed set of KAction objects.
Definition: kactioncollection.h:78
NET::KeepAbove
KSystemTray::contextMenu
KPopupMenu * contextMenu() const
Access to the context menu.
Definition: ksystemtray.cpp:134
KSystemTray::toggleActive
void toggleActive()
Toggles the state of the window associated with this system tray icon (hides it, shows it or activate...
Definition: ksystemtray.cpp:217
klocale.h
KSystemTray::mousePressEvent
void mousePressEvent(QMouseEvent *)
Reimplemented to provide the standard show/raise behavior for the parentWidget() and the context menu...
Definition: ksystemtray.cpp:140
KWin::setIcons
static void setIcons(WId win, const QPixmap &icon, const QPixmap &miniIcon)
KShortcut
KSystemTray::KSystemTray
KSystemTray(QWidget *parent=0, const char *name=0)
Construct a KSystemTray widget just like any other widget.
Definition: ksystemtray.cpp:59
KSystemTray::setPixmap
virtual void setPixmap(const QPixmap &icon)
Changes the tray's icon.
Definition: ksystemtray.cpp:318
KSystemTray::actionCollection
KActionCollection * actionCollection()
Easy access to the actions in the context menu Currently includes KStdAction::Quit and minimizeRestor...
Definition: ksystemtray.cpp:305
KSystemTray::enterEvent
void enterEvent(QEvent *)
Reimplemented for internal reasons.
Definition: ksystemtray.cpp:129
KWinModule
NET::WindowType
WindowType
KSystemTray::showEvent
void showEvent(QShowEvent *)
Reimplemented for internal reasons.
Definition: ksystemtray.cpp:106
KWin::setSystemTrayWindowFor
static void setSystemTrayWindowFor(WId trayWin, WId forWin)
KInstance
KSystemTray::loadIcon
static QPixmap loadIcon(const QString &icon, KInstance *instance=KGlobal::instance())
Loads an icon icon using the icon loader class of the given instance instance.
Definition: ksystemtray.cpp:310
KAction::setText
virtual void setText(const QString &text)
Sets the text associated with this action.
Definition: kaction.cpp:863
KWin::WindowInfo::onAllDesktops
bool onAllDesktops() const
KSystemTray::contextMenuAboutToShow
virtual void contextMenuAboutToShow(KPopupMenu *menu)
Makes it easy to adjust some menu items right before the context menu becomes visible.
Definition: ksystemtray.cpp:173
KConfigGroupSaver
KWin::setCurrentDesktop
static void setCurrentDesktop(int desktop)
KMessageBox::warningContinueCancel
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString::null, const KGuiItem &buttonContinue=KStdGuiItem::cont(), const QString &dontAskAgainName=QString::null, int options=Notify)
Display a "warning" dialog.
Definition: kmessagebox.cpp:585
KGlobal::instance
static KInstance * instance()
KWinModule::stackingOrder
const QValueList< WId > & stackingOrder() const
KStdAction::name
const char * name(StdAction id)
This will return the internal name of a given standard action.
Definition: kstdaction.cpp:136
KWin::setOnAllDesktops
static void setOnAllDesktops(WId win, bool b)
KWin::WindowInfo::hasState
bool hasState(unsigned long s) const
KWin::WindowInfo::windowType
NET::WindowType windowType(int supported_types) const
KConfig
KWin::activateWindow
static void activateWindow(WId win, long time=0)
KIcon::Panel
KAction
Class to encapsulate user-driven action or event.
Definition: kaction.h:202
KWin::WindowInfo::desktop
int desktop() const
KSystemTray::quitSelected
void quitSelected()
Emitted when quit is selected in the menu.
KWin::windowInfo
static WindowInfo windowInfo(WId win, unsigned long properties=0, unsigned long properties2=0)
KWin::WindowInfo::isMinimized
bool isMinimized() const
KSystemTray::setActive
void setActive()
Activates the window associated with this system tray icon, regardless of its current state...
Definition: ksystemtray.cpp:222
KStdAction::quit
KAction * quit(const QObject *recvr, const char *slot, KActionCollection *parent, const char *name)
Quit the program.
Definition: kstdaction.cpp:162
KAction::plug
virtual int plug(QWidget *widget, int index=-1)
"Plug" or insert this action into a given widget.
Definition: kaction.cpp:618
KWin::WindowInfo::geometry
QRect geometry() const
KConfig::readNumEntry
int readNumEntry(const QString &pKey, int nDefault=0) const
KSystemTray::setCaption
virtual void setCaption(const QString &title)
Changes the tray's text description (which can be seen e.g.
Definition: ksystemtray.cpp:326

KDE Home | KDE Accessibility Home | Description of Access Keys