1 /***************************************************************************
2 * Copyright (C) 2005-2018 by the Quassel Project *
3 * devel@quassel-irc.org *
5 * This contains code from KStatusNotifierItem, part of the KDE libs *
6 * Copyright (C) 2009 Marco Martin <notmart@gmail.com> *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) version 3. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22 ***************************************************************************/
24 #include "graphicalui.h"
26 #include "actioncollection.h"
27 #include "uisettings.h"
28 #include "contextmenuactionprovider.h"
29 #include "toolbaractionprovider.h"
35 QWidget *GraphicalUi::_mainWidget = 0;
36 QHash<QString, ActionCollection *> GraphicalUi::_actionCollections;
37 ContextMenuActionProvider *GraphicalUi::_contextMenuActionProvider = 0;
38 ToolBarActionProvider *GraphicalUi::_toolBarActionProvider = 0;
39 UiStyle *GraphicalUi::_uiStyle = 0;
42 GraphicalUi::GraphicalUi(QObject *parent) : AbstractUi(parent), Singleton<GraphicalUi>(this)
48 GetFrontProcess(&_procNum);
53 void GraphicalUi::init()
56 mainWidget()->installEventFilter(this);
61 ActionCollection *GraphicalUi::actionCollection(const QString &category, const QString &translatedCategory)
63 if (_actionCollections.contains(category))
64 return _actionCollections.value(category);
65 ActionCollection *coll = new ActionCollection(_mainWidget);
67 if (!translatedCategory.isEmpty())
68 coll->setProperty("Category", translatedCategory);
70 coll->setProperty("Category", category);
73 coll->addAssociatedWidget(_mainWidget);
74 _actionCollections.insert(category, coll);
79 QHash<QString, ActionCollection *> GraphicalUi::actionCollections()
81 return _actionCollections;
85 void GraphicalUi::loadShortcuts()
87 foreach(ActionCollection *coll, actionCollections())
92 void GraphicalUi::saveShortcuts()
96 foreach(ActionCollection *coll, actionCollections())
97 coll->writeSettings();
101 void GraphicalUi::setMainWidget(QWidget *widget)
103 _mainWidget = widget;
107 void GraphicalUi::setContextMenuActionProvider(ContextMenuActionProvider *provider)
109 _contextMenuActionProvider = provider;
113 void GraphicalUi::setToolBarActionProvider(ToolBarActionProvider *provider)
115 _toolBarActionProvider = provider;
119 void GraphicalUi::setUiStyle(UiStyle *style)
125 void GraphicalUi::disconnectedFromCore()
127 _contextMenuActionProvider->disconnectedFromCore();
128 _toolBarActionProvider->disconnectedFromCore();
129 AbstractUi::disconnectedFromCore();
133 bool GraphicalUi::eventFilter(QObject *obj, QEvent *event)
136 if (obj == mainWidget() && event->type() == QEvent::ActivationChange) {
137 _dwTickCount = GetTickCount();
140 return AbstractUi::eventFilter(obj, event);
144 // NOTE: Window activation stuff seems to work just fine in Plasma 5 without requiring X11 hacks.
145 // TODO: Evaluate cleaning all this up once we can get rid of Qt4/KDE4
147 // Code taken from KStatusNotifierItem for handling minimize/restore
149 bool GraphicalUi::checkMainWidgetVisibility(bool perform)
152 // the problem is that we lose focus when the systray icon is activated
153 // and we don't know the former active window
154 // therefore we watch for activation event and use our stopwatch :)
155 if (GetTickCount() - _dwTickCount < 300) {
156 // we were active in the last 300ms -> hide it
158 minimizeRestore(false);
163 minimizeRestore(true);
169 if (!mainWidget()->isVisible() || mainWidget()->isMinimized() || !mainWidget()->isActiveWindow()) {
171 minimizeRestore(true);
176 minimizeRestore(false);
186 bool GraphicalUi::isMainWidgetVisible()
188 return !instance()->checkMainWidgetVisibility(false);
192 void GraphicalUi::minimizeRestore(bool show)
195 activateMainWidget();
201 void GraphicalUi::activateMainWidget()
204 // Bypass focus stealing prevention
205 QX11Info::setAppUserTime(QX11Info::appTime());
208 if (mainWidget()->windowState() & Qt::WindowMinimized) {
210 mainWidget()->setWindowState((mainWidget()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
213 // this does not actually work on all platforms... and causes more evil than good
214 // mainWidget()->move(mainWidget()->frameGeometry().topLeft()); // avoid placement policies
216 SetFrontProcess(&instance()->_procNum);
218 mainWidget()->show();
219 mainWidget()->raise();
220 mainWidget()->activateWindow();
225 void GraphicalUi::hideMainWidget()
227 if (instance()->isHidingMainWidgetAllowed())
229 ShowHideProcess(&instance()->_procNum, false);
231 mainWidget()->hide();
236 void GraphicalUi::toggleMainWidget()
238 instance()->checkMainWidgetVisibility(true);