We are seeing a problem in Metacity where a fullscreen window obscures a second created window that has a particular style: WS_DLGFRAME | WS_THICKFRAME.
When window A is created fullscreen (WS_POPUP, size matches screen res) and window B is created as an "owned window" (WS_DLGFRAME|WS_THICKFRAME|WS_OVERLAPPED style with "A" as its parent) you cannot see "B" if Metacity is running.
You can if other window managers are running. We tried kwin, xfce, fluxbox, enlightenment or fvvm. So the problem is something specific to Metacity.
You can also see window "B" if you remove either the WS_DLGFRAME or WS_THICKFRAME bit from the style.
Any hints about where to look within Wine or what could be happening?
- mo
PS: the code (ctrl+c to quit)...
#include <windows.h>
const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd, hwnd4; MSG Msg;
//Step 1: Registering the Window Class wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }
// Step 2: Creating the Window int width = ::GetSystemMetrics(SM_CXSCREEN); int height = ::GetSystemMetrics(SM_CYSCREEN); hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "A", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);
if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }
hwnd4 = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "B", #if 1 // invisible WS_DLGFRAME|WS_THICKFRAME|WS_OVERLAPPED, #else // visible WS_THICKFRAME|WS_OVERLAPPED, #endif 300, 300, 240, 120, hwnd, NULL, hInstance, NULL);
if(hwnd4 == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }
ShowWindow(hwnd, nCmdShow); ShowWindow(hwnd4, nCmdShow); UpdateWindow(hwnd); UpdateWindow(hwnd4);
// Step 3: The Message Loop while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }
Michael Ost most@museresearch.com wrote:
We are seeing a problem in Metacity where a fullscreen window obscures a second created window that has a particular style: WS_DLGFRAME | WS_THICKFRAME.
When window A is created fullscreen (WS_POPUP, size matches screen res) and window B is created as an "owned window" (WS_DLGFRAME|WS_THICKFRAME|WS_OVERLAPPED style with "A" as its parent) you cannot see "B" if Metacity is running.
You can if other window managers are running. We tried kwin, xfce, fluxbox, enlightenment or fvvm. So the problem is something specific to Metacity.
You can also see window "B" if you remove either the WS_DLGFRAME or WS_THICKFRAME bit from the style.
Any hints about where to look within Wine or what could be happening?
Have a look at dlls/winex11.drv/window.c. It looks like windows of type _NET_WM_WINDOW_TYPE_DIALOG have a similar problem to the one related to _NET_WM_WINDOW_TYPE_UTILITY. Try to comment out appropriate line of code and see if that helps.
Dmitry Timoshkov wrote:
Michael Ost most@museresearch.com wrote:
We are seeing a problem in Metacity where a fullscreen window obscures a second created window that has a particular style: WS_DLGFRAME | WS_THICKFRAME.
When window A is created fullscreen (WS_POPUP, size matches screen res) and window B is created as an "owned window" (WS_DLGFRAME|WS_THICKFRAME|WS_OVERLAPPED style with "A" as its parent) you cannot see "B" if Metacity is running.
You can if other window managers are running. We tried kwin, xfce, fluxbox, enlightenment or fvvm. So the problem is something specific to Metacity.
You can also see window "B" if you remove either the WS_DLGFRAME or WS_THICKFRAME bit from the style.
Any hints about where to look within Wine or what could be happening?
Have a look at dlls/winex11.drv/window.c. It looks like windows of type _NET_WM_WINDOW_TYPE_DIALOG have a similar problem to the one related to _NET_WM_WINDOW_TYPE_UTILITY. Try to comment out appropriate line of code and see if that helps.
The problem happens because the first test in set_wm_hints catches the WS_THICKFRAME bit and sets the window style to _NET_WM_WINDOW_TYPE_NORMAL. If I move the WS_DLGFRAME test first, and set the style to _NET_WM_WINDOW_TYPE_DIALOG, then it works.
As I read the MSDN window style docs, it seems like a dialog style should trump a THICKFRAME style. But I am not so familiar with what the _NET_WM_WINDOW_TYPE_* styles mean and how to map them to Windows' styles.
So, what's the preferred fix? Should I change set_wm_hints to catch the DIALOG styles first (see diff below)? That seems reasonable to me. Does that sound safe to you?
Is this something that should be generally available or just a one off hack for my version of wine?
Thanks for your help! ... mo
PS: diff showing change to catch dialog styles first in set_wm_hints...
[root@Deceptor winex11.drv]# diff -Naur window.c-1.0-1.fc8.5muse window.c --- window.c-1.0-1.fc8.5muse 2008-10-02 09:27:09.000000000 -0700 +++ window.c 2008-10-02 09:38:22.000000000 -0700 @@ -903,10 +903,10 @@ set_size_hints( display, data, style );
/* set the WM_WINDOW_TYPE */ - if (style & WS_THICKFRAME) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_NORMAL); - else if (ex_style & WS_EX_APPWINDOW) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_NORMAL); - else if (style & WS_DLGFRAME) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_DIALOG); + if (style & WS_DLGFRAME) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_DIALOG); else if (ex_style & WS_EX_DLGMODALFRAME) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_DIALOG); + else if (style & WS_THICKFRAME) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_NORMAL); + else if (ex_style & WS_EX_APPWINDOW) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_NORMAL); else if ((style & WS_POPUP) && owner) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_DIALOG); #if 0 /* many window managers don't handle utility windows very well */ else if (ex_style & WS_EX_TOOLWINDOW) window_type = x11drv_atom(_NET_WM_WINDOW_TYPE_UTILITY);
Michael Ost most@museresearch.com wrote:
So, what's the preferred fix? Should I change set_wm_hints to catch the DIALOG styles first (see diff below)? That seems reasonable to me. Does that sound safe to you?
Is this something that should be generally available or just a one off hack for my version of wine?
I'd say go ahead and send the patch.