winex11: Rely on PropertyNotify events instead of Map/UnmapNotify to detect iconification.

This commit is contained in:
Alexandre Julliard 2008-04-02 15:58:59 +02:00
parent f89aa12829
commit a442d3b46d
3 changed files with 50 additions and 68 deletions

View File

@ -104,7 +104,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] =
/* VisibilityNotify */ /* VisibilityNotify */
/* CreateNotify */ /* CreateNotify */
{ DestroyNotify, X11DRV_DestroyNotify }, { DestroyNotify, X11DRV_DestroyNotify },
{ UnmapNotify, X11DRV_UnmapNotify }, /* UnmapNotify */
{ MapNotify, X11DRV_MapNotify }, { MapNotify, X11DRV_MapNotify },
/* MapRequest */ /* MapRequest */
/* ReparentNotify */ /* ReparentNotify */
@ -123,7 +123,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] =
{ MappingNotify, X11DRV_MappingNotify }, { MappingNotify, X11DRV_MappingNotify },
}; };
static int nb_event_handlers = 19; /* change this if you add handlers above */ static int nb_event_handlers = 18; /* change this if you add handlers above */
/* return the name of an X event */ /* return the name of an X event */
@ -691,7 +691,8 @@ int get_window_wm_state( Display *display, struct x11drv_win_data *data )
* *
* Handle a PropertyNotify for WM_STATE. * Handle a PropertyNotify for WM_STATE.
*/ */
static void handle_wm_state_notify( struct x11drv_win_data *data, XPropertyEvent *event ) static void handle_wm_state_notify( struct x11drv_win_data *data, XPropertyEvent *event,
BOOL update_window )
{ {
switch(event->state) switch(event->state)
{ {
@ -710,6 +711,50 @@ static void handle_wm_state_notify( struct x11drv_win_data *data, XPropertyEvent
} }
break; break;
} }
if (!update_window || !data->managed || !data->mapped) return;
if (data->iconic && data->wm_state == NormalState) /* restore window */
{
int x, y;
unsigned int width, height, border, depth;
Window root, top;
WINDOWPLACEMENT wp;
RECT rect;
/* FIXME: hack */
wine_tsx11_lock();
XGetGeometry( event->display, data->whole_window, &root, &x, &y, &width, &height,
&border, &depth );
XTranslateCoordinates( event->display, data->whole_window, root, 0, 0, &x, &y, &top );
wine_tsx11_unlock();
rect.left = x;
rect.top = y;
rect.right = x + width;
rect.bottom = y + height;
OffsetRect( &rect, virtual_screen_rect.left, virtual_screen_rect.top );
X11DRV_X_to_window_rect( data, &rect );
wp.length = sizeof(wp);
GetWindowPlacement( data->hwnd, &wp );
wp.flags = 0;
wp.showCmd = SW_RESTORE;
wp.rcNormalPosition = rect;
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
data->iconic = FALSE;
data->lock_changes++;
SetWindowPlacement( data->hwnd, &wp );
data->lock_changes--;
}
else if (!data->iconic && data->wm_state == IconicState)
{
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
data->iconic = TRUE;
data->lock_changes++;
ShowWindow( data->hwnd, SW_MINIMIZE );
data->lock_changes--;
}
} }
@ -724,7 +769,7 @@ static void EVENT_PropertyNotify( HWND hwnd, XEvent *xev )
if (!hwnd) return; if (!hwnd) return;
if (!(data = X11DRV_get_win_data( hwnd ))) return; if (!(data = X11DRV_get_win_data( hwnd ))) return;
if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( data, event ); if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( data, event, TRUE );
} }
@ -762,7 +807,7 @@ void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, B
else else
{ {
wine_tsx11_unlock(); wine_tsx11_unlock();
handle_wm_state_notify( data, &event.xproperty ); handle_wm_state_notify( data, &event.xproperty, FALSE );
wine_tsx11_lock(); wine_tsx11_lock();
} }
} }

View File

@ -437,7 +437,6 @@ void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
void X11DRV_MapNotify( HWND hwnd, XEvent *event ) void X11DRV_MapNotify( HWND hwnd, XEvent *event )
{ {
struct x11drv_win_data *data; struct x11drv_win_data *data;
int state;
if (!(data = X11DRV_get_win_data( hwnd ))) return; if (!(data = X11DRV_get_win_data( hwnd ))) return;
if (!data->mapped) return; if (!data->mapped) return;
@ -446,71 +445,10 @@ void X11DRV_MapNotify( HWND hwnd, XEvent *event )
{ {
HWND hwndFocus = GetFocus(); HWND hwndFocus = GetFocus();
if (hwndFocus && IsChild( hwnd, hwndFocus )) X11DRV_SetFocus(hwndFocus); /* FIXME */ if (hwndFocus && IsChild( hwnd, hwndFocus )) X11DRV_SetFocus(hwndFocus); /* FIXME */
return;
} }
if (!data->iconic) return;
state = get_window_wm_state( event->xmap.display, data );
if (state == NormalState)
{
int x, y;
unsigned int width, height, border, depth;
Window root, top;
WINDOWPLACEMENT wp;
RECT rect;
/* FIXME: hack */
wine_tsx11_lock();
XGetGeometry( event->xmap.display, data->whole_window, &root, &x, &y, &width, &height,
&border, &depth );
XTranslateCoordinates( event->xmap.display, data->whole_window, root, 0, 0, &x, &y, &top );
wine_tsx11_unlock();
rect.left = x;
rect.top = y;
rect.right = x + width;
rect.bottom = y + height;
OffsetRect( &rect, virtual_screen_rect.left, virtual_screen_rect.top );
X11DRV_X_to_window_rect( data, &rect );
wp.length = sizeof(wp);
GetWindowPlacement( hwnd, &wp );
wp.flags = 0;
wp.showCmd = SW_RESTORE;
wp.rcNormalPosition = rect;
TRACE( "restoring win %p/%lx\n", hwnd, data->whole_window );
data->iconic = FALSE;
data->lock_changes++;
SetWindowPlacement( hwnd, &wp );
data->lock_changes--;
}
else TRACE( "win %p/%lx ignoring since state=%d\n", hwnd, data->whole_window, state );
} }
/**********************************************************************
* X11DRV_UnmapNotify
*/
void X11DRV_UnmapNotify( HWND hwnd, XEvent *event )
{
struct x11drv_win_data *data;
int state;
if (!(data = X11DRV_get_win_data( hwnd ))) return;
if (!data->managed || !data->mapped || data->iconic) return;
state = get_window_wm_state( event->xunmap.display, data );
if (state == IconicState)
{
TRACE( "minimizing win %p/%lx\n", hwnd, data->whole_window );
data->iconic = TRUE;
data->lock_changes++;
ShowWindow( hwnd, SW_MINIMIZE );
data->lock_changes--;
}
else TRACE( "win %p/%lx ignoring since state=%d\n", hwnd, data->whole_window, state );
}
struct desktop_resize_data struct desktop_resize_data
{ {
RECT old_screen_rect; RECT old_screen_rect;

View File

@ -630,7 +630,6 @@ extern void X11DRV_KeymapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_Expose( HWND hwnd, XEvent *event ); extern void X11DRV_Expose( HWND hwnd, XEvent *event );
extern void X11DRV_DestroyNotify( HWND hwnd, XEvent *event ); extern void X11DRV_DestroyNotify( HWND hwnd, XEvent *event );
extern void X11DRV_MapNotify( HWND hwnd, XEvent *event ); extern void X11DRV_MapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_UnmapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event ); extern void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event );
extern void X11DRV_SelectionRequest( HWND hWnd, XEvent *event ); extern void X11DRV_SelectionRequest( HWND hWnd, XEvent *event );
extern void X11DRV_SelectionClear( HWND hWnd, XEvent *event ); extern void X11DRV_SelectionClear( HWND hWnd, XEvent *event );