diff --git a/autotests/integration/internal_window.cpp b/autotests/integration/internal_window.cpp index b027199d85..8092d3059a 100644 --- a/autotests/integration/internal_window.cpp +++ b/autotests/integration/internal_window.cpp @@ -91,6 +91,7 @@ private: HelperWindow::HelperWindow() : QRasterWindow(nullptr) { + setFlags(Qt::FramelessWindowHint); } HelperWindow::~HelperWindow() = default; diff --git a/input.cpp b/input.cpp index 37ab081145..a6de0bd8bb 100644 --- a/input.cpp +++ b/input.cpp @@ -430,6 +430,13 @@ class InternalWindowEventFilter : public InputEventFilter { if (!internal) { return false; } + if (event->buttons() == Qt::NoButton) { + // update pointer window only if no button is pressed + input()->pointer()->update(); + } + if (!internal) { + return false; + } QMouseEvent e(event->type(), event->pos() - internal->position(), event->globalPos(), @@ -1534,7 +1541,7 @@ void InputDeviceHandler::updateInternalWindow(const QPointF &pos) if (!w->isVisible()) { continue; } - if (w->geometry().contains(pos.toPoint())) { + if ((*it)->geometry().contains(pos.toPoint())) { // check input mask const QRegion mask = w->mask().translated(w->geometry().topLeft()); if (!mask.isEmpty() && !mask.contains(pos.toPoint())) { diff --git a/plugins/qpa/window.cpp b/plugins/qpa/window.cpp index e5244c323a..e969577194 100644 --- a/plugins/qpa/window.cpp +++ b/plugins/qpa/window.cpp @@ -25,6 +25,7 @@ along with this program. If not, see . #include #include +#include #include #include @@ -103,6 +104,7 @@ void Window::setGeometry(const QRect &rect) wl_egl_window_resize(m_eglWaylandWindow, geometry().width(), geometry().height(), 0, 0); } #endif + QWindowSystemInterface::handleGeometryChange(window(), geometry()); } void Window::unmap() diff --git a/pointer_input.cpp b/pointer_input.cpp index 3b5df18aee..36f99a18a7 100644 --- a/pointer_input.cpp +++ b/pointer_input.cpp @@ -367,11 +367,14 @@ void PointerInputRedirection::update() if (!m_internalWindow) { updateDecoration(t, m_pos); } else { - // TODO: send hover leave to decoration + updateDecoration(waylandServer()->findClient(m_internalWindow), m_pos); if (m_decoration) { - m_decoration->client()->leaveEvent(); + disconnect(m_internalWindowConnection); + m_internalWindowConnection = QMetaObject::Connection(); + QEvent event(QEvent::Leave); + QCoreApplication::sendEvent(m_internalWindow.data(), &event); + m_internalWindow.clear(); } - m_decoration.clear(); } if (m_decoration || m_internalWindow) { t = nullptr; diff --git a/shell_client.cpp b/shell_client.cpp index 9e4a0a5920..a6c43a14a6 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -178,6 +178,7 @@ void ShellClient::init() if (m_internalWindow) { updateInternalWindowGeometry(); setOnAllDesktops(true); + updateDecoration(true); } else { doSetGeometry(QRect(QPoint(0, 0), m_clientSize)); setDesktop(VirtualDesktopManager::self()->current()); @@ -484,6 +485,13 @@ void ShellClient::doSetGeometry(const QRect &rect) if (!m_unmapped) { addWorkspaceRepaint(visibleRect()); } + if (m_internalWindow) { + const QRect windowRect = QRect(geom.topLeft() + QPoint(borderLeft(), borderTop()), + geom.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom())); + if (m_internalWindow->geometry() != windowRect) { + m_internalWindow->setGeometry(windowRect); + } + } triggerDecorationRepaint(); if (hasStrut()) { workspace()->updateClientArea(); @@ -526,6 +534,9 @@ void ShellClient::closeWindow() if (m_qtExtendedSurface && isCloseable()) { m_qtExtendedSurface->close(); } + if (m_internalWindow) { + m_internalWindow->hide(); + } } AbstractClient *ShellClient::findModal(bool allow_itself) @@ -542,6 +553,9 @@ bool ShellClient::isCloseable() const if (m_xdgShellSurface) { return true; } + if (m_internal) { + return true; + } return m_qtExtendedSurface ? true : false; } @@ -557,6 +571,9 @@ bool ShellClient::isFullScreen() const bool ShellClient::isMaximizable() const { + if (m_internal) { + return false; + } return true; } @@ -694,7 +711,7 @@ MaximizeMode ShellClient::maximizeMode() const bool ShellClient::noBorder() const { if (isInternal()) { - return true; + return m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup); } if (m_serverDecoration) { if (m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) { @@ -791,6 +808,9 @@ bool ShellClient::userCanSetNoBorder() const if (m_serverDecoration && m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) { return !isFullScreen() && !isShade() && !tabGroup(); } + if (m_internal) { + return !m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup); + } return false; } @@ -852,6 +872,7 @@ void ShellClient::findInternalWindow() continue; } m_internalWindow = w; + m_internalWindowFlags = m_internalWindow->flags(); connect(m_internalWindow, &QWindow::xChanged, this, &ShellClient::updateInternalWindowGeometry); connect(m_internalWindow, &QWindow::yChanged, this, &ShellClient::updateInternalWindowGeometry); connect(m_internalWindow, &QWindow::destroyed, this, [this] { m_internalWindow = nullptr; }); @@ -871,7 +892,8 @@ void ShellClient::updateInternalWindowGeometry() if (!m_internalWindow) { return; } - doSetGeometry(m_internalWindow->geometry()); + doSetGeometry(QRect(m_internalWindow->geometry().topLeft() - QPoint(borderLeft(), borderTop()), + m_internalWindow->geometry().size() + QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); } bool ShellClient::isInternal() const @@ -907,6 +929,9 @@ void ShellClient::requestGeometry(const QRect &rect) m_xdgShellSurface->configure(xdgSurfaceStates(), size); } m_blockedRequestGeometry = QRect(); + if (m_internal) { + m_internalWindow->setGeometry(QRect(rect.topLeft() + QPoint(borderLeft(), borderTop()), rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); + } } void ShellClient::clientFullScreenChanged(bool fullScreen) @@ -950,6 +975,9 @@ void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force) if (m_xdgShellSurface) { m_xdgShellSurface->configure(xdgSurfaceStates(), QSize(w, h)); } + if (m_internal) { + m_internalWindow->setGeometry(QRect(pos() + QPoint(borderLeft(), borderTop()), QSize(w, h) - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); + } } void ShellClient::unmap() diff --git a/shell_client.h b/shell_client.h index 4f32b0347b..cabda7c2f2 100644 --- a/shell_client.h +++ b/shell_client.h @@ -170,6 +170,7 @@ private: bool m_closing = false; quint32 m_windowId = 0; QWindow *m_internalWindow = nullptr; + Qt::WindowFlags m_internalWindowFlags = Qt::WindowFlags(); bool m_unmapped = true; MaximizeMode m_maximizeMode = MaximizeRestore; QRect m_geomMaximizeRestore; // size and position of the window before it was set to maximize diff --git a/workspace.cpp b/workspace.cpp index a7f3961c6f..42c15c678f 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -1640,6 +1640,11 @@ AbstractClient *Workspace::findAbstractClient(std::functioninternalClients(), func)) { + return ret; + } + } return nullptr; }