diff --git a/src/Hyprpaper.cpp b/src/Hyprpaper.cpp index d4418ce..dd80407 100644 --- a/src/Hyprpaper.cpp +++ b/src/Hyprpaper.cpp @@ -85,7 +85,7 @@ void CHyprpaper::recheckMonitor(SMonitor* pMonitor) { if (pMonitor->wantsACK) { pMonitor->wantsACK = false; - zwlr_layer_surface_v1_ack_configure(pMonitor->pLayerSurface, pMonitor->configureSerial); + zwlr_layer_surface_v1_ack_configure(pMonitor->pCurrentLayerSurface->pLayerSurface, pMonitor->configureSerial); } if (pMonitor->wantsReload) { @@ -138,18 +138,16 @@ void CHyprpaper::clearWallpaperFromMonitor(const std::string& monname) { if (it != m_mMonitorActiveWallpaperTargets.end()) m_mMonitorActiveWallpaperTargets.erase(it); - if (PMONITOR->pSurface) { - wl_surface_destroy(PMONITOR->pSurface); - zwlr_layer_surface_v1_destroy(PMONITOR->pLayerSurface); - PMONITOR->pSurface = nullptr; - PMONITOR->pLayerSurface = nullptr; + if (PMONITOR->pCurrentLayerSurface) { + + PMONITOR->pCurrentLayerSurface = nullptr; PMONITOR->wantsACK = false; PMONITOR->wantsReload = false; PMONITOR->initialized = false; PMONITOR->readyForLS = true; - wl_display_flush(m_sDisplay); + } } @@ -187,48 +185,14 @@ void CHyprpaper::ensureMonitorHasActiveWallpaper(SMonitor* pMonitor) { } // create it for thy if it doesnt have - if (!pMonitor->pLayerSurface) + if (!pMonitor->pCurrentLayerSurface) createLSForMonitor(pMonitor); else pMonitor->wantsReload = true; } void CHyprpaper::createLSForMonitor(SMonitor* pMonitor) { - pMonitor->pSurface = wl_compositor_create_surface(m_sCompositor); - - if (!pMonitor->pSurface) { - Debug::log(CRIT, "The compositor did not allow hyprpaper a surface!"); - exit(1); - return; - } - - const auto PINPUTREGION = wl_compositor_create_region(m_sCompositor); - - if (!PINPUTREGION) { - Debug::log(CRIT, "The compositor did not allow hyprpaper a region!"); - exit(1); - return; - } - - wl_surface_set_input_region(pMonitor->pSurface, PINPUTREGION); - - pMonitor->pLayerSurface = zwlr_layer_shell_v1_get_layer_surface(g_pHyprpaper->m_sLayerShell, pMonitor->pSurface, pMonitor->output, ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "hyprpaper"); - - if (!pMonitor->pLayerSurface) { - Debug::log(CRIT, "The compositor did not allow hyprpaper a layersurface!"); - exit(1); - return; - } - - zwlr_layer_surface_v1_set_size(pMonitor->pLayerSurface, 0, 0); - zwlr_layer_surface_v1_set_anchor(pMonitor->pLayerSurface, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); - zwlr_layer_surface_v1_set_exclusive_zone(pMonitor->pLayerSurface, -1); - zwlr_layer_surface_v1_add_listener(pMonitor->pLayerSurface, &Events::layersurfaceListener, pMonitor); - wl_surface_commit(pMonitor->pSurface); - - wl_region_destroy(PINPUTREGION); - - wl_display_flush(m_sDisplay); + pMonitor->pCurrentLayerSurface = pMonitor->layerSurfaces.emplace_back(std::make_unique(pMonitor)).get(); } bool CHyprpaper::setCloexec(const int& FD) { @@ -354,8 +318,18 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) { cairo_paint(PCAIRO); cairo_restore(PCAIRO); - wl_surface_attach(pMonitor->pSurface, PBUFFER->buffer, 0, 0); - wl_surface_set_buffer_scale(pMonitor->pSurface, pMonitor->scale); - wl_surface_damage_buffer(pMonitor->pSurface, 0, 0, pMonitor->size.x, pMonitor->size.y); - wl_surface_commit(pMonitor->pSurface); + wl_surface_attach(pMonitor->pCurrentLayerSurface->pSurface, PBUFFER->buffer, 0, 0); + wl_surface_set_buffer_scale(pMonitor->pCurrentLayerSurface->pSurface, pMonitor->scale); + wl_surface_damage_buffer(pMonitor->pCurrentLayerSurface->pSurface, 0, 0, pMonitor->size.x, pMonitor->size.y); + wl_surface_commit(pMonitor->pCurrentLayerSurface->pSurface); + + // check if we dont need to remove a wallpaper + if (pMonitor->layerSurfaces.size() > 1) { + for (auto it = pMonitor->layerSurfaces.begin(); it != pMonitor->layerSurfaces.end(); it++) { + if (pMonitor->pCurrentLayerSurface != it->get()) { + pMonitor->layerSurfaces.erase(it); + break; + } + } + } } \ No newline at end of file diff --git a/src/events/Events.cpp b/src/events/Events.cpp index bc42748..3ff4439 100644 --- a/src/events/Events.cpp +++ b/src/events/Events.cpp @@ -34,15 +34,15 @@ void Events::description(void *data, wl_output *wl_output, const char *descripti } void Events::ls_configure(void *data, zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) { - const auto PMONITOR = (SMonitor *)data; + const auto PLAYERSURFACE = (CLayerSurface*)data; - PMONITOR->size = Vector2D(width, height); - PMONITOR->wantsReload = true; - PMONITOR->configureSerial = serial; - PMONITOR->wantsACK = true; - PMONITOR->initialized = true; + PLAYERSURFACE->m_pMonitor->size = Vector2D(width, height); + PLAYERSURFACE->m_pMonitor->wantsReload = true; + PLAYERSURFACE->m_pMonitor->configureSerial = serial; + PLAYERSURFACE->m_pMonitor->wantsACK = true; + PLAYERSURFACE->m_pMonitor->initialized = true; - Debug::log(LOG, "configure for %s", PMONITOR->name.c_str()); + Debug::log(LOG, "configure for %s", PLAYERSURFACE->m_pMonitor->name.c_str()); } void Events::handleGlobal(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 93027ca..9debb72 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -2,6 +2,7 @@ #include "../defines.hpp" #include "PoolBuffer.hpp" +#include "../render/LayerSurface.hpp" struct SMonitor { std::string name = ""; @@ -13,12 +14,13 @@ struct SMonitor { bool readyForLS = false; bool hasATarget = true; - zwlr_layer_surface_v1* pLayerSurface = nullptr; - wl_surface* pSurface = nullptr; uint32_t configureSerial = 0; SPoolBuffer buffer; bool wantsReload = false; bool wantsACK = false; bool initialized = false; + + std::vector> layerSurfaces; + CLayerSurface* pCurrentLayerSurface = nullptr; }; \ No newline at end of file diff --git a/src/render/LayerSurface.cpp b/src/render/LayerSurface.cpp new file mode 100644 index 0000000..b24a0a5 --- /dev/null +++ b/src/render/LayerSurface.cpp @@ -0,0 +1,50 @@ +#include "LayerSurface.hpp" + +#include "../Hyprpaper.hpp" + +CLayerSurface::CLayerSurface(SMonitor* pMonitor) { + m_pMonitor = pMonitor; + + pSurface = wl_compositor_create_surface(g_pHyprpaper->m_sCompositor); + + if (!pSurface) { + Debug::log(CRIT, "The compositor did not allow hyprpaper a surface!"); + exit(1); + return; + } + + const auto PINPUTREGION = wl_compositor_create_region(g_pHyprpaper->m_sCompositor); + + if (!PINPUTREGION) { + Debug::log(CRIT, "The compositor did not allow hyprpaper a region!"); + exit(1); + return; + } + + wl_surface_set_input_region(pSurface, PINPUTREGION); + + pLayerSurface = zwlr_layer_shell_v1_get_layer_surface(g_pHyprpaper->m_sLayerShell, pSurface, pMonitor->output, ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "hyprpaper"); + + if (!pLayerSurface) { + Debug::log(CRIT, "The compositor did not allow hyprpaper a layersurface!"); + exit(1); + return; + } + + zwlr_layer_surface_v1_set_size(pLayerSurface, 0, 0); + zwlr_layer_surface_v1_set_anchor(pLayerSurface, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); + zwlr_layer_surface_v1_set_exclusive_zone(pLayerSurface, -1); + zwlr_layer_surface_v1_add_listener(pLayerSurface, &Events::layersurfaceListener, this); + wl_surface_commit(pSurface); + + wl_region_destroy(PINPUTREGION); + + wl_display_flush(g_pHyprpaper->m_sDisplay); +} + +CLayerSurface::~CLayerSurface() { + wl_surface_destroy(pSurface); + zwlr_layer_surface_v1_destroy(pLayerSurface); + + wl_display_flush(g_pHyprpaper->m_sDisplay); +} \ No newline at end of file diff --git a/src/render/LayerSurface.hpp b/src/render/LayerSurface.hpp new file mode 100644 index 0000000..09aa406 --- /dev/null +++ b/src/render/LayerSurface.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "../defines.hpp" + +struct SMonitor; + +class CLayerSurface { +public: + CLayerSurface(SMonitor*); + ~CLayerSurface(); + + SMonitor* m_pMonitor = nullptr; + + zwlr_layer_surface_v1* pLayerSurface = nullptr; + wl_surface* pSurface = nullptr; + + bool m_bCurrent = false; +}; \ No newline at end of file