[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.
This commit is contained in:
parent
96691036f6
commit
4bd28e90af
2 changed files with 16 additions and 2 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
10
xcbutils.h
10
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 <typename Reply,
|
||||
|
@ -649,8 +650,7 @@ void Window::raise()
|
|||
inline
|
||||
void Window::lower()
|
||||
{
|
||||
const uint32_t values[] = { XCB_STACK_MODE_BELOW };
|
||||
xcb_configure_window(connection(), m_window, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
lowerWindow(m_window);
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -796,6 +796,12 @@ static inline void moveWindow(xcb_window_t window, uint32_t x, uint32_t y)
|
|||
xcb_configure_window(connection(), window, mask, values);
|
||||
}
|
||||
|
||||
static inline void lowerWindow(xcb_window_t window)
|
||||
{
|
||||
const uint32_t values[] = { XCB_STACK_MODE_BELOW };
|
||||
xcb_configure_window(connection(), window, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
}
|
||||
|
||||
static inline WindowId createInputWindow(const QRect &geometry, uint32_t mask, const uint32_t *values)
|
||||
{
|
||||
WindowId window = xcb_generate_id(connection());
|
||||
|
|
Loading…
Reference in a new issue