Fixed initialization #17 and improved all modes #19

pull/1/head
Johan Smith Agudelo Rodriguez 8 years ago
parent 8b1194a3d4
commit a4699e9230

@ -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<WId> &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<WId> &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);

@ -4,6 +4,7 @@
#include "dockview.h"
#include "../liblattedock/extras.h"
#include <QDebug>
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<WId, WindowInfoWrap>
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<Dock::Visibility>(config.readEntry("visibility", static_cast<int>(Dock::DodgeActive)));
auto mode = static_cast<Dock::Visibility>(config.readEntry("visibility", static_cast<int>(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();
}

@ -53,7 +53,7 @@ public:
VisibilityManager *q;
PlasmaQuick::ContainmentView *view;
std::unique_ptr<AbstractWindowInterface> wm;
Dock::Visibility mode{Dock::DodgeActive};
Dock::Visibility mode{Dock::None};
std::array<QMetaObject::Connection, 4> connections;
std::unordered_map<WId, WindowInfoWrap> windows;
QTimer timerShow;

@ -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;
}
}

@ -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};
};
}

@ -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<WId> &XWindowInterface::windows()
const std::list<WId> &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;

@ -20,16 +20,20 @@ public:
void setDockDefaultFlags() override;
WId activeWindow() const override;
WindowInfoWrap requestInfo(WId wid) override;
WindowInfoWrap requestInfoActive() override;
const std::list<WId> &windows() override;
WindowInfoWrap requestInfo(WId wid) const override;
WindowInfoWrap requestInfoActive() const override;
bool isOnCurrentDesktop(WId wid) const override;
const std::list<WId> &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;
};
}

@ -15,6 +15,7 @@ public:
~Dock() {}
enum Visibility {
None = -1,
AlwaysVisible = 0,
AutoHide,
DodgeActive,

Loading…
Cancel
Save