Handle XIO errors to keep the background running as much as possible, should fix #91

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2022-05-08 14:12:27 +02:00
parent cd3c024c48
commit 6808f31cd6
2 changed files with 45 additions and 7 deletions

View File

@ -223,14 +223,14 @@ int main (int argc, char* argv[])
return 4;
}
if (assetsDir == "")
if (assetsDir.empty () == true)
{
char* home = getenv ("HOME");
if (home == nullptr)
throw std::runtime_error ("$HOME doesn't exist");
std::string homepath = "";
std::string homepath;
error = validatePath (home, homepath);
@ -255,9 +255,9 @@ int main (int argc, char* argv[])
break;
}
if (assetsDir == "")
if (assetsDir.empty () == true)
{
int len = strlen (argv [0]) + 1;
unsigned long len = strlen (argv [0]) + 1;
char* copy = new char[len];
strncpy (copy, argv [0], len);
@ -274,7 +274,7 @@ int main (int argc, char* argv[])
std::cout << "Found assets folder alongside the binary: " << assetsDir << std::endl;
}
delete copy;
delete[] copy;
}
}
else

View File

@ -1,4 +1,6 @@
#include <iostream>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xrandr.h>
@ -11,6 +13,34 @@
using namespace WallpaperEngine::Render;
void CustomXIOErrorExitHandler (Display* dsp, void* userdata)
{
auto context = static_cast <CContext*> (userdata);
#ifdef DEBUG
std::cerr << "Critical XServer error detected. Attempting to recover..." << std::endl;
#endif /* DEBUG */
// refetch all the resources
context->initializeViewports ();
}
int CustomXErrorHandler (Display* dsp, XErrorEvent* event)
{
#ifdef DEBUG
std::cerr << "Detected X error" << std::endl;
#endif /* DEBUG */
return 0;
}
int CustomXIOErrorHandler (Display* dsp)
{
#ifdef DEBUG
std::cerr << "Detected X IO error" << std::endl;
#endif /* DEBUG */
return 0;
}
CContext::CContext (std::vector <std::string> screens, GLFWwindow* window) :
m_wallpaper (nullptr),
m_screens (std::move (screens)),
@ -26,11 +56,16 @@ void CContext::initializeViewports ()
if (this->m_isRootWindow == false || this->m_screens.empty () == true)
return;
// hide the glfw window if the viewports are to be detected
glfwHideWindow (this->m_window);
// clear the viewports we're drawing to
this->m_viewports.clear ();
this->m_display = XOpenDisplay (nullptr);
// set the error handling to try and recover from X disconnections
XSetIOErrorExitHandler (this->m_display, CustomXIOErrorExitHandler, this);
XSetErrorHandler (CustomXErrorHandler);
XSetIOErrorHandler (CustomXIOErrorHandler);
int xrandr_result, xrandr_error;
if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error))
@ -39,6 +74,9 @@ void CContext::initializeViewports ()
return;
}
// hide the glfw window if the viewports are to be detected
glfwHideWindow (this->m_window);
Window root = DefaultRootWindow (this->m_display);
int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display));
int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display));