File indexing completed on 2025-03-16 11:22:51
0001 /* 0002 SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "floatinggapwindow.h" 0007 0008 // local 0009 #include "../view.h" 0010 0011 // Qt 0012 #include <QDebug> 0013 #include <QSurfaceFormat> 0014 #include <QQuickView> 0015 #include <QTimer> 0016 0017 // KDE 0018 #include <KWayland/Client/plasmashell.h> 0019 #include <KWayland/Client/surface.h> 0020 #include <KWindowSystem> 0021 0022 // X11 0023 #include <NETWM> 0024 0025 namespace Latte { 0026 namespace ViewPart { 0027 0028 FloatingGapWindow::FloatingGapWindow(Latte::View *view) : 0029 SubWindow(view, QString("Floating Gap Window")) 0030 { 0031 if (m_debugMode) { 0032 m_showColor = QColor("green"); 0033 m_hideColor = QColor("red"); 0034 } else { 0035 m_showColor = QColor(Qt::transparent); 0036 m_hideColor = QColor(Qt::transparent); 0037 0038 m_showColor.setAlpha(0); 0039 m_hideColor.setAlpha(1); 0040 } 0041 0042 setColor(m_showColor); 0043 0044 //! this timer is used in order to identify if mouse is still present in sensitive floating 0045 //! areas and in such case to prevent a real-floating view to hide itself 0046 m_asyncMouseTimer.setSingleShot(true); 0047 m_asyncMouseTimer.setInterval(200); 0048 connect(&m_asyncMouseTimer, &QTimer::timeout, this, [this]() { 0049 if (m_inAsyncContainsMouse && !m_containsMouse) { 0050 emit asyncContainsMouseChanged(false); 0051 hideWithMask(); 0052 m_inAsyncContainsMouse = false; 0053 } 0054 }); 0055 0056 0057 updateGeometry(); 0058 hideWithMask(); 0059 } 0060 0061 FloatingGapWindow::~FloatingGapWindow() 0062 { 0063 } 0064 0065 QString FloatingGapWindow::validTitlePrefix() const 0066 { 0067 return QString("#subfloatgap#"); 0068 } 0069 0070 void FloatingGapWindow::updateGeometry() 0071 { 0072 if (m_latteView->positioner()->slideOffset() != 0) { 0073 return; 0074 } 0075 0076 QRect newGeometry; 0077 0078 m_thickness = m_latteView->screenEdgeMargin(); 0079 0080 int length = m_latteView->formFactor() == Plasma::Types::Horizontal ? m_latteView->absoluteGeometry().width() : m_latteView->absoluteGeometry().height(); 0081 0082 if (m_latteView->location() == Plasma::Types::BottomEdge) { 0083 int xF = qMax(m_latteView->screenGeometry().left(), m_latteView->absoluteGeometry().left()); 0084 newGeometry.moveLeft(xF); 0085 newGeometry.moveTop(m_latteView->screenGeometry().bottom() - m_thickness); 0086 } else if (m_latteView->location() == Plasma::Types::TopEdge) { 0087 int xF = qMax(m_latteView->screenGeometry().left(), m_latteView->absoluteGeometry().left()); 0088 newGeometry.moveLeft(xF); 0089 newGeometry.moveTop(m_latteView->screenGeometry().top()); 0090 } else if (m_latteView->location() == Plasma::Types::LeftEdge) { 0091 int yF = qMax(m_latteView->screenGeometry().top(), m_latteView->absoluteGeometry().top()); 0092 newGeometry.moveLeft(m_latteView->screenGeometry().left()); 0093 newGeometry.moveTop(yF); 0094 } else if (m_latteView->location() == Plasma::Types::RightEdge) { 0095 int yF = qMax(m_latteView->screenGeometry().top(), m_latteView->absoluteGeometry().top()); 0096 newGeometry.moveLeft(m_latteView->screenGeometry().right() - m_thickness); 0097 newGeometry.moveTop(yF); 0098 } 0099 0100 if (m_latteView->formFactor() == Plasma::Types::Horizontal) { 0101 newGeometry.setWidth(length); 0102 newGeometry.setHeight(m_thickness + 1); 0103 } else { 0104 newGeometry.setWidth(m_thickness + 1); 0105 newGeometry.setHeight(length); 0106 } 0107 0108 m_calculatedGeometry = newGeometry; 0109 0110 emit calculatedGeometryChanged(); 0111 } 0112 0113 bool FloatingGapWindow::event(QEvent *e) 0114 { 0115 if (e->type() == QEvent::DragEnter || e->type() == QEvent::DragMove) { 0116 m_containsMouse = true; 0117 0118 } else if (e->type() == QEvent::Enter) { 0119 m_containsMouse = true; 0120 0121 triggerAsyncContainsMouseSignals(); 0122 } else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave) { 0123 m_containsMouse = false; 0124 0125 if (m_inAsyncContainsMouse) { 0126 m_asyncMouseTimer.stop(); 0127 m_inAsyncContainsMouse = false; 0128 emit asyncContainsMouseChanged(true); 0129 } 0130 } 0131 0132 return SubWindow::event(e); 0133 } 0134 0135 void FloatingGapWindow::callAsyncContainsMouse() 0136 { 0137 m_inAsyncContainsMouse = true; 0138 m_asyncMouseTimer.start(); 0139 showWithMask(); 0140 } 0141 0142 void FloatingGapWindow::triggerAsyncContainsMouseSignals() 0143 { 0144 if (!m_inAsyncContainsMouse) { 0145 return; 0146 } 0147 0148 //! this function is called QEvent::Enter 0149 m_asyncMouseTimer.stop(); 0150 hideWithMask(); 0151 } 0152 0153 } 0154 }