Author: fireball Date: Mon Dec 6 14:13:08 2010 New Revision: 49963
URL: http://svn.reactos.org/svn/reactos?rev=49963&view=rev Log: - Move to a more formalized window manager interaction in winent. Based on code from winex11.drv. [1/2] - As a result, windows should appear and hide correctly, as expected by the core user32/server code.
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c branches/arwinss/reactos/dll/win32/winent.drv/winent.h branches/arwinss/reactos/dll/win32/winent.drv/wnd.c
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Mon Dec 6 14:13:08 2010 @@ -583,11 +583,11 @@ if (hwnd) { /* Capturing */ - FIXME("Capture set for hwnd %x\n", hwnd); + TRACE("Capture set for hwnd %x\n", hwnd); } else { - FIXME("Capture released\n"); + TRACE("Capture released\n"); } }
@@ -628,7 +628,27 @@
void CDECL RosDrv_SetParent( HWND hwnd, HWND parent, HWND old_parent ) { - UNIMPLEMENTED; + struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd ); + + if (!data) return; + if (parent == old_parent) return; + + if (parent != GetDesktopWindow()) /* a child window */ + { + if (old_parent == GetDesktopWindow()) + { + /* destroy the old windows */ + //destroy_whole_window( data, FALSE ); + //destroy_icon_window( data ); + FIXME("Should destroy hwnd %x\n", data->hwnd); + } + } + else /* new top level window */ + { + /* FIXME: we ignore errors since we can't really recover anyway */ + //create_whole_window( data ); + FIXME("Should create a new whole window for hwnd %x\n", data->hwnd); + } }
int CDECL RosDrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) @@ -658,6 +678,11 @@
/* Do some magic... */ TRACE("Window %x is being made visible1\n", hwnd); + + if (data->whole_window && is_window_rect_mapped( &data->window_rect )) + { + if (!data->mapped) map_window( data, style->styleNew ); + } }
if (offset == GWL_STYLE && (changed & WS_DISABLED)) @@ -737,14 +762,16 @@ const RECT *window_rect, const RECT *rectClient, const RECT *visible_rect, const RECT *valid_rects ) { - RECT old_whole_rect, old_client_rect; + RECT old_whole_rect, old_client_rect, old_window_rect; struct ntdrv_win_data *data = NTDRV_get_win_data(hwnd); + DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE );
if (!data) return;
TRACE( "win %x pos changed. new vis rect %s, old whole rect %s, swp_flags %x insert_after %x\n", hwnd, wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(&data->whole_rect), swp_flags, insert_after );
+ old_window_rect = data->window_rect; old_whole_rect = data->whole_rect; old_client_rect = data->client_rect; data->window_rect = *window_rect; @@ -778,18 +805,38 @@
if (!data->whole_window) return;
- /* Sync position change */ - if (!(swp_flags & SWP_NOREDRAW)) // HACK: When removing this, explorer's start menu starts to appear partially. Investigate! - { - /* SWM: Change windows position */ - SwmPosChanged(hwnd, &data->whole_rect, &old_whole_rect, insert_after, swp_flags); + /* Sync window position with the SWM */ + sync_window_position( data, swp_flags, + &old_window_rect, &old_whole_rect, &old_client_rect ); + + if (data->mapped) + { + if (((swp_flags & SWP_HIDEWINDOW) && !(new_style & WS_VISIBLE)) || + (!is_window_rect_mapped( window_rect ) && is_window_rect_mapped( &old_window_rect ))) + unmap_window( data ); }
/* Pass show/hide information to the window manager */ - if (swp_flags & SWP_SHOWWINDOW) - SwmShowWindow(hwnd, TRUE, swp_flags); - else if (swp_flags & SWP_HIDEWINDOW) - SwmShowWindow(hwnd, FALSE, swp_flags); + if ((new_style & WS_VISIBLE) && + ((new_style & WS_MINIMIZE) || is_window_rect_mapped( window_rect ))) + { + //if (!data->mapped || (swp_flags & (SWP_FRAMECHANGED|SWP_STATECHANGED))) + //set_wm_hints( display, data ); + + if (!data->mapped) + { + map_window( data, new_style ); + } + else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic != !(new_style & WS_MINIMIZE))) + { + data->iconic = (new_style & WS_MINIMIZE) != 0; + FIXME( "changing win %p iconic state to %u\n", data->hwnd, data->iconic ); + //if (data->iconic) + // XIconifyWindow( display, data->whole_window, DefaultScreen(display) ); + //else if (is_window_rect_mapped( rectWindow )) + // XMapWindow( display, data->whole_window ); + } + } }
/* EOF */
Modified: branches/arwinss/reactos/dll/win32/winent.drv/winent.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] Mon Dec 6 14:13:08 2010 @@ -37,6 +37,9 @@ RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to parent */ HCURSOR cursor; /* current cursor */ + BOOL mapped : 1; /* is window mapped? (in either normal or iconic state) */ + BOOL iconic : 1; /* is window in iconic state? */ + BOOL shaped : 1; /* is window using a custom region shape? */ };
/* clipboard.c */ @@ -84,3 +87,9 @@ struct ntdrv_win_data *NTDRV_create_desktop_win_data( HWND hwnd ); void NTDRV_destroy_win_data( HWND hwnd ); VOID CDECL RosDrv_UpdateZOrder(HWND hwnd, RECT *rect); +void map_window( struct ntdrv_win_data *data, DWORD new_style ); +void unmap_window( struct ntdrv_win_data *data ); +BOOL is_window_rect_mapped( const RECT *rect ); +void sync_window_position( struct ntdrv_win_data *data, + UINT swp_flags, const RECT *old_window_rect, + const RECT *old_whole_rect, const RECT *old_client_rect );
Modified: branches/arwinss/reactos/dll/win32/winent.drv/wnd.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/wnd.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/wnd.c [iso-8859-1] Mon Dec 6 14:13:08 2010 @@ -194,5 +194,95 @@ SwmRemoveWindow( hwnd ); }
+/*********************************************************************** + * map_window + */ +void map_window( struct ntdrv_win_data *data, DWORD new_style ) +{ + TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); + + SwmShowWindow( data->hwnd, TRUE, 0); + + data->mapped = TRUE; + data->iconic = (new_style & WS_MINIMIZE) != 0; +} + + +/*********************************************************************** + * unmap_window + */ +void unmap_window( struct ntdrv_win_data *data ) +{ + TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); + + SwmShowWindow( data->hwnd, FALSE, 0); + + data->mapped = FALSE; + //data->net_wm_state = 0; +} + +/*********************************************************************** + * is_window_rect_mapped + * + * Check if the SWM whole window should be mapped based on its rectangle + */ +BOOL is_window_rect_mapped( const RECT *rect ) +{ + /* don't map if rect is off-screen */ + /*if (rect->left >= virtual_screen_rect.right || + rect->top >= virtual_screen_rect.bottom || + rect->right <= virtual_screen_rect.left || + rect->bottom <= virtual_screen_rect.top) + return FALSE;*/ + + return TRUE; +} + +/*********************************************************************** + * sync_window_position + * + * Synchronize the SWM window position with the Windows one + */ +void sync_window_position( struct ntdrv_win_data *data, + UINT swp_flags, const RECT *old_window_rect, + const RECT *old_whole_rect, const RECT *old_client_rect ) +{ + SwmPosChanged(data->hwnd, &data->whole_rect, old_whole_rect, NULL, swp_flags); + + if (!(swp_flags & SWP_NOZORDER) || (swp_flags & SWP_SHOWWINDOW)) + { + /* find window that this one must be after */ + HWND prev = GetWindow( data->hwnd, GW_HWNDPREV ); + while (prev && !(GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE)) + prev = GetWindow( prev, GW_HWNDPREV ); + if (!prev) /* top child */ + { + /* Bring this window to foreground */ + SwmSetForeground(data->hwnd); + } + /* should use stack_mode Below but most window managers don't get it right */ + /* and Above with a sibling doesn't work so well either, so we ignore it */ + } + +#ifdef HAVE_LIBXSHAPE + if (IsRectEmpty( old_window_rect ) != IsRectEmpty( &data->window_rect )) + sync_window_region( display, data, (HRGN)1 ); + if (data->shaped) + { + int old_x_offset = old_window_rect->left - old_whole_rect->left; + int old_y_offset = old_window_rect->top - old_whole_rect->top; + int new_x_offset = data->window_rect.left - data->whole_rect.left; + int new_y_offset = data->window_rect.top - data->whole_rect.top; + if (old_x_offset != new_x_offset || old_y_offset != new_y_offset) + XShapeOffsetShape( display, data->whole_window, ShapeBounding, + new_x_offset - old_x_offset, new_y_offset - old_y_offset ); + } +#endif + + TRACE( "win %p/%lx pos %d,%d,%dx%d\n", + data->hwnd, data->whole_window, data->whole_rect.left, data->whole_rect.top, + data->whole_rect.right - data->whole_rect.left, + data->whole_rect.bottom - data->whole_rect.top ); +}
/* EOF */