https://bugs.winehq.org/show_bug.cgi?id=56233
Bug ID: 56233 Summary: On macOS Sonoma, applications respond slowly when caps lock is enabled Product: Wine Version: 9.0 Hardware: x86-64 OS: MacOS Status: UNCONFIRMED Severity: normal Priority: P2 Component: winemac.drv Assignee: wine-bugs@winehq.org Reporter: bshanks@codeweavers.com
macOS Sonoma introduces new "accessories" that appear below the text insertion point, like a caps lock indicator or an input language switcher (see [1]). These also show up in Wine windows, since they use existing APIs like NSTextInputClient to discover whether an insertion point is present and where in the view it's located.
But, when an accessory like the caps lock indicator is displayed, interacting with the window (say, pulling down menus) is extremely slow. There are half-second pauses when displaying/hiding menus or other windows. This can be easily reproduced using notepad.
I ran sample during the slowdown and was able to see the problem. Here's the backtrace, with some unimportant lines removed:
3294 __OnMainThread_block_invoke (in winemac.so) + 16 [0x20b56ac10] cocoa_event.m:507 3070 __macdrv_set_cocoa_window_frame_block_invoke (in winemac.so) + 100 [0x20b577dd4] cocoa_window.m:3464 3070 -[WineWindow setFrameFromWine:] (in winemac.so) + 557 [0x20b57258d] cocoa_window.m:2012 3070 -[WineWindow setFrameAndWineFrame:] (in winemac.so) + 60 [0x20b5721dc] cocoa_window.m:1938 3069 -[WineWindow setFrame:display:] (in winemac.so) + 136 [0x20b575008] cocoa_window.m:2682 ... 3066 -[WineWindow windowDidResize:skipSizeMove:] (in winemac.so) + 441 [0x20b5762d9] cocoa_window.m:3031 3066 -[TUINSCursorUIController invalidateCharacterCoordinates] (in TextInputUIMacHelper) + 113 [0x7ffc12ad733a] ... 1643 -[WineContentView firstRectForCharacterRange:actualRange:] (in winemac.so) + 196 [0x20b56ef24] cocoa_window.m:926 1643 -[WineEventQueue query:timeout:flags:] (in winemac.so) + 217 [0x20b56a209] cocoa_event.m:336 1643 -[WineApplicationController waitUntilQueryDone:timeout:processEvents:] (in winemac.so) + 224 [0x20b55eb70] cocoa_app.m:350
Pulling menus down creates new HWNDs, I think initially with 1x1 size, and then the frame is set. This triggers windowDidResize, which calls [[[self contentView] inputContext] invalidateCharacterCoordinates]. This is sensible, character coordinates might change when the window is resized. And when caps lock is enabled, the system then immediately calls firstRectForCharacterRange:actualRange: to refresh the character coordinates. This triggers a Wine QUERY_IME_CHAR_RECT query. The problem is that the thread that would answer the query is currently in OnMainThread(), things deadlock and the query times out after 300 ms. I think it's called twice, that's how you get 600 ms.
The twist is that OnMainThread() does service queries while waiting, except for QUERY_IME_CHAR_RECT, because of a 2016 bug with Japanese input in Excel 2003/2007/2010. If you undo 33610da6b4f5d9ad052173f005fdb735dc471445 so that QUERY_IME_CHAR_RECT is handled normally, the timeout goes away and things work normally.
This needs to be fixed, my first thought is that maybe there have been changes in the IME system since 2016 so that the special-case for QUERY_IME_CHAR_RECT is no longer needed? A first step is to revert the 2016 fix and see if the Excel bug can still be reproduced.
[1]: https://developer.apple.com/documentation/appkit/text_display/adopting_the_s...