From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 36 +++++++++++++++++++++++++++++++++--- dlls/winex11.drv/window.c | 1 + dlls/winex11.drv/x11drv.h | 3 ++- 3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 2b857340c78..34778fd6c5d 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -222,6 +222,21 @@ static unsigned int find_host_window_child( struct host_window *win, Window chil return i; }
+RECT host_window_configure_child( struct host_window *parent, Window window, RECT rect, BOOL root_coords ) +{ + unsigned int index; + POINT offset = {0}; + + if (parent && (index = find_host_window_child( parent, window )) != parent->children_count) + { + if (root_coords) offset = host_window_map_point( parent, 0, 0 ); + OffsetRect( &rect, -offset.x, -offset.y ); + parent->children[index].rect = rect; + } + + return rect; +} + static int host_window_error( Display *display, XErrorEvent *event, void *arg ) { return (event->error_code == BadWindow); @@ -251,6 +266,7 @@ static struct host_window *find_host_window( Window window, BOOL create )
host_window_reparent( &win->parent, xparent, win->window ); SetRect( &win->rect, attr.x, attr.y, attr.x + attr.width, attr.y + attr.height ); + host_window_configure_child( win->parent, win->window, win->rect, FALSE ); }
TRACE( "created host window %p/%lx, parent %lx rect %s\n", win, win->window, @@ -263,12 +279,14 @@ void host_window_reparent( struct host_window **win, Window parent, Window windo { struct host_window *old = *win, *new = find_host_window( parent, TRUE ); unsigned int index; + RECT rect = {0}; void *tmp;
if ((*win = new)) host_window_add_ref( new );
if (old && (index = find_host_window_child( old, window )) < old->children_count) { + rect = old->children[index].rect; old->children[index] = old->children[old->children_count - 1]; old->children_count--; } @@ -277,7 +295,11 @@ void host_window_reparent( struct host_window **win, Window parent, Window windo { if (!(tmp = realloc( new->children, (index + 1) * sizeof(*new->children) ))) return; new->children = tmp; + + OffsetRect( &rect, -rect.left, -rect.top ); new->children[index].window = window; + new->children[index].rect = rect; + new->children_count++; }
@@ -303,16 +325,15 @@ static BOOL host_window_filter_event( XEvent *event ) { XGravityEvent *gravity = (XGravityEvent *)event; OffsetRect( &win->rect, gravity->x - win->rect.left, gravity->y - win->rect.top ); + win->rect = host_window_configure_child( win->parent, win->window, win->rect, FALSE ); TRACE( "host window %p/%lx GravityNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) ); break; } case ConfigureNotify: { XConfigureEvent *configure = (XConfigureEvent *)event; - POINT offset = {0}; SetRect( &win->rect, configure->x, configure->y, configure->x + configure->width, configure->y + configure->height ); - if (configure->send_event) offset = host_window_map_point( win->parent, 0, 0 ); - OffsetRect( &win->rect, -offset.x, -offset.y ); + win->rect = host_window_configure_child( win->parent, win->window, win->rect, configure->send_event ); TRACE( "host window %p/%lx ConfigureNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) ); break; } @@ -1154,6 +1175,7 @@ static BOOL X11DRV_ReparentNotify( HWND hwnd, XEvent *xev ) { TRACE( "window %p/%lx, parent %lx\n", data->hwnd, data->whole_window, event->parent ); host_window_reparent( &data->parent, event->parent, data->whole_window ); + host_window_configure_child( data->parent, data->whole_window, data->rects.visible, TRUE ); }
if (!data->embedded) @@ -1225,6 +1247,13 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
if (!hwnd) return FALSE; if (!(data = get_win_data( hwnd ))) return FALSE; + + if (data->whole_window) + { + SetRect( &rect, event->x, event->y, event->x + event->width, event->y + event->height ); + host_window_configure_child( data->parent, data->whole_window, rect, event->send_event ); + } + if (!data->mapped || data->iconic) goto done; if (data->whole_window && !data->managed) goto done; /* ignore synthetic events on foreign windows */ @@ -1755,6 +1784,7 @@ static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event ) { TRACE( "window %p/%lx, parent %lx\n", data->hwnd, data->whole_window, data->embedder ); host_window_reparent( &data->parent, data->embedder, data->whole_window ); + host_window_configure_child( data->parent, data->whole_window, data->rects.visible, TRUE ); }
make_window_embedded( data ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 403ba346c45..bc15837190a 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1687,6 +1687,7 @@ static void create_whole_window( struct x11drv_win_data *data ) data->vis.visual, mask, &attr ); if (!data->whole_window) goto done; host_window_reparent( &data->parent, root_window, data->whole_window ); + host_window_configure_child( data->parent, data->whole_window, data->rects.visible, TRUE );
x11drv_xinput2_enable( data->display, data->whole_window ); set_initial_wm_hints( data->display, data->whole_window ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 3518f005f6c..e447c81e5df 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -370,12 +370,13 @@ struct host_window RECT rect; /* host window rect, relative to parent */ struct host_window *parent; unsigned int children_count; - struct { Window window; } *children; + struct { Window window; RECT rect; } *children; };
extern void host_window_destroy( struct host_window *win ); extern void host_window_release( struct host_window *win ); extern void host_window_reparent( struct host_window **win, Window parent, Window window ); +extern RECT host_window_configure_child( struct host_window *win, Window window, RECT rect, BOOL root_coords );
struct x11drv_thread_data {