You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
latte-dock/app/view/helpers/floatinggapwindow.cpp

169 lines
4.9 KiB
C++

/*
* Copyright 2020 Michail Vourlakos <mvourlakos@gmail.com>
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "floatinggapwindow.h"
// local
#include "../view.h"
// Qt
#include <QDebug>
#include <QSurfaceFormat>
#include <QQuickView>
#include <QTimer>
// KDE
#include <KWayland/Client/plasmashell.h>
#include <KWayland/Client/surface.h>
#include <KWindowSystem>
// X11
#include <NETWM>
namespace Latte {
namespace ViewPart {
FloatingGapWindow::FloatingGapWindow(Latte::View *view) :
SubWindow(view, QString("Floating Gap Window"))
{
if (m_debugMode) {
m_showColor = QColor("green");
m_hideColor = QColor("red");
} else {
m_showColor = QColor(Qt::transparent);
m_hideColor = QColor(Qt::transparent);
m_showColor.setAlpha(0);
m_hideColor.setAlpha(1);
}
setColor(m_showColor);
//! this timer is used in order to identify if mouse is still present in sensitive floating
//! areas and in such case to prevent a real-floating view to hide itself
m_asyncMouseTimer.setSingleShot(true);
m_asyncMouseTimer.setInterval(200);
connect(&m_asyncMouseTimer, &QTimer::timeout, this, [this]() {
if (m_inAsyncContainsMouse && !m_containsMouse) {
emit asyncContainsMouseChanged(false);
hideWithMask();
m_inAsyncContainsMouse = false;
}
});
updateGeometry();
hideWithMask();
}
FloatingGapWindow::~FloatingGapWindow()
{
}
QString FloatingGapWindow::validTitlePrefix() const
{
return QString("#subfloatgap#");
}
void FloatingGapWindow::updateGeometry()
{
if (m_latteView->positioner()->slideOffset() != 0) {
return;
}
QRect newGeometry;
m_thickness = m_latteView->screenEdgeMargin();
int length = m_latteView->formFactor() == Plasma::Types::Horizontal ? m_latteView->absoluteGeometry().width() : m_latteView->absoluteGeometry().height();
if (m_latteView->location() == Plasma::Types::BottomEdge) {
int xF = qMax(m_latteView->screenGeometry().left(), m_latteView->absoluteGeometry().left());
newGeometry.moveLeft(xF);
newGeometry.moveTop(m_latteView->screenGeometry().bottom() - m_thickness);
} else if (m_latteView->location() == Plasma::Types::TopEdge) {
int xF = qMax(m_latteView->screenGeometry().left(), m_latteView->absoluteGeometry().left());
newGeometry.moveLeft(xF);
newGeometry.moveTop(m_latteView->screenGeometry().top());
} else if (m_latteView->location() == Plasma::Types::LeftEdge) {
int yF = qMax(m_latteView->screenGeometry().top(), m_latteView->absoluteGeometry().top());
newGeometry.moveLeft(m_latteView->screenGeometry().left());
newGeometry.moveTop(yF);
} else if (m_latteView->location() == Plasma::Types::RightEdge) {
int yF = qMax(m_latteView->screenGeometry().top(), m_latteView->absoluteGeometry().top());
newGeometry.moveLeft(m_latteView->screenGeometry().right() - m_thickness);
newGeometry.moveTop(yF);
}
if (m_latteView->formFactor() == Plasma::Types::Horizontal) {
newGeometry.setWidth(length);
newGeometry.setHeight(m_thickness + 1);
} else {
newGeometry.setWidth(m_thickness + 1);
newGeometry.setHeight(length);
}
m_calculatedGeometry = newGeometry;
emit calculatedGeometryChanged();
}
bool FloatingGapWindow::event(QEvent *e)
{
if (e->type() == QEvent::DragEnter || e->type() == QEvent::DragMove) {
m_containsMouse = true;
} else if (e->type() == QEvent::Enter) {
m_containsMouse = true;
triggerAsyncContainsMouseSignals();
} else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave) {
m_containsMouse = false;
if (m_inAsyncContainsMouse) {
m_asyncMouseTimer.stop();
m_inAsyncContainsMouse = false;
emit asyncContainsMouseChanged(true);
}
}
return SubWindow::event(e);
}
void FloatingGapWindow::callAsyncContainsMouse()
{
m_inAsyncContainsMouse = true;
m_asyncMouseTimer.start();
showWithMask();
}
void FloatingGapWindow::triggerAsyncContainsMouseSignals()
{
if (!m_inAsyncContainsMouse) {
return;
}
//! this function is called QEvent::Enter
m_asyncMouseTimer.stop();
hideWithMask();
}
}
}