From a4699e923079516d04572d8146c628a65e31b400 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Mon, 2 Jan 2017 01:04:10 -0500 Subject: [PATCH] Fixed initialization #17 and improved all modes #19 --- app/abstractwindowinterface.h | 11 ++-- app/visibilitymanager.cpp | 120 ++++++++++++++++++++++++---------- app/visibilitymanager_p.h | 2 +- app/windowinfowrap.cpp | 20 +++--- app/windowinfowrap.h | 8 +-- app/xwindowinterface.cpp | 97 +++++++++++++++++---------- app/xwindowinterface.h | 16 +++-- liblattedock/dock.h | 1 + 8 files changed, 182 insertions(+), 93 deletions(-) diff --git a/app/abstractwindowinterface.h b/app/abstractwindowinterface.h index 247b0171e..6f67db8df 100644 --- a/app/abstractwindowinterface.h +++ b/app/abstractwindowinterface.h @@ -28,12 +28,13 @@ public: virtual void setDockDefaultFlags() = 0; virtual WId activeWindow() const = 0; - virtual WindowInfoWrap requestInfo(WId wid) = 0; - virtual WindowInfoWrap requestInfoActive() = 0; - virtual const std::list &windows() = 0; + virtual WindowInfoWrap requestInfo(WId wid) const = 0; + virtual WindowInfoWrap requestInfoActive() const = 0; + virtual bool isOnCurrentDesktop(WId wid) const = 0; + virtual const std::list &windows() const = 0; - virtual void setDockStruts(const QRect &dockRect, Plasma::Types::Location location) = 0; - virtual void removeDockStruts() = 0; + virtual void setDockStruts(const QRect &dockRect, Plasma::Types::Location location) const = 0; + virtual void removeDockStruts() const = 0; static AbstractWindowInterface *getInstance(QQuickWindow *const view, QObject *parent = nullptr); diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 5312b5226..6e98464e0 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -4,6 +4,7 @@ #include "dockview.h" #include "../liblattedock/extras.h" +#include namespace Latte { @@ -23,13 +24,23 @@ VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView timerShow.setSingleShot(true); timerHide.setSingleShot(true); - restoreConfig(); - connect(&timerCheckWindows, &QTimer::timeout, this, &VisibilityManagerPrivate::checkAllWindows); - connect(&timerShow, &QTimer::timeout, q, &VisibilityManager::mustBeShown); - connect(&timerHide, &QTimer::timeout, q, &VisibilityManager::mustBeHide); + connect(&timerShow, &QTimer::timeout, this, [this]() { + if (isHidden) { + qDebug() << "must be shown"; + emit this->q->mustBeShown(); + } + }); + connect(&timerHide, &QTimer::timeout, this, [this]() { + if (!isHidden) { + qDebug() << "must be hide"; + emit this->q->mustBeHide(); + } + }); wm->setDockDefaultFlags(); + + restoreConfig(); } VisibilityManagerPrivate::~VisibilityManagerPrivate() @@ -42,6 +53,8 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) if (this->mode == mode) return; + qDebug() << "restore config" << mode; + // clear mode if (this->mode == Dock::AlwaysVisible) wm->removeDockStruts(); @@ -64,7 +77,7 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) break; case Dock::AutoHide: { - raiseDock(!containsMouse); + raiseDock(containsMouse); } break; @@ -73,14 +86,26 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) , this, &VisibilityManagerPrivate::dodgeActive); connections[1] = connect(wm.get(), &AbstractWindowInterface::windowChanged , this, &VisibilityManagerPrivate::dodgeActive); - + connections[2] = connect(wm.get(), &AbstractWindowInterface::currentDesktopChanged + , this, [&](int) { + dodgeActive(wm->activeWindow()); + }); + dodgeActive(wm->activeWindow()); } break; case Dock::DodgeMaximized: { - connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged + connections[0] = connect(wm.get(), &AbstractWindowInterface::activeWindowChanged + , this, &VisibilityManagerPrivate::dodgeMaximized); + connections[1] = connect(wm.get(), &AbstractWindowInterface::windowChanged , this, &VisibilityManagerPrivate::dodgeMaximized); + connections[2] = connect(wm.get(), &AbstractWindowInterface::currentDesktopChanged + , this, [&](int) { + dodgeMaximized(wm->activeWindow()); + }); + + dodgeMaximized(wm->activeWindow()); } break; @@ -102,6 +127,12 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) windows.insert({wid, wm->requestInfo(wid)}); timerCheckWindows.start(); }); + connections[3] = connect(wm.get(), &AbstractWindowInterface::currentDesktopChanged + , this, [&](int) { + timerCheckWindows.start(); + }); + + timerCheckWindows.start(); } } @@ -135,11 +166,6 @@ inline void VisibilityManagerPrivate::setTimerHide(int msec) inline void VisibilityManagerPrivate::raiseDock(bool raise) { - // possible optimization - /* if (!isHidden == raise) { - return; - } */ - if (raise) { timerHide.stop(); @@ -149,7 +175,7 @@ inline void VisibilityManagerPrivate::raiseDock(bool raise) } else { timerShow.stop(); - if (!timerHide.isActive() && view->containment()->immutability() != Plasma::Types::Mutable) + if (!timerHide.isActive()) timerHide.start(); } } @@ -168,35 +194,47 @@ inline void VisibilityManagerPrivate::setDockRect(const QRect &dockRect) void VisibilityManagerPrivate::dodgeActive(WId wid) { - if (wid != wm->activeWindow()) - return; - auto winfo = wm->requestInfo(wid); - if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) + if (!winfo.isValid()) return; - raiseDock(!intersects(winfo)); + if (!winfo.isActive()) { + if (winfo.isPlasmaDesktop()) + raiseDock(true); + + return; + } + + raiseDock(wm->isOnCurrentDesktop(wid) && !intersects(winfo)); } void VisibilityManagerPrivate::dodgeMaximized(WId wid) { - if (wid != wm->activeWindow()) - return; - auto winfo = wm->requestInfo(wid); - if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) + if (!winfo.isValid()) return; - raiseDock(!winfo.isMaximized()); + if (!winfo.isActive()) { + if (winfo.isPlasmaDesktop()) + raiseDock(true); + + return; + } + + raiseDock(wm->isOnCurrentDesktop(wid) && !winfo.isMaximized()); } void VisibilityManagerPrivate::dodgeWindows(WId wid) { + if (windows.find(wid) == std::end(windows)) + return; + auto winfo = wm->requestInfo(wid); + windows[wid] = winfo; - if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) + if (!winfo.isValid() || !wm->isOnCurrentDesktop(wid)) return; if (intersects(winfo)) @@ -211,16 +249,13 @@ void VisibilityManagerPrivate::checkAllWindows() for (const auto &winfo : windows) { //! std::pair - if (!std::get<1>(winfo).isValid() || !std::get<1>(winfo).isOnCurrentDesktop()) + if (!std::get<1>(winfo).isValid() || !wm->isOnCurrentDesktop(std::get<0>(winfo))) continue; if (std::get<1>(winfo).isFullscreen()) { raise = false; break; - } else if (std::get<1>(winfo).isMinimized()) { - continue; - } else if (intersects(std::get<1>(winfo))) { raise = false; break; @@ -232,7 +267,7 @@ void VisibilityManagerPrivate::checkAllWindows() inline bool VisibilityManagerPrivate::intersects(const WindowInfoWrap &winfo) { - return winfo.geometry().intersects(dockRect); + return !winfo.isMinimized() && winfo.geometry().intersects(dockRect); } inline void VisibilityManagerPrivate::saveConfig() @@ -256,7 +291,9 @@ inline void VisibilityManagerPrivate::restoreConfig() auto config = view->containment()->config(); - mode = static_cast(config.readEntry("visibility", static_cast(Dock::DodgeActive))); + auto mode = static_cast(config.readEntry("visibility", static_cast(Dock::DodgeActive))); + setMode(mode); + timerShow.setInterval(config.readEntry("timerShow", 0)); timerHide.setInterval(config.readEntry("timerHide", 0)); @@ -270,16 +307,31 @@ bool VisibilityManagerPrivate::event(QEvent *ev) containsMouse = true; emit q->containsMouseChanged(); - if (mode == Dock::AutoHide) + if (mode != Dock::AlwaysVisible) raiseDock(true); } else if (ev->type() == QEvent::Leave && containsMouse) { containsMouse = false; emit q->containsMouseChanged(); - if (mode == Dock::AutoHide) - raiseDock(false); - + switch (mode) { + case Dock::AutoHide: + raiseDock(false); + break; + + case Dock::DodgeActive: + dodgeActive(wm->activeWindow()); + break; + + case Dock::DodgeMaximized: + dodgeMaximized(wm->activeWindow()); + break; + + case Dock::DodgeAllWindows: + dodgeWindows(wm->activeWindow()); + break; + } + } else if (ev->type() == QEvent::Show) { wm->setDockDefaultFlags(); } diff --git a/app/visibilitymanager_p.h b/app/visibilitymanager_p.h index c42d8e11b..e7f00856e 100644 --- a/app/visibilitymanager_p.h +++ b/app/visibilitymanager_p.h @@ -53,7 +53,7 @@ public: VisibilityManager *q; PlasmaQuick::ContainmentView *view; std::unique_ptr wm; - Dock::Visibility mode{Dock::DodgeActive}; + Dock::Visibility mode{Dock::None}; std::array connections; std::unordered_map windows; QTimer timerShow; diff --git a/app/windowinfowrap.cpp b/app/windowinfowrap.cpp index d7fa43b88..3df47764a 100644 --- a/app/windowinfowrap.cpp +++ b/app/windowinfowrap.cpp @@ -8,7 +8,7 @@ WindowInfoWrap::WindowInfoWrap() , m_isMinimized(false) , m_isMaximized(false) , m_isFullscreen(false) - , m_isOnCurrentDesktop(false) + , m_isPlasmaDesktop(false) , m_wid(0) { @@ -26,7 +26,7 @@ WindowInfoWrap &WindowInfoWrap::operator=(const WindowInfoWrap &rhs) m_isMinimized = rhs.m_isMinimized; m_isMaximized = rhs.m_isMaximized; m_isFullscreen = rhs.m_isFullscreen; - m_isOnCurrentDesktop = rhs.m_isOnCurrentDesktop; + m_isPlasmaDesktop = rhs.m_isPlasmaDesktop; m_geometry = rhs.m_geometry; m_wid = rhs.m_wid; @@ -98,14 +98,14 @@ void WindowInfoWrap::setIsFullscreen(bool isFullscreen) m_isFullscreen = isFullscreen; } -bool WindowInfoWrap::isOnCurrentDesktop() const +bool WindowInfoWrap::isPlasmaDesktop() const { - return m_isOnCurrentDesktop; + return m_isPlasmaDesktop; } -void WindowInfoWrap::setIsOnCurrentDesktop(bool isOnCurrentDesktop) +void WindowInfoWrap::setIsPlasmaDesktop(bool isPlasmaDesktop) { - m_isOnCurrentDesktop = isOnCurrentDesktop; + m_isPlasmaDesktop = isPlasmaDesktop; } QRect WindowInfoWrap::geometry() const @@ -118,14 +118,14 @@ void WindowInfoWrap::setGeometry(const QRect &geometry) m_geometry = geometry; } -WId WindowInfoWrap::wid() const +void WindowInfoWrap::setWid(WId wid) { - return m_wid; + m_wid = wid; } -void WindowInfoWrap::setWid(WId wid) +WId WindowInfoWrap::wid() const { - m_wid = wid; + return m_wid; } } diff --git a/app/windowinfowrap.h b/app/windowinfowrap.h index e3a817b5b..c0fff19c9 100644 --- a/app/windowinfowrap.h +++ b/app/windowinfowrap.h @@ -34,8 +34,8 @@ public: bool isFullscreen() const; void setIsFullscreen(bool isFullscreen); - bool isOnCurrentDesktop() const; - void setIsOnCurrentDesktop(bool isOnCurrentDesktop); + bool isPlasmaDesktop() const; + void setIsPlasmaDesktop(bool isPlasmaDesktop); QRect geometry() const; void setGeometry(const QRect &geometry); @@ -49,9 +49,9 @@ private: bool m_isMinimized : 1; bool m_isMaximized : 1; bool m_isFullscreen : 1; - bool m_isOnCurrentDesktop : 1; + bool m_isPlasmaDesktop : 1; QRect m_geometry; - WId m_wid; + WId m_wid{0}; }; } diff --git a/app/xwindowinterface.cpp b/app/xwindowinterface.cpp index 0cd8d7b02..53ef1049d 100644 --- a/app/xwindowinterface.cpp +++ b/app/xwindowinterface.cpp @@ -23,21 +23,31 @@ XWindowInterface::XWindowInterface(QQuickWindow *const view, QObject *parent) (&KWindowSystem::windowChanged) , this, &XWindowInterface::windowChangedProxy); - connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [this](WId wid) { - if (std::find(m_windows.cbegin(), m_windows.cend(), wid) != m_windows.cend()) { - m_windows.push_back(wid); + auto addWindow = [&](WId wid) { + if (std::find(m_windows.cbegin(), m_windows.cend(), wid) == m_windows.cend()) { + if (isValidWindow(KWindowInfo(wid, NET::WMWindowType))) { + m_windows.push_back(wid); + emit windowAdded(wid); + } } - - emit windowAdded(wid); - }); + }; + + connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, addWindow); - connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [this](WId wid) { - m_windows.remove(wid); - emit windowRemoved(wid); + connect(KWindowSystem::self(), &KWindowSystem::windowRemoved, [this](WId wid) { + if (std::find(m_windows.cbegin(), m_windows.cend(), wid) != m_windows.end()) { + m_windows.remove(wid); + emit windowRemoved(wid); + } }); connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged , this, &AbstractWindowInterface::currentDesktopChanged); + + // fill windows list + foreach (const auto &wid, KWindowSystem::self()->windows()) { + addWindow(wid); + } } XWindowInterface::~XWindowInterface() @@ -68,12 +78,12 @@ WId XWindowInterface::activeWindow() const return KWindowSystem::self()->activeWindow(); } -const std::list &XWindowInterface::windows() +const std::list &XWindowInterface::windows() const { return m_windows; } -void XWindowInterface::setDockStruts(const QRect &dockRect, Plasma::Types::Location location) +void XWindowInterface::setDockStruts(const QRect &dockRect, Plasma::Types::Location location) const { NETExtendedStrut strut; @@ -116,48 +126,59 @@ void XWindowInterface::setDockStruts(const QRect &dockRect, Plasma::Types::Locat ); } -void XWindowInterface::removeDockStruts() +void XWindowInterface::removeDockStruts() const { KWindowSystem::setStrut(m_view->winId(), 0, 0, 0, 0); } - -WindowInfoWrap XWindowInterface::requestInfoActive() +WindowInfoWrap XWindowInterface::requestInfoActive() const { return requestInfo(KWindowSystem::activeWindow()); } -WindowInfoWrap XWindowInterface::requestInfo(WId wid) +bool XWindowInterface::isOnCurrentDesktop(WId wid) const +{ + KWindowInfo winfo(wid, NET::WMDesktop); + return winfo.valid() && winfo.isOnCurrentDesktop(); +} + +WindowInfoWrap XWindowInterface::requestInfo(WId wid) const { - const KWindowInfo winfo{wid, NET::WMDesktop | NET::WMFrameExtents | NET::WMWindowType | NET::WMGeometry | NET::WMState}; + const KWindowInfo winfo{wid, NET::WMFrameExtents | NET::WMWindowType | NET::WMGeometry | NET::WMState}; WindowInfoWrap winfoWrap; - if (!winfo.valid() || !isValidWindow(winfo)) + if (!winfo.valid()) { return winfoWrap; - winfoWrap.setIsValid(true); - winfoWrap.setWid(wid); - winfoWrap.setIsActive(KWindowSystem::activeWindow() == wid); - winfoWrap.setIsMinimized(winfo.hasState(NET::Hidden)); - winfoWrap.setIsMaximized(winfo.hasState(NET::Max)); - winfoWrap.setIsFullscreen(winfo.hasState(NET::FullScreen)); - winfoWrap.setIsOnCurrentDesktop(winfo.isOnCurrentDesktop()); - winfoWrap.setGeometry(winfo.geometry()); + } else if (isValidWindow(winfo)) { + winfoWrap.setIsValid(true); + winfoWrap.setWid(wid); + winfoWrap.setIsActive(KWindowSystem::activeWindow() == wid); + winfoWrap.setIsMinimized(winfo.hasState(NET::Hidden)); + winfoWrap.setIsMaximized(winfo.hasState(NET::Max)); + winfoWrap.setIsFullscreen(winfo.hasState(NET::FullScreen)); + winfoWrap.setGeometry(winfo.geometry()); + + } else if (m_desktopId == wid) { + winfoWrap.setIsValid(true); + winfoWrap.setIsPlasmaDesktop(true); + winfoWrap.setWid(wid); + } + return winfoWrap; } -bool XWindowInterface::isValidWindow(const KWindowInfo &winfo) + +bool XWindowInterface::isValidWindow(const KWindowInfo &winfo) const { - const auto winType = winfo.windowType(NET::DesktopMask | NET::DockMask + const auto winType = winfo.windowType(NET::DockMask | NET::MenuMask | NET::SplashMask | NET::NormalMask); - if (winType == -1 || (winType & NET::Desktop) || (winType & NET::Menu) - || (winType & NET::Dock) || (winType & NET::Splash)) { + if (winType == -1 || (winType & NET::Menu) || (winType & NET::Dock) || (winType & NET::Splash)) return false; - } - + return true; } @@ -168,9 +189,19 @@ void XWindowInterface::windowChangedProxy(WId wid, NET::Properties prop1, NET::P return; //! ignore when, eg: the user presses a key - if (prop1 == 0 && prop2 == NET::WM2UserTime) + const auto winType = KWindowInfo(wid, NET::WMWindowType).windowType(NET::DesktopMask); + + if (winType != -1 && (winType & NET::Desktop)) { + m_desktopId = wid; + emit windowChanged(wid); + qDebug() << "desktop changed" << wid; return; - + } + + if (prop1 == 0 && prop2 == NET::WM2UserTime) { + return; + } + if (prop1 && !(prop1 & NET::WMState || prop1 & NET::WMGeometry || prop1 & NET::ActiveWindow)) return; diff --git a/app/xwindowinterface.h b/app/xwindowinterface.h index 687b05119..518fbd8b8 100644 --- a/app/xwindowinterface.h +++ b/app/xwindowinterface.h @@ -20,16 +20,20 @@ public: void setDockDefaultFlags() override; WId activeWindow() const override; - WindowInfoWrap requestInfo(WId wid) override; - WindowInfoWrap requestInfoActive() override; - const std::list &windows() override; + WindowInfoWrap requestInfo(WId wid) const override; + WindowInfoWrap requestInfoActive() const override; + bool isOnCurrentDesktop(WId wid) const override; + const std::list &windows() const override; + + void setDockStruts(const QRect &dockRect, Plasma::Types::Location location) const override; + void removeDockStruts() const override; - void setDockStruts(const QRect &dockRect, Plasma::Types::Location location) override; - void removeDockStruts() override; private: - bool isValidWindow(const KWindowInfo &winfo); + bool isValidWindow(const KWindowInfo &winfo) const; void windowChangedProxy(WId wid, NET::Properties prop1, NET::Properties2 prop2); + + WId m_desktopId; }; } diff --git a/liblattedock/dock.h b/liblattedock/dock.h index 46fbc4549..5cfb6dd66 100644 --- a/liblattedock/dock.h +++ b/liblattedock/dock.h @@ -15,6 +15,7 @@ public: ~Dock() {} enum Visibility { + None = -1, AlwaysVisible = 0, AutoHide, DodgeActive,