https://bugs.kde.org/show_bug.cgi?id=478556

--- Comment #88 from vm <vyacheslav.mayo...@gmail.com> ---
Today I encountered this bug again (with IDEA).
Accidentially forgot to disable animations.
But this helps me to finally spin off this history.

I wrote a fairly simple utility that calls xcb_query_tree (which guarantees to
returns windows in Xorg stacking order) and xcb_shape_get_rectangles to get all
the regions.
Now it's known for sure that in the case of IDEA, everything is ok with those
regions (bounding, clip, input).

The problem itself is in the title of this ticket -
KWin::Workspace::stacking_order != X11 stacking order. And the main hint was in
title of this ticket all the time.

If you reproduce that problem and then try to Minimize and open broken window
again, visually the window appears on the screen first and is drawn first, but
all the input goes to the window that is at the bottom of the list from
xcb_query_tree.
And i found that these broken IDEA windows appears BEHIND Desktop window
according to X11 stacking order, however on top of
KWin::Workspace::stacking_order.
Also some people showed here that not only IDEA windows breaks - but IDEA app
must be launched. 

Now let's recheck how restacking works (on X11):

        static inline void restackWindows(const QList<xcb_window_t> &windows)
        {
            if (windows.count() < 2) {
                // only one window, nothing to do
                return;
            }
            for (int i = 1; i < windows.count(); ++i) {
                const uint16_t mask = XCB_CONFIG_WINDOW_SIBLING |
XCB_CONFIG_WINDOW_STACK_MODE;
                const uint32_t stackingValues[] = {
                    windows.at(i - 1),
                    XCB_STACK_MODE_BELOW};
                xcb_configure_window(connection(), windows.at(i), mask,
stackingValues);
            }
        }

How its expected to work - we take a list of windows and for each window say -
the previous window MUST BE BELOW current window.
But... As you might remember - KWin has leaking Window objects (Window objects
without any bounded Xorg window to it - frameId = 0x0, wrapper = 0x0, window =
0x0, inputId = 0x0) when Open/Close animation is enabled.

And when we encounter such window - we make the next calls:

        const uint32_t stackingValues[] = {
            0x3800045, // for example
            XCB_STACK_MODE_BELOW
        };

        xcb_configure_window(connection(), 0x0, mask, stackingValues);

This must cause XCB error, but it's swallowed anyway...

The next call: 

        const uint32_t stackingValues[] = {
            0x0, // <---- ...
            XCB_STACK_MODE_BELOW
        };

        xcb_configure_window(connection(),  windows.at(i), mask,
stackingValues);

And XCB do this - places window BEHIND ALL OTHER WINDOWS (behind Desktop and
others). 
All next windows in this list - also placed behind Desktop window - making
whole pack of windows effectively unclickable (but still visible).

So, for now the fix is deadly simple - filter out 0x0 windows from X11
xcb_window_t passed to restackWindows.

To reproduce and recheck:

1. X11
2. Enable Scale animation effect (Open/Close animation group). 
3. Build KWin with debug symbols (or use debuginfod), wire up gdb:

gdb ./kwin_x11

# to preload symbols
run 

break xcbutils.h:1965
commands
silent
printf "xcb_configure_window: 0x%x below 0x%x\n",windows.at(i-1),windows.at(i)
continue
end

4. Watch videos above about how to reproduce
5. Check output produced by gdb, something like: xcb_configure_window: 0x0
below 0x1600032

Unfortunately, i dont have access to create Merge Requests to KWin directly,
so..
The next is the diff with the fix for X11 (against master branch):

diff --git a/src/layers.cpp b/src/layers.cpp
index 45baa452d6..54a5df0bd6 100644
--- a/src/layers.cpp
+++ b/src/layers.cpp
@@ -165,7 +165,7 @@ void Workspace::propagateWindows(bool
propagate_new_windows)

     for (int i = stacking_order.size() - 1; i >= 0; --i) {
         X11Window *window = qobject_cast<X11Window *>(stacking_order.at(i));
-        if (!window || window->isUnmanaged() || window->hiddenPreview()) {
+        if (!window || !window->frameId() || window->isUnmanaged() ||
window->hiddenPreview()) {
             continue;
         }

@@ -182,7 +182,7 @@ void Workspace::propagateWindows(bool
propagate_new_windows)
     // these windows that should be unmapped to interfere with other windows
     for (int i = stacking_order.size() - 1; i >= 0; --i) {
         X11Window *window = qobject_cast<X11Window *>(stacking_order.at(i));
-        if (!window || window->isUnmanaged() || !window->hiddenPreview()) {
+        if (!window || !window->frameId() || window->isUnmanaged() ||
!window->hiddenPreview()) {
             continue;
         }
         newWindowStack << window->frameId();

But im unsure about Wayland... Does it exist on Wayland?

As for Window leaks - i think its subject for another ticket - with much lower
priority. 
But Window objects are leaking - that true.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to