@@ -152,15 +152,21 @@ _pg_repeat_callback(Uint32 interval, void *param)
152152 int repeat_interval_copy = pg_key_repeat_interval ;
153153 PG_UNLOCK_EVFILTER_MUTEX
154154
155- repeat_event_copy .type = PGE_KEYREPEAT ;
155+ repeat_event_copy .type = SDL_KEYDOWN ;
156156#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
157157 repeat_event_copy .key .down = true;
158158 repeat_event_copy .key .repeat = true;
159159#else
160160 repeat_event_copy .key .state = SDL_PRESSED ;
161161 repeat_event_copy .key .repeat = 1 ;
162162#endif
163- SDL_PushEvent (& repeat_event_copy );
163+ /* Use SDL_PeepEvents and not SDL_PushEvent because we don't want
164+ * this to go through our event filter.
165+ * Because this doesn't go through our filter we have to check event
166+ * blocking beforehand. */
167+ if (PG_EventEnabled (_pg_pgevent_proxify (repeat_event_copy .type ))) {
168+ SDL_PeepEvents (& repeat_event_copy , 1 , SDL_ADDEVENT , 0 , 0 );
169+ }
164170 return repeat_interval_copy ;
165171}
166172
@@ -470,19 +476,40 @@ _pg_pgevent_deproxify(Uint32 type)
470476 return _pg_pgevent_proxify_helper (type , 0 );
471477}
472478
479+ /* Get type of an event, handling WINDOWEVENT translation on SDL2.
480+ * On SDL3 this function is trivial */
481+ static Uint32
482+ _pg_pgevent_type (SDL_Event * event )
483+ {
473484#if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
474- /* We don't need to do window event translation because in SDL3 each window
475- * event is its own thing anyways */
476- static int
477- _pg_translate_windowevent (void * _ , SDL_Event * event )
485+ if (event -> type == SDL_WINDOWEVENT ) {
486+ return PGE_WINDOWSHOWN + event -> window .event - 1 ;
487+ }
488+ #endif
489+ return event -> type ;
490+ }
491+
492+ /* Handle blocking of pseudo-blocked events.
493+ * Currently this only includes WINDOWEVENT, but can be expanded in the
494+ * future.
495+ */
496+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
497+ static bool SDLCALL
498+ #else
499+ static int SDLCALL
500+ #endif
501+ _pg_filter_blocked_events (void * _ , SDL_Event * event )
478502{
503+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
504+ if (event -> type >= SDL_EVENT_WINDOW_FIRST &&
505+ event -> type <= SDL_EVENT_WINDOW_LAST ) {
506+ #else
479507 if (event -> type == SDL_WINDOWEVENT ) {
480- event -> type = PGE_WINDOWSHOWN + event -> window . event - 1 ;
481- return PG_EventEnabled (_pg_pgevent_proxify (event -> type ));
508+ #endif
509+ return PG_EventEnabled (_pg_pgevent_proxify (_pg_pgevent_type ( event ) ));
482510 }
483511 return 1 ;
484512}
485- #endif
486513
487514#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
488515static bool SDLCALL
@@ -613,10 +640,6 @@ pg_event_filter(void *_, SDL_Event *event)
613640 PG_UNLOCK_EVFILTER_MUTEX
614641 }
615642
616- else if (event -> type == PGE_KEYREPEAT ) {
617- event -> type = SDL_KEYDOWN ;
618- }
619-
620643 else if (event -> type == SDL_KEYUP ) {
621644 PG_LOCK_EVFILTER_MUTEX
622645 /* Actual keyup is blocked, so clear unneeded cache if it exists */
@@ -709,6 +732,14 @@ pg_event_filter(void *_, SDL_Event *event)
709732 return RAISE(pgExc_SDLError, SDL_GetError()), 0;
710733 */
711734 }
735+ /* TODO:
736+ * Any event that gets blocked here will not be visible to the event
737+ * watchers. So things like WINDOWEVENT should never be blocked here.
738+ * This is taken care of in SDL2 codepaths already but needs to also
739+ * be verified in SDL3 porting.
740+ * If the user requests a block on WINDOWEVENTs we are going to handle
741+ * it specially and call it a "pseudo-block", where the filtering will
742+ * happen in a _pg_filter_blocked_events call. */
712743 return PG_EventEnabled (_pg_pgevent_proxify (event -> type ));
713744}
714745
@@ -1747,6 +1778,7 @@ pgEvent_New(SDL_Event *event)
17471778 }
17481779
17491780 if (event ) {
1781+ event -> type = _pg_pgevent_type (event );
17501782 e -> type = _pg_pgevent_deproxify (event -> type );
17511783 e -> dict = dict_from_event (event );
17521784 }
@@ -1846,14 +1878,7 @@ _pg_event_pump(int dopump)
18461878 SDL_PumpEvents ();
18471879 }
18481880
1849- /* WINDOWEVENT translation needed only on SDL2 */
1850- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
1851- /* We need to translate WINDOWEVENTS. But if we do that from the
1852- * from event filter, internal SDL stuff that rely on WINDOWEVENT
1853- * might break. So after every event pump, we translate events from
1854- * here */
1855- SDL_FilterEvents (_pg_translate_windowevent , NULL );
1856- #endif
1881+ SDL_FilterEvents (_pg_filter_blocked_events , NULL );
18571882}
18581883
18591884static int
@@ -2458,8 +2483,6 @@ pg_event_set_blocked(PyObject *self, PyObject *obj)
24582483 /* Never block SDL_WINDOWEVENT on SDL2, we need them for translation */
24592484 PG_SetEventEnabled (SDL_WINDOWEVENT , SDL_TRUE );
24602485#endif
2461- /* Never block PGE_KEYREPEAT too, its needed for pygame internal use */
2462- PG_SetEventEnabled (PGE_KEYREPEAT , SDL_TRUE );
24632486 Py_RETURN_NONE ;
24642487}
24652488
0 commit comments