• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • notifications
ksystemtrayicon.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2
3 Copyright (C) 1999 Matthias Ettrich (ettrich@kde.org)
4 Copyright (c) 2007 by Charles Connell <charles@connells.org>
5 Copyright (C) 2008 Lukas Appelhans <l.appelhans@gmx.de>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "ksystemtrayicon.h"
24#include "kaboutdata.h"
25#include "kaction.h"
26#include "kcomponentdata.h"
27#include "klocale.h"
28#include "kmenu.h"
29#include "kmessagebox.h"
30#include "kshortcut.h"
31#include "kactioncollection.h"
32#include "kstandardaction.h"
33#include <kwindowsystem.h>
34
35#ifdef Q_WS_X11
36#include <QX11Info>
37#endif
38#ifdef Q_WS_WIN
39#include <windows.h>
40#endif
41
42#include <kiconloader.h>
43#include <kapplication.h>
44#include <kconfiggroup.h>
45
46#include <QMouseEvent>
47#include <QToolButton>
48#include <QMovie>
49#include <QPointer>
50
51#ifdef Q_WS_WIN
52class KSystemTrayIconPrivate : public QObject
53#else
54class KSystemTrayIconPrivate
55#endif
56{
57public:
58 KSystemTrayIconPrivate(KSystemTrayIcon* trayIcon, QWidget* parent)
59 : q(trayIcon)
60 {
61 actionCollection = new KActionCollection( trayIcon );
62 hasQuit = false;
63 onAllDesktops = false;
64 window = parent;
65 movie = 0;
66#ifdef Q_WS_WIN
67 if ( window ) {
68 window->installEventFilter( this );
69 }
70#endif
71 }
72
73 ~KSystemTrayIconPrivate()
74 {
75#ifdef Q_WS_WIN
76 if ( window ) {
77 window->removeEventFilter( this );
78 }
79#endif
80 delete actionCollection;
81 delete menu;
82 }
83
84
85 void _k_slotNewFrame()
86 {
87 q->setIcon(QIcon(movie->currentPixmap()));
88 }
89
90#ifdef Q_WS_WIN
91 bool eventFilter(QObject *obj, QEvent *ev)
92 {
93 if(ev->type() == QEvent::ActivationChange) {
94 dwTickCount = GetTickCount();
95 }
96 return QObject::eventFilter(obj, ev);
97 }
98 DWORD dwTickCount;
99#endif
100
101 KSystemTrayIcon* q;
102 KActionCollection* actionCollection;
103 KMenu* menu;
104 QWidget* window;
105 QAction* titleAction;
106 bool onAllDesktops : 1; // valid only when the parent widget was hidden
107 bool hasQuit : 1;
108 QPointer<QMovie> movie;
109};
110
111KSystemTrayIcon::KSystemTrayIcon( QWidget* parent )
112 : QSystemTrayIcon( parent ),
113 d( new KSystemTrayIconPrivate( this, parent ) )
114{
115 init( parent );
116}
117
118KSystemTrayIcon::KSystemTrayIcon( const QString& icon, QWidget* parent )
119 : QSystemTrayIcon( loadIcon( icon ), parent ),
120 d( new KSystemTrayIconPrivate( this, parent ) )
121{
122 init( parent );
123}
124
125KSystemTrayIcon::KSystemTrayIcon( const QIcon& icon, QWidget* parent )
126 : QSystemTrayIcon( icon, parent ),
127 d( new KSystemTrayIconPrivate( this, parent ) )
128{
129 init( parent );
130}
131
132KSystemTrayIcon::KSystemTrayIcon(QMovie* movie, QWidget *parent)
133 : QSystemTrayIcon(parent),
134 d( new KSystemTrayIconPrivate( this, parent ) )
135{
136 init(parent);
137 setMovie(movie);
138}
139
140void KSystemTrayIcon::init( QWidget* parent )
141{
142 // Ensure that closing the last KMainWindow doesn't exit the application
143 // if a system tray icon is still present.
144 KGlobal::ref();
145 d->menu = new KMenu( parent );
146 d->titleAction = d->menu->addTitle( qApp->windowIcon(), KGlobal::caption() );
147 d->menu->setTitle( KGlobal::mainComponent().aboutData()->programName() );
148 connect( d->menu, SIGNAL(aboutToShow()), this, SLOT(contextMenuAboutToShow()) );
149 setContextMenu( d->menu );
150
151 KStandardAction::quit( this, SLOT(maybeQuit()), d->actionCollection );
152
153 if ( parent )
154 {
155 QAction *action = d->actionCollection->addAction("minimizeRestore");
156 action->setText(i18n("Minimize"));
157 connect( action, SIGNAL(triggered(bool)), this, SLOT(minimizeRestoreAction()) );
158
159#ifdef Q_WS_X11
160 KWindowInfo info = KWindowSystem::windowInfo( parent->winId(), NET::WMDesktop );
161 d->onAllDesktops = info.onAllDesktops();
162#else
163 d->onAllDesktops = false;
164#endif
165 }
166 else
167 {
168 d->onAllDesktops = false;
169 }
170
171 connect( this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
172 SLOT(activateOrHide(QSystemTrayIcon::ActivationReason)) );
173}
174
175QWidget *KSystemTrayIcon::parentWidget() const
176{
177 return d->window;
178}
179
180KSystemTrayIcon::~KSystemTrayIcon()
181{
182 delete d;
183 KGlobal::deref();
184}
185
186void KSystemTrayIcon::contextMenuAboutToShow( )
187{
188 if ( !d->hasQuit )
189 {
190 // we need to add the actions to the menu afterwards so that these items
191 // appear at the _END_ of the menu
192 d->menu->addSeparator();
193 QAction* action = d->actionCollection->action( "minimizeRestore" );
194
195 if ( action )
196 {
197 d->menu->addAction( action );
198 }
199
200 action = d->actionCollection->action( KStandardAction::name( KStandardAction::Quit ) );
201
202 if ( action )
203 {
204 d->menu->addAction( action );
205 }
206
207 d->hasQuit = true;
208 }
209
210 if ( d->window )
211 {
212 QAction* action = d->actionCollection->action("minimizeRestore");
213 if ( d->window->isVisible() )
214 {
215 action->setText( i18n("&Minimize") );
216 }
217 else
218 {
219 action->setText( i18n("&Restore") );
220 }
221 }
222}
223
224// called from the popup menu - always do what the menu entry says,
225// i.e. if the window is shown, no matter if active or not, the menu
226// entry is "minimize", otherwise it's "restore"
227void KSystemTrayIcon::minimizeRestoreAction()
228{
229 if ( d->window )
230 {
231 bool restore = !( d->window->isVisible() );
232 minimizeRestore( restore );
233 }
234}
235
236void KSystemTrayIcon::maybeQuit()
237{
238 QString caption = KGlobal::caption();
239 QString query = i18n("<qt>Are you sure you want to quit <b>%1</b>?</qt>",
240 caption);
241 if (KMessageBox::warningContinueCancel(d->window, query,
242 i18n("Confirm Quit From System Tray"),
243 KStandardGuiItem::quit(),
244 KStandardGuiItem::cancel(),
245 QString("systemtrayquit%1")
246 .arg(caption)) !=
247 KMessageBox::Continue)
248 {
249 return;
250 }
251
252 emit quitSelected();
253 qApp->quit();
254}
255
256// if the window is not the active one, show it if needed, and activate it
257// (just like taskbar); otherwise hide it
258void KSystemTrayIcon::activateOrHide( QSystemTrayIcon::ActivationReason reasonCalled )
259{
260 if ( reasonCalled != QSystemTrayIcon::Trigger )
261 {
262 return;
263 }
264
265 QWidget *pw = d->window;
266 if ( !pw )
267 {
268 return;
269 }
270#ifdef Q_WS_WIN
271 // the problem is that we lose focus when the systray icon is activated
272 // and we don't know the former active window
273 // therefore we watch for activation event and use our stopwatch :)
274 if( GetTickCount() - d->dwTickCount < 300 ) {
275 // we were active in the last 300ms -> hide it
276 minimizeRestore( false );
277 } else {
278 minimizeRestore( true );
279 }
280#elif defined(Q_WS_X11)
281 KWindowInfo info1 = KWindowSystem::windowInfo( pw->winId(), NET::XAWMState | NET::WMState );
282 // mapped = visible (but possibly obscured)
283 bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
284// - not mapped -> show, raise, focus
285// - mapped
286// - obscured -> raise, focus
287// - not obscured -> hide
288 if( !mapped )
289 minimizeRestore( true );
290 else
291 {
292 QListIterator< WId > it (KWindowSystem::stackingOrder());
293 it.toBack();
294 while( it.hasPrevious() )
295 {
296 WId id = it.previous();
297 if( id == pw->winId() )
298 break;
299 KWindowInfo info2 = KWindowSystem::windowInfo( id,
300 NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
301 if( info2.mappingState() != NET::Visible )
302 continue; // not visible on current desktop -> ignore
303 if( !info2.geometry().intersects( pw->geometry()))
304 continue; // not obscuring the window -> ignore
305 if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
306 continue; // obscured by window kept above -> ignore
307 NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask
308 | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
309 | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
310 if( type == NET::Dock || type == NET::TopMenu )
311 continue; // obscured by dock or topmenu -> ignore
312 pw->raise();
313 KWindowSystem::activateWindow( pw->winId());
314 return;
315 }
316 minimizeRestore( false ); // hide
317 }
318#endif
319}
320
321void KSystemTrayIcon::minimizeRestore( bool restore )
322{
323 QWidget* pw = d->window;
324 if (!pw)
325 return;
326#ifdef Q_WS_X11
327 KWindowInfo info = KWindowSystem::windowInfo(pw->winId(), NET::WMGeometry | NET::WMDesktop);
328 if (restore) {
329 if (d->onAllDesktops) {
330 KWindowSystem::setOnAllDesktops(pw->winId(), true);
331 } else {
332 KWindowSystem::setCurrentDesktop(info.desktop());
333 }
334 pw->move(info.geometry().topLeft()); // avoid placement policies
335 pw->show();
336 pw->raise();
337 KWindowSystem::activateWindow(pw->winId());
338 } else {
339 d->onAllDesktops = info.onAllDesktops();
340 pw->hide();
341 }
342#else
343 if ( restore )
344 {
345 pw->show();
346 pw->raise();
347 KWindowSystem::forceActiveWindow( pw->winId() );
348 } else {
349 pw->hide();
350 }
351#endif
352}
353
354KActionCollection* KSystemTrayIcon::actionCollection()
355{
356 return d->actionCollection;
357}
358
359QIcon KSystemTrayIcon::loadIcon(const QString &icon, const KComponentData &componentData)
360{
361 KConfigGroup cg(componentData.config(), "System Tray");
362 const int iconWidth = cg.readEntry("systrayIconWidth", 22);
363 return KIconLoader::global()->loadIcon( icon, KIconLoader::Panel, iconWidth );
364}
365
366void KSystemTrayIcon::toggleActive()
367{
368 activateOrHide( QSystemTrayIcon::Trigger );
369}
370
371bool KSystemTrayIcon::parentWidgetTrayClose() const
372{
373 if( kapp != NULL && kapp->sessionSaving())
374 return false; // normal close
375 return true;
376}
377
378void KSystemTrayIcon::setContextMenuTitle(QAction *action)
379{
380 // can never be null, and is always the requsted type, so no need to do null checks after casts.
381 QToolButton *button = static_cast<QToolButton*>((static_cast<QWidgetAction*>(d->titleAction))->defaultWidget());
382 button->setDefaultAction(action);
383}
384
385QAction *KSystemTrayIcon::contextMenuTitle() const
386{
387 QToolButton *button = static_cast<QToolButton*>((static_cast<QWidgetAction*>(d->titleAction))->defaultWidget());
388 return button->defaultAction();
389}
390
391void KSystemTrayIcon::setMovie(QMovie* m)
392{
393 if (d->movie == m) {
394 return;
395 }
396 delete d->movie;
397 m->setParent(this);
398 d->movie = m;
399 connect(d->movie, SIGNAL(frameChanged(int)), this, SLOT(_k_slotNewFrame()));
400 d->movie->setCacheMode(QMovie::CacheAll);
401}
402
403const QMovie* KSystemTrayIcon::movie() const
404{
405 return d->movie;
406}
407
408#include "ksystemtrayicon.moc"
KActionCollection
A container for a set of QAction objects.
Definition: kactioncollection.h:57
KComponentData
KComponentData::config
const KSharedConfig::Ptr & config() const
KConfigGroup
KConfigGroup::readEntry
QString readEntry(const char *key, const char *aDefault=0) const
KIconLoader::Panel
@ Panel
Panel (Plasma Taskbar) icons.
Definition: kiconloader.h:141
KIconLoader::global
static KIconLoader * global()
Returns the global icon loader initialized with the global KComponentData.
KIconLoader::loadIcon
QPixmap loadIcon(const QString &name, KIconLoader::Group group, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList(), QString *path_store=0L, bool canReturnNull=false) const
Loads an icon.
Definition: kiconloader.cpp:1100
KMenu
A menu with keyboard searching.
Definition: kmenu.h:42
KMessageBox::warningContinueCancel
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
Display a "warning" dialog.
Definition: kmessagebox.cpp:644
KMessageBox::Continue
@ Continue
Definition: kmessagebox.h:74
KSystemTrayIcon
KDE System Tray Window class
Definition: ksystemtrayicon.h:61
KSystemTrayIcon::~KSystemTrayIcon
~KSystemTrayIcon()
Destructor.
Definition: ksystemtrayicon.cpp:180
KSystemTrayIcon::movie
const QMovie * movie() const
Get a pointer to the movie.
Definition: ksystemtrayicon.cpp:403
KSystemTrayIcon::setContextMenuTitle
void setContextMenuTitle(QAction *action)
Sets the context menu title action to action.
Definition: ksystemtrayicon.cpp:378
KSystemTrayIcon::toggleActive
void toggleActive()
Definition: ksystemtrayicon.cpp:366
KSystemTrayIcon::KSystemTrayIcon
KSystemTrayIcon(QWidget *parent=0)
Construct a system tray icon.
Definition: ksystemtrayicon.cpp:111
KSystemTrayIcon::parentWidget
QWidget * parentWidget() const
Returns the QWidget set by the constructor.
Definition: ksystemtrayicon.cpp:175
KSystemTrayIcon::setMovie
void setMovie(QMovie *movie)
Set the movie to use.
Definition: ksystemtrayicon.cpp:391
KSystemTrayIcon::contextMenuTitle
QAction * contextMenuTitle() const
Returns the context menu title action.
Definition: ksystemtrayicon.cpp:385
KSystemTrayIcon::parentWidgetTrayClose
bool parentWidgetTrayClose() const
Function to be used from function handling closing of the window associated with the tray icon (i....
Definition: ksystemtrayicon.cpp:371
KSystemTrayIcon::quitSelected
void quitSelected()
Emitted when quit is selected in the menu.
KSystemTrayIcon::loadIcon
static QIcon loadIcon(const QString &icon, const KComponentData &componentData=KGlobal::mainComponent())
Loads an icon icon using the icon loader class of the given componentData componentData.
Definition: ksystemtrayicon.cpp:359
KSystemTrayIcon::actionCollection
KActionCollection * actionCollection()
Easy access to the actions in the context menu Currently includes KStandardAction::Quit and minimizeR...
Definition: ksystemtrayicon.cpp:354
KWindowInfo
Information about a window.
Definition: kwindowinfo.h:36
KWindowInfo::windowType
NET::WindowType windowType(int supported_types) const
Returns the window type of this window (see NET::WindowType).
Definition: kwindowinfo_mac.cpp:210
KWindowInfo::isMinimized
bool isMinimized() const
Returns true if the window is minimized.
Definition: kwindowinfo_mac.cpp:185
KWindowInfo::hasState
bool hasState(unsigned long s) const
Returns true if the window has the given state flag set (see the NET::State enum for details).
Definition: kwindowinfo_mac.cpp:180
KWindowInfo::onAllDesktops
bool onAllDesktops() const
Returns true if the window is on all desktops (equal to desktop()==NET::OnAllDesktops).
Definition: kwindowinfo_mac.cpp:268
KWindowInfo::geometry
QRect geometry() const
Returns the position and size of the window contents.
Definition: kwindowinfo_mac.cpp:278
KWindowInfo::desktop
int desktop() const
Returns the virtual desktop this window is on (NET::OnAllDesktops if the window is on all desktops).
Definition: kwindowinfo_mac.cpp:273
KWindowInfo::mappingState
NET::MappingState mappingState() const
Returns the mapping state of the window (see NET::MappingState).
Definition: kwindowinfo_mac.cpp:199
KWindowSystem::setOnAllDesktops
static void setOnAllDesktops(WId win, bool b)
Sets window win to be present on all virtual desktops if is true.
Definition: kwindowsystem_mac.cpp:400
KWindowSystem::stackingOrder
static QList< WId > stackingOrder()
Returns the list of all toplevel windows currently managed by the window manager in the current stack...
Definition: kwindowsystem_mac.cpp:340
KWindowSystem::activateWindow
static void activateWindow(WId win, long time=0)
Requests that window win is activated.
Definition: kwindowsystem_mac.cpp:355
KWindowSystem::windowInfo
static KWindowInfo windowInfo(WId win, unsigned long properties, unsigned long properties2=0)
Returns information about window win.
Definition: kwindowsystem_mac.cpp:330
KWindowSystem::setCurrentDesktop
static void setCurrentDesktop(int desktop)
Convenience function to set the current desktop to desktop.
Definition: kwindowsystem_mac.cpp:394
KWindowSystem::forceActiveWindow
static void forceActiveWindow(WId win, long time=0)
Sets window win to be the active window.
Definition: kwindowsystem_mac.cpp:366
NET::KeepAbove
@ KeepAbove
indicates that a window should on top of most windows (but below fullscreen windows).
Definition: netwm_def.h:462
NET::DialogMask
@ DialogMask
Definition: netwm_def.h:390
NET::MenuMask
@ MenuMask
Definition: netwm_def.h:389
NET::SplashMask
@ SplashMask
Definition: netwm_def.h:394
NET::UtilityMask
@ UtilityMask
Definition: netwm_def.h:393
NET::OverrideMask
@ OverrideMask
Definition: netwm_def.h:391
NET::ToolbarMask
@ ToolbarMask
Definition: netwm_def.h:388
NET::DockMask
@ DockMask
Definition: netwm_def.h:387
NET::NormalMask
@ NormalMask
Definition: netwm_def.h:385
NET::DesktopMask
@ DesktopMask
Definition: netwm_def.h:386
NET::TopMenuMask
@ TopMenuMask
Definition: netwm_def.h:392
NET::WindowType
WindowType
Window type.
Definition: netwm_def.h:305
NET::TopMenu
@ TopMenu
indicates a toplevel menu (AKA macmenu).
Definition: netwm_def.h:345
NET::Dock
@ Dock
indicates a dock or panel feature
Definition: netwm_def.h:324
NET::WMWindowType
@ WMWindowType
Definition: netwm_def.h:634
NET::XAWMState
@ XAWMState
Definition: netwm_def.h:642
NET::WMGeometry
@ WMGeometry
Definition: netwm_def.h:648
NET::WMState
@ WMState
Definition: netwm_def.h:635
NET::WMDesktop
@ WMDesktop
Definition: netwm_def.h:633
NET::Visible
@ Visible
indicates the client window is visible to the user.
Definition: netwm_def.h:537
QAction
QObject
QSystemTrayIcon
QToolButton
QWidgetAction
QWidget
kaboutdata.h
kaction.h
kactioncollection.h
kapplication.h
kapp
#define kapp
Definition: kapplication.h:56
kcomponentdata.h
kconfiggroup.h
kiconloader.h
klocale.h
i18n
QString i18n(const char *text)
kmenu.h
kmessagebox.h
kshortcut.h
Defines platform-independent classes for keyboard shortcut handling.
kstandardaction.h
ksystemtrayicon.h
kwindowsystem.h
KGlobal::mainComponent
const KComponentData & mainComponent()
KGlobal::deref
void deref()
KGlobal::ref
void ref()
KGlobal::caption
QString caption()
KStandardAction::quit
KAction * quit(const QObject *recvr, const char *slot, QObject *parent)
Quit the program.
Definition: kstandardaction.cpp:279
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
KStandardAction::Quit
@ Quit
Definition: kstandardaction.h:130
KStandardGuiItem::cancel
KGuiItem cancel()
Returns the 'Cancel' gui item.
Definition: kstandardguiitem.cpp:113
KStandardGuiItem::quit
KGuiItem quit()
Returns the 'Quit' gui item.
Definition: kstandardguiitem.cpp:252
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal