diff --git a/gdk/win32/gdkdevice-win32.c b/gdk/win32/gdkdevice-win32.c index 96d4d2bec5..f304bdb98e 100644 --- a/gdk/win32/gdkdevice-win32.c +++ b/gdk/win32/gdkdevice-win32.c @@ -75,6 +75,7 @@ gdk_device_win32_query_state (GdkDevice *device, POINT point; HWND hwnd, hwndc; int scale; + GdkDisplay *display = gdk_device_get_display (device); if (surface) { @@ -83,8 +84,6 @@ gdk_device_win32_query_state (GdkDevice *device, } else { - GdkDisplay *display = gdk_device_get_display (device); - scale = GDK_WIN32_DISPLAY (display)->surface_scale; hwnd = NULL; } @@ -105,7 +104,7 @@ gdk_device_win32_query_state (GdkDevice *device, hwndc = ChildWindowFromPoint (hwnd, point); if (hwndc && hwndc != hwnd) - *child_surface = gdk_win32_handle_table_lookup_ (hwndc); + *child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc); else *child_surface = NULL; /* Direct child unknown to gdk */ } @@ -183,7 +182,7 @@ _gdk_device_win32_surface_at_position (GdkDevice *device, if (!PtInRect (&rect, client_pt)) hwnd = NULL; - surface = gdk_win32_handle_table_lookup_ (hwnd); + surface = gdk_win32_display_handle_table_lookup_ (gdk_device_get_display (device), hwnd); if (surface && (win_x || win_y)) { diff --git a/gdk/win32/gdkdevice-winpointer.c b/gdk/win32/gdkdevice-winpointer.c index f6633aecf9..13d83ca7f0 100644 --- a/gdk/win32/gdkdevice-winpointer.c +++ b/gdk/win32/gdkdevice-winpointer.c @@ -65,6 +65,7 @@ gdk_device_winpointer_query_state (GdkDevice *device, POINT point; HWND hwnd, hwndc; int scale; + GdkDisplay *display = gdk_device_get_display (device); device_winpointer = GDK_DEVICE_WINPOINTER (device); if (surface) @@ -74,8 +75,6 @@ gdk_device_winpointer_query_state (GdkDevice *device, } else { - GdkDisplay *display = gdk_device_get_display (device); - scale = GDK_WIN32_DISPLAY (display)->surface_scale; hwnd = NULL; } @@ -96,7 +95,7 @@ gdk_device_winpointer_query_state (GdkDevice *device, hwndc = ChildWindowFromPoint (hwnd, point); if (hwndc && hwndc != hwnd) - *child_surface = gdk_win32_handle_table_lookup_ (hwndc); + *child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc); else *child_surface = NULL; /* Direct child unknown to gdk */ } @@ -160,7 +159,8 @@ gdk_device_winpointer_surface_at_position (GdkDevice *device, if (!PtInRect (&rect, client_pt)) hwnd = NULL; - surface = gdk_win32_handle_table_lookup_ (hwnd); + surface = gdk_win32_display_handle_table_lookup_ (gdk_device_get_display (device), + hwnd); if (surface && (win_x || win_y)) { diff --git a/gdk/win32/gdkdevice-wintab.c b/gdk/win32/gdkdevice-wintab.c index 553886ee74..82ad243541 100644 --- a/gdk/win32/gdkdevice-wintab.c +++ b/gdk/win32/gdkdevice-wintab.c @@ -73,6 +73,7 @@ gdk_device_wintab_query_state (GdkDevice *device, POINT point; HWND hwnd, hwndc; int scale; + GdkDisplay *display = gdk_device_get_display (device); device_wintab = GDK_DEVICE_WINTAB (device); if (surface) @@ -82,8 +83,6 @@ gdk_device_wintab_query_state (GdkDevice *device, } else { - GdkDisplay *display = gdk_device_get_display (device); - scale = GDK_WIN32_DISPLAY (display)->surface_scale; hwnd = NULL; } @@ -104,7 +103,7 @@ gdk_device_wintab_query_state (GdkDevice *device, hwndc = ChildWindowFromPoint (hwnd, point); if (hwndc && hwndc != hwnd) - *child_surface = gdk_win32_handle_table_lookup_ (hwndc); + *child_surface = gdk_win32_display_handle_table_lookup_ (display, hwndc); else *child_surface = NULL; /* Direct child unknown to gdk */ } diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index b20730f4c9..39bf95710f 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -686,6 +686,9 @@ gdk_win32_display_finalize (GObject *object) { GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object); + g_slist_free_full (display_win32->display_surface_record->modal_surface_stack, g_object_unref); + g_hash_table_destroy (display_win32->display_surface_record->handle_ht); + g_free (display_win32->display_surface_record); _gdk_win32_display_finalize_cursors (display_win32); gdk_win32_display_close_dmanip_manager (GDK_DISPLAY (display_win32)); _gdk_win32_dnd_exit (); @@ -1027,6 +1030,30 @@ _gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type) } } +static guint +gdk_handle_hash (HANDLE *handle) +{ +#ifdef _WIN64 + return ((guint *) handle)[0] ^ ((guint *) handle)[1]; +#else + return (guint) *handle; +#endif +} + +static int +gdk_handle_equal (HANDLE *a, + HANDLE *b) +{ + return (*a == *b); +} + +/* facts of life, DestroyWindow() is a __stdcall function */ +static void +gdk_destroy_surface_hwnd (gpointer hwnd) +{ + DestroyWindow ((HWND)hwnd); +} + static void gdk_win32_display_init (GdkWin32Display *display_win32) { @@ -1037,6 +1064,9 @@ gdk_win32_display_init (GdkWin32Display *display_win32) display_win32->cb_dnd_items = g_new0 (GdkWin32CbDnDItems, 1); display_win32->cb_dnd_items->display_main_thread = g_thread_self (); display_win32->cb_dnd_items->clipdrop = GDK_WIN32_CLIPDROP (g_object_new (GDK_TYPE_WIN32_CLIPDROP, NULL)); + display_win32->display_surface_record = g_new0 (surface_records, 1); + display_win32->display_surface_record->handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash, + (GEqualFunc) gdk_handle_equal); _gdk_win32_enable_hidpi (display_win32); display_win32->running_on_arm64 = _gdk_win32_check_processor (GDK_WIN32_ARM64); diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h index 55a764b70b..88c23f5d8c 100644 --- a/gdk/win32/gdkdisplay-win32.h +++ b/gdk/win32/gdkdisplay-win32.h @@ -146,6 +146,13 @@ typedef struct void *getPointerType; } dmanip_items; +/* for surface tracking items (modal, HWNDs used, etc) */ +typedef struct +{ + GHashTable *handle_ht; + GSList *modal_surface_stack; +} surface_records; + struct _GdkWin32Display { GdkDisplay display; @@ -163,6 +170,7 @@ struct _GdkWin32Display GdkWin32PointerDeviceItems *pointer_device_items; GdkWin32CbDnDItems *cb_dnd_items; GdkDeviceManagerWin32 *device_manager; + surface_records *display_surface_record; dmanip_items *dmanip_items; diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 48293921df..80ac7d0bef 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -386,7 +386,7 @@ low_level_keyboard_proc (int code, if (kbd_focus_owner == NULL) break; - gdk_kbd_focus_owner = gdk_win32_handle_table_lookup_ (kbd_focus_owner); + gdk_kbd_focus_owner = gdk_win32_display_handle_table_lookup_ (NULL, kbd_focus_owner); if (gdk_kbd_focus_owner == NULL) break; @@ -615,7 +615,7 @@ find_surface_for_mouse_event (GdkSurface *reported_surface, ScreenToClient (hwnd, &client_pt); GetClientRect (hwnd, &rect); if (PtInRect (&rect, client_pt)) - event_surface = gdk_win32_handle_table_lookup_ (hwnd); + event_surface = gdk_win32_display_handle_table_lookup_ (display, hwnd); } if (event_surface == NULL) event_surface = grab->surface; @@ -1775,7 +1775,7 @@ gdk_event_translate (MSG *msg, return TRUE; } - surface = gdk_win32_handle_table_lookup_ (msg->hwnd); + surface = gdk_win32_display_handle_table_lookup_ (display, msg->hwnd); if (surface == NULL) { @@ -2265,7 +2265,7 @@ gdk_event_translate (MSG *msg, ScreenToClient (hwnd, &client_pt); GetClientRect (hwnd, &rect); if (PtInRect (&rect, client_pt)) - new_surface = gdk_win32_handle_table_lookup_ (hwnd); + new_surface = gdk_win32_display_handle_table_lookup_ (display, hwnd); } synthesize_crossing_events (display, @@ -2407,7 +2407,7 @@ gdk_event_translate (MSG *msg, ScreenToClient (hwnd, &client_pt); GetClientRect (hwnd, &rect); if (PtInRect (&rect, client_pt)) - new_surface = gdk_win32_handle_table_lookup_ (hwnd); + new_surface = gdk_win32_display_handle_table_lookup_ (display, hwnd); } if (!ignore_leave) @@ -2685,7 +2685,7 @@ gdk_event_translate (MSG *msg, msg->hwnd = hwnd; - g_set_object (&surface, gdk_win32_handle_table_lookup_ (hwnd)); + g_set_object (&surface, gdk_win32_display_handle_table_lookup_ (display, hwnd)); if (!surface) break; @@ -3222,7 +3222,7 @@ gdk_event_translate (MSG *msg, { if (msg->lParam != 0) { - GdkSurface *other_surface = gdk_win32_handle_table_lookup_ ((HWND) msg->lParam); + GdkSurface *other_surface = gdk_win32_display_handle_table_lookup_ (display, (HWND) msg->lParam); if (other_surface != NULL && (GDK_IS_POPUP (other_surface) || GDK_IS_DRAG_SURFACE (other_surface))) { diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 79a23e069d..e9ea061bda 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -76,9 +76,13 @@ gboolean _gdk_win32_surface_enable_transparency (GdkSurface *surface); void _gdk_win32_dnd_exit (void); -void gdk_win32_handle_table_insert (HANDLE *handle, - gpointer data); -void gdk_win32_handle_table_remove (HANDLE handle); +void gdk_win32_display_handle_table_insert (GdkDisplay *display, + HANDLE *handle, + gpointer data); +void gdk_win32_display_handle_table_remove (GdkDisplay *display, + HANDLE handle); +gpointer gdk_win32_display_handle_table_lookup_ (GdkDisplay *display, + HWND handle); cairo_region_t *_gdk_win32_hrgn_to_region (HRGN hrgn, guint scale); @@ -287,8 +291,6 @@ GdkPixbuf *gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon, double *y_hot); void gdk_win32_set_modal_dialog_libgtk_only (HWND hwnd); -gpointer gdk_win32_handle_table_lookup_ (HWND handle); - extern IMAGE_DOS_HEADER __ImageBase; static inline HMODULE diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c index 05bca9a624..29bcf644bc 100644 --- a/gdk/win32/gdksurface-win32.c +++ b/gdk/win32/gdksurface-win32.c @@ -75,9 +75,6 @@ static void gdk_win32_surface_maximize (GdkSurface *surface); static void gdk_win32_surface_unmaximize (GdkSurface *surface); static void gdk_win32_surface_minimize (GdkSurface *surface); -/* TODO: get rid of these global variables */ -static GSList *modal_surface_stack = NULL; - typedef struct _FullscreenInfo FullscreenInfo; struct _FullscreenInfo @@ -185,7 +182,8 @@ gdk_surface_win32_finalize (GObject *object) if (!GDK_SURFACE_DESTROYED (surface)) { - gdk_win32_handle_table_remove (surface->handle); + gdk_win32_display_handle_table_remove (gdk_surface_get_display (GDK_SURFACE (surface)), + surface->handle); } g_clear_pointer (&surface->snap_stash, g_free); @@ -517,7 +515,7 @@ gdk_win32_surface_constructed (GObject *object) * on the bitness of the OS. That pointer is still unique, * so this works out in the end. */ - gdk_win32_handle_table_insert (&GDK_SURFACE_HWND (impl), impl); + gdk_win32_display_handle_table_insert (display, &GDK_SURFACE_HWND (impl), impl); g_free (wtitle); @@ -605,7 +603,8 @@ gdk_win32_surface_destroy_notify (GdkSurface *surface) _gdk_surface_destroy (surface, TRUE); } - gdk_win32_handle_table_remove (GDK_SURFACE_HWND (surface)); + gdk_win32_display_handle_table_remove (gdk_surface_get_display (surface), + GDK_SURFACE_HWND (surface)); g_object_unref (surface); } @@ -1399,10 +1398,12 @@ gdk_win32_surface_set_transient_for (GdkSurface *surface, WIN32_API_FAILED ("SetWindowLongPtr"); } +#define MODAL_SURFACE_STACK(s) GDK_WIN32_DISPLAY (gdk_surface_get_display (s))->display_surface_record->modal_surface_stack + static void gdk_win32_push_modal_surface (GdkSurface *surface) { - modal_surface_stack = g_slist_prepend (modal_surface_stack, surface); + MODAL_SURFACE_STACK (surface) = g_slist_prepend (MODAL_SURFACE_STACK (surface), surface); } static void @@ -1414,15 +1415,15 @@ gdk_win32_remove_modal_surface (GdkSurface *surface) /* It's possible to be NULL here if someone sets the modal hint of the surface * to FALSE before a modal surface stack has ever been created. */ - if (modal_surface_stack == NULL) + if (MODAL_SURFACE_STACK (surface) == NULL) return; /* Find the requested surface in the stack and remove it. Yeah, I realize this * means we're not a 'real stack', strictly speaking. Sue me. :) */ - tmp = g_slist_find (modal_surface_stack, surface); + tmp = g_slist_find (MODAL_SURFACE_STACK (surface), surface); if (tmp != NULL) { - modal_surface_stack = g_slist_delete_link (modal_surface_stack, tmp); + MODAL_SURFACE_STACK (surface) = g_slist_delete_link (MODAL_SURFACE_STACK (surface), tmp); } } @@ -1432,7 +1433,7 @@ _gdk_modal_blocked (GdkSurface *surface) GSList *l; gboolean found_any = FALSE; - for (l = modal_surface_stack; l != NULL; l = l->next) + for (l = MODAL_SURFACE_STACK (surface); l != NULL; l = l->next) { GdkSurface *modal = l->data; @@ -1450,8 +1451,11 @@ GdkSurface * _gdk_modal_current (void) { GSList *l; + GdkDisplay *display = gdk_display_get_default (); - for (l = modal_surface_stack; l != NULL; l = l->next) + for (l = GDK_WIN32_DISPLAY (display)->display_surface_record->modal_surface_stack; + l != NULL; + l = l->next) { GdkSurface *modal = l->data; @@ -4133,7 +4137,7 @@ gdk_win32_surface_lookup_for_display (GdkDisplay *display, { g_return_val_if_fail (display == gdk_display_get_default (), NULL); - return (GdkSurface*) gdk_win32_handle_table_lookup_ (anid); + return (GdkSurface*) gdk_win32_display_handle_table_lookup_ (display, anid); } /** diff --git a/gdk/win32/gdkwin32misc.c b/gdk/win32/gdkwin32misc.c index 021e5c5b78..0ceab4e78b 100644 --- a/gdk/win32/gdkwin32misc.c +++ b/gdk/win32/gdkwin32misc.c @@ -50,8 +50,6 @@ struct _GdkWin32InputLocaleItems DWORD actlangchangenotify_id; }; -static GHashTable *handle_ht = NULL; - static guint gdk_handle_hash (HANDLE *handle) { @@ -69,36 +67,34 @@ gdk_handle_equal (HANDLE *a, return (*a == *b); } +#define GDK_DISPLAY_HANDLE_HT(d) GDK_WIN32_DISPLAY(d)->display_surface_record->handle_ht + void -gdk_win32_handle_table_insert (HANDLE *handle, - gpointer data) +gdk_win32_display_handle_table_insert (GdkDisplay *display, + HANDLE *handle, + gpointer data) { g_return_if_fail (handle != NULL); - if (!handle_ht) - handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash, - (GEqualFunc) gdk_handle_equal); - - g_hash_table_insert (handle_ht, handle, data); + g_hash_table_insert (GDK_DISPLAY_HANDLE_HT (display), handle, data); } void -gdk_win32_handle_table_remove (HANDLE handle) +gdk_win32_display_handle_table_remove (GdkDisplay *display, + HANDLE handle) { - if (!handle_ht) - handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash, - (GEqualFunc) gdk_handle_equal); - - g_hash_table_remove (handle_ht, &handle); + g_hash_table_remove (GDK_DISPLAY_HANDLE_HT (display), &handle); } gpointer -gdk_win32_handle_table_lookup_ (HWND handle) +gdk_win32_display_handle_table_lookup_ (GdkDisplay *display, + HWND handle) { gpointer data = NULL; + if (display == NULL) + display = gdk_display_get_default (); - if (handle_ht) - data = g_hash_table_lookup (handle_ht, &handle); + data = g_hash_table_lookup (GDK_DISPLAY_HANDLE_HT (display), &handle); return data; } @@ -106,7 +102,7 @@ gdk_win32_handle_table_lookup_ (HWND handle) gpointer gdk_win32_handle_table_lookup (HWND handle) { - return gdk_win32_handle_table_lookup_ (handle); + return gdk_win32_display_handle_table_lookup_ (NULL, handle); } /* set up input language or text service change notification for our GdkDisplay */