From 0fc235c5030ee6fb70dd145b1faad1567cf39788 Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Wed, 13 Mar 2024 17:39:41 +0100 Subject: [PATCH] QWaylandWindow: requestActivate on show For simplicitly, a Wayland compositor typically activates a window when it is mapped. However, it does not necessarily have to and might not want to in order to prevent stealing focus. Inttroduce a requestActivateOnShow() on the shell which is called when showing a window and, in case of XDG Shell, will explicitly request activation (unless Qt::WA_ShowWithoutActivating is set) and make use of the existing XDG Activation infrastructure. Change-Id: I69ab5f2cee4540d5baefa5a266f22dbb165e4192 Reviewed-by: David Edmundson --- .../shellintegration/xdg-shell/qwaylandxdgshell.cpp | 12 ++++++++++++ .../shellintegration/xdg-shell/qwaylandxdgshell_p.h | 1 + .../platforms/wayland/qwaylandshellsurface_p.h | 1 + src/plugins/platforms/wayland/qwaylandwindow.cpp | 3 +++ 4 files changed, 17 insertions(+) diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index d65d4e7223f..c7b95e0d05e 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -662,6 +662,18 @@ bool QWaylandXdgSurface::requestActivate() return false; } +bool QWaylandXdgSurface::requestActivateOnShow() +{ + const Qt::WindowType type = m_window->window()->type(); + if (type == Qt::ToolTip || type == Qt::Popup || type == Qt::SplashScreen) + return false; + + if (m_window->window()->property("_q_showWithoutActivating").toBool()) + return false; + + return requestActivate(); +} + void QWaylandXdgSurface::requestXdgActivationToken(quint32 serial) { if (auto *activation = m_shell->activation()) { diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index 22a207a25f7..fa33259f744 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -64,6 +64,7 @@ public: void propagateSizeHints() override; void setWindowGeometry(const QRect &rect) override; bool requestActivate() override; + bool requestActivateOnShow() override; void setXdgActivationToken(const QString &token) override; void requestXdgActivationToken(quint32 serial) override; void setAlertState(bool enabled) override; diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface_p.h b/src/plugins/platforms/wayland/qwaylandshellsurface_p.h index 6499a2bb009..8632efd04de 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface_p.h +++ b/src/plugins/platforms/wayland/qwaylandshellsurface_p.h @@ -70,6 +70,7 @@ public: virtual void setWindowPosition(const QPoint &position) { Q_UNUSED(position); } virtual bool requestActivate() { return false; } + virtual bool requestActivateOnShow() { return false; } virtual void setXdgActivationToken(const QString &token); virtual void requestXdgActivationToken(quint32 serial); diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 7fc9f398b5c..081110f8334 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -576,6 +576,9 @@ void QWaylandWindow::setVisible(bool visible) // Don't flush the events here, or else the newly visible window may start drawing, but since // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). + + if (mShellSurface) + mShellSurface->requestActivateOnShow(); } else { sendExposeEvent(QRect()); reset();