From 4bd28e90afc1aeab1a43213cc61bf578da34cd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sun, 27 Oct 2013 09:52:45 +0100 Subject: [PATCH] [kwin] Do not allow Qt to raise decoration widget above the Client If the user actions menu is closed Qt looks for a QWidget at the mouse position. If it finds one it tries to activate and raise it. If the QWidget at the mouse position is a window decoration, it gets raised above the Client. This makes the window unfortunately unusable. To prevent this from happening we listen for the ZOrderChange event in our event filter on the decoration widget and unconditionally lower the decoration widget again - we never want the decoration widget to be above our Client, so we can just always lower it. We have to use the low level functionality and cannot use QWidget::lower as that would result in a loop. --- events.cpp | 8 ++++++++ xcbutils.h | 10 ++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/events.cpp b/events.cpp index ac7a15d0f1..1d64b49a16 100644 --- a/events.cpp +++ b/events.cpp @@ -1014,6 +1014,14 @@ bool Client::eventFilter(QObject* o, QEvent* e) decoration->widget()->update(); return false; } + if (e->type() == QEvent::ZOrderChange) { + // when the user actions menu is closed by clicking on the window decoration (which is not unlikely) + // Qt will raise the decoration window and thus the decoration window is above the actual Client + // see QWidgetWindow::handleMouseEvent (qtbase/src/widgets/kernel/qwidgetwindow.cpp) + // when this happens also a ZOrderChange event is sent, we intercept all of them and make sure that + // the window is lowest in stack again. + Xcb::lowerWindow(decorationId()); + } return false; } diff --git a/xcbutils.h b/xcbutils.h index 88a5156d54..6c44920be0 100644 --- a/xcbutils.h +++ b/xcbutils.h @@ -42,6 +42,7 @@ static void defineCursor(xcb_window_t window, xcb_cursor_t cursor); static void setInputFocus(xcb_window_t window, uint8_t revertTo = XCB_INPUT_FOCUS_POINTER_ROOT, xcb_timestamp_t time = xTime()); static void moveWindow(xcb_window_t window, const QPoint &pos); static void moveWindow(xcb_window_t window, uint32_t x, uint32_t y); +static void lowerWindow(xcb_window_t window); static void selectInput(xcb_window_t window, uint32_t events); template