Making all the windows handled by the driver to be either GL/VK client surfaces, or top-level windows. This avoids leaking host windows into the Win32 space, and makes it possible to get rid of some remaining NtUserMapWindowPoints in `map_event_coords` for mouse input.
-- v8: winex11: Get rid of the now unnecessary foreign windows. winex11: Generate relative ConfigureNotify on parent ConfigureNotify events. winex11: Use the new host windows to register foreign window events. winex11: Keep track of the host windows children window rects. winex11: Keep track of the host windows relative rects. winex11: Keep track of the host window children of interest. winex11: Create host windows recursively up to root_window. winex11: Introduce a new struct host_window for host-only windows.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 2 ++ dlls/winex11.drv/window.c | 68 +++++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 12 +++++++ 3 files changed, 82 insertions(+)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 34a364e11e3..c5523ba27f6 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -996,6 +996,7 @@ static BOOL X11DRV_ReparentNotify( HWND hwnd, XEvent *xev ) struct x11drv_win_data *data;
if (!(data = get_win_data( hwnd ))) return FALSE; + set_window_parent( data, event->parent );
if (!data->embedded) { @@ -1592,6 +1593,7 @@ static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event ) break; }
+ set_window_parent( data, data->embedder ); make_window_embedded( data ); release_win_data( data ); reparent_notify( event->display, hwnd, event->data.l[3], 0, 0 ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index ab17cb40a1c..81547b72bb4 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -98,6 +98,7 @@ XContext winContext = 0;
/* X context to associate a struct x11drv_win_data to an hwnd */ static XContext win_data_context = 0; +static XContext host_window_context = 0;
/* time of last user event and window where it's stored */ static Time last_user_time; @@ -112,6 +113,50 @@ static const WCHAR clip_window_prop[] =
static pthread_mutex_t win_data_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void host_window_add_ref( struct host_window *win ) +{ + int ref = ++win->refcount; + TRACE( "host window %p/%lx increasing refcount to %d\n", win, win->window, ref ); +} + +static void host_window_release( struct host_window *win ) +{ + int ref = --win->refcount; + + TRACE( "host window %p/%lx decreasing refcount to %d\n", win, win->window, ref ); + + if (!ref) + { + struct x11drv_thread_data *data = x11drv_thread_data(); + + XDeleteContext( data->display, win->window, host_window_context ); + free( win ); + } +} + +static struct host_window *get_host_window( Window window, BOOL create ) +{ + struct x11drv_thread_data *data = x11drv_thread_data(); + struct host_window *win; + + if (window == root_window) return NULL; + if (!XFindContext( data->display, window, host_window_context, (XPointer *)&win )) return win; + + if (!create || !(win = calloc( 1, sizeof(*win) ))) return NULL; + win->window = window; + + TRACE( "created host window %p/%lx\n", win, win->window ); + XSaveContext( data->display, window, host_window_context, (char *)win ); + return win; +} + +static void host_window_reparent( struct host_window **win, Window parent, Window window ) +{ + struct host_window *old = *win, *new = get_host_window( parent, TRUE ); + if ((*win = new)) host_window_add_ref( new ); + if (old) host_window_release( old ); +} +
/*********************************************************************** * http://standards.freedesktop.org/startup-notification-spec @@ -1762,6 +1807,18 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des /* Outlook stops processing messages after destroying a dialog, so we need an explicit flush */ XFlush( data->display ); NtUserRemoveProp( data->hwnd, whole_window_prop ); + + /* It's possible that we are in a different thread, when called from + * set_window_visual, and about to recreate the window. In this case + * just set a window flag to indicate the parent isn't valid and let + * the thread eventually replace it with the proper one later on. + */ + if (data->display != thread_init_display()) data->parent_invalid = 1; + else if (data->parent) + { + host_window_release( data->parent ); + data->parent = NULL; + } }
@@ -1847,6 +1904,7 @@ void X11DRV_DestroyWindow( HWND hwnd ) if (thread_data->last_xic_hwnd == hwnd) thread_data->last_xic_hwnd = 0; if (data->icon_pixmap) XFreePixmap( gdi_display, data->icon_pixmap ); if (data->icon_mask) XFreePixmap( gdi_display, data->icon_mask ); + if (data->parent) host_window_release( data->parent ); free( data->icon_bits ); XDeleteContext( gdi_display, (XID)hwnd, win_data_context ); release_win_data( data ); @@ -2032,6 +2090,15 @@ void release_win_data( struct x11drv_win_data *data ) if (data) pthread_mutex_unlock( &win_data_mutex ); }
+/* update the whole window parent host window, must be called from the window's owner thread */ +void set_window_parent( struct x11drv_win_data *data, Window parent ) +{ + if (!data->whole_window) return; /* only keep track of parent if we have a toplevel */ + TRACE( "window %p/%lx, parent %lx\n", data->hwnd, data->whole_window, parent ); + host_window_reparent( &data->parent, parent, data->whole_window ); + data->parent_invalid = 0; +} +
/*********************************************************************** * X11DRV_create_win_data @@ -3110,5 +3177,6 @@ void init_win_context(void)
winContext = XUniqueContext(); win_data_context = XUniqueContext(); + host_window_context = XUniqueContext(); cursor_context = XUniqueContext(); } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 2ecf3cb54cd..e6ec04ce050 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -361,6 +361,15 @@ extern HRGN get_dc_monitor_region( HWND hwnd, HDC hdc ); * X11 USER driver */
+/* thread-local host-only window, for X11 relative position tracking */ +struct host_window +{ + LONG refcount; + Window window; +}; + +extern void host_window_destroy( struct host_window *win ); + struct x11drv_thread_data { Display *display; @@ -600,6 +609,7 @@ struct x11drv_win_data Window whole_window; /* X window for the complete window */ Window client_window; /* X window for the client area */ struct window_rects rects; /* window rects in monitor DPI, relative to parent client area */ + struct host_window *parent; /* the host window parent, frame or embedder, NULL if root_window */ XIC xic; /* X input context */ UINT managed : 1; /* is window managed? */ UINT mapped : 1; /* is window mapped? (in either normal or iconic state) */ @@ -612,6 +622,7 @@ struct x11drv_win_data UINT add_taskbar : 1; /* does window should be added to taskbar regardless of style */ UINT net_wm_fullscreen_monitors_set : 1; /* is _NET_WM_FULLSCREEN_MONITORS set */ UINT is_fullscreen : 1; /* is the window visible rect fullscreen */ + UINT parent_invalid : 1; /* is the parent host window possibly invalid */ int wm_state; /* current value of the WM_STATE property */ DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */ Window embedder; /* window id of embedder */ @@ -624,6 +635,7 @@ struct x11drv_win_data
extern struct x11drv_win_data *get_win_data( HWND hwnd ); extern void release_win_data( struct x11drv_win_data *data ); +extern void set_window_parent( struct x11drv_win_data *data, Window parent ); extern Window X11DRV_get_whole_window( HWND hwnd ); extern Window get_dummy_parent(void);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 26 ++++++++++++++++++++++++++ dlls/winex11.drv/window.c | 25 +++++++++++++++++++++++-- dlls/winex11.drv/x11drv.h | 3 +++ 3 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index c5523ba27f6..7956a83252e 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -172,6 +172,29 @@ static inline void free_event_data( XEvent *event ) #endif }
+static BOOL host_window_filter_event( XEvent *event ) +{ + struct host_window *win; + HWND hwnd; + + if (!(win = get_host_window( event->xany.window, FALSE ))) return FALSE; + + switch (event->type) + { + case ReparentNotify: + { + XReparentEvent *reparent = (XReparentEvent *)event; + TRACE( "host window %p/%lx ReparentNotify, parent %lx\n", win, win->window, reparent->parent ); + host_window_set_parent( win, reparent->parent ); + break; + } + } + + /* keep processing the event for foreign windows */ + if (!XFindContext( event->xany.display, event->xany.window, winContext, (char **)&hwnd )) return FALSE; + return TRUE; +} + /*********************************************************************** * xembed_request_focus */ @@ -445,6 +468,9 @@ BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,XPointer else continue; /* filtered, ignore it */ } + + if (host_window_filter_event( &event )) continue; + get_event_data( &event ); if (prev_event.type) action = merge_events( &prev_event, &event ); switch( action ) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 81547b72bb4..64fc91e02bf 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -130,14 +130,22 @@ static void host_window_release( struct host_window *win ) struct x11drv_thread_data *data = x11drv_thread_data();
XDeleteContext( data->display, win->window, host_window_context ); + if (win->parent) host_window_release( win->parent ); free( win ); } }
-static struct host_window *get_host_window( Window window, BOOL create ) +static int host_window_error( Display *display, XErrorEvent *event, void *arg ) +{ + return (event->error_code == BadWindow); +} + +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; + unsigned int nchildren;
if (window == root_window) return NULL; if (!XFindContext( data->display, window, host_window_context, (XPointer *)&win )) return win; @@ -145,7 +153,14 @@ static struct host_window *get_host_window( Window window, BOOL create ) if (!create || !(win = calloc( 1, sizeof(*win) ))) return NULL; win->window = window;
- TRACE( "created host window %p/%lx\n", win, win->window ); + X11DRV_expect_error( data->display, host_window_error, NULL ); + 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 ); + + TRACE( "created host window %p/%lx, parent %lx\n", win, win->window, xparent ); XSaveContext( data->display, window, host_window_context, (char *)win ); return win; } @@ -157,6 +172,12 @@ static void host_window_reparent( struct host_window **win, Window parent, Windo if (old) host_window_release( old ); }
+void host_window_set_parent( struct host_window *win, Window parent ) +{ + TRACE( "host window %p/%lx, parent %lx\n", win, win->window, parent ); + host_window_reparent( &win->parent, parent, win->window ); +} +
/*********************************************************************** * http://standards.freedesktop.org/startup-notification-spec diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index e6ec04ce050..4f555d8e32f 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -366,9 +366,12 @@ struct host_window { LONG refcount; Window window; + struct host_window *parent; };
extern void host_window_destroy( struct host_window *win ); +extern void host_window_set_parent( struct host_window *win, Window parent ); +extern struct host_window *get_host_window( Window window, BOOL create );
struct x11drv_thread_data {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 26 ++++++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 2 ++ 2 files changed, 28 insertions(+)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 64fc91e02bf..f4ea317824d 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -131,10 +131,18 @@ static void host_window_release( struct host_window *win )
XDeleteContext( data->display, win->window, host_window_context ); if (win->parent) host_window_release( win->parent ); + free( win->children ); free( win ); } }
+static unsigned int find_host_window_child( struct host_window *win, Window child ) +{ + unsigned int i; + for (i = 0; i < win->children_count; i++) if (win->children[i].window == child) break; + return i; +} + static int host_window_error( Display *display, XErrorEvent *event, void *arg ) { return (event->error_code == BadWindow); @@ -168,7 +176,25 @@ struct host_window *get_host_window( Window window, BOOL create ) static void host_window_reparent( struct host_window **win, Window parent, Window window ) { struct host_window *old = *win, *new = get_host_window( parent, TRUE ); + unsigned int index; + void *tmp; + if ((*win = new)) host_window_add_ref( new ); + + if (old && (index = find_host_window_child( old, window )) < old->children_count) + { + old->children[index] = old->children[old->children_count - 1]; + old->children_count--; + } + + if (new && (index = find_host_window_child( new, window )) == new->children_count) + { + if (!(tmp = realloc( new->children, (index + 1) * sizeof(*new->children) ))) return; + new->children = tmp; + new->children[index].window = window; + new->children_count++; + } + if (old) host_window_release( old ); }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 4f555d8e32f..1c2468e8a63 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -367,6 +367,8 @@ struct host_window LONG refcount; Window window; struct host_window *parent; + unsigned int children_count; + struct { Window window; } *children; };
extern void host_window_destroy( struct host_window *win );
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 7956a83252e..559cef596c4 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -188,6 +188,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 */ @@ -1093,6 +1109,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
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 12 ++++++++++++ dlls/winex11.drv/x11drv.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0c8db3dedef..0e2c587e858 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -184,6 +184,7 @@ struct host_window *get_host_window( Window window, BOOL create )
host_window_set_parent( win, xparent ); SetRect( &win->rect, attr.x, attr.y, attr.x + attr.width, attr.y + attr.height ); + if (win->parent) 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, xparent, wine_dbgstr_rect(&win->rect) ); @@ -195,12 +196,14 @@ static void host_window_reparent( struct host_window **win, Window parent, Windo { struct host_window *old = *win, *new = get_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--; } @@ -209,7 +212,11 @@ static void host_window_reparent( struct host_window **win, Window parent, 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++; }
@@ -218,12 +225,16 @@ static void host_window_reparent( struct host_window **win, Window parent, Windo
RECT host_window_configure_child( struct host_window *win, Window window, RECT rect, BOOL root_coords ) { + unsigned int index; + if (root_coords) { POINT offset = host_window_map_point( win, 0, 0 ); OffsetRect( &rect, -offset.x, -offset.y ); }
+ index = find_host_window_child( win, window ); + if (index < win->children_count) win->children[index].rect = rect; return rect; }
@@ -2172,6 +2183,7 @@ void set_window_parent( struct x11drv_win_data *data, Window parent ) if (!data->whole_window) return; /* only keep track of parent if we have a toplevel */ TRACE( "window %p/%lx, parent %lx\n", data->hwnd, data->whole_window, parent ); host_window_reparent( &data->parent, parent, data->whole_window ); + if (data->parent) host_window_configure_child( data->parent, data->whole_window, data->rects.visible, TRUE ); data->parent_invalid = 0; }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 59c18a91a13..b8711f30b1a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -369,7 +369,7 @@ 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 );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 4 ++++ dlls/winex11.drv/window.c | 7 ++----- dlls/winex11.drv/x11drv.h | 1 + 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 559cef596c4..3bddde9c9b4 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -181,6 +181,10 @@ static BOOL host_window_filter_event( XEvent *event )
switch (event->type) { + case DestroyNotify: + TRACE( "host window %p/%lx DestroyNotify\n", win, win->window ); + win->destroyed = TRUE; + break; case ReparentNotify: { XReparentEvent *reparent = (XReparentEvent *)event; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0e2c587e858..299ea8cdcd5 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -129,6 +129,7 @@ static void host_window_release( struct host_window *win ) { struct x11drv_thread_data *data = x11drv_thread_data();
+ if (!win->destroyed) XSelectInput( data->display, win->window, 0 ); XDeleteContext( data->display, win->window, host_window_context ); if (win->parent) host_window_release( win->parent ); free( win->children ); @@ -177,6 +178,7 @@ struct host_window *get_host_window( Window window, BOOL create ) win->window = window;
X11DRV_expect_error( data->display, host_window_error, NULL ); + XSelectInput( data->display, window, StructureNotifyMask ); 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 ); @@ -1861,7 +1863,6 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des Window xwin = (Window)NtUserGetProp( data->hwnd, foreign_window_prop ); if (xwin) { - if (!already_destroyed) XSelectInput( data->display, xwin, 0 ); XDeleteContext( data->display, xwin, winContext ); NtUserRemoveProp( data->hwnd, foreign_window_prop ); } @@ -2267,13 +2268,9 @@ HWND create_foreign_window( Display *display, Window xwin ) if (XFindContext( display, xwin, winContext, (char **)&hwnd )) hwnd = 0; if (hwnd) return hwnd; /* already created */
- XSelectInput( display, xwin, StructureNotifyMask ); if (!XGetWindowAttributes( display, xwin, &attr ) || !XQueryTree( display, xwin, &xroot, &xparent, &xchildren, &nchildren )) - { - XSelectInput( display, xwin, 0 ); return 0; - } XFree( xchildren );
if (xparent == xroot) diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index b8711f30b1a..388a6d4fc86 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -366,6 +366,7 @@ struct host_window { LONG refcount; Window window; + BOOL destroyed; /* host window has already been destroyed */ RECT rect; /* host window rect, relative to parent */ struct host_window *parent; unsigned int children_count;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 3bddde9c9b4..795320881bd 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -175,9 +175,11 @@ static inline void free_event_data( XEvent *event ) static BOOL host_window_filter_event( XEvent *event ) { struct host_window *win; + RECT old_rect; HWND hwnd;
if (!(win = get_host_window( event->xany.window, FALSE ))) return FALSE; + old_rect = win->rect;
switch (event->type) { @@ -210,6 +212,27 @@ static BOOL host_window_filter_event( XEvent *event ) } }
+ if (old_rect.left != win->rect.left || old_rect.top != win->rect.top) + { + XConfigureEvent configure = {.type = ConfigureNotify, .serial = event->xany.serial, .display = event->xany.display}; + unsigned int i; + + for (i = 0; i < win->children_count; i++) + { + RECT rect = win->children[i].rect; + + configure.event = win->children[i].window; + configure.window = configure.event; + configure.x = rect.left; + configure.y = rect.top; + configure.width = rect.right - rect.left; + configure.height = rect.bottom - rect.top; + configure.send_event = 0; + + XPutBackEvent( configure.display, (XEvent *)&configure ); + } + } + /* keep processing the event for foreign windows */ if (!XFindContext( event->xany.display, event->xany.window, winContext, (char **)&hwnd )) return FALSE; return TRUE;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/Makefile.in | 1 - dlls/winex11.drv/dllmain.c | 1 - dlls/winex11.drv/event.c | 122 +++------------------------------ dlls/winex11.drv/mouse.c | 16 ++--- dlls/winex11.drv/systray.c | 55 --------------- dlls/winex11.drv/unixlib.h | 1 - dlls/winex11.drv/window.c | 98 +------------------------- dlls/winex11.drv/x11drv.h | 3 +- dlls/winex11.drv/x11drv_dll.h | 3 - dlls/winex11.drv/x11drv_main.c | 2 - 10 files changed, 18 insertions(+), 284 deletions(-) delete mode 100644 dlls/winex11.drv/systray.c
diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in index f570b026db4..155c0be5345 100644 --- a/dlls/winex11.drv/Makefile.in +++ b/dlls/winex11.drv/Makefile.in @@ -20,7 +20,6 @@ SOURCES = \ opengl.c \ palette.c \ pen.c \ - systray.c \ version.rc \ vulkan.c \ window.c \ diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index 14336adf583..01e5d417800 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -34,7 +34,6 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) .dnd_post_drop_callback = (UINT_PTR)x11drv_dnd_post_drop, .dnd_drop_event_callback = (UINT_PTR)x11drv_dnd_drop_event, .dnd_leave_event_callback = (UINT_PTR)x11drv_dnd_leave_event, - .foreign_window_proc = (UINT_PTR)foreign_window_proc, };
if (reason != DLL_PROCESS_ATTACH) return TRUE; diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 795320881bd..fe8c734b197 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -89,7 +89,6 @@ static BOOL X11DRV_ReparentNotify( HWND hwnd, XEvent *event ); static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *event ); static BOOL X11DRV_PropertyNotify( HWND hwnd, XEvent *event ); static BOOL X11DRV_ClientMessage( HWND hwnd, XEvent *event ); -static BOOL X11DRV_GravityNotify( HWND hwnd, XEvent *event );
#define MAX_EVENT_HANDLERS 128
@@ -119,7 +118,7 @@ static x11drv_event_handler handlers[MAX_EVENT_HANDLERS] = X11DRV_ReparentNotify, /* 21 ReparentNotify */ X11DRV_ConfigureNotify, /* 22 ConfigureNotify */ NULL, /* 23 ConfigureRequest */ - X11DRV_GravityNotify, /* 24 GravityNotify */ + NULL, /* 24 GravityNotify */ NULL, /* 25 ResizeRequest */ NULL, /* 26 CirculateNotify */ NULL, /* 27 CirculateRequest */ @@ -176,7 +175,6 @@ static BOOL host_window_filter_event( XEvent *event ) { struct host_window *win; RECT old_rect; - HWND hwnd;
if (!(win = get_host_window( event->xany.window, FALSE ))) return FALSE; old_rect = win->rect; @@ -233,8 +231,6 @@ static BOOL host_window_filter_event( XEvent *event ) } }
- /* keep processing the event for foreign windows */ - if (!XFindContext( event->xany.display, event->xany.window, winContext, (char **)&hwnd )) return FALSE; return TRUE; }
@@ -1022,40 +1018,6 @@ static BOOL X11DRV_UnmapNotify( HWND hwnd, XEvent *event ) }
-/*********************************************************************** - * reparent_notify - */ -static void reparent_notify( Display *display, HWND hwnd, Window xparent, int x, int y ) -{ - HWND parent, old_parent; - DWORD style, flags = 0; - RECT rect; - - style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); - if (xparent == root_window) - { - parent = NtUserGetDesktopWindow(); - style = (style & ~WS_CHILD) | WS_POPUP; - } - else - { - if (!(parent = create_foreign_window( display, xparent ))) return; - style = (style & ~WS_POPUP) | WS_CHILD; - } - - NtUserShowWindow( hwnd, SW_HIDE ); - old_parent = NtUserSetParent( hwnd, parent ); - NtUserSetWindowLong( hwnd, GWL_STYLE, style, FALSE ); - - if (style & WS_VISIBLE) flags = SWP_SHOWWINDOW; - SetRect( &rect, x, y, x, y ); - NtUserSetRawWindowPos( hwnd, rect, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS | flags, FALSE ); - - /* make old parent destroy itself if it no longer has children */ - if (old_parent != NtUserGetDesktopWindow()) NtUserPostMessage( old_parent, WM_CLOSE, 0, 0 ); -} - - /*********************************************************************** * X11DRV_ReparentNotify */ @@ -1088,39 +1050,9 @@ static BOOL X11DRV_ReparentNotify( HWND hwnd, XEvent *xev )
TRACE( "%p/%lx reparented to %lx\n", hwnd, data->whole_window, event->parent ); release_win_data( data ); - - reparent_notify( event->display, hwnd, event->parent, event->x, event->y ); return TRUE; }
-/* map XConfigureNotify event coordinates to parent-relative monitor DPI coordinates */ -static POINT map_configure_event_coords( struct x11drv_win_data *data, XConfigureEvent *event ) -{ - Window child, parent = data->embedder ? data->embedder : root_window; - POINT pos; - - if (event->send_event && parent == DefaultRootWindow( event->display )) - { - pos.x = event->x; - pos.y = event->y; - } - else if (event->send_event) - { - /* synthetic events are always in root coords */ - XTranslateCoordinates( event->display, DefaultRootWindow( event->display ), parent, - event->x, event->y, (int *)&pos.x, (int *)&pos.y, &child ); - } - else - { - /* query the current window position, events are relative to their parent */ - XTranslateCoordinates( event->display, event->window, parent, 0, 0, - (int *)&pos.x, (int *)&pos.y, &child ); - } - - if (parent == root_window) pos = root_to_virtual_screen( pos.x, pos.y ); - return pos; -} - /*********************************************************************** * X11DRV_ConfigureNotify */ @@ -1129,9 +1061,9 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) XConfigureEvent *event = &xev->xconfigure; struct x11drv_win_data *data; RECT rect; - POINT pos; + POINT pos = {event->x, event->y}; UINT flags; - int cx, cy, x = event->x, y = event->y; + int cx, cy, x, y; DWORD style;
if (!hwnd) return FALSE; @@ -1144,9 +1076,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) }
if (!data->mapped || data->iconic) goto done; - if (data->whole_window && !data->managed) goto done; - /* ignore synthetic events on foreign windows */ - if (event->send_event && !data->whole_window) goto done; + if (!data->whole_window || !data->managed) goto done; if (data->configure_serial && (long)(data->configure_serial - event->serial) > 0) { TRACE( "win %p/%lx event %d,%d,%dx%d ignoring old serial %lu/%lu\n", @@ -1155,9 +1085,11 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) goto done; }
- /* Get geometry */ + /* synthetic events are already in absolute coordinates */ + if (!event->send_event) pos = host_window_map_point( data->parent, event->x, event->y ); + else if (is_virtual_desktop()) FIXME( "synthetic event mapping not implemented\n" );
- pos = map_configure_event_coords( data, event ); + pos = root_to_virtual_screen( pos.x, pos.y ); SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height ); rect = window_rect_from_visible( &data->rects, rect );
@@ -1226,43 +1158,6 @@ done: }
-/********************************************************************** - * X11DRV_GravityNotify - */ -static BOOL X11DRV_GravityNotify( HWND hwnd, XEvent *xev ) -{ - XGravityEvent *event = &xev->xgravity; - struct x11drv_win_data *data = get_win_data( hwnd ); - RECT window_rect; - int x, y; - - if (!data) return FALSE; - - if (data->whole_window) /* only handle this for foreign windows */ - { - release_win_data( data ); - return FALSE; - } - - x = event->x + data->rects.window.left - data->rects.visible.left; - y = event->y + data->rects.window.top - data->rects.visible.top; - - TRACE( "win %p/%lx new X pos %d,%d (event %d,%d)\n", - hwnd, data->whole_window, x, y, event->x, event->y ); - - window_rect = data->rects.window; - release_win_data( data ); - - if (window_rect.left != x || window_rect.top != y) - { - RECT rect = {x, y, x, y}; - NtUserSetRawWindowPos( hwnd, rect, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS, FALSE ); - } - - return TRUE; -} - - /*********************************************************************** * get_window_wm_state */ @@ -1672,7 +1567,6 @@ static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event ) set_window_parent( data, data->embedder ); make_window_embedded( data ); release_win_data( data ); - reparent_notify( event->display, hwnd, event->data.l[3], 0, 0 ); } break;
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 15557c3d917..cbbb27d6798 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -509,17 +509,15 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x { if (window == root_window) pt = root_to_virtual_screen( pt.x, pt.y ); else if (event_root == root_window) pt = root_to_virtual_screen( x_root, y_root ); + else if (window == data->client_window) + { + pt.x += data->rects.client.left; + pt.y += data->rects.client.top; + } else { - if (window == data->whole_window) - { - pt.x += data->rects.visible.left - data->rects.client.left; - pt.y += data->rects.visible.top - data->rects.client.top; - } - - if (NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - pt.x = data->rects.client.right - data->rects.client.left - 1 - pt.x; - NtUserMapWindowPoints( hwnd, 0, &pt, 1, 0 /* per-monitor DPI */ ); + pt.x += data->rects.visible.left; + pt.y += data->rects.visible.top; } release_win_data( data ); } diff --git a/dlls/winex11.drv/systray.c b/dlls/winex11.drv/systray.c deleted file mode 100644 index e21ce481f9b..00000000000 --- a/dlls/winex11.drv/systray.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * X11 system tray management - * - * Copyright (C) 2004 Mike Hearn, for CodeWeavers - * Copyright (C) 2005 Robert Shearman - * Copyright (C) 2008 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "x11drv_dll.h" -#include "commctrl.h" -#include "shellapi.h" - -#include "wine/list.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(systray); - -/* window procedure for foreign windows */ -LRESULT WINAPI foreign_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) -{ - switch(msg) - { - case WM_WINDOWPOSCHANGED: - { - HWND hwnd = FindWindowW( L"Shell_TrayWnd", NULL ); - PostMessageW( hwnd, WM_USER + 0, 0, 0 ); - break; - } - case WM_PARENTNOTIFY: - if (LOWORD(wparam) == WM_DESTROY) - { - TRACE( "%p: got parent notify destroy for win %Ix\n", hwnd, lparam ); - PostMessageW( hwnd, WM_CLOSE, 0, 0 ); /* so that we come back here once the child is gone */ - } - return 0; - case WM_CLOSE: - if (GetWindow( hwnd, GW_CHILD )) return 0; /* refuse to die if we still have children */ - break; - } - return DefWindowProcW( hwnd, msg, wparam, lparam ); -} diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 522411f8e55..f23d7204bcd 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -40,7 +40,6 @@ struct init_params UINT64 dnd_post_drop_callback; UINT64 dnd_drop_event_callback; UINT64 dnd_leave_event_callback; - UINT64 foreign_window_proc; };
/* x11drv_tablet_info params */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 299ea8cdcd5..b3ffbfb2a90 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -104,8 +104,6 @@ static XContext host_window_context = 0; static Time last_user_time; static Window user_time_window;
-static const WCHAR foreign_window_prop[] = - {'_','_','w','i','n','e','_','x','1','1','_','f','o','r','e','i','g','n','_','w','i','n','d','o','w',0}; static const WCHAR whole_window_prop[] = {'_','_','w','i','n','e','_','x','1','1','_','w','h','o','l','e','_','w','i','n','d','o','w',0}; static const WCHAR clip_window_prop[] = @@ -137,7 +135,7 @@ static void host_window_release( struct host_window *win ) } }
-static POINT host_window_map_point( struct host_window *win, int x, int y ) +POINT host_window_map_point( struct host_window *win, int x, int y ) { POINT pos = {x, y};
@@ -1858,16 +1856,7 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
if (!data->whole_window) { - if (data->embedded) - { - Window xwin = (Window)NtUserGetProp( data->hwnd, foreign_window_prop ); - if (xwin) - { - XDeleteContext( data->display, xwin, winContext ); - NtUserRemoveProp( data->hwnd, foreign_window_prop ); - } - return; - } + if (data->embedded) return; } else { @@ -2229,89 +2218,6 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const struct w }
-/*********************************************************************** - * create_foreign_window - * - * Create a foreign window for the specified X window and its ancestors - */ -HWND create_foreign_window( Display *display, Window xwin ) -{ - static BOOL class_registered; - struct x11drv_win_data *data; - HWND hwnd, parent; - POINT pos; - Window xparent, xroot; - Window *xchildren; - unsigned int nchildren; - XWindowAttributes attr; - UINT style = WS_CLIPCHILDREN; - UNICODE_STRING class_name = RTL_CONSTANT_STRING( foreign_window_prop ); - - if (!class_registered) - { - UNICODE_STRING version = { 0 }; - WNDCLASSEXW class; - - memset( &class, 0, sizeof(class) ); - class.cbSize = sizeof(class); - class.lpfnWndProc = (WNDPROC)(UINT_PTR)client_foreign_window_proc; - class.lpszClassName = foreign_window_prop; - if (!NtUserRegisterClassExWOW( &class, &class_name, &version, NULL, 0, 0, NULL ) && - RtlGetLastWin32Error() != ERROR_CLASS_ALREADY_EXISTS) - { - ERR( "Could not register foreign window class\n" ); - return FALSE; - } - class_registered = TRUE; - } - - if (XFindContext( display, xwin, winContext, (char **)&hwnd )) hwnd = 0; - if (hwnd) return hwnd; /* already created */ - - if (!XGetWindowAttributes( display, xwin, &attr ) || - !XQueryTree( display, xwin, &xroot, &xparent, &xchildren, &nchildren )) - return 0; - XFree( xchildren ); - - if (xparent == xroot) - { - parent = NtUserGetDesktopWindow(); - style |= WS_POPUP; - pos = root_to_virtual_screen( attr.x, attr.y ); - } - else - { - parent = create_foreign_window( display, xparent ); - style |= WS_CHILD; - pos.x = attr.x; - pos.y = attr.y; - } - - hwnd = NtUserCreateWindowEx( 0, &class_name, &class_name, NULL, style, pos.x, pos.y, - attr.width, attr.height, parent, 0, NULL, NULL, 0, NULL, - 0, FALSE ); - if (!(data = get_win_data( hwnd ))) - { - NtUserDestroyWindow( hwnd ); - return 0; - } - destroy_whole_window( data, FALSE ); - data->embedded = TRUE; - data->mapped = TRUE; - - NtUserSetProp( hwnd, foreign_window_prop, (HANDLE)xwin ); - XSaveContext( display, xwin, winContext, (char *)data->hwnd ); - - TRACE( "win %lx parent %p style %08x %s -> hwnd %p\n", - xwin, parent, style, wine_dbgstr_rect(&data->rects.window), hwnd ); - - release_win_data( data ); - - NtUserShowWindow( hwnd, SW_SHOW ); - return hwnd; -} - - /*********************************************************************** * SystrayDockInit (X11DRV.@) */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 388a6d4fc86..d0a9b57ebc2 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -376,6 +376,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 POINT host_window_map_point( struct host_window *win, int x, int y ); extern struct host_window *get_host_window( Window window, BOOL create );
struct x11drv_thread_data @@ -450,7 +451,6 @@ extern int alloc_system_colors; extern int xrender_error_base; extern char *process_name; extern Display *clipboard_display; -extern UINT64 client_foreign_window_proc; extern UINT64 dnd_enter_event_callback; extern UINT64 dnd_position_event_callback; extern UINT64 dnd_post_drop_callback; @@ -664,7 +664,6 @@ extern void attach_client_window( struct x11drv_win_data *data, Window client_wi extern void destroy_client_window( HWND hwnd, Window client_window ); extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BOOL use_alpha ); extern void change_systray_owner( Display *display, Window systray_window ); -extern HWND create_foreign_window( Display *display, Window window ); extern BOOL update_clipboard( HWND hwnd ); extern void init_win_context(void); extern DROPFILES *file_list_to_drop_files( const void *data, size_t size, size_t *ret_size ); diff --git a/dlls/winex11.drv/x11drv_dll.h b/dlls/winex11.drv/x11drv_dll.h index bc68c3996c3..6113f01344a 100644 --- a/dlls/winex11.drv/x11drv_dll.h +++ b/dlls/winex11.drv/x11drv_dll.h @@ -33,9 +33,6 @@ extern NTSTATUS WINAPI x11drv_dnd_post_drop( void *data, ULONG size ); extern NTSTATUS WINAPI x11drv_dnd_drop_event( void *params, ULONG size ); extern NTSTATUS WINAPI x11drv_dnd_leave_event( void *params, ULONG size );
-extern LRESULT WINAPI foreign_window_proc( HWND hwnd, UINT msg, WPARAM wparam, - LPARAM lparam ); - extern HMODULE x11drv_module;
#endif /* __WINE_X11DRV_DLL_H */ diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 3f8e48a7a8d..490a662c16a 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -85,7 +85,6 @@ int copy_default_colors = 128; int alloc_system_colors = 256; int xrender_error_base = 0; char *process_name = NULL; -UINT64 client_foreign_window_proc = 0; UINT64 dnd_enter_event_callback = 0; UINT64 dnd_position_event_callback = 0; UINT64 dnd_post_drop_callback = 0; @@ -653,7 +652,6 @@ static NTSTATUS x11drv_init( void *arg ) dnd_post_drop_callback = params->dnd_post_drop_callback; dnd_drop_event_callback = params->dnd_drop_event_callback; dnd_leave_event_callback = params->dnd_leave_event_callback; - client_foreign_window_proc = params->foreign_window_proc;
fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */ root_window = DefaultRootWindow( display );
v7: Check whether the event window is known when filtering host window messages to avoid breaking ConfigureNotify merges, filter all host windows events when foreign windows are finally removed.
Is there any chance for this? I can come up with a different solution for display mode virtualization, export a NtUserMapRectVirtToRaw call from win32u for winex11 but that would be the only place that needs it, and I think it would be good to get rid of the NtUserMapWindowPoint call instead.
The foreign window removal will conflict with https://gitlab.winehq.org/wine/wine/-/merge_requests/6694 so in any case it'll have to be rebased on top of it.
It looks OK, but I'd rather not merge it just before the release, so if you could rebase it once !6694 is merged that would be great.
Sounds good, thanks!