GDK/Win32: Drop surface tracking global variables

...including the list of modal surfaces and hashes of opened HWNDs for
various surfaces, and tuck them into GdkWin32Display.
This commit is contained in:
Chun-wei Fan
2024-08-30 15:42:35 +08:00
parent 0a65221721
commit 789bb83b5a
9 changed files with 93 additions and 55 deletions

View File

@@ -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))
{

View File

@@ -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))
{

View File

@@ -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 */
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)))
{

View File

@@ -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

View File

@@ -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);
}
/**

View File

@@ -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 */