3333
3434#include " wx/gtk/private/wrapgtk.h"
3535
36+ #include < dlfcn.h>
37+ #include < link.h>
38+
3639GdkWindow* wxGetTopLevelGDK ();
3740
3841// ============================================================================
@@ -364,9 +367,31 @@ static void wxgtk_main_do_event(GdkEvent* event, void* data)
364367}
365368}
366369
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+
367392void wxGUIEventLoop::DoYieldFor (long eventsToProcess)
368393{
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 .
370395 // Because this trick rely on one uncertain assumption:
371396 // No one besides us, had done gdk_event_handler_set() already.
372397 // In most case, this might be true.
@@ -379,15 +404,34 @@ void wxGUIEventLoop::DoYieldFor(long eventsToProcess)
379404 // If there're GdkEvents, we handle them via 'wxgtk_main_do_event',
380405 // all other events should be handle by one gtk_main_iteration().
381406 // 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 ;
387416 }
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
389429 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+ }
391435
392436 wxEventLoopBase::DoYieldFor (eventsToProcess);
393437
0 commit comments