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_BEGIN\0"
"_NET_STARTUP_ID\0"
"_NET_SUPPORTING_WM_CHECK\0"

View File

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

View File

@ -81,8 +81,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_drag = new QXcbDrag(this);
#endif
m_startupId = qgetenv("DESKTOP_STARTUP_ID");
if (!m_startupId.isNull())
setStartupId(qgetenv("DESKTOP_STARTUP_ID"));
if (!startupId().isNull())
qunsetenv("DESKTOP_STARTUP_ID");
const int focusInDelay = 100;
@ -771,6 +771,28 @@ void QXcbConnection::setMousePressWindow(QXcbWindow *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()
{
if (m_canGrabServer)
@ -917,6 +939,8 @@ xcb_window_t QXcbConnection::clientLeader()
session.constData());
}
#endif
setStartupId(startupId());
}
return m_clientLeader;
}

View File

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

View File

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