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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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 */