From d00e37f6de82330023b018f960c0ffedaa4ac59f Mon Sep 17 00:00:00 2001 From: Andrew Mickelson Date: Fri, 17 Aug 2018 12:00:29 -0700 Subject: [PATCH] Added log message when frontend unexpectedly loses focus - hopefully this will help troubleshooting for people who are losing focus while running the frontend - on Windows and Linux the process for the new foreground window will be reported in the log --- src/fe_util.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++-- src/fe_util.hpp | 3 ++ src/main.cpp | 22 ++++++++- src/scraper_xml.cpp | 5 +- 4 files changed, 135 insertions(+), 7 deletions(-) diff --git a/src/fe_util.cpp b/src/fe_util.cpp index 376f21816..6b4a48697 100755 --- a/src/fe_util.cpp +++ b/src/fe_util.cpp @@ -51,6 +51,8 @@ #include #include #include +#include // for CreateToolhelp32Snapshot() +#include // for GetModuleFileNameEx() #else #include #include @@ -968,10 +970,13 @@ bool run_program( const std::string &prog, FeLog() << "Parameter word expansion failed. [" << args << "]." << std::endl; // Provide some debugging output for what we are doing - FeDebug() << "execvp(): file='" << prog.c_str() << "', argv="; - for ( int r=0; we.we_wordv[r]; r++ ) - FeDebug() << "[" << we.we_wordv[r] << "]"; - FeDebug() << std::endl; + if ( callback == NULL ) + { + FeDebug() << "execvp(): file='" << prog.c_str() << "', argv="; + for ( int r=0; we.we_wordv[r]; r++ ) + FeDebug() << "[" << we.we_wordv[r] << "]"; + FeDebug() << std::endl; + } execvp( prog.c_str(), we.we_wordv ); @@ -1352,3 +1357,102 @@ bool get_console_stdin( std::string &str ) return ( !str.empty() ); } + +std::string get_focus_process() +{ + std::string retval( "Unknown" ); + +#if defined( SFML_SYSTEM_WINDOWS ) + HWND focus_wnd = GetForegroundWindow(); + if ( !focus_wnd ) + return "None"; + + DWORD focus_pid( 0 ); + GetWindowThreadProcessId( focus_wnd, &focus_pid ); + + HANDLE snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); + if ( snap == INVALID_HANDLE_VALUE ) + { + FeLog() << "Could not get process snapshot." << std::endl; + return retval; + } + + PROCESSENTRY32 pei; + pei.dwSize = sizeof( pei ); + BOOL np = Process32First( snap, &pei ); + while ( np ) + { + if ( pei.th32ProcessID == focus_pid ) + { + retval = pei.szExeFile; + break; + } + np = Process32Next( snap, &pei ); + } + + CloseHandle( snap ); + retval += " (" + as_str( (int)focus_pid ) + ")"; + +#elif defined( USE_XLIB ) + + ::Display *xdisp = XOpenDisplay( NULL ); + Atom atom = XInternAtom( xdisp, "_NET_WM_PID", True ); + + Window wnd( 0 ); + int revert; + XGetInputFocus( xdisp, &wnd, &revert ); + if ( wnd == PointerRoot ) + return "Pointer Root"; + else if ( wnd == None ) + return "None"; + + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + unsigned char *prop = NULL; + + if ( XGetWindowProperty( xdisp, + wnd, + atom, + 0, + 1024, + False, + AnyPropertyType, + &actual_type, + &actual_format, + &nitems, + &bytes_after, + &prop ) != Success ) + { + FeLog() << "Could not get window property." << std::endl; + return retval; + } + + if ( !prop ) + { + FeLog() << "Empty window property." << std::endl; + return retval; + } + + int pid = prop[1] * 256; + pid += prop[0]; + XFree( prop ); + + // Try to get the actual name for the process id + // + // Note: this is Linux specific + // + std::string fn = "/proc/" + as_str( pid ) + "/cmdline"; + std::ifstream myfile( fn.c_str() ); + if ( myfile.good() ) + { + getline( myfile, retval ); + myfile.close(); + } + + retval += " (" + as_str( pid ) + ")"; + +#endif + + return retval; +} diff --git a/src/fe_util.hpp b/src/fe_util.hpp index 0604eca46..b62bc2af2 100644 --- a/src/fe_util.hpp +++ b/src/fe_util.hpp @@ -279,6 +279,9 @@ bool line_to_setting_and_value( const std::string &line, std::string &value, const char *sep=FE_WHITESPACE ); +// return the name of the process that currently has window focus +std::string get_focus_process(); + // // Non-blocking check for input on stdin // return true if input found, false otherwise diff --git a/src/main.cpp b/src/main.cpp index abfa6964f..062ddd2d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) soundsys.play_ambient(); FeBlend::load_default_shaders(); - + FeWindow window( feSettings ); window.initial_create(); @@ -162,7 +162,7 @@ int main(int argc, char *argv[]) soundsys.sound_event( FeInputMap::EventStartup ); - bool redraw=true; + bool redraw=true, has_focus=true; int guard_joyid=-1, guard_axis=-1; // variables used to track movement when a key is held down @@ -303,6 +303,8 @@ int main(int argc, char *argv[]) soundsys.sound_event( FeInputMap::EventGameReturn ); soundsys.play_ambient(); + + has_focus=true; } launch_game=false; @@ -977,6 +979,22 @@ int main(int argc, char *argv[]) } } +#if ( SFML_VERSION_INT >= FE_VERSION_INT( 2, 2, 0 ) ) + // + // Log any unexpected loss of window focus + // + if ( has_focus ) + { + if ( !window.hasFocus() ) + { + has_focus = false; + FeLog() << " ! Unexpectedly lost focus to: " << get_focus_process() << std::endl; + } + } + else + has_focus = window.hasFocus(); +#endif + if ( feVM.on_tick() ) redraw=true; diff --git a/src/scraper_xml.cpp b/src/scraper_xml.cpp index 9c6b72dc6..4b96b27a1 100644 --- a/src/scraper_xml.cpp +++ b/src/scraper_xml.cpp @@ -131,7 +131,9 @@ std::string get_crc( const std::string &full_path, return ""; correct_buff_for_format( buff, size, *itr ); - return get_crc32( buff, size ); + std::string retval = get_crc32( buff, size ); + FeDebug() << "CRC: " << full_path << "=" << retval << std::endl; + return retval; } } @@ -165,6 +167,7 @@ std::string get_crc( const std::string &full_path, delete [] orig_buff_ptr; + FeDebug() << "CRC: " << full_path << "=" << retval << std::endl; return retval; }