diff --git a/CMakeLists.txt b/CMakeLists.txt index af76f30..82ff662 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,14 +108,19 @@ add_executable( src/WallpaperEngine/Render/Helpers/CContextAware.cpp src/WallpaperEngine/Render/Helpers/CContextAware.h + src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.cpp + src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h + src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.cpp + src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h + src/WallpaperEngine/Render/Drivers/Output/COutput.cpp src/WallpaperEngine/Render/Drivers/Output/COutput.h src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp src/WallpaperEngine/Render/Drivers/Output/CX11Output.h src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h - src/WallpaperEngine/Render/Drivers/COpenGLDriver.h - src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp + src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h + src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.cpp src/WallpaperEngine/Render/Drivers/CVideoDriver.h src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp src/WallpaperEngine/Render/CRenderContext.h diff --git a/src/WallpaperEngine/Application/CWallpaperApplication.cpp b/src/WallpaperEngine/Application/CWallpaperApplication.cpp index 67eada4..cb2091e 100644 --- a/src/WallpaperEngine/Application/CWallpaperApplication.cpp +++ b/src/WallpaperEngine/Application/CWallpaperApplication.cpp @@ -10,6 +10,7 @@ #include "WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h" #include "WallpaperEngine/Render/Drivers/Output/CX11Output.h" #include "WallpaperEngine/Application/CApplicationState.h" +#include "WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h" #include @@ -65,7 +66,7 @@ namespace WallpaperEngine::Application ); // TODO: move this somewhere else? - CVirtualContainer* virtualContainer = new CVirtualContainer (); + auto* virtualContainer = new CVirtualContainer (); // // Had to get a little creative with the effects to achieve the same bloom effect without any custom code @@ -183,7 +184,7 @@ namespace WallpaperEngine::Application Core::CProject* CWallpaperApplication::loadBackground (const std::string& bg) { - CCombinedContainer* container = new CCombinedContainer (); + auto* container = new CCombinedContainer (); this->setupContainer (*container, bg); @@ -269,22 +270,24 @@ namespace WallpaperEngine::Application // initialize audio context WallpaperEngine::Audio::CAudioContext audioContext (audioDriver); // initialize OpenGL driver - WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver ("wallpaperengine"); + WallpaperEngine::Render::Drivers::CX11OpenGLDriver videoDriver ("wallpaperengine"); // initialize the input subsystem WallpaperEngine::Input::CInputContext inputContext (videoDriver); // output requested WallpaperEngine::Render::Drivers::Output::COutput* output; + // fullscreen detector is common for the different render modes + WallpaperEngine::Render::Drivers::Detectors::CX11FullScreenDetector fullscreenDetector (videoDriver); // initialize the requested output switch (this->m_context.settings.render.mode) { case CApplicationContext::EXPLICIT_WINDOW: case CApplicationContext::NORMAL_WINDOW: - output = new WallpaperEngine::Render::Drivers::Output::CGLFWWindowOutput (this->m_context, videoDriver); + output = new WallpaperEngine::Render::Drivers::Output::CGLFWWindowOutput (this->m_context, videoDriver, fullscreenDetector); break; case CApplicationContext::X11_BACKGROUND: - output = new WallpaperEngine::Render::Drivers::Output::CX11Output (this->m_context, videoDriver); + output = new WallpaperEngine::Render::Drivers::Output::CX11Output (this->m_context, videoDriver, fullscreenDetector); break; } diff --git a/src/WallpaperEngine/Application/CWallpaperApplication.h b/src/WallpaperEngine/Application/CWallpaperApplication.h index de68d57..959f595 100644 --- a/src/WallpaperEngine/Application/CWallpaperApplication.h +++ b/src/WallpaperEngine/Application/CWallpaperApplication.h @@ -8,7 +8,7 @@ #include "WallpaperEngine/Render/CWallpaper.h" #include "WallpaperEngine/Render/CRenderContext.h" -#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h" +#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h" namespace WallpaperEngine::Application { diff --git a/src/WallpaperEngine/Audio/CAudioStream.h b/src/WallpaperEngine/Audio/CAudioStream.h index 3b5e395..ca379c1 100644 --- a/src/WallpaperEngine/Audio/CAudioStream.h +++ b/src/WallpaperEngine/Audio/CAudioStream.h @@ -46,7 +46,7 @@ namespace WallpaperEngine::Audio /** * @return The audio context in use for this audio stream */ - CAudioContext& getAudioContext () const; + [[nodiscard]] CAudioContext& getAudioContext () const; /** * @return to the codec context, which provides information on the audio stream's format diff --git a/src/WallpaperEngine/Input/CInputContext.cpp b/src/WallpaperEngine/Input/CInputContext.cpp index cf97ccf..8ae463f 100644 --- a/src/WallpaperEngine/Input/CInputContext.cpp +++ b/src/WallpaperEngine/Input/CInputContext.cpp @@ -1,10 +1,10 @@ #include "CInputContext.h" -#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h" +#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h" using namespace WallpaperEngine::Input; using namespace WallpaperEngine::Render::Drivers; -CInputContext::CInputContext (COpenGLDriver& videoDriver) : +CInputContext::CInputContext (CX11OpenGLDriver& videoDriver) : m_mouse (videoDriver.getWindow ()) { } diff --git a/src/WallpaperEngine/Input/CInputContext.h b/src/WallpaperEngine/Input/CInputContext.h index 5c47718..bffc9c3 100644 --- a/src/WallpaperEngine/Input/CInputContext.h +++ b/src/WallpaperEngine/Input/CInputContext.h @@ -1,11 +1,11 @@ #pragma once -#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h" +#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h" #include "CMouseInput.h" namespace WallpaperEngine::Render::Drivers { - class COpenGLDriver; + class CX11OpenGLDriver; } namespace WallpaperEngine::Input @@ -13,10 +13,10 @@ namespace WallpaperEngine::Input class CInputContext { public: - explicit CInputContext (Render::Drivers::COpenGLDriver& videoDriver); + explicit CInputContext (Render::Drivers::CX11OpenGLDriver& videoDriver); void update (); - const CMouseInput& getMouseInput () const; + [[nodiscard]] const CMouseInput& getMouseInput () const; private: CMouseInput m_mouse; diff --git a/src/WallpaperEngine/Input/CMouseInput.h b/src/WallpaperEngine/Input/CMouseInput.h index 08f9f7e..7909081 100644 --- a/src/WallpaperEngine/Input/CMouseInput.h +++ b/src/WallpaperEngine/Input/CMouseInput.h @@ -22,6 +22,7 @@ namespace WallpaperEngine::Input * The virtual pointer's position */ glm::dvec2 position; + private: /** * The GLFW window to get mouse position from diff --git a/src/WallpaperEngine/Render/CObject.cpp b/src/WallpaperEngine/Render/CObject.cpp index 10b74cd..6ca889d 100644 --- a/src/WallpaperEngine/Render/CObject.cpp +++ b/src/WallpaperEngine/Render/CObject.cpp @@ -6,6 +6,7 @@ using namespace WallpaperEngine; using namespace WallpaperEngine::Render; CObject::CObject(CScene* scene, std::string type, Core::CObject *object) : + Helpers::CContextAware (scene), m_scene (scene), m_object (object), m_type (std::move (type)) diff --git a/src/WallpaperEngine/Render/CObject.h b/src/WallpaperEngine/Render/CObject.h index 8b84d3c..fa1100d 100644 --- a/src/WallpaperEngine/Render/CObject.h +++ b/src/WallpaperEngine/Render/CObject.h @@ -3,6 +3,7 @@ #include #include "WallpaperEngine/Core/CObject.h" +#include "WallpaperEngine/Render/Helpers/CContextAware.h" #include "CScene.h" @@ -10,7 +11,7 @@ namespace WallpaperEngine::Render { class CScene; - class CObject + class CObject : public Helpers::CContextAware { public: template const T* as () const { assert (is()); return (const T*) this; } diff --git a/src/WallpaperEngine/Render/Drivers/CVideoDriver.h b/src/WallpaperEngine/Render/Drivers/CVideoDriver.h index 90bd31c..c164b2e 100644 --- a/src/WallpaperEngine/Render/Drivers/CVideoDriver.h +++ b/src/WallpaperEngine/Render/Drivers/CVideoDriver.h @@ -8,6 +8,10 @@ namespace WallpaperEngine::Render::Drivers class CVideoDriver { public: + /** + * @return The window handle used by this video driver + */ + virtual void* getWindowHandle () const = 0; /** * @return The time that has passed since the driver started */ diff --git a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp b/src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.cpp similarity index 73% rename from src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp rename to src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.cpp index 65cadc6..a0cf65c 100644 --- a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp +++ b/src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.cpp @@ -1,7 +1,10 @@ -#include "COpenGLDriver.h" +#include "CX11OpenGLDriver.h" #include "common.h" #include +#define GLFW_EXPOSE_NATIVE_X11 +#include + using namespace WallpaperEngine::Render::Drivers; void CustomGLFWErrorHandler (int errorCode, const char* reason) @@ -9,7 +12,7 @@ void CustomGLFWErrorHandler (int errorCode, const char* reason) sLog.error ("GLFW error ", errorCode, ": ", reason); } -COpenGLDriver::COpenGLDriver (const char* windowTitle) : +CX11OpenGLDriver::CX11OpenGLDriver (const char* windowTitle) : m_frameCounter (0) { glfwSetErrorCallback (CustomGLFWErrorHandler); @@ -48,44 +51,49 @@ COpenGLDriver::COpenGLDriver (const char* windowTitle) : FreeImage_Initialise (TRUE); } -COpenGLDriver::~COpenGLDriver () +CX11OpenGLDriver::~CX11OpenGLDriver () { glfwTerminate (); FreeImage_DeInitialise(); } -float COpenGLDriver::getRenderTime () const +void* CX11OpenGLDriver::getWindowHandle () const +{ + return reinterpret_cast (glfwGetX11Window (this->m_window)); +} + +float CX11OpenGLDriver::getRenderTime () const { return (float) glfwGetTime (); } -bool COpenGLDriver::closeRequested () +bool CX11OpenGLDriver::closeRequested () { return glfwWindowShouldClose (this->m_window); } -void COpenGLDriver::resizeWindow (glm::ivec2 size) +void CX11OpenGLDriver::resizeWindow (glm::ivec2 size) { glfwSetWindowSize (this->m_window, size.x, size.y); } -void COpenGLDriver::resizeWindow (glm::ivec4 sizeandpos) +void CX11OpenGLDriver::resizeWindow (glm::ivec4 sizeandpos) { glfwSetWindowPos (this->m_window, sizeandpos.x, sizeandpos.y); glfwSetWindowSize (this->m_window, sizeandpos.z, sizeandpos.w); } -void COpenGLDriver::showWindow () +void CX11OpenGLDriver::showWindow () { glfwShowWindow (this->m_window); } -void COpenGLDriver::hideWindow () +void CX11OpenGLDriver::hideWindow () { glfwHideWindow (this->m_window); } -glm::ivec2 COpenGLDriver::getFramebufferSize () const +glm::ivec2 CX11OpenGLDriver::getFramebufferSize () const { glm::ivec2 size; @@ -94,7 +102,7 @@ glm::ivec2 COpenGLDriver::getFramebufferSize () const return size; } -void COpenGLDriver::swapBuffers () +void CX11OpenGLDriver::swapBuffers () { // do buffer swapping first glfwSwapBuffers (this->m_window); @@ -104,12 +112,12 @@ void COpenGLDriver::swapBuffers () this->m_frameCounter ++; } -uint32_t COpenGLDriver::getFrameCounter () const +uint32_t CX11OpenGLDriver::getFrameCounter () const { return this->m_frameCounter; } -GLFWwindow* COpenGLDriver::getWindow () +GLFWwindow* CX11OpenGLDriver::getWindow () { return this->m_window; } diff --git a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h b/src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h similarity index 83% rename from src/WallpaperEngine/Render/Drivers/COpenGLDriver.h rename to src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h index 14fd63d..1140479 100644 --- a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h +++ b/src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h @@ -14,12 +14,13 @@ namespace WallpaperEngine::Render::Drivers { using namespace WallpaperEngine::Application; - class COpenGLDriver : public CVideoDriver + class CX11OpenGLDriver : public CVideoDriver { public: - explicit COpenGLDriver (const char* windowTitle); - ~COpenGLDriver(); + explicit CX11OpenGLDriver (const char* windowTitle); + ~CX11OpenGLDriver(); + void* getWindowHandle () const; float getRenderTime () const override; bool closeRequested () override; void resizeWindow (glm::ivec2 size) override; diff --git a/src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.cpp b/src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.cpp new file mode 100644 index 0000000..9ee4865 --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.cpp @@ -0,0 +1 @@ +#include "CFullScreenDetector.h" diff --git a/src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h b/src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h new file mode 100644 index 0000000..cb4b994 --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h @@ -0,0 +1,18 @@ +#pragma once + +namespace WallpaperEngine::Render::Drivers::Detectors +{ + class CFullScreenDetector + { + public: + /** + * @return If anything is fullscreen + */ + [[nodiscard]] virtual bool anythingFullscreen () const = 0; + + /** + * Restarts the fullscreen detector, specially useful if there's any resources tied to the output driver + */ + virtual void reset () = 0; + }; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.cpp b/src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.cpp new file mode 100644 index 0000000..0ee439b --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.cpp @@ -0,0 +1,176 @@ +#include "CX11FullScreenDetector.h" +#include "WallpaperEngine/Logging/CLog.h" + +#include +#include + + +namespace WallpaperEngine::Render::Drivers::Detectors +{ + void CustomXIOErrorExitHandler (Display* dsp, void* userdata) + { + auto context = static_cast (userdata); + + sLog.debugerror ("Critical XServer error detected. Attempting to recover..."); + + // refetch all the resources + context->reset (); + } + + int CustomXErrorHandler (Display* dpy, XErrorEvent* event) + { + sLog.debugerror ("Detected X error"); + + return 0; + } + + int CustomXIOErrorHandler (Display* dsp) + { + sLog.debugerror ("Detected X error"); + + return 0; + } + + CX11FullScreenDetector::CX11FullScreenDetector (CVideoDriver& driver) : + m_driver (driver) + { + // do not use previous handler, it might stop the app under weird circumstances + // these handlers might be replaced by other X11-specific functionality, they + // should only be used to ignore X11 errors and nothing else + // so this doesn't affect functionality + XSetErrorHandler (CustomXErrorHandler); + XSetIOErrorHandler (CustomXIOErrorHandler); + + this->initialize (); + } + + CX11FullScreenDetector::~CX11FullScreenDetector () + { + this->stop (); + } + + bool CX11FullScreenDetector::anythingFullscreen () const + { + // stop rendering if anything is fullscreen + bool isFullscreen = false; + XWindowAttributes attribs; + Window _; + Window* children; + unsigned int nchildren; + + isFullscreen = false; + + if (!XQueryTree (this->m_display, this->m_root, &_, &_, &children, &nchildren)) + return false; + + auto ourWindow = reinterpret_cast (this->m_driver.getWindowHandle ()); + Window parentWindow; + + { + Window root, * schildren = NULL; + unsigned int num_children; + + if (!XQueryTree (m_display, ourWindow, &root, &parentWindow, &schildren, &num_children)) + return false; + + if (schildren) + XFree ((char*) children); + } + + for (int i = 0; i < nchildren; i++) + { + if (!XGetWindowAttributes (this->m_display, children [i], &attribs)) + continue; + + // ignore ourselves + if (ourWindow == children [i] || parentWindow == children [i]) + continue; + + if (attribs.map_state != IsViewable) + continue; + + // compare width and height with the different screens we have + for (const auto& screen : this->m_screens) + { + if ( + attribs.x == screen.viewport.x && attribs.y == screen.viewport.y && + attribs.width == screen.viewport.z && attribs.height == screen.viewport.w + ) + { + isFullscreen = true; + break; + } + } + } + + XFree (children); + + return isFullscreen; + } + + void CX11FullScreenDetector::reset () + { + this->stop (); + this->initialize (); + } + + void CX11FullScreenDetector::initialize () + { + this->m_display = XOpenDisplay (nullptr); + + // set the error handling to try and recover from X disconnections +#ifdef HAVE_XSETIOERROREXITHANDLER + XSetIOErrorExitHandler (this->m_display, CustomXIOErrorExitHandler, this); +#endif /* HAVE_XSETIOERROREXITHANDLER */ + + int xrandr_result, xrandr_error; + + if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error)) + { + sLog.error ("XRandr is not present, fullscreen detection might not work"); + return; + } + + this->m_root = DefaultRootWindow (this->m_display); + XRRScreenResources* screenResources = XRRGetScreenResources (this->m_display, this->m_root); + + if (screenResources == nullptr) + { + sLog.error ("Cannot detect screen sizes using xrandr, fullscreen detection might not work"); + return; + } + + for (int i = 0; i < screenResources->noutput; i ++) + { + XRROutputInfo* info = XRRGetOutputInfo (this->m_display, screenResources, screenResources->outputs [i]); + + // screen not in use, ignore it + if (info == nullptr || info->connection != RR_Connected) + continue; + + XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc); + + // add the screen to the list of screens + this->m_screens.push_back ( + { + {crtc->x, crtc->y, crtc->width, crtc->height}, + info->name + } + ); + + XRRFreeCrtcInfo (crtc); + } + + XRRFreeScreenResources (screenResources); + } + + void CX11FullScreenDetector::stop () + { + if (this->m_display == nullptr) + return; + + XCloseDisplay (this->m_display); + this->m_display = nullptr; + } + +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h b/src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h new file mode 100644 index 0000000..975514c --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +#include "CFullScreenDetector.h" +#include "WallpaperEngine/Render/Drivers/CVideoDriver.h" + +#include + +namespace WallpaperEngine::Render::Drivers::Detectors +{ + class CX11FullScreenDetector : public CFullScreenDetector + { + public: + CX11FullScreenDetector (CVideoDriver& driver); + ~CX11FullScreenDetector (); + + [[nodiscard]] bool anythingFullscreen () const override; + void reset () override; + + private: + void initialize (); + void stop (); + + struct ScreenInfo + { + glm::ivec4 viewport; + std::string name; + }; + + Display* m_display; + Window m_root; + std::vector m_screens; + CVideoDriver& m_driver; + }; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp b/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp index af7a36b..4b10aa4 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp +++ b/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp @@ -2,10 +2,14 @@ #include "CGLFWWindowOutput.h" #include "WallpaperEngine/Logging/CLog.h" +#include + +#define FULLSCREEN_CHECK_WAIT_TIME 250 + using namespace WallpaperEngine::Render::Drivers::Output; -CGLFWWindowOutput::CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver) : - COutput (context), +CGLFWWindowOutput::CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector) : + COutput (context, detector), m_driver (driver) { if ( @@ -75,4 +79,8 @@ void CGLFWWindowOutput::updateRender () const // update the default viewport this->m_viewports ["default"] = {{0, 0, this->m_fullWidth, this->m_fullHeight}, "default"}; + + // check for fullscreen windows and wait until there's none fullscreen + while (this->m_detector.anythingFullscreen () && this->m_context.state.general.keepRunning) + usleep (FULLSCREEN_CHECK_WAIT_TIME); } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h b/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h index 17b638e..7486cc6 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h +++ b/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h @@ -8,7 +8,7 @@ namespace WallpaperEngine::Render::Drivers::Output class CGLFWWindowOutput : public COutput { public: - CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver); + CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector); void reset () override; bool renderVFlip () const override; diff --git a/src/WallpaperEngine/Render/Drivers/Output/COutput.cpp b/src/WallpaperEngine/Render/Drivers/Output/COutput.cpp index 529e3a7..ab3a4e7 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/COutput.cpp +++ b/src/WallpaperEngine/Render/Drivers/Output/COutput.cpp @@ -2,8 +2,9 @@ using namespace WallpaperEngine::Render::Drivers::Output; -COutput::COutput (CApplicationContext& context) : - m_context (context) +COutput::COutput (CApplicationContext& context, Detectors::CFullScreenDetector& detector) : + m_context (context), + m_detector (detector) { } diff --git a/src/WallpaperEngine/Render/Drivers/Output/COutput.h b/src/WallpaperEngine/Render/Drivers/Output/COutput.h index 469cf44..79330fd 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/COutput.h +++ b/src/WallpaperEngine/Render/Drivers/Output/COutput.h @@ -5,6 +5,7 @@ #include #include "WallpaperEngine/Application/CApplicationContext.h" +#include "WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h" using namespace WallpaperEngine::Application; @@ -13,12 +14,17 @@ namespace WallpaperEngine::Application class CApplicationContext; } +namespace WallpaperEngine::Render::Drivers::Detectors +{ + class CFullScreenDetector; +} + namespace WallpaperEngine::Render::Drivers::Output { class COutput { public: - COutput (CApplicationContext& context); + COutput (CApplicationContext& context, Detectors::CFullScreenDetector& detector); virtual void reset () = 0; @@ -43,5 +49,6 @@ namespace WallpaperEngine::Render::Drivers::Output mutable int m_fullHeight; mutable std::map m_viewports; CApplicationContext& m_context; + Detectors::CFullScreenDetector& m_detector; }; } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp index 5483743..aadfa0d 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp +++ b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp @@ -24,9 +24,6 @@ int CustomXErrorHandler (Display* dpy, XErrorEvent* event) { sLog.debugerror ("Detected X error"); - // call the original handler so we can keep some information reporting - // originalErrorHandler (dpy, event); - return 0; } @@ -37,8 +34,8 @@ int CustomXIOErrorHandler (Display* dsp) return 0; } -CX11Output::CX11Output (CApplicationContext& context, CVideoDriver& driver) : - COutput (context), +CX11Output::CX11Output (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector) : + COutput (context, detector), m_driver (driver) { // do not use previous handler, it might stop the app under weird circumstances @@ -59,6 +56,8 @@ void CX11Output::reset () this->free (); // re-load screen info this->loadScreenInfo (); + // do the same for the detector + this->m_detector.reset (); } void CX11Output::free () @@ -187,46 +186,7 @@ void CX11Output::updateRender () const XClearWindow(this->m_display, this->m_root); XFlush(this->m_display); - // stop rendering if anything is fullscreen - bool isFullscreen = false; - XWindowAttributes attribs; - Window _; - Window* children; - unsigned int nchildren; - - do - { - isFullscreen = false; - - if (!XQueryTree (this->m_display, this->m_root, &_, &_, &children, &nchildren)) - return; - - for (int i = 0; i < nchildren; i++) - { - if (!XGetWindowAttributes (this->m_display, children [i], &attribs)) - continue; - - if (attribs.map_state != IsViewable) - continue; - - // compare width and height with the different screens we have - for (const auto& screen : this->m_screens) - { - if ( - attribs.x == screen.viewport.x && attribs.y == screen.viewport.y && - attribs.width == screen.viewport.z && attribs.height == screen.viewport.w - ) - { - isFullscreen = true; - break; - } - } - } - - XFree (children); - - // give the cpu some time to check again later + // check for fullscreen windows and wait until there's none fullscreen + while (this->m_detector.anythingFullscreen () && this->m_context.state.general.keepRunning) usleep (FULLSCREEN_CHECK_WAIT_TIME); - } - while (isFullscreen && this->m_context.state.general.keepRunning); } diff --git a/src/WallpaperEngine/Render/Drivers/Output/CX11Output.h b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.h index d35b318..7bbd88e 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CX11Output.h +++ b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.h @@ -14,7 +14,7 @@ namespace WallpaperEngine::Render::Drivers::Output class CX11Output : public COutput { public: - CX11Output (CApplicationContext& context, CVideoDriver& driver); + CX11Output (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector); ~CX11Output (); void reset () override; diff --git a/src/WallpaperEngine/Render/Helpers/CContextAware.cpp b/src/WallpaperEngine/Render/Helpers/CContextAware.cpp index ecd5593..4786385 100644 --- a/src/WallpaperEngine/Render/Helpers/CContextAware.cpp +++ b/src/WallpaperEngine/Render/Helpers/CContextAware.cpp @@ -7,6 +7,11 @@ namespace WallpaperEngine::Render::Helpers { } + CContextAware::CContextAware (CContextAware* from) : + CContextAware (from->getContext ()) + { + } + CContextAware::CContextAware (CRenderContext& context) : m_context (context) { diff --git a/src/WallpaperEngine/Render/Helpers/CContextAware.h b/src/WallpaperEngine/Render/Helpers/CContextAware.h index cfa912e..23f3075 100644 --- a/src/WallpaperEngine/Render/Helpers/CContextAware.h +++ b/src/WallpaperEngine/Render/Helpers/CContextAware.h @@ -17,6 +17,10 @@ namespace WallpaperEngine::Render * @param from Object to get the render context from */ CContextAware (CContextAware& from); + /** + * @param from Object to get the render context from + */ + explicit CContextAware (CContextAware* from); explicit CContextAware (CRenderContext& context); /** diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index 01b4b82..cd671b6 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -81,7 +81,7 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : else { // get the first texture on the first pass (this one represents the image assigned to this object) - this->m_texture = this->getScene ()->getContext ().resolveTexture (textureName); + this->m_texture = this->getContext ().resolveTexture (textureName); } } else diff --git a/src/WallpaperEngine/Render/Objects/CSound.cpp b/src/WallpaperEngine/Render/Objects/CSound.cpp index 5d441aa..0aca8e7 100644 --- a/src/WallpaperEngine/Render/Objects/CSound.cpp +++ b/src/WallpaperEngine/Render/Objects/CSound.cpp @@ -8,7 +8,7 @@ CSound::CSound (CScene* scene, Core::Objects::CSound* sound) : CObject (scene, Type, sound), m_sound (sound) { - if (this->getScene ()->getContext ().getApp ().getContext ().settings.audio.enabled) + if (this->getContext ().getApp ().getContext ().settings.audio.enabled) this->load (); } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp index 9522603..6468e11 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp @@ -5,6 +5,7 @@ using namespace WallpaperEngine::Render::Objects; using namespace WallpaperEngine::Render::Objects::Effects; CMaterial::CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material) : + Helpers::CContextAware (effect->getImage ()), m_effect (effect), m_material (material) { diff --git a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h index 8ccb5e1..c482bb7 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h @@ -6,6 +6,8 @@ #include "WallpaperEngine/Render/Objects/Effects/CPass.h" #include "WallpaperEngine/Render/Objects/CEffect.h" +#include "WallpaperEngine/Render/Helpers/CContextAware.h" + #include "CPass.h" using namespace WallpaperEngine; @@ -20,16 +22,16 @@ namespace WallpaperEngine::Render::Objects::Effects { class CPass; - class CMaterial + class CMaterial : public Helpers::CContextAware { friend class CPass; public: CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material); - const std::vector& getPasses () const; - CImage* getImage () const; - const Core::Objects::Images::CMaterial* getMaterial () const; - const CEffect* getEffect () const; + [[nodiscard]] const std::vector& getPasses () const; + [[nodiscard]] CImage* getImage () const; + [[nodiscard]] const Core::Objects::Images::CMaterial* getMaterial () const; + [[nodiscard]] const CEffect* getEffect () const; private: void generatePasses (); diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index 8860168..30784d9 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -23,6 +23,7 @@ using namespace WallpaperEngine::Render::Objects::Effects; extern float g_Time; CPass::CPass (CMaterial* material, Core::Objects::Images::Materials::CPass* pass) : + Helpers::CContextAware (material), m_material (material), m_pass (pass) { @@ -132,7 +133,7 @@ void CPass::render () if (texture->isAnimated ()) { // calculate current texture and frame - double currentRenderTime = fmod (static_cast (this->getMaterial ()->getImage ()->getScene ()->getContext ().getDriver ().getRenderTime ()), this->m_material->getImage ()->getAnimationTime ()); + double currentRenderTime = fmod (static_cast (this->getContext ().getDriver ().getRenderTime ()), this->m_material->getImage ()->getAnimationTime ()); for (const auto& frameCur : texture->getFrames ()) { @@ -522,7 +523,7 @@ void CPass::setupUniforms () textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName); } else - textureRef = this->getMaterial ()->getImage ()->getScene ()->getContext ().resolveTexture (textureName); + textureRef = this->getContext ().resolveTexture (textureName); this->m_finalTextures.insert (std::make_pair ((*fragCur).first, textureRef)); } @@ -551,7 +552,7 @@ void CPass::setupUniforms () textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName); } else - textureRef = this->getMaterial ()->getImage ()->getScene ()->getContext ().resolveTexture (textureName); + textureRef = this->getContext ().resolveTexture (textureName); this->m_finalTextures.insert (std::make_pair ((*vertCur).first, textureRef)); } @@ -695,7 +696,7 @@ void CPass::setupTextures () else { this->m_textures.emplace_back ( - this->m_material->getImage ()->getScene ()->getContext ().resolveTexture ((*cur)) + this->m_material->getImage ()->getContext ().resolveTexture ((*cur)) ); } } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h index 129e84e..bd68eb4 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -10,6 +10,8 @@ #include "WallpaperEngine/Assets/ITexture.h" #include "WallpaperEngine/Render/CFBO.h" +#include "WallpaperEngine/Render/Helpers/CContextAware.h" + namespace WallpaperEngine::Render::Objects::Effects { using namespace WallpaperEngine::Assets; @@ -18,7 +20,7 @@ namespace WallpaperEngine::Render::Objects::Effects class CMaterial; - class CPass + class CPass : public Helpers::CContextAware { public: CPass (CMaterial* material, Core::Objects::Images::Materials::CPass* pass);