@@ -707,10 +707,7 @@ static void Cocoa_UpdateClipCursor(SDL_Window *window)
707707static void Cocoa_SetKeyboardFocus (SDL_Window *window, bool set_active_focus)
708708{
709709 SDL_Window *toplevel = GetParentToplevelWindow (window);
710- SDL_CocoaWindowData *toplevel_data;
711-
712- toplevel_data = (__bridge SDL_CocoaWindowData *)toplevel->internal ;
713- toplevel_data.keyboard_focus = window;
710+ toplevel->keyboard_focus = window;
714711
715712 if (set_active_focus && !window->is_hiding && !window->is_destroying ) {
716713 SDL_SetKeyboardFocus (window);
@@ -1252,7 +1249,7 @@ - (void)windowDidBecomeKey:(NSNotification *)aNotification
12521249
12531250 // We're going to get keyboard events, since we're key.
12541251 // This needs to be done before restoring the relative mouse mode.
1255- Cocoa_SetKeyboardFocus (_data. keyboard_focus ? _data. keyboard_focus : window, true );
1252+ Cocoa_SetKeyboardFocus (window-> keyboard_focus ? window-> keyboard_focus : window, true );
12561253
12571254 // If we just gained focus we need the updated mouse position
12581255 if (!(window->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE)) {
@@ -2211,8 +2208,8 @@ then immediately ordering out (removing) the window does work. */
22112208 if (window->flags & SDL_WINDOW_TOOLTIP) {
22122209 [nswindow setIgnoresMouseEvents: YES ];
22132210 [nswindow setAcceptsMouseMovedEvents: NO ];
2214- } else if (window->flags & SDL_WINDOW_POPUP_MENU) {
2215- Cocoa_SetKeyboardFocus (window, window-> parent == SDL_GetKeyboardFocus () );
2211+ } else if (( window->flags & SDL_WINDOW_POPUP_MENU) && !(window-> flags & SDL_WINDOW_NOT_FOCUSABLE) ) {
2212+ Cocoa_SetKeyboardFocus (window, true );
22162213 }
22172214 }
22182215
@@ -2301,7 +2298,7 @@ bool Cocoa_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properti
23012298 rect.origin .y -= screenRect.origin .y ;
23022299
23032300 // Constrain the popup
2304- if (SDL_WINDOW_IS_POPUP (window)) {
2301+ if (SDL_WINDOW_IS_POPUP (window) && window-> constrain_popup ) {
23052302 if (rect.origin .x + rect.size .width > screenRect.origin .x + screenRect.size .width ) {
23062303 rect.origin .x -= (rect.origin .x + rect.size .width ) - (screenRect.origin .x + screenRect.size .width );
23072304 }
@@ -2457,7 +2454,7 @@ bool Cocoa_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
24572454 ConvertNSRect (&rect);
24582455
24592456 // Position and constrain the popup
2460- if (SDL_WINDOW_IS_POPUP (window)) {
2457+ if (SDL_WINDOW_IS_POPUP (window) && window-> constrain_popup ) {
24612458 NSRect screenRect = [ScreenForRect (&rect) frame ];
24622459
24632460 if (rect.origin .x + rect.size .width > screenRect.origin .x + screenRect.size .width ) {
@@ -2629,20 +2626,9 @@ void Cocoa_HideWindow(SDL_VideoDevice *_this, SDL_Window *window)
26292626 Cocoa_SetWindowModal (_this, window, false );
26302627
26312628 // Transfer keyboard focus back to the parent when closing a popup menu
2632- if (window->flags & SDL_WINDOW_POPUP_MENU) {
2633- SDL_Window *new_focus = window->parent ;
2634- bool set_focus = window == SDL_GetKeyboardFocus ();
2635-
2636- // Find the highest level window, up to the toplevel parent, that isn't being hidden or destroyed.
2637- while (SDL_WINDOW_IS_POPUP (new_focus) && (new_focus->is_hiding || new_focus->is_destroying )) {
2638- new_focus = new_focus->parent ;
2639-
2640- // If some window in the chain currently had focus, set it to the new lowest-level window.
2641- if (!set_focus) {
2642- set_focus = new_focus == SDL_GetKeyboardFocus ();
2643- }
2644- }
2645-
2629+ if ((window->flags & SDL_WINDOW_POPUP_MENU) && !(window->flags & SDL_WINDOW_NOT_FOCUSABLE)) {
2630+ SDL_Window *new_focus;
2631+ const bool set_focus = SDL_ShouldRelinquishPopupFocus (window, &new_focus);
26462632 Cocoa_SetKeyboardFocus (new_focus, set_focus);
26472633 } else if (window->parent && waskey) {
26482634 /* Key status is not automatically set on the parent when a child is hidden. Check if the
@@ -3068,20 +3054,19 @@ void Cocoa_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
30683054
30693055#endif // SDL_VIDEO_OPENGL
30703056 SDL_Window *topmost = GetParentToplevelWindow (window);
3071- SDL_CocoaWindowData *topmost_data = (__bridge SDL_CocoaWindowData *)topmost->internal ;
30723057
30733058 /* Reset the input focus of the root window if this window is still set as keyboard focus.
30743059 * SDL_DestroyWindow will have already taken care of reassigning focus if this is the SDL
30753060 * keyboard focus, this ensures that an inactive window with this window set as input focus
30763061 * does not try to reference it the next time it gains focus.
30773062 */
3078- if (topmost_data. keyboard_focus == window) {
3063+ if (topmost-> keyboard_focus == window) {
30793064 SDL_Window *new_focus = window;
30803065 while (SDL_WINDOW_IS_POPUP (new_focus) && (new_focus->is_hiding || new_focus->is_destroying )) {
30813066 new_focus = new_focus->parent ;
30823067 }
30833068
3084- topmost_data. keyboard_focus = new_focus;
3069+ topmost-> keyboard_focus = new_focus;
30853070 }
30863071
30873072 if ([data.listener isInFullscreenSpace ]) {
@@ -3246,6 +3231,20 @@ bool Cocoa_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOper
32463231
32473232bool Cocoa_SetWindowFocusable (SDL_VideoDevice *_this, SDL_Window *window, bool focusable)
32483233{
3234+ if (window->flags & SDL_WINDOW_POPUP_MENU) {
3235+ if (!(window->flags & SDL_WINDOW_HIDDEN)) {
3236+ if (!focusable && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
3237+ SDL_Window *new_focus;
3238+ const bool set_focus = SDL_ShouldRelinquishPopupFocus (window, &new_focus);
3239+ Cocoa_SetKeyboardFocus (new_focus, set_focus);
3240+ } else if (focusable) {
3241+ if (SDL_ShouldFocusPopup (window)) {
3242+ Cocoa_SetKeyboardFocus (window, true );
3243+ }
3244+ }
3245+ }
3246+ }
3247+
32493248 return true ; // just succeed, the real work is done elsewhere.
32503249}
32513250
0 commit comments