Add support for _NET_ACTIVE_WINDOW on xcb

Use a _NET_ACTIVE_WINDOW client message instead of xcb_set_input_focus
for activating toplevel windows on xcb.

According to the Extended Window Manager Hints the right way to activate
a top-level window is using _NET_ACTIVE_WINDOW (when it is supported by
the WM). Other approaches like calling xcb_set_input_focus should be
avoided when possible, since the WM cannot intercept them.

Change-Id: I9be4901f56cbcfb563baf73ccd71ff17a9bdc1d2
Reviewed-by: Uli Schlachter <psychon@znc.in>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
bb10
Jan Arne Petersen 2012-02-28 10:54:34 +01:00 committed by Qt by Nokia
parent 9e893f6810
commit fe092d1a6d
1 changed files with 23 additions and 2 deletions

View File

@ -1168,10 +1168,31 @@ void QXcbWindow::propagateSizeHints()
void QXcbWindow::requestActivateWindow()
{
if (m_mapped){
updateNetWmUserTime(connection()->time());
if (!m_mapped)
return;
updateNetWmUserTime(connection()->time());
if (window()->isTopLevel()
&& connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_ACTIVE_WINDOW))) {
xcb_client_message_event_t event;
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.window = m_window;
event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW);
event.data.data32[0] = 1;
event.data.data32[1] = connection()->time();
QWindow *focusWindow = QGuiApplication::focusWindow();
event.data.data32[2] = focusWindow ? focusWindow->winId() : XCB_NONE;
event.data.data32[3] = 0;
event.data.data32[4] = 0;
Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
} else {
Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time()));
}
connection()->sync();
}