winemac: Make macdrv_process_text_input() asynchronous and process internal events while awaiting its result.
It had been using the synchronous OnMainThread() to submit its work to the Cocoa thread, but only queries are processed while OnMainThread() waits for the work to complete. This led to QUERY_IME_CHAR_RECT queries being processed out of order relative to IM_SET_TEXT events, making the character range out of bounds with respect to the composition string. Signed-off-by: Ken Thomases <ken@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
48d755f61d
commit
3482c47469
|
@ -3230,11 +3230,11 @@ uint32_t macdrv_window_background_color(void)
|
|||
/***********************************************************************
|
||||
* macdrv_send_text_input_event
|
||||
*/
|
||||
int macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, void* data)
|
||||
void macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, void* data, int* done)
|
||||
{
|
||||
__block BOOL ret;
|
||||
|
||||
OnMainThread(^{
|
||||
OnMainThreadAsync(^{
|
||||
BOOL ret;
|
||||
macdrv_event* event;
|
||||
WineWindow* window = (WineWindow*)[NSApp keyWindow];
|
||||
if (![window isKindOfClass:[WineWindow class]])
|
||||
{
|
||||
|
@ -3266,7 +3266,11 @@ int macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, in
|
|||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
});
|
||||
|
||||
return ret;
|
||||
event = macdrv_create_event(SENT_TEXT_INPUT, window);
|
||||
event->sent_text_input.handled = ret;
|
||||
event->sent_text_input.done = done;
|
||||
[[window queue] postEvent:event];
|
||||
macdrv_release_event(event);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ static const char *dbgstr_event(int type)
|
|||
"QUERY_EVENT",
|
||||
"REASSERT_WINDOW_POSITION",
|
||||
"RELEASE_CAPTURE",
|
||||
"SENT_TEXT_INPUT",
|
||||
"STATUS_ITEM_MOUSE_BUTTON",
|
||||
"STATUS_ITEM_MOUSE_MOVE",
|
||||
"WINDOW_BROUGHT_FORWARD",
|
||||
|
@ -118,6 +119,7 @@ static macdrv_event_mask get_event_mask(DWORD mask)
|
|||
event_mask |= event_mask_for_type(QUERY_EVENT);
|
||||
event_mask |= event_mask_for_type(REASSERT_WINDOW_POSITION);
|
||||
event_mask |= event_mask_for_type(RELEASE_CAPTURE);
|
||||
event_mask |= event_mask_for_type(SENT_TEXT_INPUT);
|
||||
event_mask |= event_mask_for_type(WINDOW_BROUGHT_FORWARD);
|
||||
event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED);
|
||||
event_mask |= event_mask_for_type(WINDOW_DRAG_BEGIN);
|
||||
|
@ -245,6 +247,9 @@ void macdrv_handle_event(const macdrv_event *event)
|
|||
case RELEASE_CAPTURE:
|
||||
macdrv_release_capture(hwnd, event);
|
||||
break;
|
||||
case SENT_TEXT_INPUT:
|
||||
macdrv_sent_text_input(event);
|
||||
break;
|
||||
case STATUS_ITEM_MOUSE_BUTTON:
|
||||
macdrv_status_item_mouse_button(event);
|
||||
break;
|
||||
|
|
|
@ -690,7 +690,7 @@ UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState,
|
|||
LPIMEPRIVATE myPrivate;
|
||||
HWND hwndDefault;
|
||||
UINT repeat;
|
||||
INT rc;
|
||||
int done = 0;
|
||||
|
||||
TRACE("uVKey 0x%04x uScanCode 0x%04x fuState %u hIMC %p\n", uVKey, uScanCode, fuState, hIMC);
|
||||
|
||||
|
@ -717,9 +717,12 @@ UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState,
|
|||
UnlockRealIMC(hIMC);
|
||||
|
||||
TRACE("Processing Mac 0x%04x\n", vkey);
|
||||
rc = macdrv_process_text_input(uVKey, uScanCode, repeat, lpbKeyState, hIMC);
|
||||
macdrv_process_text_input(uVKey, uScanCode, repeat, lpbKeyState, hIMC, &done);
|
||||
|
||||
if (!rc)
|
||||
while (!done)
|
||||
MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_POSTMESSAGE | QS_SENDMESSAGE, 0);
|
||||
|
||||
if (done < 0)
|
||||
{
|
||||
UINT msgs = 0;
|
||||
UINT msg = (uScanCode & 0x8000) ? WM_KEYUP : WM_KEYDOWN;
|
||||
|
@ -1482,6 +1485,15 @@ void macdrv_im_set_text(const macdrv_event *event)
|
|||
IME_NotifyComplete(himc);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_sent_text_input
|
||||
*/
|
||||
void macdrv_sent_text_input(const macdrv_event *event)
|
||||
{
|
||||
TRACE("handled: %s\n", event->sent_text_input.handled ? "TRUE" : "FALSE");
|
||||
*event->sent_text_input.done = event->sent_text_input.handled ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* query_ime_char_rect
|
||||
|
|
|
@ -1117,12 +1117,11 @@ void macdrv_hotkey_press(const macdrv_event *event)
|
|||
/***********************************************************************
|
||||
* macdrv_process_text_input
|
||||
*/
|
||||
BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state, void *himc)
|
||||
void macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state, void *himc, int* done)
|
||||
{
|
||||
struct macdrv_thread_data *thread_data = macdrv_thread_data();
|
||||
unsigned int flags;
|
||||
int keyc;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("vkey 0x%04x scan 0x%04x repeat %u himc %p\n", vkey, scan, repeat, himc);
|
||||
|
||||
|
@ -1149,15 +1148,11 @@ BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *ke
|
|||
if (thread_data->keyc2vkey[keyc] == vkey) break;
|
||||
|
||||
if (keyc >= sizeof(thread_data->keyc2vkey)/sizeof(thread_data->keyc2vkey[0]))
|
||||
goto done;
|
||||
return;
|
||||
|
||||
TRACE("flags 0x%08x keyc 0x%04x\n", flags, keyc);
|
||||
|
||||
ret = macdrv_send_text_input_event(((scan & 0x8000) == 0), flags, repeat, keyc, himc);
|
||||
|
||||
done:
|
||||
TRACE(" -> %s\n", ret ? "TRUE" : "FALSE");
|
||||
return ret;
|
||||
macdrv_send_text_input_event(((scan & 0x8000) == 0), flags, repeat, keyc, himc, done);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -224,10 +224,11 @@ extern CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP
|
|||
* Mac IME driver
|
||||
*/
|
||||
|
||||
extern BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state,
|
||||
void *himc) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state,
|
||||
void *himc, int* done) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void macdrv_im_set_text(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_sent_text_input(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
extern BOOL query_ime_char_rect(macdrv_query* query) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_MACDRV_H */
|
||||
|
|
|
@ -201,6 +201,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
QUERY_EVENT,
|
||||
REASSERT_WINDOW_POSITION,
|
||||
RELEASE_CAPTURE,
|
||||
SENT_TEXT_INPUT,
|
||||
STATUS_ITEM_MOUSE_BUTTON,
|
||||
STATUS_ITEM_MOUSE_MOVE,
|
||||
WINDOW_BROUGHT_FORWARD,
|
||||
|
@ -285,6 +286,10 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
struct {
|
||||
struct macdrv_query *query;
|
||||
} query_event;
|
||||
struct {
|
||||
int handled;
|
||||
int *done;
|
||||
} sent_text_input;
|
||||
struct {
|
||||
macdrv_status_item item;
|
||||
int button;
|
||||
|
@ -438,8 +443,8 @@ extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat
|
|||
extern void macdrv_add_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_remove_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN;
|
||||
extern uint32_t macdrv_window_background_color(void) DECLSPEC_HIDDEN;
|
||||
extern int macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc,
|
||||
void* data) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc,
|
||||
void* data, int* done) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/* keyboard */
|
||||
|
|
Loading…
Reference in New Issue