added class visibilitymanagerprivate to implement visibility

v0.6
audoban 8 years ago committed by Michail Vourlakos
parent 43f1bc4ff6
commit 880aa1decf

@ -1,450 +1,186 @@
#include "visibilitymanager.h" #include "visibilitymanager.h"
#include "visibilitymanager_p.h"
#include "abstractinterface.h" namespace Latte {
#include "xwindowinterface.h"
#include "plasmaquick/containmentview.h"
#include "../liblattedock/dock.h"
#include <QDebug> //! BEGIN: VisiblityManagerPrivate implementation
VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q)
: QObject(view), q(q)
{
#include <Plasma/Containment> }
VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) : VisibilityManagerPrivate::~VisibilityManagerPrivate()
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)
{ {
// 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) { if (ev->type() == QEvent::Enter && !containsMouse) {
return; 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; return QObject::event(ev);
emit isHoveredChanged();
} }
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();
} }
/*******************************/ VisibilityManager::~VisibilityManager()
void VisibilityManager::initialize()
{ {
m_secondInitPass = true;
m_initTimer.start();
} }
void VisibilityManager::initWindow() Dock::Visibility VisibilityManager::mode() const
{ {
updateVisibilityFlags(); return d->mode;
// 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;
}
} }
void VisibilityManager::setMode(Dock::Visibility mode)
/*void VisibilityManager::updateWindowPosition()
{ {
//setPanelScreen(screen()); d->setMode(mode);
// 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);
}*/
//}
void VisibilityManager::updateVisibilityFlags() bool VisibilityManager::isHidden() const
{ {
m_interface->setDockToAllDesktops(); return d->isHidden;
/* 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();
} }
/* void VisibilityManager::setHidden(bool 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()
{ {
// qDebug() << "in update state disableHiding:" <<m_disableHiding; d->setIsHidden(isHidden);
//update the dock behavior
switch (m_panelVisibility) {
case Latte::Dock::DodgeActive:
if (!m_interface->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;
}
} }
void VisibilityManager::showOnTop() bool VisibilityManager::containsMouse() const
{ {
// qDebug() << "reached make top..."; return d->containsMouse;
m_interface->showDockOnTop();
} }
void VisibilityManager::showNormal() int VisibilityManager::timerShow() const
{ {
// qDebug() << "reached make normal..."; return d->timerShow.interval();
m_interface->showDockAsNormal();
} }
void VisibilityManager::showOnBottom() void VisibilityManager::setTimerShow(int msec)
{ {
// qDebug() << "reached make bottom..."; d->setTimerShow(msec);
m_interface->showDockOnBottom();
} }
/***************/ int VisibilityManager::timerHide() const
void VisibilityManager::activeWindowChanged()
{ {
// if ((m_panelVisibility == LatteDock::Types::WindowsGoBelow) return d->timerHide.interval();
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();
}
} }
void VisibilityManager::setTimerHide(int msec)
//It is used in order to trigger a beautiful slide in effect when
//the dock is totally hidden underneath
void VisibilityManager::showOnTopCheck()
{ {
if ((m_panelVisibility == Latte::Dock::DodgeActive) || (m_panelVisibility == Latte::Dock::DodgeMaximized)) { d->setTimerHide(msec);
//|| (m_panelVisibility == Latte::Dock::LetWindowsCover)) {
if (m_interface->dockIsCovered(true)) {
m_updateStateTimer.stop();
setIsHovered(true);
emit mustBeRaisedImmediately();
} else {
showOnTop();
}
}
} }
bool VisibilityManager::event(QEvent *event) void VisibilityManager::updateDockGeometry(const QRect &geometry)
{ {
if (!event) { d->setDockRect(geometry);
return false; }
}
//! END: VisibilityManager implementation
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;
} }
#include "abstractwindowinterface.h"
#include "xwindowinterface.h"
#include "plasmaquick/containmentview.h"

@ -0,0 +1,64 @@
#ifndef VISIBILITYMANAGERPRIVATE_H
#define VISIBILITYMANAGERPRIVATE_H
#include "../liblattedock/dock.h"
#include "windowinfowrap.h"
#include <memory>
#include <unordered_map>
#include <QObject>
#include <QTimer>
#include <QEvent>
#include <plasmaquick/containmentview.h>
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<QMetaObject::Connection, 4> connections;
std::unordered_map<WId, std::unique_ptr<WindowInfoWrap>> windows;
QTimer timerShow;
QTimer timerHide;
QTimer timerCheckWindows;
QRect dockRect;
bool isHidden{false};
bool containsMouse{false};
};
}
#endif // VISIBILITYMANAGERPRIVATE_H
Loading…
Cancel
Save