Skip to content

Commit b871ac0

Browse files
committed
Add support for non-constrained and non-grabbing popups
By default, popups are automatically constrained to be completely within display bounds, so as not to cut off information and result in an unusable menu, or unreadable tooltip. In some cases, however, this is not wanted, so a property to toggle this behavior is added. There are also cases where the client may not want a popup menu to implicitly grab the keyboard focus, as is the default behavior, so popup menus now respect the focusable flag/property, as well as being able to toggle focus grabbing via SDL_SetWindowFocusable().
1 parent 8abcc27 commit b871ac0

15 files changed

+281
-156
lines changed

include/SDL3/SDL_video.h

+13
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,15 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, int
11881188
* Popup windows implicitly do not have a border/decorations and do not appear
11891189
* on the taskbar/dock or in lists of windows such as alt-tab menus.
11901190
*
1191+
* By default, popup window positions will automatically be constrained to keep
1192+
* the entire window within display bounds. This can be overridden with the
1193+
* `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN` property.
1194+
*
1195+
* By default, popup menus will automatically grab keyboard focus from the parent
1196+
* when shown. This behavior can be overridden by setting the `SDL_WINDOW_NOT_FOCUSABLE`
1197+
* flag, setting the `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN` property to false, or
1198+
* toggling it after creation via the `SDL_SetWindowFocusable()` function.
1199+
*
11911200
* If a parent window is hidden or destroyed, any child popup windows will be
11921201
* recursively hidden or destroyed as well. Child popup windows not explicitly
11931202
* hidden will be restored when the parent is shown.
@@ -1228,6 +1237,9 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren
12281237
* be always on top
12291238
* - `SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN`: true if the window has no
12301239
* window decoration
1240+
* - `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN`: true if the "tooltip" and
1241+
* "menu" window types should be automatically constrained to be entirely within
1242+
* display bounds (default), false if no constraints on the position are desired.
12311243
* - `SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN`: true if the
12321244
* window will be used with an externally managed graphics context.
12331245
* - `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN`: true if the window should
@@ -1356,6 +1368,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop
13561368

13571369
#define SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN "SDL.window.create.always_on_top"
13581370
#define SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN "SDL.window.create.borderless"
1371+
#define SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN "SDL.window.create.constrain_popup"
13591372
#define SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN "SDL.window.create.focusable"
13601373
#define SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN "SDL.window.create.external_graphics_context"
13611374
#define SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER "SDL.window.create.flags"

src/video/SDL_sysvideo.h

+6
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ struct SDL_Window
104104
bool last_position_pending; // This should NOT be cleared by the backend, as it is used for fullscreen positioning.
105105
bool last_size_pending; // This should be cleared by the backend if the new size cannot be applied.
106106
bool update_fullscreen_on_display_changed;
107+
bool constrain_popup;
107108
bool is_destroying;
108109
bool is_dropping; // drag/drop in progress, expecting SDL_SendDropComplete().
109110

@@ -133,6 +134,9 @@ struct SDL_Window
133134

134135
SDL_WindowData *internal;
135136

137+
// If a toplevel window, holds the current keyboard focus for grabbing popups.
138+
SDL_Window *keyboard_focus;
139+
136140
SDL_Window *prev;
137141
SDL_Window *next;
138142

@@ -571,6 +575,8 @@ extern bool SDL_RecreateWindow(SDL_Window *window, SDL_WindowFlags flags);
571575
extern bool SDL_HasWindows(void);
572576
extern void SDL_RelativeToGlobalForWindow(SDL_Window *window, int rel_x, int rel_y, int *abs_x, int *abs_y);
573577
extern void SDL_GlobalToRelativeForWindow(SDL_Window *window, int abs_x, int abs_y, int *rel_x, int *rel_y);
578+
extern bool SDL_ShouldFocusPopup(SDL_Window *window);
579+
extern bool SDL_ShouldRelinquishPopupFocus(SDL_Window *window, SDL_Window **new_focus);
574580

575581
extern void SDL_OnDisplayAdded(SDL_VideoDisplay *display);
576582
extern void SDL_OnDisplayMoved(SDL_VideoDisplay *display);

src/video/SDL_video.c

+43
Original file line numberDiff line numberDiff line change
@@ -2491,6 +2491,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
24912491
window->is_destroying = false;
24922492
window->last_displayID = SDL_GetDisplayForWindow(window);
24932493
window->external_graphics_context = external_graphics_context;
2494+
window->constrain_popup = SDL_GetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN, true);
24942495

24952496
if (_this->windows) {
24962497
_this->windows->prev = window;
@@ -3692,6 +3693,48 @@ bool SDL_SetWindowModal(SDL_Window *window, bool modal)
36923693
return _this->SetWindowModal(_this, window, modal);
36933694
}
36943695

3696+
bool SDL_ShouldRelinquishPopupFocus(SDL_Window *window, SDL_Window **new_focus)
3697+
{
3698+
SDL_Window *focus = window->parent;
3699+
bool set_focus = !!(window->flags & SDL_WINDOW_INPUT_FOCUS);
3700+
3701+
// Find the highest level window, up to the toplevel parent, that isn't being hidden or destroyed, and can grab the keyboard focus.
3702+
while (SDL_WINDOW_IS_POPUP(focus) && ((focus->flags & SDL_WINDOW_NOT_FOCUSABLE) || focus->is_hiding || focus->is_destroying)) {
3703+
focus = focus->parent;
3704+
3705+
// If some window in the chain currently had focus, set it to the new lowest-level window.
3706+
if (!set_focus) {
3707+
set_focus = !!(focus->flags & SDL_WINDOW_INPUT_FOCUS);
3708+
}
3709+
}
3710+
3711+
*new_focus = focus;
3712+
return set_focus;
3713+
}
3714+
3715+
bool SDL_ShouldFocusPopup(SDL_Window *window)
3716+
{
3717+
SDL_Window *toplevel_parent;
3718+
for (toplevel_parent = window->parent; SDL_WINDOW_IS_POPUP(toplevel_parent); toplevel_parent = toplevel_parent->parent) {
3719+
}
3720+
3721+
SDL_Window *current_focus = toplevel_parent->keyboard_focus;
3722+
bool found_higher_focus = false;
3723+
3724+
/* Traverse the window tree from the currently focused window to the toplevel parent and see if we encounter
3725+
* the new focus request. If the new window is found, a higher-level window already has focus.
3726+
*/
3727+
SDL_Window *w;
3728+
for (w = current_focus; w != toplevel_parent; w = w->parent) {
3729+
if (w == window) {
3730+
found_higher_focus = true;
3731+
break;
3732+
}
3733+
}
3734+
3735+
return !found_higher_focus || w == toplevel_parent;
3736+
}
3737+
36953738
bool SDL_SetWindowFocusable(SDL_Window *window, bool focusable)
36963739
{
36973740
CHECK_WINDOW_MAGIC(window, false);

src/video/cocoa/SDL_cocoawindow.h

-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ typedef enum
146146
@property(nonatomic) BOOL was_zoomed;
147147
@property(nonatomic) NSInteger window_number;
148148
@property(nonatomic) NSInteger flash_request;
149-
@property(nonatomic) SDL_Window *keyboard_focus;
150149
@property(nonatomic) SDL3Cocoa_WindowListener *listener;
151150
@property(nonatomic) NSModalSession modal_session;
152151
@property(nonatomic) SDL_CocoaVideoData *videodata;

src/video/cocoa/SDL_cocoawindow.m

+29-26
Original file line numberDiff line numberDiff line change
@@ -707,10 +707,7 @@ static void Cocoa_UpdateClipCursor(SDL_Window *window)
707707
static 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)) {
@@ -2244,7 +2241,9 @@ then immediately ordering out (removing) the window does work. */
22442241
[nswindow setIgnoresMouseEvents:YES];
22452242
[nswindow setAcceptsMouseMovedEvents:NO];
22462243
} else if ((window->flags & SDL_WINDOW_POPUP_MENU) && !(window->flags & SDL_WINDOW_HIDDEN)) {
2247-
Cocoa_SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus());
2244+
if (!(window->flags & SDL_WINDOW_NOT_FOCUSABLE)) {
2245+
Cocoa_SetKeyboardFocus(window, true);
2246+
}
22482247
Cocoa_UpdateMouseFocus();
22492248
}
22502249
}
@@ -2334,7 +2333,7 @@ bool Cocoa_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properti
23342333
rect.origin.y -= screenRect.origin.y;
23352334

23362335
// Constrain the popup
2337-
if (SDL_WINDOW_IS_POPUP(window)) {
2336+
if (SDL_WINDOW_IS_POPUP(window) && window->constrain_popup) {
23382337
if (rect.origin.x + rect.size.width > screenRect.origin.x + screenRect.size.width) {
23392338
rect.origin.x -= (rect.origin.x + rect.size.width) - (screenRect.origin.x + screenRect.size.width);
23402339
}
@@ -2490,7 +2489,7 @@ bool Cocoa_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
24902489
ConvertNSRect(&rect);
24912490

24922491
// Position and constrain the popup
2493-
if (SDL_WINDOW_IS_POPUP(window)) {
2492+
if (SDL_WINDOW_IS_POPUP(window) && window->constrain_popup) {
24942493
NSRect screenRect = [ScreenForRect(&rect) frame];
24952494

24962495
if (rect.origin.x + rect.size.width > screenRect.origin.x + screenRect.size.width) {
@@ -2631,7 +2630,9 @@ void Cocoa_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
26312630
}
26322631
}
26332632
} else if (window->flags & SDL_WINDOW_POPUP_MENU) {
2634-
Cocoa_SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus());
2633+
if (!(window->flags & SDL_WINDOW_NOT_FOCUSABLE)) {
2634+
Cocoa_SetKeyboardFocus(window, true);
2635+
}
26352636
Cocoa_UpdateMouseFocus();
26362637
}
26372638
}
@@ -2665,20 +2666,9 @@ void Cocoa_HideWindow(SDL_VideoDevice *_this, SDL_Window *window)
26652666
Cocoa_SetWindowModal(_this, window, false);
26662667

26672668
// Transfer keyboard focus back to the parent when closing a popup menu
2668-
if (window->flags & SDL_WINDOW_POPUP_MENU) {
2669-
SDL_Window *new_focus = window->parent;
2670-
bool set_focus = window == SDL_GetKeyboardFocus();
2671-
2672-
// Find the highest level window, up to the toplevel parent, that isn't being hidden or destroyed.
2673-
while (SDL_WINDOW_IS_POPUP(new_focus) && (new_focus->is_hiding || new_focus->is_destroying)) {
2674-
new_focus = new_focus->parent;
2675-
2676-
// If some window in the chain currently had focus, set it to the new lowest-level window.
2677-
if (!set_focus) {
2678-
set_focus = new_focus == SDL_GetKeyboardFocus();
2679-
}
2680-
}
2681-
2669+
if ((window->flags & SDL_WINDOW_POPUP_MENU) && !(window->flags & SDL_WINDOW_NOT_FOCUSABLE)) {
2670+
SDL_Window *new_focus;
2671+
const bool set_focus = SDL_ShouldRelinquishPopupFocus(window, &new_focus);
26822672
Cocoa_SetKeyboardFocus(new_focus, set_focus);
26832673
Cocoa_UpdateMouseFocus();
26842674
} else if (window->parent && waskey) {
@@ -3105,20 +3095,19 @@ void Cocoa_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
31053095

31063096
#endif // SDL_VIDEO_OPENGL
31073097
SDL_Window *topmost = GetParentToplevelWindow(window);
3108-
SDL_CocoaWindowData *topmost_data = (__bridge SDL_CocoaWindowData *)topmost->internal;
31093098

31103099
/* Reset the input focus of the root window if this window is still set as keyboard focus.
31113100
* SDL_DestroyWindow will have already taken care of reassigning focus if this is the SDL
31123101
* keyboard focus, this ensures that an inactive window with this window set as input focus
31133102
* does not try to reference it the next time it gains focus.
31143103
*/
3115-
if (topmost_data.keyboard_focus == window) {
3104+
if (topmost->keyboard_focus == window) {
31163105
SDL_Window *new_focus = window;
31173106
while (SDL_WINDOW_IS_POPUP(new_focus) && (new_focus->is_hiding || new_focus->is_destroying)) {
31183107
new_focus = new_focus->parent;
31193108
}
31203109

3121-
topmost_data.keyboard_focus = new_focus;
3110+
topmost->keyboard_focus = new_focus;
31223111
}
31233112

31243113
if ([data.listener isInFullscreenSpace]) {
@@ -3283,6 +3272,20 @@ bool Cocoa_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOper
32833272

32843273
bool Cocoa_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, bool focusable)
32853274
{
3275+
if (window->flags & SDL_WINDOW_POPUP_MENU) {
3276+
if (!(window->flags & SDL_WINDOW_HIDDEN)) {
3277+
if (!focusable && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
3278+
SDL_Window *new_focus;
3279+
const bool set_focus = SDL_ShouldRelinquishPopupFocus(window, &new_focus);
3280+
Cocoa_SetKeyboardFocus(new_focus, set_focus);
3281+
} else if (focusable) {
3282+
if (SDL_ShouldFocusPopup(window)) {
3283+
Cocoa_SetKeyboardFocus(window, true);
3284+
}
3285+
}
3286+
}
3287+
}
3288+
32863289
return true; // just succeed, the real work is done elsewhere.
32873290
}
32883291

src/video/wayland/SDL_waylandevents.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1824,7 +1824,7 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
18241824
seat->keyboard.focus = window;
18251825

18261826
// Restore the keyboard focus to the child popup that was holding it
1827-
SDL_SetKeyboardFocus(window->keyboard_focus ? window->keyboard_focus : window->sdlwindow);
1827+
SDL_SetKeyboardFocus(window->sdlwindow->keyboard_focus ? window->sdlwindow->keyboard_focus : window->sdlwindow);
18281828

18291829
// Update the keyboard grab and any relative pointer grabs related to this keyboard focus.
18301830
Wayland_SeatUpdateKeyboardGrab(seat);

src/video/wayland/SDL_waylandvideo.c

+1
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols)
632632
device->HasScreenKeyboardSupport = Wayland_HasScreenKeyboardSupport;
633633
device->ShowWindowSystemMenu = Wayland_ShowWindowSystemMenu;
634634
device->SyncWindow = Wayland_SyncWindow;
635+
device->SetWindowFocusable = Wayland_SetWindowFocusable;
635636

636637
#ifdef SDL_USE_LIBDBUS
637638
if (SDL_SystemTheme_Init())

src/video/wayland/SDL_waylandwindow.c

+32-21
Original file line numberDiff line numberDiff line change
@@ -1677,7 +1677,7 @@ static const struct wp_color_management_surface_feedback_v1_listener color_manag
16771677
feedback_surface_preferred_changed
16781678
};
16791679

1680-
static void SetKeyboardFocus(SDL_Window *window, bool set_focus)
1680+
static void Wayland_SetKeyboardFocus(SDL_Window *window, bool set_focus)
16811681
{
16821682
SDL_Window *toplevel = window;
16831683

@@ -1686,7 +1686,7 @@ static void SetKeyboardFocus(SDL_Window *window, bool set_focus)
16861686
toplevel = toplevel->parent;
16871687
}
16881688

1689-
toplevel->internal->keyboard_focus = window;
1689+
toplevel->keyboard_focus = window;
16901690

16911691
if (set_focus && !window->is_hiding && !window->is_destroying) {
16921692
SDL_SetKeyboardFocus(window);
@@ -1916,8 +1916,9 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
19161916
data->shell_surface.xdg.popup.xdg_positioner = xdg_wm_base_create_positioner(c->shell.xdg);
19171917
xdg_positioner_set_anchor(data->shell_surface.xdg.popup.xdg_positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT);
19181918
xdg_positioner_set_anchor_rect(data->shell_surface.xdg.popup.xdg_positioner, 0, 0, parent->internal->current.logical_width, parent->internal->current.logical_width);
1919-
xdg_positioner_set_constraint_adjustment(data->shell_surface.xdg.popup.xdg_positioner,
1920-
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y);
1919+
1920+
const Uint32 constraint = window->constrain_popup ? (XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y) : XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE;
1921+
xdg_positioner_set_constraint_adjustment(data->shell_surface.xdg.popup.xdg_positioner, constraint);
19211922
xdg_positioner_set_gravity(data->shell_surface.xdg.popup.xdg_positioner, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT);
19221923
xdg_positioner_set_size(data->shell_surface.xdg.popup.xdg_positioner, data->current.logical_width, data->current.logical_height);
19231924

@@ -1946,8 +1947,8 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
19461947
wl_region_add(region, 0, 0, 0, 0);
19471948
wl_surface_set_input_region(data->surface, region);
19481949
wl_region_destroy(region);
1949-
} else if (window->flags & SDL_WINDOW_POPUP_MENU) {
1950-
SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus());
1950+
} else if ((window->flags & SDL_WINDOW_POPUP_MENU) && !(window->flags & SDL_WINDOW_NOT_FOCUSABLE)) {
1951+
Wayland_SetKeyboardFocus(window, true);
19511952
}
19521953

19531954
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_POPUP_POINTER, data->shell_surface.xdg.popup.xdg_popup);
@@ -2094,21 +2095,10 @@ static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup)
20942095
return;
20952096
}
20962097

2097-
if (popup->flags & SDL_WINDOW_POPUP_MENU) {
2098-
SDL_Window *new_focus = popup->parent;
2099-
bool set_focus = popup == SDL_GetKeyboardFocus();
2100-
2101-
// Find the highest level window, up to the toplevel parent, that isn't being hidden or destroyed.
2102-
while (SDL_WINDOW_IS_POPUP(new_focus) && (new_focus->is_hiding || new_focus->is_destroying)) {
2103-
new_focus = new_focus->parent;
2104-
2105-
// If some window in the chain currently had focus, set it to the new lowest-level window.
2106-
if (!set_focus) {
2107-
set_focus = new_focus == SDL_GetKeyboardFocus();
2108-
}
2109-
}
2110-
2111-
SetKeyboardFocus(new_focus, set_focus);
2098+
if ((popup->flags & SDL_WINDOW_POPUP_MENU) && !(popup->flags & SDL_WINDOW_NOT_FOCUSABLE)) {
2099+
SDL_Window *new_focus;
2100+
const bool set_focus = SDL_ShouldRelinquishPopupFocus(popup, &new_focus);
2101+
Wayland_SetKeyboardFocus(new_focus, set_focus);
21122102
}
21132103

21142104
xdg_popup_destroy(popupdata->shell_surface.xdg.popup.xdg_popup);
@@ -3002,6 +2992,27 @@ bool Wayland_SyncWindow(SDL_VideoDevice *_this, SDL_Window *window)
30022992
return true;
30032993
}
30042994

2995+
bool Wayland_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, bool focusable)
2996+
{
2997+
if (window->flags & SDL_WINDOW_POPUP_MENU) {
2998+
if (!(window->flags & SDL_WINDOW_HIDDEN)) {
2999+
if (!focusable && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
3000+
SDL_Window *new_focus;
3001+
const bool set_focus = SDL_ShouldRelinquishPopupFocus(window, &new_focus);
3002+
Wayland_SetKeyboardFocus(new_focus, set_focus);
3003+
} else if (focusable) {
3004+
if (SDL_ShouldFocusPopup(window)) {
3005+
Wayland_SetKeyboardFocus(window, true);
3006+
}
3007+
}
3008+
}
3009+
3010+
return true;
3011+
}
3012+
3013+
return SDL_SetError("wayland: focus can only be toggled on popup menu windows");
3014+
}
3015+
30053016
void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y)
30063017
{
30073018
SDL_WindowData *wind = window->internal;

src/video/wayland/SDL_waylandwindow.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ struct SDL_WindowData
126126
SDL_DisplayData **outputs;
127127
int num_outputs;
128128

129-
SDL_Window *keyboard_focus;
130-
131129
char *app_id;
132130
double scale_factor;
133131

@@ -249,6 +247,7 @@ extern void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
249247
extern void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
250248
extern bool Wayland_SuspendScreenSaver(SDL_VideoDevice *_this);
251249
extern bool Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *icon);
250+
extern bool Wayland_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, bool focusable);
252251
extern float Wayland_GetWindowContentScale(SDL_VideoDevice *_this, SDL_Window *window);
253252
extern void *Wayland_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
254253

src/video/windows/SDL_windowsevents.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ static void WIN_UpdateFocus(SDL_Window *window, bool expect_focus, DWORD pos)
354354
}
355355
}
356356

357-
SDL_SetKeyboardFocus(data->keyboard_focus ? data->keyboard_focus : window);
357+
SDL_SetKeyboardFocus(window->keyboard_focus ? window->keyboard_focus : window);
358358

359359
// In relative mode we are guaranteed to have mouse focus if we have keyboard focus
360360
if (!SDL_GetMouse()->relative_mode) {

0 commit comments

Comments
 (0)