xcb: set _NET_STARTUP_ID at client leader window

This should help to overcome WM's focus prevention mechanism

Fixes: QTBUG-96276
Pick-to: 6.4 6.3 6.2 5.15
Change-Id: Ic5fb46f7ce54f0df29850725bafa364b74e30d25
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Liang Qi <liang.qi@qt.io>
This commit is contained in:
Ilya Fedin 2022-04-21 14:07:19 +04:00
parent 43aaffb018
commit ba8c4b4ac6
5 changed files with 31 additions and 6 deletions

View File

@ -114,6 +114,7 @@ static const char *xcb_atomnames = {
"_NET_STARTUP_INFO\0" "_NET_STARTUP_INFO\0"
"_NET_STARTUP_INFO_BEGIN\0" "_NET_STARTUP_INFO_BEGIN\0"
"_NET_STARTUP_ID\0"
"_NET_SUPPORTING_WM_CHECK\0" "_NET_SUPPORTING_WM_CHECK\0"

View File

@ -115,6 +115,7 @@ public:
_NET_STARTUP_INFO, _NET_STARTUP_INFO,
_NET_STARTUP_INFO_BEGIN, _NET_STARTUP_INFO_BEGIN,
_NET_STARTUP_ID,
_NET_SUPPORTING_WM_CHECK, _NET_SUPPORTING_WM_CHECK,

View File

@ -81,8 +81,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_drag = new QXcbDrag(this); m_drag = new QXcbDrag(this);
#endif #endif
m_startupId = qgetenv("DESKTOP_STARTUP_ID"); setStartupId(qgetenv("DESKTOP_STARTUP_ID"));
if (!m_startupId.isNull()) if (!startupId().isNull())
qunsetenv("DESKTOP_STARTUP_ID"); qunsetenv("DESKTOP_STARTUP_ID");
const int focusInDelay = 100; const int focusInDelay = 100;
@ -771,6 +771,28 @@ void QXcbConnection::setMousePressWindow(QXcbWindow *w)
m_mousePressWindow = w; m_mousePressWindow = w;
} }
QByteArray QXcbConnection::startupId() const
{
return m_startupId;
}
void QXcbConnection::setStartupId(const QByteArray &nextId)
{
m_startupId = nextId;
if (m_clientLeader) {
if (!nextId.isEmpty())
xcb_change_property(xcb_connection(),
XCB_PROP_MODE_REPLACE,
clientLeader(),
atom(QXcbAtom::_NET_STARTUP_ID),
atom(QXcbAtom::UTF8_STRING),
8,
nextId.length(),
nextId.constData());
else
xcb_delete_property(xcb_connection(), clientLeader(), atom(QXcbAtom::_NET_STARTUP_ID));
}
}
void QXcbConnection::grabServer() void QXcbConnection::grabServer()
{ {
if (m_canGrabServer) if (m_canGrabServer)
@ -917,6 +939,8 @@ xcb_window_t QXcbConnection::clientLeader()
session.constData()); session.constData());
} }
#endif #endif
setStartupId(startupId());
} }
return m_clientLeader; return m_clientLeader;
} }

View File

@ -170,9 +170,8 @@ public:
QXcbWindow *mousePressWindow() const { return m_mousePressWindow; } QXcbWindow *mousePressWindow() const { return m_mousePressWindow; }
void setMousePressWindow(QXcbWindow *); void setMousePressWindow(QXcbWindow *);
QByteArray startupId() const { return m_startupId; } QByteArray startupId() const;
void setStartupId(const QByteArray &nextId) { m_startupId = nextId; } void setStartupId(const QByteArray &nextId);
void clearStartupId() { m_startupId.clear(); }
void grabServer(); void grabServer();
void ungrabServer(); void ungrabServer();

View File

@ -796,7 +796,7 @@ void QXcbScreen::windowShown(QXcbWindow *window)
// Freedesktop.org Startup Notification // Freedesktop.org Startup Notification
if (!connection()->startupId().isEmpty() && window->window()->isTopLevel()) { if (!connection()->startupId().isEmpty() && window->window()->isTopLevel()) {
sendStartupMessage(QByteArrayLiteral("remove: ID=") + connection()->startupId()); sendStartupMessage(QByteArrayLiteral("remove: ID=") + connection()->startupId());
connection()->clearStartupId(); connection()->setStartupId({});
} }
} }