xquartz: Ensure we call into TIS on the main thread

There is a place where this code was called on the main thread.

We're using a rather nasty anti-pattern to just call a block inline rather
than synchonously calling it on the main thread if we're already on the main
thread.  This code could use a good overhaul, but I don't have time to rip
it apart right now.  This will address the immediate issue.

Fixes: https://github.com/XQuartz/XQuartz/issues/40
Fixes: https://github.com/XQuartz/XQuartz/issues/48
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
This commit is contained in:
Jeremy Huddleston Sequoia 2021-02-01 16:27:38 -08:00
parent af17b5c499
commit c9a3b14c14

View File

@ -746,23 +746,33 @@ make_dead_key(KeySym in)
static Bool static Bool
QuartzReadSystemKeymap(darwinKeyboardInfo *info) QuartzReadSystemKeymap(darwinKeyboardInfo *info)
{ {
const void *chr_data = NULL; __block const void *chr_data = NULL;
int num_keycodes = NUM_KEYCODES; int num_keycodes = NUM_KEYCODES;
UInt32 keyboard_type = LMGetKbdType(); __block UInt32 keyboard_type;
int i, j; int i, j;
OSStatus err; OSStatus err;
KeySym *k; KeySym *k;
CFDataRef currentKeyLayoutDataRef = NULL;
TISInputSourceRef currentKeyLayoutRef = dispatch_block_t getKeyboardData = ^{
TISCopyCurrentKeyboardLayoutInputSource(); keyboard_type = LMGetKbdType();
if (currentKeyLayoutRef) { TISInputSourceRef currentKeyLayoutRef = TISCopyCurrentKeyboardLayoutInputSource();
currentKeyLayoutDataRef = (CFDataRef)TISGetInputSourceProperty(
currentKeyLayoutRef, kTISPropertyUnicodeKeyLayoutData); if (currentKeyLayoutRef) {
if (currentKeyLayoutDataRef) CFDataRef currentKeyLayoutDataRef = (CFDataRef)TISGetInputSourceProperty(currentKeyLayoutRef,
chr_data = CFDataGetBytePtr(currentKeyLayoutDataRef); kTISPropertyUnicodeKeyLayoutData);
CFRelease(currentKeyLayoutRef); if (currentKeyLayoutDataRef)
chr_data = CFDataGetBytePtr(currentKeyLayoutDataRef);
CFRelease(currentKeyLayoutRef);
}
};
/* This is an ugly ant-pattern, but it is more expedient to address the problem right now. */
if (pthread_main_np()) {
getKeyboardData();
} else {
dispatch_sync(dispatch_get_main_queue(), getKeyboardData);
} }
if (chr_data == NULL) { if (chr_data == NULL) {