From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 23 +++++++++++++++++++++++ dlls/winex11.drv/window.c | 31 ++++++++++++++++++++++++++++++- dlls/winex11.drv/x11drv.h | 2 ++ 3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 718277ce4cb..c13762996fc 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -187,6 +187,22 @@ static BOOL host_window_filter_event( XEvent *event ) host_window_set_parent( win, reparent->parent ); break; } + case GravityNotify: + { + XGravityEvent *gravity = (XGravityEvent *)event; + OffsetRect( &win->rect, gravity->x - win->rect.left, gravity->y - win->rect.top ); + if (win->parent) 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; + SetRect( &win->rect, configure->x, configure->y, configure->x + configure->width, configure->y + configure->height ); + if (win->parent) 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; + } }
/* keep processing the event for foreign windows */ @@ -1091,6 +1107,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 && data->parent && !data->parent_invalid) + { + 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 */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index f4ea317824d..0c8db3dedef 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -136,6 +136,20 @@ static void host_window_release( struct host_window *win ) } }
+static POINT host_window_map_point( struct host_window *win, int x, int y ) +{ + POINT pos = {x, y}; + + while (win) + { + pos.x += win->rect.left; + pos.y += win->rect.top; + win = win->parent; + } + + return pos; +} + static unsigned int find_host_window_child( struct host_window *win, Window child ) { unsigned int i; @@ -153,6 +167,7 @@ struct host_window *get_host_window( Window window, BOOL create ) struct x11drv_thread_data *data = x11drv_thread_data(); Window xparent = 0, xroot, *xchildren; struct host_window *win; + XWindowAttributes attr; unsigned int nchildren;
if (window == root_window) return NULL; @@ -162,13 +177,16 @@ struct host_window *get_host_window( Window window, BOOL create ) win->window = window;
X11DRV_expect_error( data->display, host_window_error, NULL ); + if (!XGetWindowAttributes( data->display, window, &attr )) memset( &attr, 0, sizeof(attr) ); if (!XQueryTree( data->display, window, &xroot, &xparent, &xchildren, &nchildren )) xparent = root_window; else XFree( xchildren ); if (X11DRV_check_error()) WARN( "window %lx already destroyed\n", window );
host_window_set_parent( win, xparent ); + SetRect( &win->rect, attr.x, attr.y, attr.x + attr.width, attr.y + attr.height );
- TRACE( "created host window %p/%lx, parent %lx\n", win, win->window, xparent ); + TRACE( "created host window %p/%lx, parent %lx rect %s\n", win, win->window, + xparent, wine_dbgstr_rect(&win->rect) ); XSaveContext( data->display, window, host_window_context, (char *)win ); return win; } @@ -198,6 +216,17 @@ static void host_window_reparent( struct host_window **win, Window parent, Windo if (old) host_window_release( old ); }
+RECT host_window_configure_child( struct host_window *win, Window window, RECT rect, BOOL root_coords ) +{ + if (root_coords) + { + POINT offset = host_window_map_point( win, 0, 0 ); + OffsetRect( &rect, -offset.x, -offset.y ); + } + + return rect; +} + void host_window_set_parent( struct host_window *win, Window parent ) { TRACE( "host window %p/%lx, parent %lx\n", win, win->window, parent ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 1c2468e8a63..59c18a91a13 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -366,6 +366,7 @@ struct host_window { LONG refcount; Window window; + RECT rect; /* host window rect, relative to parent */ struct host_window *parent; unsigned int children_count; struct { Window window; } *children; @@ -373,6 +374,7 @@ struct host_window
extern void host_window_destroy( struct host_window *win ); extern void host_window_set_parent( struct host_window *win, Window parent ); +extern RECT host_window_configure_child( struct host_window *win, Window window, RECT rect, BOOL root_coords ); extern struct host_window *get_host_window( Window window, BOOL create );
struct x11drv_thread_data