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;
}