33
33
34
34
#include " wx/gtk/private/wrapgtk.h"
35
35
36
+ #include < dlfcn.h>
37
+ #include < link.h>
38
+
36
39
GdkWindow* wxGetTopLevelGDK ();
37
40
38
41
// ============================================================================
@@ -364,9 +367,31 @@ static void wxgtk_main_do_event(GdkEvent* event, void* data)
364
367
}
365
368
}
366
369
370
+ bool isUsingCef (){
371
+ static bool is_using_cef = false ;
372
+ static bool known_already = false ;
373
+ if (known_already)
374
+ return is_using_cef;
375
+ // Use dl_iterate_phdr to iterate over the program headers of the current process
376
+ dl_iterate_phdr ([](struct dl_phdr_info *info, size_t WXUNUSED (size), void *WXUNUSED(data)) {
377
+ auto so_name = std::string{info->dlpi_name };
378
+ auto pos = so_name.find_last_of (' /' );
379
+ if (pos == std::string::npos)
380
+ return 0 ;
381
+ so_name = so_name.substr (pos + 1 );
382
+ if (so_name.compare (0 , 9 , " libcef.so" ) == 0 ){
383
+ is_using_cef = true ;
384
+ return 1 ;
385
+ }
386
+ return 0 ;
387
+ }, nullptr );
388
+ known_already = true ;
389
+ return is_using_cef;
390
+ }
391
+
367
392
void wxGUIEventLoop::DoYieldFor (long eventsToProcess)
368
393
{
369
- // DO NOT replace the global GDK event handler with our 'wxgtk_main_do_event'.
394
+ // DO NOT replace the global GDK event handler with our 'wxgtk_main_do_event' WHEN-USING-CEF .
370
395
// Because this trick rely on one uncertain assumption:
371
396
// No one besides us, had done gdk_event_handler_set() already.
372
397
// In most case, this might be true.
@@ -379,15 +404,34 @@ void wxGUIEventLoop::DoYieldFor(long eventsToProcess)
379
404
// If there're GdkEvents, we handle them via 'wxgtk_main_do_event',
380
405
// all other events should be handle by one gtk_main_iteration().
381
406
// I'm not sure whether this is really okay, but it seems a nicer and less intrusive way to do things.
382
- while (Pending ()){
383
- auto gdk_event_ = gdk_event_get ();
384
- if (gdk_event_ != nullptr ){
385
- wxgtk_main_do_event (gdk_event_, this );
386
- gdk_event_free (gdk_event_);
407
+ if (isUsingCef ()){
408
+ while (Pending ()){
409
+ auto gdk_event_ = gdk_event_get ();
410
+ if (gdk_event_ != nullptr ){
411
+ wxgtk_main_do_event (gdk_event_, this );
412
+ gdk_event_free (gdk_event_);
413
+ }
414
+ else
415
+ break ;
387
416
}
388
- else
417
+ }
418
+ else {
419
+ // temporarily replace the global GDK event handler with our function, which
420
+ // categorizes the events and using m_eventsToProcessInsideYield decides
421
+ // if an event should be processed immediately or not
422
+ // NOTE: this approach is better than using gdk_display_get_event() because
423
+ // gtk_main_iteration() does more than just calling gdk_display_get_event()
424
+ // and then call gtk_main_do_event()!
425
+ // In particular in this way we also process input from sources like
426
+ // GIOChannels (this is needed for e.g. wxGUIAppTraits::WaitForChild).
427
+ gdk_event_handler_set (wxgtk_main_do_event, this , NULL );
428
+ while (Pending ()) // avoid false positives from our idle source
389
429
gtk_main_iteration ();
390
- }
430
+
431
+ wxGCC_WARNING_SUPPRESS_CAST_FUNCTION_TYPE ()
432
+ gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL , NULL );
433
+ wxGCC_WARNING_RESTORE_CAST_FUNCTION_TYPE ()
434
+ }
391
435
392
436
wxEventLoopBase::DoYieldFor (eventsToProcess);
393
437
0 commit comments