@@ -152,15 +152,21 @@ _pg_repeat_callback(Uint32 interval, void *param)
152
152
int repeat_interval_copy = pg_key_repeat_interval ;
153
153
PG_UNLOCK_EVFILTER_MUTEX
154
154
155
- repeat_event_copy .type = PGE_KEYREPEAT ;
155
+ repeat_event_copy .type = SDL_KEYDOWN ;
156
156
#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
157
157
repeat_event_copy .key .down = true;
158
158
repeat_event_copy .key .repeat = true;
159
159
#else
160
160
repeat_event_copy .key .state = SDL_PRESSED ;
161
161
repeat_event_copy .key .repeat = 1 ;
162
162
#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
+ }
164
170
return repeat_interval_copy ;
165
171
}
166
172
@@ -470,19 +476,40 @@ _pg_pgevent_deproxify(Uint32 type)
470
476
return _pg_pgevent_proxify_helper (type , 0 );
471
477
}
472
478
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
+ {
473
484
#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 )
478
502
{
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
479
507
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 ) ));
482
510
}
483
511
return 1 ;
484
512
}
485
- #endif
486
513
487
514
#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
488
515
static bool SDLCALL
@@ -613,10 +640,6 @@ pg_event_filter(void *_, SDL_Event *event)
613
640
PG_UNLOCK_EVFILTER_MUTEX
614
641
}
615
642
616
- else if (event -> type == PGE_KEYREPEAT ) {
617
- event -> type = SDL_KEYDOWN ;
618
- }
619
-
620
643
else if (event -> type == SDL_KEYUP ) {
621
644
PG_LOCK_EVFILTER_MUTEX
622
645
/* Actual keyup is blocked, so clear unneeded cache if it exists */
@@ -709,6 +732,14 @@ pg_event_filter(void *_, SDL_Event *event)
709
732
return RAISE(pgExc_SDLError, SDL_GetError()), 0;
710
733
*/
711
734
}
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. */
712
743
return PG_EventEnabled (_pg_pgevent_proxify (event -> type ));
713
744
}
714
745
@@ -1747,6 +1778,7 @@ pgEvent_New(SDL_Event *event)
1747
1778
}
1748
1779
1749
1780
if (event ) {
1781
+ event -> type = _pg_pgevent_type (event );
1750
1782
e -> type = _pg_pgevent_deproxify (event -> type );
1751
1783
e -> dict = dict_from_event (event );
1752
1784
}
@@ -1846,14 +1878,7 @@ _pg_event_pump(int dopump)
1846
1878
SDL_PumpEvents ();
1847
1879
}
1848
1880
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 );
1857
1882
}
1858
1883
1859
1884
static int
@@ -2458,8 +2483,6 @@ pg_event_set_blocked(PyObject *self, PyObject *obj)
2458
2483
/* Never block SDL_WINDOWEVENT on SDL2, we need them for translation */
2459
2484
PG_SetEventEnabled (SDL_WINDOWEVENT , SDL_TRUE );
2460
2485
#endif
2461
- /* Never block PGE_KEYREPEAT too, its needed for pygame internal use */
2462
- PG_SetEventEnabled (PGE_KEYREPEAT , SDL_TRUE );
2463
2486
Py_RETURN_NONE ;
2464
2487
}
2465
2488
0 commit comments