#include "CollapseController.h" #include "FloatingWindow.h" #include namespace { constexpr int ExpandTimeoutMs = 500; bool roughlyEqual(QSize a, QSize b) { return qAbs(a.width() - b.width()) <= 1 && qAbs(a.height() - b.height()) <= 1; } } // namespace CollapseController::CollapseController(QQuickWindow &window, FloatingWindow &placement, QObject *parent) : QObject(parent) , m_window(window) , m_placement(placement) { m_expanding.setSingleShot(true); m_expanding.setInterval(ExpandTimeoutMs); connect(&m_expanding, &QTimer::timeout, this, &CollapseController::finishExpanding); connect(&window, &QWindow::widthChanged, this, &CollapseController::windowResized); connect(&window, &QWindow::heightChanged, this, &CollapseController::windowResized); } bool CollapseController::collapse() { if (m_collapsed) return true; QVariant rect; QMetaObject::invokeMethod(&m_window, "dismissKeyRect", Q_RETURN_ARG(QVariant, rect)); if (rect.toRectF().isEmpty()) return false; m_keyRect = rect.toRectF(); m_expandedSize = m_window.size(); m_collapsed = true; Q_EMIT collapsedChanged(); // Wait one frame, so the compositor has the new (lower) minimum size before the resize. connect(&m_window, &QQuickWindow::frameSwapped, this, [this] { if (m_collapsed) m_placement.moveResize(m_keyRect, false); }, Qt::SingleShotConnection); return true; } void CollapseController::expand() { if (!m_collapsed || m_expanding.isActive()) return; if (roughlyEqual(m_window.size(), m_expandedSize)) { finishExpanding(); // window never shrank: nothing to resize return; } // Stay collapsed until the window has grown, so the keys aren't drawn squeezed. m_placement.moveResize(QRectF(-m_keyRect.topLeft(), m_expandedSize), true); m_expanding.start(); } void CollapseController::windowResized() { if (m_expanding.isActive() && roughlyEqual(m_window.size(), m_expandedSize)) finishExpanding(); } void CollapseController::finishExpanding() { m_expanding.stop(); if (!roughlyEqual(m_window.size(), m_expandedSize)) m_window.resize(m_expandedSize); // KWin didn't resize (timeout): resize directly m_collapsed = false; Q_EMIT collapsedChanged(); }