X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fsystemtray.cpp;h=afa7964f602b9c372fc399a5370903a009bc5684;hp=27aeb086c59bd44671c0204b045b1ad01d76fdcf;hb=5ba28fb36a747bd9a2c05a58f0533d1e38c2a0de;hpb=d452877910888c25d40590b5fff57eb8197ca9b0 diff --git a/src/qtui/systemtray.cpp b/src/qtui/systemtray.cpp index 27aeb086..afa7964f 100644 --- a/src/qtui/systemtray.cpp +++ b/src/qtui/systemtray.cpp @@ -2,9 +2,6 @@ * Copyright (C) 2005-2010 by the Quassel Project * * devel@quassel-irc.org * * * - * This contains code from KStatusNotifierItem, part of the KDE libs * - * Copyright (C) 2009 Marco Martin * - * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -20,16 +17,19 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include #include #include "systemtray.h" +#include "action.h" #include "actioncollection.h" #include "client.h" #include "iconloader.h" #include "qtui.h" #ifdef HAVE_KDE +# include # include # include #endif @@ -38,7 +38,6 @@ SystemTray::SystemTray(QWidget *parent) : QObject(parent), _mode(Invalid), _state(Passive), - _inhibitActivation(false), _passiveIcon(DesktopIcon("quassel_inactive")), _activeIcon(DesktopIcon("quassel")), _needsAttentionIcon(DesktopIcon("quassel_message")), @@ -46,20 +45,9 @@ SystemTray::SystemTray(QWidget *parent) _associatedWidget(parent) { Q_ASSERT(parent); - -#ifdef Q_WS_WIN - _dwTickCount = 0; - associatedWidget()->installEventFilter(this); -#endif - - qApp->installEventFilter(this); } SystemTray::~SystemTray() { -#ifdef Q_WS_WIN - associatedWidget()->removeEventFilter(this); -#endif - _trayMenu->deleteLater(); } @@ -67,31 +55,53 @@ QWidget *SystemTray::associatedWidget() const { return _associatedWidget; } -void SystemTray::setTrayMenu(QMenu *menu) { - if(menu) - _trayMenu = menu; - else - _trayMenu = new QMenu(); - +void SystemTray::init() { ActionCollection *coll = QtUi::actionCollection("General"); + _minimizeRestoreAction = new Action(tr("&Minimize"), this, this, SLOT(minimizeRestore())); + +#ifdef HAVE_KDE + KMenu *kmenu; + _trayMenu = kmenu = new KMenu(); + kmenu->addTitle(qApp->windowIcon(), "Quassel IRC"); +#else + _trayMenu = new QMenu(associatedWidget()); +#endif + + _trayMenu->setTitle("Quassel IRC"); + +#ifndef HAVE_KDE + _trayMenu->setAttribute(Qt::WA_Hover); +#endif _trayMenu->addAction(coll->action("ConnectCore")); _trayMenu->addAction(coll->action("DisconnectCore")); _trayMenu->addAction(coll->action("CoreInfo")); -#ifndef HAVE_KDE _trayMenu->addSeparator(); + _trayMenu->addAction(_minimizeRestoreAction); _trayMenu->addAction(coll->action("Quit")); -#endif /* HAVE_KDE */ + + connect(_trayMenu, SIGNAL(aboutToShow()), SLOT(trayMenuAboutToShow())); +} + +void SystemTray::trayMenuAboutToShow() { + if(GraphicalUi::isMainWidgetVisible()) + _minimizeRestoreAction->setText(tr("&Minimize")); + else + _minimizeRestoreAction->setText(tr("&Restore")); } void SystemTray::setMode(Mode mode_) { if(mode_ != _mode) { _mode = mode_; - if(_mode == Legacy) { - _trayMenu->setWindowFlags(Qt::Popup); - } else { - _trayMenu->setWindowFlags(Qt::Window); +#ifdef HAVE_KDE + if(_trayMenu) { + if(_mode == Legacy) { + _trayMenu->setWindowFlags(Qt::Popup); + } else { + _trayMenu->setWindowFlags(Qt::Window); + } } +#endif } } @@ -134,140 +144,18 @@ void SystemTray::setToolTip(const QString &title, const QString &subtitle) { emit toolTipChanged(title, subtitle); } -void SystemTray::showMessage(const QString &title, const QString &message, MessageIcon icon, int millisecondsTimeoutHint) { +void SystemTray::showMessage(const QString &title, const QString &message, MessageIcon icon, int millisecondsTimeoutHint, uint id) { Q_UNUSED(title) Q_UNUSED(message) Q_UNUSED(icon) Q_UNUSED(millisecondsTimeoutHint) + Q_UNUSED(id) } void SystemTray::activate(SystemTray::ActivationReason reason) { - emit activated(reason); - - if(reason == Trigger && !isActivationInhibited()) { - toggleMainWidget(); - } -} - -bool SystemTray::eventFilter(QObject *obj, QEvent *event) { - if(event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease) { - _inhibitActivation = false; - } -#ifdef Q_WS_WIN - if(obj == associatedWidget() && event->type() == QEvent::ActivationChange) { - _dwTickCount = GetTickCount(); - } -#endif - return QObject::eventFilter(obj, event); -} - -// Code taken from KStatusNotifierItem for handling minimize/restore - -bool SystemTray::checkVisibility(bool perform) { -#ifdef Q_WS_WIN - // the problem is that we lose focus when the systray icon is activated - // and we don't know the former active window - // therefore we watch for activation event and use our stopwatch :) - if(GetTickCount() - _dwTickCount < 300) { - // we were active in the last 300ms -> hide it - minimizeRestore(false); - } else { - minimizeRestore(true); - } - -#elif defined(HAVE_KDE) && defined(Q_WS_X11) - KWindowInfo info1 = KWindowSystem::windowInfo(associatedWidget()->winId(), NET::XAWMState | NET::WMState | NET::WMDesktop); - // 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 - //info1.mappingState() != NET::Visible -> window on another desktop? - if(!mapped) { - if(perform) - minimizeRestore(true); - return true; - - } else { - QListIterator< WId > it (KWindowSystem::stackingOrder()); - it.toBack(); - while(it.hasPrevious()) { - WId id = it.previous(); - if(id == associatedWidget()->winId()) - break; - - KWindowInfo info2 = KWindowSystem::windowInfo(id, NET::WMDesktop | NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType); - - if(info2.mappingState() != NET::Visible) - continue; // not visible on current desktop -> ignore - - if(!info2.geometry().intersects(associatedWidget()->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 - - if(perform) { - KWindowSystem::raiseWindow(associatedWidget()->winId()); - KWindowSystem::activateWindow(associatedWidget()->winId()); - } - return true; - } - - //not on current desktop? - if(!info1.isOnCurrentDesktop()) { - if(perform) - KWindowSystem::activateWindow(associatedWidget()->winId()); - return true; - } - - if(perform) - minimizeRestore(false); // hide - return false; - } -#else - - if(!associatedWidget()->isVisible() || associatedWidget()->isMinimized()) { - if(perform) - minimizeRestore(true); - return true; - } else { - if(perform) - minimizeRestore(false); - return false; - } - -#endif - - return true; -} - -void SystemTray::minimizeRestore(bool show) { - if(show) - GraphicalUi::activateMainWidget(); - else { - if(isSystemTrayAvailable()) { - if(!isVisible()) - setVisible(); - GraphicalUi::hideMainWidget(); - } - } -} - -void SystemTray::hideMainWidget() { - minimizeRestore(false); } -void SystemTray::toggleMainWidget() { - checkVisibility(true); +void SystemTray::minimizeRestore() { + GraphicalUi::toggleMainWidget(); }