qa: Simplify main window activation logic
[quassel.git] / src / uisupport / graphicalui.cpp
index fb4a2c7..33b0d87 100644 (file)
 #include "graphicalui.h"
 
 #include "actioncollection.h"
-#include "uisettings.h"
 #include "contextmenuactionprovider.h"
 #include "toolbaractionprovider.h"
+#include "uisettings.h"
 
 #ifdef Q_WS_X11
-#  include <QX11Info>
+#    include <QX11Info>
 #endif
-#ifdef HAVE_KDE4
-#  include <KWindowInfo>
-#  include <KWindowSystem>
-#endif
-
-QWidget *GraphicalUi::_mainWidget = 0;
-QHash<QString, ActionCollection *> GraphicalUi::_actionCollections;
-ContextMenuActionProvider *GraphicalUi::_contextMenuActionProvider = 0;
-ToolBarActionProvider *GraphicalUi::_toolBarActionProvider = 0;
-UiStyle *GraphicalUi::_uiStyle = 0;
-bool GraphicalUi::_onAllDesktops = false;
-
-namespace {
-
-GraphicalUi *_instance{nullptr};
-
-}
 
-
-GraphicalUi *GraphicalUi::instance() {
-    return _instance;
-}
-
-
-GraphicalUi::GraphicalUi(QObject *parent) : AbstractUi(parent)
-{
-    Q_ASSERT(!_instance);
-    _instance = this;
+QWidget* GraphicalUi::_mainWidget = nullptr;
+QHash<QString, ActionCollection*> GraphicalUi::_actionCollections;
+ContextMenuActionProvider* GraphicalUi::_contextMenuActionProvider = nullptr;
+ToolBarActionProvider* GraphicalUi::_toolBarActionProvider = nullptr;
+UiStyle* GraphicalUi::_uiStyle = nullptr;
+
+GraphicalUi::GraphicalUi(QObject* parent)
+    : AbstractUi(parent)
+    , Singleton<GraphicalUi>(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;
@@ -68,7 +57,6 @@ GraphicalUi::GraphicalUi(QObject *parent) : AbstractUi(parent)
 #endif
 }
 
-
 void GraphicalUi::init()
 {
 #ifdef Q_OS_WIN
@@ -76,12 +64,11 @@ void GraphicalUi::init()
 #endif
 }
 
-
-ActionCollection *GraphicalUi::actionCollection(const QString &category, const QString &translatedCategory)
+ActionCollection* GraphicalUi::actionCollection(const QString& category, const QString& translatedCategory)
 {
     if (_actionCollections.contains(category))
         return _actionCollections.value(category);
-    ActionCollection *coll = new ActionCollection(_mainWidget);
+    auto* coll = new ActionCollection(_mainWidget);
 
     if (!translatedCategory.isEmpty())
         coll->setProperty("Category", translatedCategory);
@@ -94,53 +81,45 @@ ActionCollection *GraphicalUi::actionCollection(const QString &category, const Q
     return coll;
 }
 
-
-QHash<QString, ActionCollection *> GraphicalUi::actionCollections()
+QHash<QString, ActionCollection*> GraphicalUi::actionCollections()
 {
     return _actionCollections;
 }
 
-
 void GraphicalUi::loadShortcuts()
 {
-    foreach(ActionCollection *coll, actionCollections())
-    coll->readSettings();
+    foreach (ActionCollection* coll, actionCollections())
+        coll->readSettings();
 }
 
-
 void GraphicalUi::saveShortcuts()
 {
     ShortcutSettings s;
     s.clear();
-    foreach(ActionCollection *coll, actionCollections())
-    coll->writeSettings();
+    foreach (ActionCollection* coll, actionCollections())
+        coll->writeSettings();
 }
 
-
-void GraphicalUi::setMainWidget(QWidget *widget)
+void GraphicalUi::setMainWidget(QWidget* widget)
 {
     _mainWidget = widget;
 }
 
-
-void GraphicalUi::setContextMenuActionProvider(ContextMenuActionProvider *provider)
+void GraphicalUi::setContextMenuActionProvider(ContextMenuActionProvider* provider)
 {
     _contextMenuActionProvider = provider;
 }
 
-
-void GraphicalUi::setToolBarActionProvider(ToolBarActionProvider *provider)
+void GraphicalUi::setToolBarActionProvider(ToolBarActionProvider* provider)
 {
     _toolBarActionProvider = provider;
 }
 
-
-void GraphicalUi::setUiStyle(UiStyle *style)
+void GraphicalUi::setUiStyle(UiStyle* style)
 {
     _uiStyle = style;
 }
 
-
 void GraphicalUi::disconnectedFromCore()
 {
     _contextMenuActionProvider->disconnectedFromCore();
@@ -148,8 +127,7 @@ void GraphicalUi::disconnectedFromCore()
     AbstractUi::disconnectedFromCore();
 }
 
-
-bool GraphicalUi::eventFilter(QObject *obj, QEvent *event)
+bool GraphicalUi::eventFilter(QObject* obj, QEvent* event)
 {
 #ifdef Q_OS_WIN
     if (obj == mainWidget() && event->type() == QEvent::ActivationChange) {
@@ -159,7 +137,6 @@ bool GraphicalUi::eventFilter(QObject *obj, QEvent *event)
     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
 
@@ -167,106 +144,33 @@ bool GraphicalUi::eventFilter(QObject *obj, QEvent *event)
 
 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
-        if (perform)
-            minimizeRestore(false);
-        return false;
-    }
-    else {
-        if (perform)
-            minimizeRestore(true);
-        return true;
-    }
-
-#elif defined(HAVE_KDE4) && defined(Q_WS_X11)
-    KWindowInfo info1 = KWindowSystem::windowInfo(mainWidget()->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 == mainWidget()->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(mainWidget()->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(mainWidget()->winId());
-                KWindowSystem::activateWindow(mainWidget()->winId());
-            }
-            return true;
-        }
-
-        //not on current desktop?
-        if (!info1.isOnCurrentDesktop()) {
-            if (perform)
-                KWindowSystem::activateWindow(mainWidget()->winId());
-            return true;
-        }
-
-        if (perform)
-            minimizeRestore(false);  // hide
-        return false;
+        needsActivation = false;
     }
 #else
-
-    if (!mainWidget()->isVisible() || mainWidget()->isMinimized() || !mainWidget()->isActiveWindow()) {
-        if (perform)
-            minimizeRestore(true);
-        return true;
-    }
-    else {
-        if (perform)
-            minimizeRestore(false);
-        return false;
+    if (mainWidget()->isVisible() && !mainWidget()->isMinimized() && mainWidget()->isActiveWindow()) {
+        needsActivation = false;
     }
-
 #endif
 
-    return true;
+    if (perform) {
+        minimizeRestore(needsActivation);
+    }
+    return needsActivation;
 }
 
-
 bool GraphicalUi::isMainWidgetVisible()
 {
     return !instance()->checkMainWidgetVisibility(false);
 }
 
-
 void GraphicalUi::minimizeRestore(bool show)
 {
     if (show)
@@ -275,32 +179,8 @@ void GraphicalUi::minimizeRestore(bool show)
         hideMainWidget();
 }
 
-
 void GraphicalUi::activateMainWidget()
 {
-#ifdef HAVE_KDE4
-#  ifdef Q_WS_X11
-    KWindowInfo info = KWindowSystem::windowInfo(mainWidget()->winId(), NET::WMDesktop | NET::WMFrameExtents);
-    if (_onAllDesktops) {
-        KWindowSystem::setOnAllDesktops(mainWidget()->winId(), true);
-    }
-    else {
-        KWindowSystem::setCurrentDesktop(info.desktop());
-    }
-
-    mainWidget()->move(info.frameGeometry().topLeft()); // avoid placement policies
-    mainWidget()->show();
-    mainWidget()->raise();
-    KWindowSystem::raiseWindow(mainWidget()->winId());
-    KWindowSystem::activateWindow(mainWidget()->winId());
-#  else
-    mainWidget()->show();
-    KWindowSystem::raiseWindow(mainWidget()->winId());
-    KWindowSystem::forceActiveWindow(mainWidget()->winId());
-#  endif
-
-#else /* HAVE_KDE4 */
-
 #ifdef Q_WS_X11
     // Bypass focus stealing prevention
     QX11Info::setAppUserTime(QX11Info::appTime());
@@ -320,18 +200,10 @@ void GraphicalUi::activateMainWidget()
     mainWidget()->raise();
     mainWidget()->activateWindow();
 #endif
-
-#endif /* HAVE_KDE4 */
 }
 
-
 void GraphicalUi::hideMainWidget()
 {
-#if defined(HAVE_KDE4) && defined(Q_WS_X11)
-    KWindowInfo info = KWindowSystem::windowInfo(mainWidget()->winId(), NET::WMDesktop | NET::WMFrameExtents);
-    _onAllDesktops = info.onAllDesktops();
-#endif
-
     if (instance()->isHidingMainWidgetAllowed())
 #ifdef Q_OS_MAC
         ShowHideProcess(&instance()->_procNum, false);
@@ -340,7 +212,6 @@ void GraphicalUi::hideMainWidget()
 #endif
 }
 
-
 void GraphicalUi::toggleMainWidget()
 {
     instance()->checkMainWidgetVisibility(true);