From 6808f31cd69d185b7cd6ac4587db4bafe1c5503f Mon Sep 17 00:00:00 2001 From: Alexis Maiquez Date: Sun, 8 May 2022 14:12:27 +0200 Subject: [PATCH] Handle XIO errors to keep the background running as much as possible, should fix #91 Signed-off-by: Alexis Maiquez --- main.cpp | 10 +++--- src/WallpaperEngine/Render/CContext.cpp | 42 +++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/main.cpp b/main.cpp index 9a65d44..1130843 100644 --- a/main.cpp +++ b/main.cpp @@ -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 diff --git a/src/WallpaperEngine/Render/CContext.cpp b/src/WallpaperEngine/Render/CContext.cpp index f3fadb1..b2750bb 100644 --- a/src/WallpaperEngine/Render/CContext.cpp +++ b/src/WallpaperEngine/Render/CContext.cpp @@ -1,4 +1,6 @@ #include +#include + #include #include #include @@ -11,6 +13,34 @@ using namespace WallpaperEngine::Render; +void CustomXIOErrorExitHandler (Display* dsp, void* userdata) +{ + auto context = static_cast (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 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));