https://bugs.winehq.org/show_bug.cgi?id=52811
Bug ID: 52811 Summary: Apps starting with wrong non-client area decoration Product: Wine Version: 7.6 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: trivial Priority: P2 Component: user32 Assignee: wine-bugs@winehq.org Reporter: leandrohr@riseup.net Distribution: ---
Created attachment 72186 --> https://bugs.winehq.org/attachment.cgi?id=72186 Small client to reproduce the bug
Arch Linux wine-6.0-rc1-11894-gafd7b319e56
---
# Bug description
During the development of the Wine Wayland driver we've noticed a bug that also affects the X11 driver when using client-side decorations.
Some applications start with the wrong decoration. It's a visual-only issue, as the application starts with focus and works nicely. But its non-client area starts with the decoration of inactive applications (greyed out).
This is how it should start: https://share.collabora.com/index.php/s/tZQxBEaybgwGgpi
But this is how it looks like: https://share.collabora.com/index.php/s/bQbASjTXg8oxg3W
---
# How to reproduce
You can easily reproduce this by running notepad with the X11 driver option "Decorated" set to "N". I wrote some small clients to debug this, and the simple program attached reproduces the issue. TLDR: it is a program that activates a window of a non-foreground thread and then tries to show it.
---
# What I think is going on
When we call SetActiveWindow(hwnd), hwnd does not become the foreground window, as the application thread is not the foreground thread yet (at this point the desktop window is the foreground window). SetActiveWindow() activates the non-client area only if the window is the foreground window, so we have activated the window but didn't activate its non-client area (which is correct AFAIU).
Next we call ShowWindow(hwnd), and now the thread that owns hwnd should become foreground and SetActiveWindow(hwnd) is called. But as hwnd is already active it does nothing and returns, so the non-client area is draw as inactive.
---
# Possible fix
In order to fix this, we could change SetActiveWindow() behavior to the following:
if (hwnd == current active window) if (hwnd == NtUserGetForegroundWindow() && non-client area of hwnd not active) activate non-client area of hwnd bail out
I wrote a test for this, and I could see that this fix didn't break any other tests. I've decided to post here in order to know if the fix seems reasonable to you.
Also, I had a question while debugging this and still couldn't figure out. I thought that focus was a global property related to the foreground window. But it seems that when a window is set to active the function to change the focus to it may also be called (even when the window does not belong to the foreground thread). So can a non-foreground window be active and have the focus?
---
Thanks a lot!