#include "FloatingWindow.h" #include #include #include #include namespace { bool isWayland() { return QGuiApplication::platformName().startsWith(QLatin1String("wayland")); } constexpr int BottomGap = 24; } // namespace FloatingWindow::FloatingWindow(QWindow *window, QObject *parent) : QObject(parent) , m_window(window) { if (isWayland()) { m_layerSurface = LayerShellQt::Window::get(window); m_layerSurface->setLayer(LayerShellQt::Window::LayerOverlay); m_layerSurface->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityNone); m_layerSurface->setAnchors({LayerShellQt::Window::AnchorTop | LayerShellQt::Window::AnchorLeft}); m_layerSurface->setExclusiveZone(-1); m_layerSurface->setScope(QStringLiteral("sloposk-keyboard")); m_layerSurface->setActivateOnShow(false); } else { window->setFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus); } m_position = defaultPosition(); apply(); } void FloatingWindow::setPosition(QPoint position) { position = clamped(position); if (position == m_position) return; m_position = position; apply(); Q_EMIT positionChanged(); } void FloatingWindow::moveBy(qreal dx, qreal dy) { setPosition(m_position + QPoint(qRound(dx), qRound(dy))); } void FloatingWindow::show() { m_window->setVisible(true); } void FloatingWindow::hide() { m_window->setVisible(false); } QPoint FloatingWindow::clamped(QPoint position) const { const QRect area = m_window->screen()->geometry(); const int maxX = qMax(0, area.width() - m_window->width()); const int maxY = qMax(0, area.height() - m_window->height()); return {qBound(0, position.x(), maxX), qBound(0, position.y(), maxY)}; } QPoint FloatingWindow::defaultPosition() const { const QRect area = m_window->screen()->geometry(); return clamped({(area.width() - m_window->width()) / 2, area.height() - m_window->height() - BottomGap}); } void FloatingWindow::apply() { if (m_layerSurface) m_layerSurface->setMargins({m_position.x(), m_position.y(), 0, 0}); else m_window->setPosition(m_window->screen()->geometry().topLeft() + m_position); }