From 880aa1decfa5fb7e792903c75a652380aa04263f Mon Sep 17 00:00:00 2001 From: audoban Date: Thu, 29 Dec 2016 00:40:35 -0500 Subject: [PATCH] added class visibilitymanagerprivate to implement visibility --- app/visibilitymanager.cpp | 462 ++++++++------------------------------ app/visibilitymanager_p.h | 64 ++++++ 2 files changed, 163 insertions(+), 363 deletions(-) create mode 100644 app/visibilitymanager_p.h diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 584640430..537e18211 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -1,450 +1,186 @@ #include "visibilitymanager.h" +#include "visibilitymanager_p.h" -#include "abstractinterface.h" -#include "xwindowinterface.h" -#include "plasmaquick/containmentview.h" - -#include "../liblattedock/dock.h" +namespace Latte { -#include +//! BEGIN: VisiblityManagerPrivate implementation +VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q) + : QObject(view), q(q) +{ -#include +} -VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) : - QObject(view), - m_disableHiding(false), - m_isAutoHidden(false), - m_isDockWindowType(true), - m_isHovered(false), - m_secondInitPass(false), - m_windowIsInAttention(false), - m_childrenLength(-1), - m_view(view) +VisibilityManagerPrivate::~VisibilityManagerPrivate() { - // m_windowSystem = new WindowSystem(this); - // connect(m_windowSystem, SIGNAL(compositingChanged()), this, SLOT(compositingChanged())); - - m_interface = new NowDock::XWindowInterface(m_view); - connect(m_interface, SIGNAL(windowInAttention(bool)), this, SLOT(setWindowInAttention(bool))); - connect(m_interface, SIGNAL(activeWindowChanged()), this, SLOT(activeWindowChanged())); - m_interface->setDockToAllDesktops(); - //fixes a bug in plasma-framework with wrong popups placement - m_interface->setDockNumber(2); - - // connect(this, SIGNAL(screenChanged(QScreen *)), this, SLOT(screenChanged(QScreen *))); - // setPanelScreen(screen()); - m_updateStateTimer.setSingleShot(true); - m_updateStateTimer.setInterval(900); - connect(&m_updateStateTimer, &QTimer::timeout, this, &VisibilityManager::updateState); - - m_initTimer.setSingleShot(true); - m_initTimer.setInterval(400); - connect(&m_initTimer, &QTimer::timeout, this, &VisibilityManager::initWindow); - - connect(this, SIGNAL(panelVisibilityChanged()), this, SLOT(updateVisibilityFlags())); - setPanelVisibility(Latte::Dock::DodgeActive); - // updateVisibilityFlags(); - - // connect(this, SIGNAL(locationChanged()), this, SLOT(updateWindowPosition())); - connect(this, SIGNAL(windowInAttentionChanged()), this, SLOT(updateState())); - - initialize(); } -VisibilityManager::~VisibilityManager() +void VisibilityManagerPrivate::setMode(Dock::Visibility mode) { + } -void VisibilityManager::setContainment(Plasma::Containment *containment) +void VisibilityManagerPrivate::setIsHidden(bool isHidden) { - if (containment == m_containment) { - return; - } - - m_containment = containment; - // setVisibility(mode); -} +} -Latte::Dock::Visibility VisibilityManager::panelVisibility() const +void VisibilityManagerPrivate::setTimerShow(int msec) { - return m_panelVisibility; + } -void VisibilityManager::setPanelVisibility(Latte::Dock::Visibility state) +void VisibilityManagerPrivate::setTimerHide(int msec) { - if (m_panelVisibility == state) { - return; - } - - m_panelVisibility = state; - emit panelVisibilityChanged(); + } -bool VisibilityManager::isAutoHidden() const +void VisibilityManagerPrivate::raiseDock(bool raise) { - return m_isAutoHidden; + if (raise) { + timerHide.stop(); + + if (!timerShow.isActive()) + timerShow.start(); + } else { + timerShow.stop(); + + if (!timerHide.isActive()) + timerHide.start(); + } } -void VisibilityManager::setIsAutoHidden(bool state) +void VisibilityManagerPrivate::setDockRect(const QRect &rect) { - if (m_isAutoHidden == state) { - return; - } - - m_isAutoHidden = state; - emit isAutoHiddenChanged(); + } -bool VisibilityManager::windowInAttention() const +void VisibilityManagerPrivate::windowAdded(WId id) { - return m_windowIsInAttention; + } -void VisibilityManager::setWindowInAttention(bool state) +void VisibilityManagerPrivate::dodgeActive(WId id) { - if (m_windowIsInAttention == state) { - return; - } - - m_windowIsInAttention = state; - emit windowInAttentionChanged(); + } -bool VisibilityManager::disableHiding() const +void VisibilityManagerPrivate::dodgeWindows(WId id) { - return m_disableHiding; + } -void VisibilityManager::setDisableHiding(bool value) +void VisibilityManagerPrivate::checkAllWindows() { - if (m_disableHiding == value) { - return; - } - - m_disableHiding = value; - - emit disableHidingChanged(); - - if (!m_disableHiding) { - m_updateStateTimer.start(); - } + } -bool VisibilityManager::isDockWindowType() const +bool VisibilityManagerPrivate::intersects(const WindowInfoWrap &info) { - return m_isDockWindowType; + } -void VisibilityManager::setIsDockWindowType(bool state) +void VisibilityManagerPrivate::saveConfig() { - if (m_isDockWindowType == state) { - return; - } - - m_isDockWindowType = state; - - updateVisibilityFlags(); - - emit isDockWindowTypeChanged(); - - m_updateStateTimer.start(); + } -bool VisibilityManager::isHovered() const +void VisibilityManagerPrivate::restoreConfig() { - return m_isHovered; + } -void VisibilityManager::setIsHovered(bool state) +bool VisibilityManagerPrivate::event(QEvent *ev) { - if (m_isHovered == state) { - return; + if (ev->type() == QEvent::Enter && !containsMouse) { + containsMouse = true; + emit q->containsMouseChanged(); + + if (mode == Dock::AutoHide) + raiseDock(true); + + } else if (ev->type() == QEvent::Leave && containsMouse) { + containsMouse = false; + emit q->containsMouseChanged(); + + if (mode == Dock::AutoHide) + raiseDock(false); } - m_isHovered = state; - emit isHoveredChanged(); + return QObject::event(ev); } -void VisibilityManager::setMaskArea(QRect area) +//! END: VisibilityManager implementation + +//! BEGIN: VisiblityManager implementation +VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) + : d(new VisibilityManagerPrivate(view, this)) { - m_interface->setMaskArea(area); + d->restoreConfig(); } -/*******************************/ - -void VisibilityManager::initialize() +VisibilityManager::~VisibilityManager() { - m_secondInitPass = true; - m_initTimer.start(); + } -void VisibilityManager::initWindow() +Dock::Visibility VisibilityManager::mode() const { - updateVisibilityFlags(); - - // updateWindowPosition(); - - // The initialization phase makes two passes because - // changing the window style and type wants a small delay - // and afterwards the second pass positions them correctly - if (m_secondInitPass) { - m_initTimer.start(); - m_secondInitPass = false; - } + return d->mode; } - -/*void VisibilityManager::updateWindowPosition() +void VisibilityManager::setMode(Dock::Visibility mode) { - //setPanelScreen(screen()); - // qDebug() << "updateWindowPosition: start..."; - if (!transientParent() || !transientParent()->screen()) { - // qDebug() << "updateWindowPosition: break transient..."; - return; - } - - // qDebug() << "updateWindowPosition: transientParent setting screen position..."; - setPanelScreen(transientParent()->screen()); - - if (!m_screen || m_screenGeometry.isNull()) { - // qDebug() << "updateWindowPosition: break m_screen..."; - return; - } - // qDebug() << "updateWindowPosition: check passed..."; - // qDebug() << m_screen->geometry().x() << " - " << m_screen->geometry().y() << " - " << m_screen->geometry().width() << " - " << m_screen->geometry().height(); - - if (m_location == Plasma::Types::BottomEdge) { - setX(m_screenGeometry.x()); - setY(m_screenGeometry.y()+m_screenGeometry.height() - height()); - } else if (m_location == Plasma::Types::TopEdge) { - setX(m_screenGeometry.x()); - setY(m_screenGeometry.y()); - } else if (m_location == Plasma::Types::LeftEdge) { - setX(m_screenGeometry.x()); - setY(m_screenGeometry.y()); - } else if (m_location == Plasma::Types::RightEdge) { - setX(m_screenGeometry.x()+m_screenGeometry.width() - width()); - setY(m_screenGeometry.y()); - } - - ///FIXME: in come cases the below can not catch up and this may be the reason - //that on start up in some cases dock's contents are not shown, - //needs a timer maybe? - /*if (m_screen != screen()) { - setScreen(m_screen); - }*/ -//} + d->setMode(mode); +} -void VisibilityManager::updateVisibilityFlags() +bool VisibilityManager::isHidden() const { - m_interface->setDockToAllDesktops(); - - /* if ((m_panelVisibility == AutoHide)||(m_isDockWindowType)) { - m_updateStateTimer.setInterval(2500); - } else { - m_updateStateTimer.setInterval(1500); - }*/ - - m_interface->setDockDefaultFlags(m_isDockWindowType); - - // updateWindowPosition(); - if (!m_isDockWindowType) { - showOnTop(); - } - - m_updateStateTimer.start(); + return d->isHidden; } -/* - * It is used from the m_updateStateTimer in order to check the dock's - * visibility and trigger events and actions which are needed to - * respond accordingly - */ -void VisibilityManager::updateState() +void VisibilityManager::setHidden(bool isHidden) { - // qDebug() << "in update state disableHiding:" <desktopIsActive() && m_interface->dockIntersectsActiveWindow()) { - if (m_interface->dockIsOnTop() || (m_isDockWindowType && !m_isAutoHidden)) { - // qDebug() << m_isHovered << " - " << m_windowIsInAttention << " - "<< m_disableHiding; - if (!m_isHovered && !m_windowIsInAttention && !m_disableHiding) { - // qDebug() << "must be lowered...."; - emit mustBeLowered(); //showNormal(); - } - } else { - if (m_windowIsInAttention) { - if (!m_isDockWindowType || (m_isDockWindowType && m_isAutoHidden)) { - emit mustBeRaised(); //showOnTop(); - } - } - } - } else { - if (!m_interface->activeIsDialog()) { - if ((!m_interface->desktopIsActive() && m_interface->dockIsCovered()) - || (m_isDockWindowType && m_isAutoHidden)) { - // qDebug() << "must be raised...."; - emit mustBeRaised(); - } else { - showOnTop(); - } - } - } - - break; - - case Latte::Dock::DodgeMaximized: - if (!m_interface->desktopIsActive() && m_interface->activeIsMaximized() && m_interface->dockIntersectsActiveWindow()) { - if (m_interface->dockIsOnTop() || (m_isDockWindowType && !m_isAutoHidden)) { - if (!m_isHovered && !m_windowIsInAttention && !m_disableHiding) { - emit mustBeLowered(); //showNormal(); - } - } else { - if (m_windowIsInAttention) { - if (!m_isDockWindowType || (m_isDockWindowType && m_isAutoHidden)) { - emit mustBeRaised(); //showOnTop(); - } - } - } - } else { - if ((!m_interface->desktopIsActive() && m_interface->dockIsCovered()) - || (m_isDockWindowType && m_isAutoHidden)) { - emit mustBeRaised(); - } else { - showOnTop(); - } - } - - break; - - /* case Latte::Dock::LetWindowsCover: - - //this is not supported in clean Dock Window Types such as in wayland case - if (m_isDockWindowType) { - return; - } - - if (!m_isHovered && m_interface->dockIsOnTop()) { - if (m_interface->dockIsCovering()) { - if (!m_disableHiding) { - emit mustBeLowered(); - } - } else { - showOnBottom(); - } - } else if (m_windowIsInAttention) { - if (!m_interface->dockIsOnTop()) { - if (m_interface->dockIsCovered()) { - emit mustBeRaised(); - } else { - showOnTop(); - } - } - } - - break; - - case LatteDock::Types::WindowsGoBelow: - //Do nothing, the dock is OnTop state in every case - break;*/ - - case Latte::Dock::AutoHide: - if (m_windowIsInAttention && m_isAutoHidden) { - emit mustBeRaised(); - } else if (!m_isHovered && !m_disableHiding) { - emit mustBeLowered(); - } - - break; - - case Latte::Dock::AlwaysVisible: - //Do nothing, the dock in OnTop state in every case - break; - } - + d->setIsHidden(isHidden); } -void VisibilityManager::showOnTop() +bool VisibilityManager::containsMouse() const { - // qDebug() << "reached make top..."; - m_interface->showDockOnTop(); + return d->containsMouse; } -void VisibilityManager::showNormal() +int VisibilityManager::timerShow() const { - // qDebug() << "reached make normal..."; - m_interface->showDockAsNormal(); + return d->timerShow.interval(); } -void VisibilityManager::showOnBottom() +void VisibilityManager::setTimerShow(int msec) { - // qDebug() << "reached make bottom..."; - m_interface->showDockOnBottom(); + d->setTimerShow(msec); } -/***************/ -void VisibilityManager::activeWindowChanged() +int VisibilityManager::timerHide() const { - // if ((m_panelVisibility == LatteDock::Types::WindowsGoBelow) - if ((m_panelVisibility == Latte::Dock::AlwaysVisible) - || (m_panelVisibility == Latte::Dock::AutoHide)) { - return; - } - - //this check is important because otherwise the signals are so often - //that the timer is never triggered - if (!m_updateStateTimer.isActive()) { - m_updateStateTimer.start(); - } + return d->timerHide.interval(); } - -//It is used in order to trigger a beautiful slide in effect when -//the dock is totally hidden underneath -void VisibilityManager::showOnTopCheck() +void VisibilityManager::setTimerHide(int msec) { - if ((m_panelVisibility == Latte::Dock::DodgeActive) || (m_panelVisibility == Latte::Dock::DodgeMaximized)) { - //|| (m_panelVisibility == Latte::Dock::LetWindowsCover)) { - if (m_interface->dockIsCovered(true)) { - m_updateStateTimer.stop(); - setIsHovered(true); - - emit mustBeRaisedImmediately(); - } else { - showOnTop(); - } - } + d->setTimerHide(msec); } -bool VisibilityManager::event(QEvent *event) +void VisibilityManager::updateDockGeometry(const QRect &geometry) { - if (!event) { - return false; - } - - if ((event->type() == QEvent::Enter) && !m_isHovered) { - m_updateStateTimer.stop(); - setIsHovered(true); - - if ((m_panelVisibility == Latte::Dock::AutoHide) || (m_isDockWindowType)) { - if (m_isAutoHidden) { - emit mustBeRaised(); - } - } else { - showOnTop(); - } - } else if (event->type() == QEvent::Leave) { - setIsHovered(false); - - // if ((m_panelVisibility != LatteDock::Types::WindowsGoBelow) && - if (m_panelVisibility != Latte::Dock::AlwaysVisible) { - m_updateStateTimer.start(); - } - } - - return true; + d->setDockRect(geometry); +} + +//! END: VisibilityManager implementation } + +#include "abstractwindowinterface.h" +#include "xwindowinterface.h" +#include "plasmaquick/containmentview.h" + + + + diff --git a/app/visibilitymanager_p.h b/app/visibilitymanager_p.h new file mode 100644 index 000000000..4f330791c --- /dev/null +++ b/app/visibilitymanager_p.h @@ -0,0 +1,64 @@ +#ifndef VISIBILITYMANAGERPRIVATE_H +#define VISIBILITYMANAGERPRIVATE_H + +#include "../liblattedock/dock.h" +#include "windowinfowrap.h" + +#include +#include + +#include +#include +#include + +#include + +namespace Latte { + +class VisibilityManager; + +/*! + * \brief The Latte::VisibilityManagerPrivate is a class d-pointer + */ +class VisibilityManagerPrivate : public QObject { + Q_GADGET + +public: + VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q); + ~VisibilityManagerPrivate(); + + void setMode(Dock::Visibility mode); + void setTimerShow(int msec); + void setTimerHide(int msec); + + void raiseDock(bool raise); + + void setDockRect(const QRect &rect); + + void windowAdded(WId id); + void dodgeActive(WId id); + void dodgeWindows(WId id); + void checkAllWindows(); + + bool intersects(const WindowInfoWrap &info); + + void saveConfig(); + void restoreConfig(); + + bool event(QEvent *ev) override; + + VisibilityManager *q; + Dock::Visibility mode{Dock::DodgeActive}; + std::array connections; + std::unordered_map> windows; + QTimer timerShow; + QTimer timerHide; + QTimer timerCheckWindows; + QRect dockRect; + bool isHidden{false}; + bool containsMouse{false}; +}; + +} + +#endif // VISIBILITYMANAGERPRIVATE_H