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 <davidedmundson@kde.org>
This commit is contained in:
Kai Uwe Broulik 2024-03-13 17:39:41 +01:00
parent 682f7c4b78
commit 0fc235c503
4 changed files with 17 additions and 0 deletions

View File

@ -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()) {

View File

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

View File

@ -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);

View File

@ -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();