Cocoa metal layers need their size updated before renderer updates

Also refactored event watch code so it can be shared between internal window event dispatch and public event watchers.

Fixes https://github.com/libsdl-org/SDL/issues/12376
This commit is contained in:
Sam Lantinga 2025-02-24 15:01:53 -08:00
parent 0a592b78c1
commit db4e6c1931
13 changed files with 301 additions and 137 deletions

View file

@ -442,6 +442,7 @@
<ClInclude Include="..\..\src\events\SDL_displayevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_events_c.h" />
<ClInclude Include="..\..\src\events\SDL_eventwatch_c.h" />
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
<ClInclude Include="..\..\src\events\SDL_keymap_c.h" />
<ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
@ -676,6 +677,7 @@
<ClCompile Include="..\..\src\events\SDL_displayevents.c" />
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
<ClCompile Include="..\..\src\events\SDL_events.c" />
<ClCompile Include="..\..\src\events\SDL_eventwatch.c" />
<ClCompile Include="..\..\src\events\SDL_keyboard.c" />
<ClCompile Include="..\..\src\events\SDL_keymap.c" />
<ClCompile Include="..\..\src\events\SDL_mouse.c" />

View file

@ -39,6 +39,7 @@
<ClCompile Include="..\..\src\events\SDL_displayevents.c" />
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
<ClCompile Include="..\..\src\events\SDL_events.c" />
<ClCompile Include="..\..\src\events\SDL_eventwatch.c" />
<ClCompile Include="..\..\src\events\SDL_keyboard.c" />
<ClCompile Include="..\..\src\events\SDL_keymap.c" />
<ClCompile Include="..\..\src\events\SDL_mouse.c" />
@ -333,6 +334,7 @@
<ClInclude Include="..\..\src\events\SDL_displayevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_events_c.h" />
<ClInclude Include="..\..\src\events\SDL_eventwatch_c.h" />
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
<ClInclude Include="..\..\src\events\SDL_keymap_c.h" />
<ClInclude Include="..\..\src\events\SDL_mouse_c.h" />

View file

@ -354,6 +354,7 @@
<ClInclude Include="..\..\src\events\SDL_displayevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_events_c.h" />
<ClInclude Include="..\..\src\events\SDL_eventwatch_c.h" />
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
<ClInclude Include="..\..\src\events\SDL_keymap_c.h" />
<ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
@ -558,6 +559,7 @@
<ClCompile Include="..\..\src\events\SDL_displayevents.c" />
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
<ClCompile Include="..\..\src\events\SDL_events.c" />
<ClCompile Include="..\..\src\events\SDL_eventwatch.c" />
<ClCompile Include="..\..\src\events\SDL_keyboard.c" />
<ClCompile Include="..\..\src\events\SDL_keymap.c" />
<ClCompile Include="..\..\src\events\SDL_mouse.c" />

View file

@ -534,6 +534,9 @@
<ClInclude Include="..\..\src\events\SDL_events_c.h">
<Filter>events</Filter>
</ClInclude>
<ClInclude Include="..\..\src\events\SDL_eventfilter_c.h">
<Filter>events</Filter>
</ClInclude>
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h">
<Filter>events</Filter>
</ClInclude>
@ -1076,6 +1079,9 @@
<ClCompile Include="..\..\src\events\SDL_events.c">
<Filter>events</Filter>
</ClCompile>
<ClCompile Include="..\..\src\events\SDL_eventfilter.c">
<Filter>events</Filter>
</ClCompile>
<ClCompile Include="..\..\src\events\SDL_keyboard.c">
<Filter>events</Filter>
</ClCompile>

View file

@ -512,6 +512,8 @@
F3D46B122D20625800D9CBDF /* SDL_egl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D46A8E2D20625800D9CBDF /* SDL_egl.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3D46B132D20625800D9CBDF /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D46A922D20625800D9CBDF /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3D60A8328C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; };
F3D8BDFC2D6D2C7000B22FA1 /* SDL_eventwatch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D8BDFB2D6D2C7000B22FA1 /* SDL_eventwatch_c.h */; };
F3D8BDFD2D6D2C7000B22FA1 /* SDL_eventwatch.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D8BDFA2D6D2C7000B22FA1 /* SDL_eventwatch.c */; };
F3DDCC562AFD42B600B0842B /* SDL_clipboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */; };
F3DDCC5B2AFD42B600B0842B /* SDL_video_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC522AFD42B600B0842B /* SDL_video_c.h */; };
F3DDCC5D2AFD42B600B0842B /* SDL_rect_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */; };
@ -1079,6 +1081,8 @@
F3D46AC82D20625800D9CBDF /* SDL_video.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_video.h; sourceTree = "<group>"; };
F3D46AC92D20625800D9CBDF /* SDL_vulkan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = "<group>"; };
F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_wii.c; sourceTree = "<group>"; };
F3D8BDFA2D6D2C7000B22FA1 /* SDL_eventwatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_eventwatch.c; sourceTree = "<group>"; };
F3D8BDFB2D6D2C7000B22FA1 /* SDL_eventwatch_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_eventwatch_c.h; sourceTree = "<group>"; };
F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_clipboard_c.h; sourceTree = "<group>"; };
F3DDCC522AFD42B600B0842B /* SDL_video_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_video_c.h; sourceTree = "<group>"; };
F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_rect_impl.h; sourceTree = "<group>"; };
@ -2209,29 +2213,31 @@
A7D8A93623E2514000DCD162 /* scancodes_linux.h */,
A7D8A92C23E2514000DCD162 /* scancodes_windows.h */,
A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */,
F3C2CB202C5DDDB2004D7998 /* SDL_categories_c.h */,
F3C2CB212C5DDDB2004D7998 /* SDL_categories.c */,
A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */,
F3C2CB202C5DDDB2004D7998 /* SDL_categories_c.h */,
A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */,
A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */,
A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */,
A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */,
A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */,
A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */,
A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */,
A7D8A94223E2514000DCD162 /* SDL_events_c.h */,
A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */,
A7D8A93523E2514000DCD162 /* SDL_events.c */,
A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */,
A7D8A94223E2514000DCD162 /* SDL_events_c.h */,
F3D8BDFA2D6D2C7000B22FA1 /* SDL_eventwatch.c */,
F3D8BDFB2D6D2C7000B22FA1 /* SDL_eventwatch_c.h */,
A7D8A93823E2514000DCD162 /* SDL_keyboard.c */,
F31013C62C24E98200FBE946 /* SDL_keymap_c.h */,
A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */,
F31013C52C24E98200FBE946 /* SDL_keymap.c */,
A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */,
F31013C62C24E98200FBE946 /* SDL_keymap_c.h */,
A7D8A92A23E2514000DCD162 /* SDL_mouse.c */,
63134A232A7902FD0021E9A6 /* SDL_pen_c.h */,
A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */,
63134A242A7902FD0021E9A6 /* SDL_pen.c */,
63134A232A7902FD0021E9A6 /* SDL_pen_c.h */,
A7D8A93C23E2514000DCD162 /* SDL_quit.c */,
A7D8A93723E2514000DCD162 /* SDL_touch_c.h */,
A7D8A93E23E2514000DCD162 /* SDL_touch.c */,
A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */,
A7D8A93723E2514000DCD162 /* SDL_touch_c.h */,
A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */,
A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */,
);
path = events;
sourceTree = "<group>";
@ -2707,6 +2713,7 @@
A7D8B3D423E2514300DCD162 /* yuv_rgb.h in Headers */,
F3FA5A252B59ACE000FEAD97 /* yuv_rgb_common.h in Headers */,
F3FA5A1D2B59ACE000FEAD97 /* yuv_rgb_internal.h in Headers */,
F3D8BDFC2D6D2C7000B22FA1 /* SDL_eventwatch_c.h in Headers */,
F3FA5A242B59ACE000FEAD97 /* yuv_rgb_lsx.h in Headers */,
F3FA5A1E2B59ACE000FEAD97 /* yuv_rgb_lsx_func.h in Headers */,
F3FA5A1F2B59ACE000FEAD97 /* yuv_rgb_sse.h in Headers */,
@ -2965,6 +2972,7 @@
566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */,
A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */,
A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */,
F3D8BDFD2D6D2C7000B22FA1 /* SDL_eventwatch.c in Sources */,
F3EFA5F02D5AB97300BCF22F /* SDL_stb.c in Sources */,
A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */,
A7D8B3DA23E2514300DCD162 /* SDL_bmp.c in Sources */,

View file

@ -23,6 +23,8 @@
// General event handling code for SDL
#include "SDL_events_c.h"
#include "SDL_eventwatch_c.h"
#include "SDL_windowevents_c.h"
#include "../SDL_hints_c.h"
#include "../audio/SDL_audio_c.h"
#include "../camera/SDL_camera_c.h"
@ -98,19 +100,7 @@ typedef struct SDL2_SysWMmsg
} msg;
} SDL2_SysWMmsg;
typedef struct SDL_EventWatcher
{
SDL_EventFilter callback;
void *userdata;
bool removed;
} SDL_EventWatcher;
static SDL_Mutex *SDL_event_watchers_lock;
static SDL_EventWatcher SDL_EventOK;
static SDL_EventWatcher *SDL_event_watchers = NULL;
static int SDL_event_watchers_count = 0;
static bool SDL_event_watchers_dispatching = false;
static bool SDL_event_watchers_removed = false;
static SDL_EventWatchList SDL_event_watchers;
static SDL_AtomicInt SDL_sentinel_pending;
static Uint32 SDL_last_event_id = 0;
@ -938,16 +928,8 @@ void SDL_StopEventLoop(void)
SDL_disabled_events[i] = NULL;
}
if (SDL_event_watchers_lock) {
SDL_DestroyMutex(SDL_event_watchers_lock);
SDL_event_watchers_lock = NULL;
}
if (SDL_event_watchers) {
SDL_free(SDL_event_watchers);
SDL_event_watchers = NULL;
SDL_event_watchers_count = 0;
}
SDL_zero(SDL_EventOK);
SDL_QuitEventWatchList(&SDL_event_watchers);
SDL_QuitWindowEventWatch();
SDL_Mutex *lock = NULL;
if (SDL_EventQ.lock) {
@ -981,17 +963,19 @@ bool SDL_StartEventLoop(void)
}
SDL_LockMutex(SDL_EventQ.lock);
if (SDL_event_watchers_lock == NULL) {
SDL_event_watchers_lock = SDL_CreateMutex();
if (SDL_event_watchers_lock == NULL) {
SDL_UnlockMutex(SDL_EventQ.lock);
return false;
}
if (!SDL_InitEventWatchList(&SDL_event_watchers)) {
SDL_UnlockMutex(SDL_EventQ.lock);
return false;
}
#endif // !SDL_THREADS_DISABLED
SDL_InitWindowEventWatch();
SDL_EventQ.active = true;
#ifndef SDL_THREADS_DISABLED
SDL_UnlockMutex(SDL_EventQ.lock);
#endif
return true;
}
@ -1735,44 +1719,11 @@ bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
static bool SDL_CallEventWatchers(SDL_Event *event)
{
if ((SDL_EventOK.callback || SDL_event_watchers_count > 0) &&
(event->common.type != SDL_EVENT_POLL_SENTINEL)) {
SDL_LockMutex(SDL_event_watchers_lock);
{
if (SDL_EventOK.callback && !SDL_EventOK.callback(SDL_EventOK.userdata, event)) {
SDL_UnlockMutex(SDL_event_watchers_lock);
return false;
}
if (SDL_event_watchers_count > 0) {
// Make sure we only dispatch the current watcher list
int i, event_watchers_count = SDL_event_watchers_count;
SDL_event_watchers_dispatching = true;
for (i = 0; i < event_watchers_count; ++i) {
if (!SDL_event_watchers[i].removed) {
SDL_event_watchers[i].callback(SDL_event_watchers[i].userdata, event);
}
}
SDL_event_watchers_dispatching = false;
if (SDL_event_watchers_removed) {
for (i = SDL_event_watchers_count; i--;) {
if (SDL_event_watchers[i].removed) {
--SDL_event_watchers_count;
if (i < SDL_event_watchers_count) {
SDL_memmove(&SDL_event_watchers[i], &SDL_event_watchers[i + 1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i]));
}
}
}
SDL_event_watchers_removed = false;
}
}
}
SDL_UnlockMutex(SDL_event_watchers_lock);
if (event->common.type == SDL_EVENT_POLL_SENTINEL) {
return true;
}
return true;
return SDL_DispatchEventWatchList(&SDL_event_watchers, event);
}
bool SDL_PushEvent(SDL_Event *event)
@ -1796,11 +1747,11 @@ bool SDL_PushEvent(SDL_Event *event)
void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata)
{
SDL_EventEntry *event, *next;
SDL_LockMutex(SDL_event_watchers_lock);
SDL_LockMutex(SDL_event_watchers.lock);
{
// Set filter and discard pending events
SDL_EventOK.callback = filter;
SDL_EventOK.userdata = userdata;
SDL_event_watchers.filter.callback = filter;
SDL_event_watchers.filter.userdata = userdata;
if (filter) {
// Cut all events not accepted by the filter
SDL_LockMutex(SDL_EventQ.lock);
@ -1815,18 +1766,18 @@ void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata)
SDL_UnlockMutex(SDL_EventQ.lock);
}
}
SDL_UnlockMutex(SDL_event_watchers_lock);
SDL_UnlockMutex(SDL_event_watchers.lock);
}
bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata)
{
SDL_EventWatcher event_ok;
SDL_LockMutex(SDL_event_watchers_lock);
SDL_LockMutex(SDL_event_watchers.lock);
{
event_ok = SDL_EventOK;
event_ok = SDL_event_watchers.filter;
}
SDL_UnlockMutex(SDL_event_watchers_lock);
SDL_UnlockMutex(SDL_event_watchers.lock);
if (filter) {
*filter = event_ok.callback;
@ -1839,53 +1790,12 @@ bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata)
bool SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
{
bool result = true;
SDL_LockMutex(SDL_event_watchers_lock);
{
SDL_EventWatcher *event_watchers;
event_watchers = (SDL_EventWatcher *)SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(*event_watchers));
if (event_watchers) {
SDL_EventWatcher *watcher;
SDL_event_watchers = event_watchers;
watcher = &SDL_event_watchers[SDL_event_watchers_count];
watcher->callback = filter;
watcher->userdata = userdata;
watcher->removed = false;
++SDL_event_watchers_count;
} else {
result = false;
}
}
SDL_UnlockMutex(SDL_event_watchers_lock);
return result;
return SDL_AddEventWatchList(&SDL_event_watchers, filter, userdata);
}
void SDL_RemoveEventWatch(SDL_EventFilter filter, void *userdata)
{
SDL_LockMutex(SDL_event_watchers_lock);
{
int i;
for (i = 0; i < SDL_event_watchers_count; ++i) {
if (SDL_event_watchers[i].callback == filter && SDL_event_watchers[i].userdata == userdata) {
if (SDL_event_watchers_dispatching) {
SDL_event_watchers[i].removed = true;
SDL_event_watchers_removed = true;
} else {
--SDL_event_watchers_count;
if (i < SDL_event_watchers_count) {
SDL_memmove(&SDL_event_watchers[i], &SDL_event_watchers[i + 1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i]));
}
}
break;
}
}
}
SDL_UnlockMutex(SDL_event_watchers_lock);
SDL_RemoveEventWatchList(&SDL_event_watchers, filter, userdata);
}
void SDL_FilterEvents(SDL_EventFilter filter, void *userdata)

143
src/events/SDL_eventwatch.c Normal file
View file

@ -0,0 +1,143 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_eventwatch_c.h"
bool SDL_InitEventWatchList(SDL_EventWatchList *list)
{
if (list->lock == NULL) {
list->lock = SDL_CreateMutex();
if (list->lock == NULL) {
return false;
}
}
return true;
}
void SDL_QuitEventWatchList(SDL_EventWatchList *list)
{
if (list->lock) {
SDL_DestroyMutex(list->lock);
list->lock = NULL;
}
if (list->watchers) {
SDL_free(list->watchers);
list->watchers = NULL;
list->count = 0;
}
SDL_zero(list->filter);
}
bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event)
{
SDL_EventWatcher *filter = &list->filter;
if (!filter->callback && list->count == 0) {
return true;
}
SDL_LockMutex(list->lock);
{
// Make sure we only dispatch the current watcher list
int i, count = list->count;
if (filter->callback && !filter->callback(filter->userdata, event)) {
SDL_UnlockMutex(list->lock);
return false;
}
list->dispatching = true;
for (i = 0; i < count; ++i) {
if (!list->watchers[i].removed) {
list->watchers[i].callback(list->watchers[i].userdata, event);
}
}
list->dispatching = false;
if (list->removed) {
for (i = list->count; i--;) {
if (list->watchers[i].removed) {
--list->count;
if (i < list->count) {
SDL_memmove(&list->watchers[i], &list->watchers[i + 1], (list->count - i) * sizeof(list->watchers[i]));
}
}
}
list->removed = false;
}
}
SDL_UnlockMutex(list->lock);
return true;
}
bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata)
{
bool result = true;
SDL_LockMutex(list->lock);
{
SDL_EventWatcher *watchers;
watchers = (SDL_EventWatcher *)SDL_realloc(list->watchers, (list->count + 1) * sizeof(*watchers));
if (watchers) {
SDL_EventWatcher *watcher;
list->watchers = watchers;
watcher = &list->watchers[list->count];
watcher->callback = filter;
watcher->userdata = userdata;
watcher->removed = false;
++list->count;
} else {
result = false;
}
}
SDL_UnlockMutex(list->lock);
return result;
}
void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata)
{
SDL_LockMutex(list->lock);
{
int i;
for (i = 0; i < list->count; ++i) {
if (list->watchers[i].callback == filter && list->watchers[i].userdata == userdata) {
if (list->dispatching) {
list->watchers[i].removed = true;
list->removed = true;
} else {
--list->count;
if (i < list->count) {
SDL_memmove(&list->watchers[i], &list->watchers[i + 1], (list->count - i) * sizeof(list->watchers[i]));
}
}
break;
}
}
}
SDL_UnlockMutex(list->lock);
}

View file

@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
typedef struct SDL_EventWatcher
{
SDL_EventFilter callback;
void *userdata;
bool removed;
} SDL_EventWatcher;
typedef struct SDL_EventWatchList
{
SDL_Mutex *lock;
SDL_EventWatcher filter;
SDL_EventWatcher *watchers;
int count;
bool dispatching;
bool removed;
} SDL_EventWatchList;
extern bool SDL_InitEventWatchList(SDL_EventWatchList *list);
extern void SDL_QuitEventWatchList(SDL_EventWatchList *list);
extern bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event);
extern bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata);
extern void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata);

View file

@ -23,10 +23,39 @@
// Window event handling code for SDL
#include "SDL_events_c.h"
#include "SDL_eventwatch_c.h"
#include "SDL_mouse_c.h"
#include "../render/SDL_sysrender.h"
#include "../tray/SDL_tray_utils.h"
#define NUM_WINDOW_EVENT_WATCH_PRIORITIES (SDL_WINDOW_EVENT_WATCH_NORMAL + 1)
static SDL_EventWatchList SDL_window_event_watchers[NUM_WINDOW_EVENT_WATCH_PRIORITIES];
void SDL_InitWindowEventWatch(void)
{
for (int i = 0; i < SDL_arraysize(SDL_window_event_watchers); ++i) {
SDL_InitEventWatchList(&SDL_window_event_watchers[i]);
}
}
void SDL_QuitWindowEventWatch(void)
{
for (int i = 0; i < SDL_arraysize(SDL_window_event_watchers); ++i) {
SDL_QuitEventWatchList(&SDL_window_event_watchers[i]);
}
}
void SDL_AddWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata)
{
SDL_AddEventWatchList(&SDL_window_event_watchers[priority], filter, userdata);
}
void SDL_RemoveWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata)
{
SDL_RemoveEventWatchList(&SDL_window_event_watchers[priority], filter, userdata);
}
static bool SDLCALL RemoveSupercededWindowEvents(void *userdata, SDL_Event *event)
{
SDL_Event *new_event = (SDL_Event *)userdata;
@ -191,10 +220,8 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
event.window.data2 = data2;
event.window.windowID = window->id;
for (int i = 0; i < window->num_renderers; ++i) {
SDL_Renderer *renderer = window->renderers[i];
SDL_RendererEventWatch(renderer, &event);
}
SDL_DispatchEventWatchList(&SDL_window_event_watchers[SDL_WINDOW_EVENT_WATCH_EARLY], &event);
SDL_DispatchEventWatchList(&SDL_window_event_watchers[SDL_WINDOW_EVENT_WATCH_NORMAL], &event);
if (SDL_EventEnabled(windowevent)) {
// Fixes queue overflow with move/resize events that aren't processed

View file

@ -23,6 +23,17 @@
#ifndef SDL_windowevents_c_h_
#define SDL_windowevents_c_h_
typedef enum
{
SDL_WINDOW_EVENT_WATCH_EARLY,
SDL_WINDOW_EVENT_WATCH_NORMAL
} SDL_WindowEventWatchPriority;
extern void SDL_InitWindowEventWatch(void);
extern void SDL_QuitWindowEventWatch(void);
extern void SDL_AddWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata);
extern void SDL_RemoveWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata);
extern bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data1, int data2);
#endif // SDL_windowevents_c_h_

View file

@ -25,6 +25,7 @@
#include "SDL_sysrender.h"
#include "SDL_render_debug_font.h"
#include "software/SDL_render_sw_c.h"
#include "../events/SDL_windowevents_c.h"
#include "../video/SDL_pixels_c.h"
#include "../video/SDL_video_c.h"
@ -820,8 +821,9 @@ const char *SDL_GetRenderDriver(int index)
#endif
}
void SDL_RendererEventWatch(SDL_Renderer *renderer, SDL_Event *event)
static bool SDL_RendererEventWatch(void *userdata, SDL_Event *event)
{
SDL_Renderer *renderer = (SDL_Renderer *)userdata;
SDL_Window *window = renderer->window;
if (renderer->WindowEvent) {
@ -849,6 +851,7 @@ void SDL_RendererEventWatch(SDL_Renderer *renderer, SDL_Event *event)
event->type == SDL_EVENT_WINDOW_HDR_STATE_CHANGED) {
UpdateHDRProperties(renderer);
}
return true;
}
bool SDL_CreateWindowAndRenderer(const char *title, int width, int height, SDL_WindowFlags window_flags, SDL_Window **window, SDL_Renderer **renderer)
@ -1107,6 +1110,10 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
SDL_SetRenderViewport(renderer, NULL);
if (window) {
SDL_AddWindowEventWatch(SDL_WINDOW_EVENT_WATCH_NORMAL, SDL_RendererEventWatch, renderer);
}
int vsync = (int)SDL_GetNumberProperty(props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 0);
if (!SDL_SetRenderVSync(renderer, vsync)) {
if (vsync == 0) {
@ -5224,6 +5231,8 @@ void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer)
renderer->destroyed = true;
SDL_RemoveWindowEventWatch(SDL_WINDOW_EVENT_WATCH_NORMAL, SDL_RendererEventWatch, renderer);
if (renderer->window) {
SDL_PropertiesID props = SDL_GetWindowProperties(renderer->window);
if (SDL_GetPointerProperty(props, SDL_PROP_WINDOW_RENDERER_POINTER, NULL) == renderer) {

View file

@ -339,9 +339,6 @@ extern SDL_RenderDriver GPU_RenderDriver;
// Clean up any renderers at shutdown
extern void SDL_QuitRender(void);
// Handle window events for a renderer
extern void SDL_RendererEventWatch(SDL_Renderer *renderer, SDL_Event *event);
// Add a supported texture format to a renderer
extern bool SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormat format);

View file

@ -26,6 +26,8 @@
*/
#include "SDL_internal.h"
#include "../../events/SDL_windowevents_c.h"
#import "SDL_cocoametalview.h"
#if defined(SDL_VIDEO_DRIVER_COCOA) && (defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL))
@ -88,7 +90,7 @@ static bool SDLCALL SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
self.layer.opaque = opaque;
SDL_AddEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self));
SDL_AddWindowEventWatch(SDL_WINDOW_EVENT_WATCH_EARLY, SDL_MetalViewEventWatch, (__bridge void *)(self));
[self updateDrawableSize];
}
@ -98,7 +100,7 @@ static bool SDLCALL SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
- (void)dealloc
{
SDL_RemoveEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self));
SDL_RemoveWindowEventWatch(SDL_WINDOW_EVENT_WATCH_EARLY, SDL_MetalViewEventWatch, (__bridge void *)(self));
}
- (NSInteger)tag