forked from Mirrors/wine-wine
Don't try to resync Z-order on ConfigureNotify events, this cannot
work right anyway.oldstable
parent
811725ac20
commit
44e6d5a48d
|
@ -1275,128 +1275,6 @@ void X11DRV_UnmapNotify( HWND hwnd, XEvent *event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* query_zorder
|
|
||||||
*
|
|
||||||
* Synchronize internal z-order with the window manager's.
|
|
||||||
*/
|
|
||||||
static Window __get_common_ancestor( Display *display, Window A, Window B,
|
|
||||||
Window** children, unsigned* total )
|
|
||||||
{
|
|
||||||
/* find the real root window */
|
|
||||||
|
|
||||||
Window root, *childrenB;
|
|
||||||
unsigned totalB;
|
|
||||||
|
|
||||||
wine_tsx11_lock();
|
|
||||||
while( A != B && A && B )
|
|
||||||
{
|
|
||||||
XQueryTree( display, A, &root, &A, children, total );
|
|
||||||
XQueryTree( display, B, &root, &B, &childrenB, &totalB );
|
|
||||||
if( childrenB ) XFree( childrenB );
|
|
||||||
if( *children ) XFree( *children ), *children = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( A && B )
|
|
||||||
{
|
|
||||||
XQueryTree( display, A, &root, &B, children, total );
|
|
||||||
wine_tsx11_unlock();
|
|
||||||
return A;
|
|
||||||
}
|
|
||||||
wine_tsx11_unlock();
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Window __get_top_decoration( Display *display, Window w, Window ancestor )
|
|
||||||
{
|
|
||||||
Window* children, root, prev = w, parent = w;
|
|
||||||
unsigned total;
|
|
||||||
|
|
||||||
wine_tsx11_lock();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
w = parent;
|
|
||||||
XQueryTree( display, w, &root, &parent, &children, &total );
|
|
||||||
if( children ) XFree( children );
|
|
||||||
} while( parent && parent != ancestor );
|
|
||||||
wine_tsx11_unlock();
|
|
||||||
TRACE("\t%08x -> %08x\n", (unsigned)prev, (unsigned)w );
|
|
||||||
return ( parent ) ? w : 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned __td_lookup( Window w, Window* list, unsigned max )
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
for( i = max; i > 0; i-- ) if( list[i - 1] == w ) break;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HWND query_zorder( Display *display, HWND hWndCheck)
|
|
||||||
{
|
|
||||||
HWND hwndInsertAfter = HWND_TOP;
|
|
||||||
Window w, parent, *children = NULL;
|
|
||||||
unsigned total, check, pos, best;
|
|
||||||
HWND *list = WIN_ListChildren( GetDesktopWindow() );
|
|
||||||
HWND hwndA = 0, hwndB = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* find at least two managed windows */
|
|
||||||
if (!list) return 0;
|
|
||||||
for (i = 0; list[i]; i++)
|
|
||||||
{
|
|
||||||
if (!(GetWindowLongW( list[i], GWL_STYLE ) & WS_VISIBLE)) continue;
|
|
||||||
if (!GetPropA( list[i], "__wine_x11_managed" )) continue;
|
|
||||||
if (!hwndA) hwndA = list[i];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hwndB = list[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hwndA || !hwndB) goto done;
|
|
||||||
|
|
||||||
parent = __get_common_ancestor( display, X11DRV_get_whole_window(hwndA),
|
|
||||||
X11DRV_get_whole_window(hwndB), &children, &total );
|
|
||||||
if( parent && children )
|
|
||||||
{
|
|
||||||
/* w is the ancestor if hWndCheck that is a direct descendant of 'parent' */
|
|
||||||
|
|
||||||
w = __get_top_decoration( display, X11DRV_get_whole_window(hWndCheck), parent );
|
|
||||||
|
|
||||||
if( w != children[total-1] ) /* check if at the top */
|
|
||||||
{
|
|
||||||
/* X child at index 0 is at the bottom, at index total-1 is at the top */
|
|
||||||
check = __td_lookup( w, children, total );
|
|
||||||
best = total;
|
|
||||||
|
|
||||||
/* go through all windows in Wine z-order... */
|
|
||||||
for (i = 0; list[i]; i++)
|
|
||||||
{
|
|
||||||
if (list[i] == hWndCheck) continue;
|
|
||||||
if (!GetPropA( list[i], "__wine_x11_managed" )) continue;
|
|
||||||
if (!(w = __get_top_decoration( display, X11DRV_get_whole_window(list[i]),
|
|
||||||
parent ))) continue;
|
|
||||||
pos = __td_lookup( w, children, total );
|
|
||||||
if( pos < best && pos > check )
|
|
||||||
{
|
|
||||||
/* find a nearest Wine window precedes hWndCheck in the real z-order */
|
|
||||||
best = pos;
|
|
||||||
hwndInsertAfter = list[i];
|
|
||||||
}
|
|
||||||
if( best - check == 1 ) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wine_tsx11_lock();
|
|
||||||
if( children ) XFree( children );
|
|
||||||
wine_tsx11_unlock();
|
|
||||||
|
|
||||||
done:
|
|
||||||
HeapFree( GetProcessHeap(), 0, list );
|
|
||||||
return hwndInsertAfter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* X11DRV_handle_desktop_resize
|
* X11DRV_handle_desktop_resize
|
||||||
*/
|
*/
|
||||||
|
@ -1421,11 +1299,10 @@ void X11DRV_handle_desktop_resize( unsigned int width, unsigned int height )
|
||||||
void X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
void X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
||||||
{
|
{
|
||||||
XConfigureEvent *event = &xev->xconfigure;
|
XConfigureEvent *event = &xev->xconfigure;
|
||||||
HWND oldInsertAfter;
|
|
||||||
struct x11drv_win_data *data;
|
struct x11drv_win_data *data;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
WINDOWPOS winpos;
|
UINT flags;
|
||||||
int x = event->x, y = event->y;
|
int cx, cy, x = event->x, y = event->y;
|
||||||
|
|
||||||
if (!hwnd) return;
|
if (!hwnd) return;
|
||||||
if (!(data = X11DRV_get_win_data( hwnd ))) return;
|
if (!(data = X11DRV_get_win_data( hwnd ))) return;
|
||||||
|
@ -1449,57 +1326,32 @@ void X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
||||||
event->x, event->y, event->width, event->height );
|
event->x, event->y, event->width, event->height );
|
||||||
X11DRV_X_to_window_rect( data, &rect );
|
X11DRV_X_to_window_rect( data, &rect );
|
||||||
|
|
||||||
winpos.hwnd = hwnd;
|
x = rect.left;
|
||||||
winpos.x = rect.left;
|
y = rect.top;
|
||||||
winpos.y = rect.top;
|
cx = rect.right - rect.left;
|
||||||
winpos.cx = rect.right - rect.left;
|
cy = rect.bottom - rect.top;
|
||||||
winpos.cy = rect.bottom - rect.top;
|
flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_WINE_NOHOSTMOVE;
|
||||||
winpos.flags = SWP_NOACTIVATE;
|
|
||||||
|
|
||||||
/* Get Z-order (FIXME) */
|
|
||||||
|
|
||||||
winpos.hwndInsertAfter = query_zorder( event->display, hwnd );
|
|
||||||
|
|
||||||
/* needs to find the first Visible Window above the current one */
|
|
||||||
oldInsertAfter = hwnd;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
oldInsertAfter = GetWindow( oldInsertAfter, GW_HWNDPREV );
|
|
||||||
if (!oldInsertAfter)
|
|
||||||
{
|
|
||||||
oldInsertAfter = HWND_TOP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (GetWindowLongA( oldInsertAfter, GWL_STYLE ) & WS_VISIBLE) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare what has changed */
|
/* Compare what has changed */
|
||||||
|
|
||||||
GetWindowRect( hwnd, &rect );
|
GetWindowRect( hwnd, &rect );
|
||||||
if (rect.left == winpos.x && rect.top == winpos.y) winpos.flags |= SWP_NOMOVE;
|
if (rect.left == x && rect.top == y) flags |= SWP_NOMOVE;
|
||||||
else
|
else
|
||||||
TRACE( "%p moving from (%ld,%ld) to (%d,%d)\n",
|
TRACE( "%p moving from (%ld,%ld) to (%d,%d)\n",
|
||||||
hwnd, rect.left, rect.top, winpos.x, winpos.y );
|
hwnd, rect.left, rect.top, x, y );
|
||||||
|
|
||||||
if ((rect.right - rect.left == winpos.cx && rect.bottom - rect.top == winpos.cy) ||
|
if ((rect.right - rect.left == cx && rect.bottom - rect.top == cy) ||
|
||||||
IsIconic(hwnd) ||
|
IsIconic(hwnd) ||
|
||||||
(IsRectEmpty( &rect ) && winpos.cx == 1 && winpos.cy == 1))
|
(IsRectEmpty( &rect ) && cx == 1 && cy == 1))
|
||||||
winpos.flags |= SWP_NOSIZE;
|
{
|
||||||
|
if (flags & SWP_NOMOVE) return; /* if nothing changed, don't do anything */
|
||||||
|
flags |= SWP_NOSIZE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
TRACE( "%p resizing from (%ldx%ld) to (%dx%d)\n",
|
TRACE( "%p resizing from (%ldx%ld) to (%dx%d)\n",
|
||||||
hwnd, rect.right - rect.left, rect.bottom - rect.top,
|
hwnd, rect.right - rect.left, rect.bottom - rect.top, cx, cy );
|
||||||
winpos.cx, winpos.cy );
|
|
||||||
|
|
||||||
if (winpos.hwndInsertAfter == oldInsertAfter) winpos.flags |= SWP_NOZORDER;
|
SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
|
||||||
else
|
|
||||||
TRACE( "%p restacking from after %p to after %p\n",
|
|
||||||
hwnd, oldInsertAfter, winpos.hwndInsertAfter );
|
|
||||||
|
|
||||||
/* if nothing changed, don't do anything */
|
|
||||||
if (winpos.flags == (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE)) return;
|
|
||||||
|
|
||||||
SetWindowPos( hwnd, winpos.hwndInsertAfter, winpos.x, winpos.y,
|
|
||||||
winpos.cx, winpos.cy, winpos.flags | SWP_WINE_NOHOSTMOVE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue