GDK/Win32: Drop global variables from GdkKeys implementation

We get to create our GdkKey with a display as a property for free, so
just stuff the default keymap and keymap serial (to track IME state
changes and so) into our GdkWin32Display under an existing sub-struct
that is for holding these items.
This commit is contained in:
Chun-wei Fan 2024-09-12 12:57:50 +08:00
parent 004d787cb2
commit d120aaf6ee
6 changed files with 146 additions and 97 deletions

View File

@ -573,7 +573,7 @@ _gdk_win32_display_open (const char *display_name)
g_signal_emit_by_name (display, "opened");
/* Precalculate keymap, see #6203 */
_gdk_win32_display_get_keymap (display);
gdk_display_get_keymap (display);
GDK_NOTE (MISC, g_print ("... gdk_display now set up\n"));
@ -1340,6 +1340,13 @@ gdk_win32_display_get_clipdrop (GdkDisplay *display)
return display_win32->cb_dnd_items->clipdrop;
}
static GdkKeymap*
_gdk_win32_display_get_keymap (GdkDisplay *display)
{
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
return gdk_win32_display_get_default_keymap (GDK_WIN32_DISPLAY (display));
}
static void
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)

View File

@ -162,6 +162,12 @@ typedef struct
/* for tracking various events that go on */
typedef struct
{
/* for tracking various mouse/wintab/winpointer events */
GdkSurface *mouse_surface;
GdkSurface *mouse_surface_ignored_leave;
int current_root_x;
int current_root_y;
int debug_indent_displaychange;
} event_records;

View File

@ -136,10 +136,6 @@ static GSourceFuncs event_funcs = {
};
/* TODO: Get rid of these global variables... */
static GdkSurface *mouse_surface = NULL;
static GdkSurface *mouse_surface_ignored_leave = NULL;
static int current_root_x, current_root_y;
static UINT got_gdk_events_message;
static HWND modal_win32_dialog = NULL;
@ -635,7 +631,7 @@ build_key_event_state (GdkDisplay *display,
{
GdkModifierType state;
GdkWin32Keymap *keymap;
keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (display));
keymap = GDK_WIN32_KEYMAP (gdk_display_get_keymap (display));
state = _gdk_win32_keymap_get_mod_mask (keymap);
@ -661,7 +657,7 @@ get_active_group (GdkDisplay *display)
{
GdkWin32Keymap *keymap;
keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (display));
keymap = GDK_WIN32_KEYMAP (gdk_display_get_keymap (display));
return _gdk_win32_keymap_get_active_group (keymap);
}
@ -1241,10 +1237,13 @@ make_crossing_event (GdkDevice *physical_device,
POINT *screen_pt,
guint32 time_)
{
GdkDisplay *display = surface != NULL ? gdk_surface_get_display (surface) : gdk_display_get_default ();
GdkSurface *mouse_surface = GDK_WIN32_DISPLAY (display)->event_record->mouse_surface;
GDK_NOTE (EVENTS, g_print (" mouse_surface %p -> %p",
mouse_surface ? GDK_SURFACE_HWND (mouse_surface) : NULL,
surface ? GDK_SURFACE_HWND (surface) : NULL));
synthesize_crossing_events (surface != NULL ? gdk_surface_get_display (surface) : gdk_display_get_default (),
synthesize_crossing_events (display,
physical_device,
mouse_surface, surface,
GDK_CROSSING_NORMAL,
@ -1252,7 +1251,7 @@ make_crossing_event (GdkDevice *physical_device,
0, /* TODO: Set right mask */
time_,
FALSE);
g_set_object (&mouse_surface, surface);
g_set_object (&GDK_WIN32_DISPLAY (display)->event_record->mouse_surface, surface);
}
/* Acquires actual client area size of the underlying native surface HWND.
@ -1831,12 +1830,12 @@ gdk_event_translate (MSG *msg,
GdkTranslatedKey translated;
HKL input_locale;
win32_keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (display));
win32_keymap = GDK_WIN32_KEYMAP (gdk_display_get_keymap (display));
input_locale = (HKL) msg->lParam;
gdk_win32_display_set_input_locale (win32_display, input_locale);
_gdk_win32_keymap_set_active_layout (win32_keymap, input_locale);
_gdk_keymap_serial++;
gdk_win32_display_increment_keymap_serial (win32_display);
GDK_NOTE (EVENTS,
g_print (" cs:%lu hkl:%p%s",
(gulong) msg->wParam,
@ -1929,7 +1928,7 @@ gdk_event_translate (MSG *msg,
if (GDK_SURFACE_DESTROYED (surface))
break;
win32_keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (display));
win32_keymap = GDK_WIN32_KEYMAP (gdk_display_get_keymap (display));
impl = GDK_WIN32_SURFACE (surface);
API_CALL (GetKeyboardState, (key_state));
@ -2284,8 +2283,8 @@ gdk_event_translate (MSG *msg,
0, /* TODO: Set right mask */
_gdk_win32_get_next_tick (msg->time),
FALSE);
g_set_object (&mouse_surface, new_surface);
mouse_surface_ignored_leave = NULL;
g_set_object (&win32_display->event_record->mouse_surface, new_surface);
win32_display->event_record->mouse_surface_ignored_leave = NULL;
}
*ret_valp = (msg->message == WM_XBUTTONUP ? TRUE : 0);
@ -2318,32 +2317,34 @@ gdk_event_translate (MSG *msg,
g_set_object (&surface, find_surface_for_mouse_event (surface, msg));
if (mouse_surface != surface)
{
GDK_NOTE (EVENTS, g_print (" mouse_surface %p -> %p",
mouse_surface ? GDK_SURFACE_HWND (mouse_surface) : NULL,
surface ? GDK_SURFACE_HWND (surface) : NULL));
synthesize_crossing_events (display,
if (win32_display->event_record->mouse_surface != surface)
{
GdkSurface *mouse_surface = win32_display->event_record->mouse_surface;
GDK_NOTE (EVENTS, g_print (" mouse_surface %p -> %p",
mouse_surface ? GDK_SURFACE_HWND (mouse_surface) : NULL,
surface ? GDK_SURFACE_HWND (surface) : NULL));
synthesize_crossing_events (display,
win32_display->device_manager->system_pointer,
mouse_surface, surface,
GDK_CROSSING_NORMAL,
&msg->pt,
0, /* TODO: Set right mask */
_gdk_win32_get_next_tick (msg->time),
FALSE);
g_set_object (&mouse_surface, surface);
mouse_surface_ignored_leave = NULL;
if (surface != NULL)
track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (surface));
}
else if (surface != NULL && surface == mouse_surface_ignored_leave)
{
/* If we ignored a leave event for this surface and we're now getting
input again we need to re-arm the mouse tracking, as that was
cancelled by the mouseleave. */
mouse_surface_ignored_leave = NULL;
GDK_CROSSING_NORMAL,
&msg->pt,
0, /* TODO: Set right mask */
_gdk_win32_get_next_tick (msg->time),
FALSE);
g_set_object (&win32_display->event_record->mouse_surface, surface);
win32_display->event_record->mouse_surface_ignored_leave = NULL;
if (surface != NULL)
track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (surface));
}
else if (surface != NULL && surface == win32_display->event_record->mouse_surface_ignored_leave)
{
/* If we ignored a leave event for this surface and we're now getting
input again we need to re-arm the mouse tracking, as that was
cancelled by the mouseleave. */
win32_display->event_record->mouse_surface_ignored_leave = NULL;
track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (surface));
}
}
impl = GDK_WIN32_SURFACE (surface);
@ -2351,12 +2352,12 @@ gdk_event_translate (MSG *msg,
* sends WM_MOUSEMOVE messages after a new surface is shown under
* the mouse, even if the mouse hasn't moved. This disturbs gtk.
*/
if (msg->pt.x == current_root_x &&
msg->pt.y == current_root_y)
if (msg->pt.x == win32_display->event_record->current_root_x &&
msg->pt.y == win32_display->event_record->current_root_y)
break;
current_root_x = msg->pt.x;
current_root_y = msg->pt.y;
win32_display->event_record->current_root_x = msg->pt.x;
win32_display->event_record->current_root_y = msg->pt.y;
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
gdk_win32_surface_do_move_resize_drag (surface, msg->pt.x, msg->pt.y);
@ -2419,16 +2420,16 @@ gdk_event_translate (MSG *msg,
}
if (!ignore_leave)
synthesize_crossing_events (display,
synthesize_crossing_events (display,
win32_display->device_manager->system_pointer,
mouse_surface, new_surface,
GDK_CROSSING_NORMAL,
&msg->pt,
0, /* TODO: Set right mask */
_gdk_win32_get_next_tick (msg->time),
FALSE);
g_set_object (&mouse_surface, new_surface);
mouse_surface_ignored_leave = ignore_leave ? new_surface : NULL;
win32_display->event_record->mouse_surface, new_surface,
GDK_CROSSING_NORMAL,
&msg->pt,
0, /* TODO: Set right mask */
_gdk_win32_get_next_tick (msg->time),
FALSE);
g_set_object (&win32_display->event_record->mouse_surface, new_surface);
win32_display->event_record->mouse_surface_ignored_leave = ignore_leave ? new_surface : NULL;
return_val = TRUE;
@ -2444,8 +2445,8 @@ gdk_event_translate (MSG *msg,
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
{
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
win32_display->event_record->current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
win32_display->event_record->current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
pen_touch_input = TRUE;
last_digitizer_time = msg->time;
}
@ -2455,7 +2456,7 @@ gdk_event_translate (MSG *msg,
!pointer_grab->owner_events)
g_set_object (&surface, pointer_grab->surface);
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && mouse_surface != surface)
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && win32_display->event_record->mouse_surface != surface)
crossing_cb = make_crossing_event;
gdk_winpointer_input_events (surface, crossing_cb, msg);
@ -2474,8 +2475,8 @@ gdk_event_translate (MSG *msg,
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
{
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
win32_display->event_record->current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
win32_display->event_record->current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
pen_touch_input = TRUE;
last_digitizer_time = msg->time;
}
@ -2507,8 +2508,8 @@ gdk_event_translate (MSG *msg,
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
{
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
win32_display->event_record->current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
win32_display->event_record->current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
pen_touch_input = TRUE;
last_digitizer_time = msg->time;
}
@ -2518,14 +2519,16 @@ gdk_event_translate (MSG *msg,
!pointer_grab->owner_events)
g_set_object (&surface, pointer_grab->surface);
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && mouse_surface != surface)
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && win32_display->event_record->mouse_surface != surface)
crossing_cb = make_crossing_event;
impl = GDK_WIN32_SURFACE (surface);
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
{
gdk_win32_surface_do_move_resize_drag (surface, current_root_x, current_root_y);
gdk_win32_surface_do_move_resize_drag (surface,
win32_display->event_record->current_root_x,
win32_display->event_record->current_root_y);
}
else
{
@ -2546,15 +2549,15 @@ gdk_event_translate (MSG *msg,
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
{
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
win32_display->event_record->current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
win32_display->event_record->current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
pen_touch_input = TRUE;
last_digitizer_time = msg->time;
}
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) &&
!IS_POINTER_INCONTACT_WPARAM (msg->wParam) &&
mouse_surface != NULL)
win32_display->event_record->mouse_surface != NULL)
{
GdkDevice *event_device = NULL;
guint32 event_time = 0;
@ -2581,8 +2584,8 @@ gdk_event_translate (MSG *msg,
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
{
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
win32_display->event_record->current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
win32_display->event_record->current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
pen_touch_input = TRUE;
last_digitizer_time = msg->time;
}
@ -2611,8 +2614,8 @@ gdk_event_translate (MSG *msg,
if (IS_POINTER_PRIMARY_WPARAM (msg->wParam))
{
current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
win32_display->event_record->current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam);
win32_display->event_record->current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam);
pen_touch_input = TRUE;
last_digitizer_time = msg->time;
}
@ -2621,7 +2624,7 @@ gdk_event_translate (MSG *msg,
{
gdk_winpointer_input_events (surface, NULL, msg);
}
else if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && mouse_surface != NULL)
else if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && win32_display->event_record->mouse_surface != NULL)
{
GdkDevice *event_device = NULL;
guint32 event_time = 0;

View File

@ -29,7 +29,7 @@
#include "gdkprivate-win32.h"
#include "gdkdebugprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkdisplay-win32.h"
#include "gdkkeysyms.h"
#include "gdkkeysprivate.h"
#include "gdkkeys-win32.h"
@ -77,9 +77,7 @@ struct _GdkWin32Keymap
G_DEFINE_TYPE (GdkWin32Keymap, gdk_win32_keymap, GDK_TYPE_KEYMAP)
guint _gdk_keymap_serial = 0;
static GdkKeymap *default_keymap = NULL;
/* forward declarations */
static void update_keymap (GdkWin32Keymap *gdk_keymap);
static void clear_keyboard_layout_info (gpointer data);
@ -107,7 +105,14 @@ gdk_win32_keymap_init (GdkWin32Keymap *keymap)
if (_gdk_win32_check_processor (GDK_WIN32_WOW64))
keymap->gdkwin32_keymap_impl = &gdkwin32_keymap_impl_wow64;
#endif
}
static void
gdk_win32_keymap_constructed (GObject *object)
{
GdkWin32Keymap *keymap;
keymap = GDK_WIN32_KEYMAP (object);
update_keymap (keymap);
}
@ -583,8 +588,10 @@ update_keymap (GdkWin32Keymap *keymap)
BOOL changed = FALSE;
int n_layouts;
int i;
GdkWin32Display *display = GDK_WIN32_DISPLAY (GDK_KEYMAP (keymap)->display);
if (keymap->current_serial == _gdk_keymap_serial &&
if (keymap->current_serial == gdk_win32_display_get_keymap_serial (display) &&
keymap->layout_handles->len > 0)
{
return;
@ -643,7 +650,7 @@ update_keymap (GdkWin32Keymap *keymap)
if (changed)
ActivateKeyboardLayout (current_layout, 0);
keymap->current_serial = _gdk_keymap_serial;
keymap->current_serial = gdk_win32_display_get_keymap_serial (display);
}
guint8
@ -677,17 +684,6 @@ _gdk_win32_keymap_get_active_group (GdkWin32Keymap *keymap)
return 0;
}
GdkKeymap*
_gdk_win32_display_get_keymap (GdkDisplay *display)
{
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
if (default_keymap == NULL)
default_keymap = g_object_new (gdk_win32_keymap_get_type (), NULL);
return default_keymap;
}
GdkModifierType
_gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap)
{
@ -1071,6 +1067,7 @@ gdk_win32_keymap_class_init (GdkWin32KeymapClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
object_class->constructed = gdk_win32_keymap_constructed;
object_class->finalize = gdk_win32_keymap_finalize;
keymap_class->get_direction = gdk_win32_keymap_get_direction;

View File

@ -143,8 +143,6 @@ extern LRESULT CALLBACK _gdk_win32_surface_procedure (HWND, UINT, WPARAM, LPARAM
* from a single thread anyway.
*/
extern guint _gdk_keymap_serial;
typedef enum {
GDK_WIN32_MODAL_OP_NONE = 0x0,
GDK_WIN32_MODAL_OP_SIZE = 0x1 << 0,
@ -205,8 +203,6 @@ void _gdk_win32_keymap_set_active_layout (GdkWin32Keymap *keymap,
HKL hkl);
GdkModifierType _gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap);
GdkKeymap *_gdk_win32_display_get_keymap (GdkDisplay *display);
/* stray GdkSurfaceImplWin32 members */
void _gdk_win32_surface_register_dnd (GdkSurface *surface);
void _gdk_win32_surface_unregister_dnd (GdkSurface *surface);
@ -218,15 +214,18 @@ GdkDrag *_gdk_win32_surface_drag_begin (GdkSurface *surface,
double x_root,
double y_root);
/* miscellaneous items (property setup, language notification) */
gboolean gdk_win32_display_get_setting (GdkDisplay *display,
const char *name,
GValue *value);
void gdk_win32_display_lang_notification_init (GdkWin32Display *display);
void gdk_win32_display_lang_notification_exit (GdkWin32Display *display);
void gdk_win32_display_set_input_locale (GdkWin32Display *display,
HKL input_locale);
gboolean gdk_win32_display_input_locale_is_ime (GdkWin32Display *display);
/* miscellaneous items (property setup, language notification, keymap serial) */
gboolean gdk_win32_display_get_setting (GdkDisplay *display,
const char *name,
GValue *value);
void gdk_win32_display_lang_notification_init (GdkWin32Display *display);
void gdk_win32_display_lang_notification_exit (GdkWin32Display *display);
void gdk_win32_display_set_input_locale (GdkWin32Display *display,
HKL input_locale);
gboolean gdk_win32_display_input_locale_is_ime (GdkWin32Display *display);
GdkKeymap *gdk_win32_display_get_default_keymap (GdkWin32Display *display);
void gdk_win32_display_increment_keymap_serial (GdkWin32Display *display);
guint gdk_win32_display_get_keymap_serial (GdkWin32Display *display);
/* Stray GdkWin32Screen members */
void _gdk_win32_screen_on_displaychange_event (GdkWin32Screen *screen);

View File

@ -48,6 +48,10 @@ struct _GdkWin32InputLocaleItems
GdkWin32ALPNSink *notification_sink;
ITfSource *itf_source;
DWORD actlangchangenotify_id;
/* keymap items */
GdkKeymap *default_keymap;
guint keymap_serial;
};
static guint
@ -234,6 +238,7 @@ gdk_win32_display_lang_notification_exit (GdkWin32Display *display)
CoUninitialize ();
g_clear_pointer (&display->input_locale_items->default_keymap, g_object_unref);
g_free (display->input_locale_items->notification_sink);
g_free (display->input_locale_items);
}
@ -254,6 +259,38 @@ gdk_win32_display_input_locale_is_ime (GdkWin32Display *display)
return display->input_locale_items->notification_sink->input_locale_is_ime;
}
GdkKeymap *
gdk_win32_display_get_default_keymap (GdkWin32Display *display)
{
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), NULL);
if (display->input_locale_items->default_keymap == NULL)
{
display->input_locale_items->default_keymap =
g_object_new (GDK_TYPE_WIN32_KEYMAP,
"display", display,
NULL);
}
return display->input_locale_items->default_keymap;
}
void
gdk_win32_display_increment_keymap_serial (GdkWin32Display *display)
{
g_return_if_fail (GDK_IS_WIN32_DISPLAY (display));
display->input_locale_items->keymap_serial++;
}
guint
gdk_win32_display_get_keymap_serial (GdkWin32Display *display)
{
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), 0);
return display->input_locale_items->keymap_serial;
}
static char *
_get_system_font_name (HDC hdc)
{