X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fuisupport%2Fgraphicalui.cpp;h=33b0d87b9f9d35df8abd98d1479e4a0453b3bc6d;hp=abd8cd173d343f50eb4566a11e9b582ecba92eb3;hb=219d124b5000b39d90482f575b6ceb838c037ebc;hpb=ab16c77fe03b73a863d9b52b11919bcbac903f58 diff --git a/src/uisupport/graphicalui.cpp b/src/uisupport/graphicalui.cpp index abd8cd17..33b0d87b 100644 --- a/src/uisupport/graphicalui.cpp +++ b/src/uisupport/graphicalui.cpp @@ -1,7 +1,10 @@ /*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * + * Copyright (C) 2005-2018 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 * @@ -15,42 +18,201 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "graphicalui.h" #include "actioncollection.h" #include "contextmenuactionprovider.h" +#include "toolbaractionprovider.h" +#include "uisettings.h" + +#ifdef Q_WS_X11 +# include +#endif + +QWidget* GraphicalUi::_mainWidget = nullptr; +QHash GraphicalUi::_actionCollections; +ContextMenuActionProvider* GraphicalUi::_contextMenuActionProvider = nullptr; +ToolBarActionProvider* GraphicalUi::_toolBarActionProvider = nullptr; +UiStyle* GraphicalUi::_uiStyle = nullptr; + +GraphicalUi::GraphicalUi(QObject* parent) + : AbstractUi(parent) + , Singleton(this) +{ + Q_INIT_RESOURCE(pics); + Q_INIT_RESOURCE(hicolor_icons); +#ifdef EMBED_DATA + Q_INIT_RESOURCE(icons); + Q_INIT_RESOURCE(iconthemes); +#endif + +#ifdef Q_OS_WIN + _dwTickCount = 0; +#endif +#ifdef Q_OS_MAC + GetFrontProcess(&_procNum); +#endif +} -QWidget *GraphicalUi::_mainWidget = 0; -QHash GraphicalUi::_actionCollections; -ContextMenuActionProvider *GraphicalUi::_contextMenuActionProvider = 0; -ToolBarActionProvider *GraphicalUi::_toolBarActionProvider = 0; +void GraphicalUi::init() +{ +#ifdef Q_OS_WIN + mainWidget()->installEventFilter(this); +#endif +} -GraphicalUi::GraphicalUi(QObject *parent) : AbstractUi(parent) +ActionCollection* GraphicalUi::actionCollection(const QString& category, const QString& translatedCategory) { + if (_actionCollections.contains(category)) + return _actionCollections.value(category); + auto* coll = new ActionCollection(_mainWidget); + if (!translatedCategory.isEmpty()) + coll->setProperty("Category", translatedCategory); + else + coll->setProperty("Category", category); + + if (_mainWidget) + coll->addAssociatedWidget(_mainWidget); + _actionCollections.insert(category, coll); + return coll; } -ActionCollection *GraphicalUi::actionCollection(const QString &category) { - if(_actionCollections.contains(category)) - return _actionCollections.value(category); - ActionCollection *coll = new ActionCollection(_mainWidget); - if(_mainWidget) - coll->addAssociatedWidget(_mainWidget); - _actionCollections.insert(category, coll); - return coll; +QHash GraphicalUi::actionCollections() +{ + return _actionCollections; } -void GraphicalUi::setMainWidget(QWidget *widget) { - _mainWidget = widget; +void GraphicalUi::loadShortcuts() +{ + foreach (ActionCollection* coll, actionCollections()) + coll->readSettings(); } -void GraphicalUi::setContextMenuActionProvider(ContextMenuActionProvider *provider) { - _contextMenuActionProvider = provider; +void GraphicalUi::saveShortcuts() +{ + ShortcutSettings s; + s.clear(); + foreach (ActionCollection* coll, actionCollections()) + coll->writeSettings(); } -void GraphicalUi::setToolBarActionProvider(ToolBarActionProvider *provider) { - _toolBarActionProvider = provider; +void GraphicalUi::setMainWidget(QWidget* widget) +{ + _mainWidget = widget; +} + +void GraphicalUi::setContextMenuActionProvider(ContextMenuActionProvider* provider) +{ + _contextMenuActionProvider = provider; +} + +void GraphicalUi::setToolBarActionProvider(ToolBarActionProvider* provider) +{ + _toolBarActionProvider = provider; +} + +void GraphicalUi::setUiStyle(UiStyle* style) +{ + _uiStyle = style; +} + +void GraphicalUi::disconnectedFromCore() +{ + _contextMenuActionProvider->disconnectedFromCore(); + _toolBarActionProvider->disconnectedFromCore(); + AbstractUi::disconnectedFromCore(); +} + +bool GraphicalUi::eventFilter(QObject* obj, QEvent* event) +{ +#ifdef Q_OS_WIN + if (obj == mainWidget() && event->type() == QEvent::ActivationChange) { + _dwTickCount = GetTickCount(); + } +#endif + return AbstractUi::eventFilter(obj, event); +} + +// NOTE: Window activation stuff seems to work just fine in Plasma 5 without requiring X11 hacks. +// TODO: Evaluate cleaning all this up once we can get rid of Qt4/KDE4 + +// Code taken from KStatusNotifierItem for handling minimize/restore + +bool GraphicalUi::checkMainWidgetVisibility(bool perform) +{ + bool needsActivation{true}; + +#ifdef Q_OS_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 + needsActivation = false; + } +#else + if (mainWidget()->isVisible() && !mainWidget()->isMinimized() && mainWidget()->isActiveWindow()) { + needsActivation = false; + } +#endif + + if (perform) { + minimizeRestore(needsActivation); + } + return needsActivation; +} + +bool GraphicalUi::isMainWidgetVisible() +{ + return !instance()->checkMainWidgetVisibility(false); +} + +void GraphicalUi::minimizeRestore(bool show) +{ + if (show) + activateMainWidget(); + else + hideMainWidget(); +} + +void GraphicalUi::activateMainWidget() +{ +#ifdef Q_WS_X11 + // Bypass focus stealing prevention + QX11Info::setAppUserTime(QX11Info::appTime()); +#endif + + if (mainWidget()->windowState() & Qt::WindowMinimized) { + // restore + mainWidget()->setWindowState((mainWidget()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + } + + // this does not actually work on all platforms... and causes more evil than good + // mainWidget()->move(mainWidget()->frameGeometry().topLeft()); // avoid placement policies +#ifdef Q_OS_MAC + SetFrontProcess(&instance()->_procNum); +#else + mainWidget()->show(); + mainWidget()->raise(); + mainWidget()->activateWindow(); +#endif +} + +void GraphicalUi::hideMainWidget() +{ + if (instance()->isHidingMainWidgetAllowed()) +#ifdef Q_OS_MAC + ShowHideProcess(&instance()->_procNum, false); +#else + mainWidget()->hide(); +#endif +} + +void GraphicalUi::toggleMainWidget() +{ + instance()->checkMainWidgetVisibility(true); }