Author: fireball Date: Sat Nov 14 10:29:44 2009 New Revision: 44149
URL: http://svn.reactos.org/svn/reactos?rev=44149&view=rev Log: - Create windata for the desktop window in RosDrv_CreateWindow. - Fix RosDrv_SetFocus (it should bring to forward only parent window whenever any of its child is clicked, previously such events would be ignored). - Add some checks to RosDrv_ShowWindow, but without changing logic. - Fix a key problem of not differentiating between SWM managed and child windows. Fix this by adding the "whole_window" pointer to the windata structure, which will be a pointer to SWM's window structure. Right now it's just set to non-zero value if a window is an SWM window. - Zero win data structure in NTDRV_create_win_data.
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] Sat Nov 14 10:29:44 2009 @@ -42,9 +42,9 @@ HRGN rgn = 0; HWND parent = 0;
- if (TRUE) - { - //OffsetRect( &dst_rect, -data->window_rect.left, -data->window_rect.top ); + if (!data->whole_window) + { + OffsetRect( &dst_rect, -data->window_rect.left, -data->window_rect.top ); parent = GetAncestor( data->hwnd, GA_PARENT ); hdc_src = GetDCEx( parent, 0, DCX_CACHE ); hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE | DCX_WINDOW ); @@ -70,7 +70,7 @@
if (rgn) { - if (/*!data->whole_window*/TRUE) + if (!data->whole_window) { /* map region to client rect since we are using DCX_WINDOW */ OffsetRgn( rgn, data->window_rect.left - data->client_rect.left, @@ -203,8 +203,8 @@ PVOID pbits; static const WORD ICON_HOTSPOT = 0x4242; /* From user32/cursoricon.c:128 */
- TRACE("%p => %dx%d, %d bpp\n", ciconinfo, - ciconinfo->nWidth, ciconinfo->nHeight, ciconinfo->bBitsPerPixel); + //TRACE("%p => %dx%d, %d bpp\n", ciconinfo, + // ciconinfo->nWidth, ciconinfo->nHeight, ciconinfo->bBitsPerPixel);
if ( (ciconinfo->ptHotSpot.x == ICON_HOTSPOT) && (ciconinfo->ptHotSpot.y == ICON_HOTSPOT) ) @@ -483,6 +483,13 @@ BOOL CDECL RosDrv_CreateWindow( HWND hwnd ) { WARN("RosDrv_CreateWindow(%x)\n", hwnd); + + if (hwnd == GetDesktopWindow()) + { + /* create desktop win data */ + if (!NTDRV_create_desktop_win_data( hwnd )) return FALSE; + } + return TRUE; }
@@ -725,11 +732,34 @@ } }
+/******************************************************************* + * can_activate_window + * + * Check if we can activate the specified window. + */ +/*static inline BOOL can_activate_window( HWND hwnd ) +{ + LONG style = GetWindowLongW( hwnd, GWL_STYLE ); + if (!(style & WS_VISIBLE)) return FALSE; + if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; + if (style & WS_MINIMIZE) return FALSE; + if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_NOACTIVATE) return FALSE; + if (hwnd == GetDesktopWindow()) return FALSE; + return !(style & WS_DISABLED); +}*/ + void CDECL RosDrv_SetFocus( HWND hwnd ) { + struct ntdrv_win_data *data; + + if (!(hwnd = GetAncestor( hwnd, GA_ROOT ))) return; + if (!(data = NTDRV_get_win_data( hwnd ))) return; + if (!data->whole_window) return; + TRACE("SetFocus %x, desk %x\n", hwnd, GetDesktopWindow()); - if (GetDesktopWindow() != hwnd) - SwmSetForeground(hwnd); + + /* Bring this window to foreground */ + SwmSetForeground(hwnd); }
void CDECL RosDrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags ) @@ -790,8 +820,18 @@
UINT CDECL RosDrv_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) { + DWORD style = GetWindowLongW( hwnd, GWL_STYLE ); + struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd ); + + if (!data || !data->whole_window) return swp; + if (style & WS_MINIMIZE) return swp; + if (IsRectEmpty( rect )) return swp; + FIXME( "win %p cmd %d at %s flags %08x\n", hwnd, cmd, wine_dbgstr_rect(rect), swp ); + + /* ???: only fetch the new rectangle if the ShowWindow was a result of a window manager event */ + // TODO: Need to think about this
return swp; } @@ -842,8 +882,8 @@
if (!data) return;
- TRACE( "win %x pos changed. new vis rect %s, old whole rect %s, swp_flags %x\n", - hwnd, wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(&data->whole_rect), swp_flags ); + 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_whole_rect = data->whole_rect; old_client_rect = data->client_rect; @@ -866,20 +906,31 @@ old_client_rect.bottom - data->client_rect.bottom == y_offset && !memcmp( &valid_rects[0], &data->client_rect, sizeof(RECT) )) { - //move_window_bits( data, &old_whole_rect, &data->whole_rect, &old_client_rect ); - SwmPosChanged(hwnd, &data->whole_rect, &old_whole_rect); + /* if we have an SWM window the bits will be moved by the SWM */ + if (!data->whole_window) + ;//move_window_bits( data, &old_whole_rect, &data->whole_rect, &old_client_rect ); + else + SwmPosChanged(hwnd, &data->whole_rect, &old_whole_rect); FIXME("change1\n"); } else { - move_window_bits( data, &valid_rects[1], &valid_rects[0], &old_client_rect ); + //move_window_bits( data, &valid_rects[1], &valid_rects[0], &old_client_rect ); FIXME("change2\n"); } }
+ if (!data->whole_window) return; + /* Pass show/hide information to the window manager */ if (swp_flags & SWP_SHOWWINDOW) + { + if (swp_flags & SWP_NOZORDER) FIXME("no zorder change, ignoring!\n"); + if (swp_flags & SWP_NOACTIVATE) FIXME("no activate change, ignoring!\n"); + + SwmSetForeground(hwnd); SwmShowWindow(hwnd, TRUE); + } else if (swp_flags & SWP_HIDEWINDOW) SwmShowWindow(hwnd, FALSE);
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] Sat Nov 14 10:29:44 2009 @@ -31,6 +31,7 @@ struct ntdrv_win_data { HWND hwnd; /* hwnd that this private data belongs to */ + PVOID whole_window; /* SWM window for the complete window */ RECT window_rect; /* USER window rectangle relative to parent */ RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to parent */ @@ -60,5 +61,6 @@ /* wnd.c */ struct ntdrv_win_data *NTDRV_get_win_data( HWND hwnd ); struct ntdrv_win_data *NTDRV_create_win_data( HWND hwnd ); +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);
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] Sat Nov 14 10:29:44 2009 @@ -78,8 +78,9 @@ /* don't create win data for HWND_MESSAGE windows */ if (parent != GetDesktopWindow() && !GetAncestor( parent, GA_PARENT )) return NULL;
- data = HeapAlloc(GetProcessHeap(), 0, sizeof(struct ntdrv_win_data)); + data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ntdrv_win_data)); if (!data) return NULL; + data->hwnd = hwnd;
/* Add it as a property to the window */ SetPropA( hwnd, window_data_prop, (HANDLE)data ); @@ -98,11 +99,26 @@
/* Inform window manager about window rect in screen coords */ SwmAddWindow(hwnd, &data->window_rect); + data->whole_window = (PVOID)1; }
- /* Add desktop window too */ - if (hwnd == GetDesktopWindow()) - SwmAddWindow(hwnd, &data->window_rect); + return data; +} + +/* initialize the desktop window id in the desktop manager process */ +struct ntdrv_win_data *NTDRV_create_desktop_win_data( HWND hwnd ) +{ + struct ntdrv_win_data *data; + + data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ntdrv_win_data)); + if (!data) return NULL; + data->hwnd = hwnd; + + /* Add it as a property to the window */ + SetPropA( hwnd, window_data_prop, (HANDLE)data ); + + /* Mark it as being a whole window */ + data->whole_window = (PVOID)1;
return data; }