Commit 2f69329a authored by Alexandre Julliard's avatar Alexandre Julliard

server: Add a separate request to set the window visible rect.

parent 755d806f
...@@ -241,7 +241,7 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow, ...@@ -241,7 +241,7 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
{ {
Display *display = thread_display(); Display *display = thread_display();
struct x11drv_win_data *data; struct x11drv_win_data *data;
RECT new_whole_rect, old_client_rect; RECT new_whole_rect, old_client_rect, visible_rect;
WND *win; WND *win;
DWORD old_style, new_style, new_ex_style; DWORD old_style, new_style, new_ex_style;
BOOL ret, make_managed = FALSE; BOOL ret, make_managed = FALSE;
...@@ -262,15 +262,12 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow, ...@@ -262,15 +262,12 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
} }
} }
new_whole_rect = *rectWindow;
X11DRV_window_to_X_rect( data, &new_whole_rect );
old_client_rect = data->client_rect; old_client_rect = data->client_rect;
if (!data->whole_window) swp_flags |= SWP_NOCOPYBITS; /* we can't rely on X11 to move the bits */ if (!data->whole_window) swp_flags |= SWP_NOCOPYBITS; /* we can't rely on X11 to move the bits */
if (!(win = WIN_GetPtr( hwnd ))) return FALSE; if (!(win = WIN_GetPtr( hwnd ))) return FALSE;
if (win == WND_OTHER_PROCESS) if (win == WND_DESKTOP || win == WND_OTHER_PROCESS)
{ {
if (IsWindow( hwnd )) ERR( "cannot set rectangles of other process window %p\n", hwnd ); if (IsWindow( hwnd )) ERR( "cannot set rectangles of other process window %p\n", hwnd );
return FALSE; return FALSE;
...@@ -288,34 +285,52 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow, ...@@ -288,34 +285,52 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
req->client.top = rectClient->top; req->client.top = rectClient->top;
req->client.right = rectClient->right; req->client.right = rectClient->right;
req->client.bottom = rectClient->bottom; req->client.bottom = rectClient->bottom;
if (memcmp( rectWindow, &new_whole_rect, sizeof(RECT) ) || !IsRectEmpty( &valid_rects[0] )) if (!IsRectEmpty( &valid_rects[0] ))
wine_server_add_data( req, valid_rects, 2 * sizeof(*valid_rects) );
if ((ret = !wine_server_call( req )))
{ {
wine_server_add_data( req, &new_whole_rect, sizeof(new_whole_rect) ); new_style = reply->new_style;
if (!IsRectEmpty( &valid_rects[0] )) new_ex_style = reply->new_ex_style;
wine_server_add_data( req, valid_rects, 2 * sizeof(*valid_rects) ); visible_rect.left = reply->visible.left;
visible_rect.top = reply->visible.top;
visible_rect.right = reply->visible.right;
visible_rect.bottom = reply->visible.bottom;
} }
ret = !wine_server_call( req );
new_style = reply->new_style;
new_ex_style = reply->new_ex_style;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (win == WND_DESKTOP || data->whole_window == DefaultRootWindow(gdi_display)) if (ret)
{ {
data->whole_rect = data->client_rect = data->window_rect = *rectWindow; if (data->whole_window == DefaultRootWindow(gdi_display))
if (win != WND_DESKTOP)
{ {
data->whole_rect = data->client_rect = data->window_rect = *rectWindow;
win->rectWindow = *rectWindow; win->rectWindow = *rectWindow;
win->rectClient = *rectClient; win->rectClient = *rectClient;
win->dwStyle = new_style; win->dwStyle = new_style;
win->dwExStyle = new_ex_style; win->dwExStyle = new_ex_style;
WIN_ReleasePtr( win ); WIN_ReleasePtr( win );
return TRUE;
}
new_whole_rect = *rectWindow;
X11DRV_window_to_X_rect( data, &new_whole_rect );
if (memcmp( &visible_rect, &new_whole_rect, sizeof(RECT) ))
{
TRACE( "%p: need to update visible rect %s -> %s\n", hwnd,
wine_dbgstr_rect(&visible_rect), wine_dbgstr_rect(&new_whole_rect) );
SERVER_START_REQ( set_window_visible_rect )
{
req->handle = hwnd;
req->flags = swp_flags;
req->visible.left = new_whole_rect.left;
req->visible.top = new_whole_rect.top;
req->visible.right = new_whole_rect.right;
req->visible.bottom = new_whole_rect.bottom;
wine_server_call( req );
}
SERVER_END_REQ;
} }
return ret;
}
if (ret)
{
/* invalidate DCEs */ /* invalidate DCEs */
if ((((swp_flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && (new_style & WS_VISIBLE)) || if ((((swp_flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && (new_style & WS_VISIBLE)) ||
......
...@@ -2965,6 +2965,21 @@ struct set_window_pos_reply ...@@ -2965,6 +2965,21 @@ struct set_window_pos_reply
struct reply_header __header; struct reply_header __header;
unsigned int new_style; unsigned int new_style;
unsigned int new_ex_style; unsigned int new_ex_style;
rectangle_t visible;
};
struct set_window_visible_rect_request
{
struct request_header __header;
unsigned int flags;
user_handle_t handle;
rectangle_t visible;
};
struct set_window_visible_rect_reply
{
struct reply_header __header;
}; };
...@@ -4416,6 +4431,7 @@ enum request ...@@ -4416,6 +4431,7 @@ enum request
REQ_get_window_children_from_point, REQ_get_window_children_from_point,
REQ_get_window_tree, REQ_get_window_tree,
REQ_set_window_pos, REQ_set_window_pos,
REQ_set_window_visible_rect,
REQ_get_window_rectangles, REQ_get_window_rectangles,
REQ_get_window_text, REQ_get_window_text,
REQ_set_window_text, REQ_set_window_text,
...@@ -4655,6 +4671,7 @@ union generic_request ...@@ -4655,6 +4671,7 @@ union generic_request
struct get_window_children_from_point_request get_window_children_from_point_request; struct get_window_children_from_point_request get_window_children_from_point_request;
struct get_window_tree_request get_window_tree_request; struct get_window_tree_request get_window_tree_request;
struct set_window_pos_request set_window_pos_request; struct set_window_pos_request set_window_pos_request;
struct set_window_visible_rect_request set_window_visible_rect_request;
struct get_window_rectangles_request get_window_rectangles_request; struct get_window_rectangles_request get_window_rectangles_request;
struct get_window_text_request get_window_text_request; struct get_window_text_request get_window_text_request;
struct set_window_text_request set_window_text_request; struct set_window_text_request set_window_text_request;
...@@ -4892,6 +4909,7 @@ union generic_reply ...@@ -4892,6 +4909,7 @@ union generic_reply
struct get_window_children_from_point_reply get_window_children_from_point_reply; struct get_window_children_from_point_reply get_window_children_from_point_reply;
struct get_window_tree_reply get_window_tree_reply; struct get_window_tree_reply get_window_tree_reply;
struct set_window_pos_reply set_window_pos_reply; struct set_window_pos_reply set_window_pos_reply;
struct set_window_visible_rect_reply set_window_visible_rect_reply;
struct get_window_rectangles_reply get_window_rectangles_reply; struct get_window_rectangles_reply get_window_rectangles_reply;
struct get_window_text_reply get_window_text_reply; struct get_window_text_reply get_window_text_reply;
struct set_window_text_reply set_window_text_reply; struct set_window_text_reply set_window_text_reply;
...@@ -4976,6 +4994,6 @@ union generic_reply ...@@ -4976,6 +4994,6 @@ union generic_reply
struct add_fd_completion_reply add_fd_completion_reply; struct add_fd_completion_reply add_fd_completion_reply;
}; };
#define SERVER_PROTOCOL_VERSION 336 #define SERVER_PROTOCOL_VERSION 337
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -2185,6 +2185,15 @@ enum message_type ...@@ -2185,6 +2185,15 @@ enum message_type
@REPLY @REPLY
unsigned int new_style; /* new window style */ unsigned int new_style; /* new window style */
unsigned int new_ex_style; /* new window extended style */ unsigned int new_ex_style; /* new window extended style */
rectangle_t visible; /* new visible rectangle */
@END
/* Set the visible rectangle of a window */
@REQ(set_window_visible_rect)
unsigned int flags; /* SWP_* flags */
user_handle_t handle; /* handle to the window */
rectangle_t visible; /* visible rectangle */
@END @END
......
...@@ -260,6 +260,7 @@ DECL_HANDLER(get_window_children); ...@@ -260,6 +260,7 @@ DECL_HANDLER(get_window_children);
DECL_HANDLER(get_window_children_from_point); DECL_HANDLER(get_window_children_from_point);
DECL_HANDLER(get_window_tree); DECL_HANDLER(get_window_tree);
DECL_HANDLER(set_window_pos); DECL_HANDLER(set_window_pos);
DECL_HANDLER(set_window_visible_rect);
DECL_HANDLER(get_window_rectangles); DECL_HANDLER(get_window_rectangles);
DECL_HANDLER(get_window_text); DECL_HANDLER(get_window_text);
DECL_HANDLER(set_window_text); DECL_HANDLER(set_window_text);
...@@ -498,6 +499,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -498,6 +499,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_window_children_from_point, (req_handler)req_get_window_children_from_point,
(req_handler)req_get_window_tree, (req_handler)req_get_window_tree,
(req_handler)req_set_window_pos, (req_handler)req_set_window_pos,
(req_handler)req_set_window_visible_rect,
(req_handler)req_get_window_rectangles, (req_handler)req_get_window_rectangles,
(req_handler)req_get_window_text, (req_handler)req_get_window_text,
(req_handler)req_set_window_text, (req_handler)req_set_window_text,
......
...@@ -2719,7 +2719,17 @@ static void dump_set_window_pos_request( const struct set_window_pos_request *re ...@@ -2719,7 +2719,17 @@ static void dump_set_window_pos_request( const struct set_window_pos_request *re
static void dump_set_window_pos_reply( const struct set_window_pos_reply *req ) static void dump_set_window_pos_reply( const struct set_window_pos_reply *req )
{ {
fprintf( stderr, " new_style=%08x,", req->new_style ); fprintf( stderr, " new_style=%08x,", req->new_style );
fprintf( stderr, " new_ex_style=%08x", req->new_ex_style ); fprintf( stderr, " new_ex_style=%08x,", req->new_ex_style );
fprintf( stderr, " visible=" );
dump_rectangle( &req->visible );
}
static void dump_set_window_visible_rect_request( const struct set_window_visible_rect_request *req )
{
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " visible=" );
dump_rectangle( &req->visible );
} }
static void dump_get_window_rectangles_request( const struct get_window_rectangles_request *req ) static void dump_get_window_rectangles_request( const struct get_window_rectangles_request *req )
...@@ -3921,6 +3931,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -3921,6 +3931,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_window_children_from_point_request, (dump_func)dump_get_window_children_from_point_request,
(dump_func)dump_get_window_tree_request, (dump_func)dump_get_window_tree_request,
(dump_func)dump_set_window_pos_request, (dump_func)dump_set_window_pos_request,
(dump_func)dump_set_window_visible_rect_request,
(dump_func)dump_get_window_rectangles_request, (dump_func)dump_get_window_rectangles_request,
(dump_func)dump_get_window_text_request, (dump_func)dump_get_window_text_request,
(dump_func)dump_set_window_text_request, (dump_func)dump_set_window_text_request,
...@@ -4156,6 +4167,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -4156,6 +4167,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_window_children_from_point_reply, (dump_func)dump_get_window_children_from_point_reply,
(dump_func)dump_get_window_tree_reply, (dump_func)dump_get_window_tree_reply,
(dump_func)dump_set_window_pos_reply, (dump_func)dump_set_window_pos_reply,
(dump_func)0,
(dump_func)dump_get_window_rectangles_reply, (dump_func)dump_get_window_rectangles_reply,
(dump_func)dump_get_window_text_reply, (dump_func)dump_get_window_text_reply,
(dump_func)0, (dump_func)0,
...@@ -4391,6 +4403,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -4391,6 +4403,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_window_children_from_point", "get_window_children_from_point",
"get_window_tree", "get_window_tree",
"set_window_pos", "set_window_pos",
"set_window_visible_rect",
"get_window_rectangles", "get_window_rectangles",
"get_window_text", "get_window_text",
"set_window_text", "set_window_text",
......
...@@ -1409,12 +1409,10 @@ static struct region *expose_window( struct window *win, const rectangle_t *old_ ...@@ -1409,12 +1409,10 @@ static struct region *expose_window( struct window *win, const rectangle_t *old_
/* set the window and client rectangles, updating the update region if necessary */ /* set the window and client rectangles, updating the update region if necessary */
static void set_window_pos( struct window *win, struct window *previous, static void set_window_pos( struct window *win, struct window *previous,
unsigned int swp_flags, const rectangle_t *window_rect, unsigned int swp_flags, const rectangle_t *window_rect,
const rectangle_t *client_rect, const rectangle_t *visible_rect, const rectangle_t *client_rect, const rectangle_t *valid_rects )
const rectangle_t *valid_rects )
{ {
struct region *old_vis_rgn = NULL, *exposed_rgn = NULL; struct region *old_vis_rgn = NULL, *exposed_rgn = NULL;
const rectangle_t old_window_rect = win->window_rect; const rectangle_t old_window_rect = win->window_rect;
const rectangle_t old_visible_rect = win->visible_rect;
const rectangle_t old_client_rect = win->client_rect; const rectangle_t old_client_rect = win->client_rect;
int client_changed, frame_changed; int client_changed, frame_changed;
int visible = (win->style & WS_VISIBLE) || (swp_flags & SWP_SHOWWINDOW); int visible = (win->style & WS_VISIBLE) || (swp_flags & SWP_SHOWWINDOW);
...@@ -1426,12 +1424,26 @@ static void set_window_pos( struct window *win, struct window *previous, ...@@ -1426,12 +1424,26 @@ static void set_window_pos( struct window *win, struct window *previous,
/* set the new window info before invalidating anything */ /* set the new window info before invalidating anything */
win->window_rect = *window_rect; win->window_rect = *window_rect;
win->visible_rect = *visible_rect;
win->client_rect = *client_rect; win->client_rect = *client_rect;
if (!(swp_flags & SWP_NOZORDER) && win->parent) link_window( win, previous ); if (!(swp_flags & SWP_NOZORDER) && win->parent) link_window( win, previous );
if (swp_flags & SWP_SHOWWINDOW) win->style |= WS_VISIBLE; if (swp_flags & SWP_SHOWWINDOW) win->style |= WS_VISIBLE;
else if (swp_flags & SWP_HIDEWINDOW) win->style &= ~WS_VISIBLE; else if (swp_flags & SWP_HIDEWINDOW) win->style &= ~WS_VISIBLE;
/* assume the visible rect stays at the same offset from the window rect */
win->visible_rect.left += window_rect->left - old_window_rect.left;
win->visible_rect.top += window_rect->top - old_window_rect.top;
win->visible_rect.right += window_rect->right - old_window_rect.right;
win->visible_rect.bottom += window_rect->bottom - old_window_rect.bottom;
/* but don't make it smaller than the client rect */
if (win->visible_rect.left > client_rect->left)
win->visible_rect.left = max( window_rect->left, client_rect->left );
if (win->visible_rect.top > client_rect->top)
win->visible_rect.top = max( window_rect->top, client_rect->top );
if (win->visible_rect.right < client_rect->right)
win->visible_rect.right = min( window_rect->right, client_rect->right );
if (win->visible_rect.bottom < client_rect->bottom)
win->visible_rect.bottom = min( window_rect->bottom, client_rect->bottom );
/* if the window is not visible, everything is easy */ /* if the window is not visible, everything is easy */
if (!visible) return; if (!visible) return;
...@@ -1474,8 +1486,7 @@ static void set_window_pos( struct window *win, struct window *previous, ...@@ -1474,8 +1486,7 @@ static void set_window_pos( struct window *win, struct window *previous,
if (swp_flags & SWP_NOCOPYBITS) if (swp_flags & SWP_NOCOPYBITS)
{ {
frame_changed = ((swp_flags & SWP_FRAMECHANGED) || frame_changed = ((swp_flags & SWP_FRAMECHANGED) ||
memcmp( window_rect, &old_window_rect, sizeof(old_window_rect) ) || memcmp( window_rect, &old_window_rect, sizeof(old_window_rect) ));
memcmp( visible_rect, &old_visible_rect, sizeof(old_visible_rect) ));
client_changed = memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) ); client_changed = memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) );
} }
else else
...@@ -1485,11 +1496,7 @@ static void set_window_pos( struct window *win, struct window *previous, ...@@ -1485,11 +1496,7 @@ static void set_window_pos( struct window *win, struct window *previous,
int y_offset = window_rect->top - old_window_rect.top; int y_offset = window_rect->top - old_window_rect.top;
frame_changed = ((swp_flags & SWP_FRAMECHANGED) || frame_changed = ((swp_flags & SWP_FRAMECHANGED) ||
window_rect->right - old_window_rect.right != x_offset || window_rect->right - old_window_rect.right != x_offset ||
window_rect->bottom - old_window_rect.bottom != y_offset || window_rect->bottom - old_window_rect.bottom != y_offset);
visible_rect->left - old_visible_rect.left != x_offset ||
visible_rect->right - old_visible_rect.right != x_offset ||
visible_rect->top - old_visible_rect.top != y_offset ||
visible_rect->bottom - old_visible_rect.bottom != y_offset);
client_changed = (client_rect->left - old_client_rect.left != x_offset || client_changed = (client_rect->left - old_client_rect.left != x_offset ||
client_rect->right - old_client_rect.right != x_offset || client_rect->right - old_client_rect.right != x_offset ||
client_rect->top - old_client_rect.top != y_offset || client_rect->top - old_client_rect.top != y_offset ||
...@@ -1533,6 +1540,45 @@ done: ...@@ -1533,6 +1540,45 @@ done:
clear_error(); /* we ignore out of memory errors once the new rects have been set */ clear_error(); /* we ignore out of memory errors once the new rects have been set */
} }
/* set the window visible rect */
static void set_window_visible_rect( struct window *win, const rectangle_t *visible_rect,
unsigned int swp_flags )
{
struct region *old_vis_rgn = NULL, *exposed_rgn = NULL;
const rectangle_t old_visible_rect = win->visible_rect;
if (!memcmp( visible_rect, &old_visible_rect, sizeof(old_visible_rect) )) return;
/* if the window is not visible, everything is easy */
if (!is_visible( win ) || (swp_flags & SWP_NOREDRAW))
{
win->visible_rect = *visible_rect;
return;
}
if (!(old_vis_rgn = get_visible_region( win, DCX_WINDOW ))) return;
win->visible_rect = *visible_rect;
/* expose anything revealed by the change */
exposed_rgn = expose_window( win, &win->window_rect, old_vis_rgn );
if (exposed_rgn)
{
/* subtract the client rect from the total window rect */
set_region_rect( exposed_rgn, &win->window_rect );
set_region_rect( old_vis_rgn, &win->client_rect );
if (subtract_region( exposed_rgn, exposed_rgn, old_vis_rgn ))
{
if (!is_desktop_window(win))
offset_region( exposed_rgn, -win->client_rect.left, -win->client_rect.top );
redraw_window( win, exposed_rgn, 1, RDW_INVALIDATE | RDW_FRAME | RDW_NOCHILDREN );
}
free_region( exposed_rgn );
}
free_region( old_vis_rgn );
clear_error(); /* we ignore out of memory errors once the new rect has been set */
}
/* set the window region, updating the update region if necessary */ /* set the window region, updating the update region if necessary */
static void set_window_region( struct window *win, struct region *region, int redraw ) static void set_window_region( struct window *win, struct region *region, int redraw )
...@@ -1850,7 +1896,7 @@ DECL_HANDLER(get_window_tree) ...@@ -1850,7 +1896,7 @@ DECL_HANDLER(get_window_tree)
/* set the position and Z order of a window */ /* set the position and Z order of a window */
DECL_HANDLER(set_window_pos) DECL_HANDLER(set_window_pos)
{ {
const rectangle_t *visible_rect = NULL, *valid_rects = NULL; const rectangle_t *valid_rects = NULL;
struct window *previous = NULL; struct window *previous = NULL;
struct window *win = get_window( req->handle ); struct window *win = get_window( req->handle );
unsigned int flags = req->flags; unsigned int flags = req->flags;
...@@ -1894,13 +1940,19 @@ DECL_HANDLER(set_window_pos) ...@@ -1894,13 +1940,19 @@ DECL_HANDLER(set_window_pos)
return; return;
} }
if (get_req_data_size() >= sizeof(rectangle_t)) visible_rect = get_req_data(); if (get_req_data_size() >= 2 * sizeof(rectangle_t)) valid_rects = get_req_data();
if (get_req_data_size() >= 3 * sizeof(rectangle_t)) valid_rects = visible_rect + 1; set_window_pos( win, previous, flags, &req->window, &req->client, valid_rects );
if (!visible_rect) visible_rect = &req->window;
set_window_pos( win, previous, flags, &req->window, &req->client, visible_rect, valid_rects );
reply->new_style = win->style; reply->new_style = win->style;
reply->new_ex_style = win->ex_style; reply->new_ex_style = win->ex_style;
reply->visible = win->visible_rect;
}
/* set the visible rectangle of a window */
DECL_HANDLER(set_window_visible_rect)
{
struct window *win = get_window( req->handle );
if (win) set_window_visible_rect( win, &req->visible, req->flags );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment