diff --git a/src/Compositor.cpp b/src/Compositor.cpp index baa098b0..9636be9d 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -322,6 +322,15 @@ SLayerSurface* CCompositor::getLayerForPopup(SLayerPopup* pPopup) { } } } - + return CurrentPopup->parentSurface; +} + +CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) { + for (auto& p : m_lXDGPopups) { + if (p.popup == popup) + return p.parentWindow; + } + + return nullptr; } \ No newline at end of file diff --git a/src/Compositor.hpp b/src/Compositor.hpp index fb58a6f3..c9d1c528 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -49,6 +49,7 @@ public: std::list m_lMonitors; std::list m_lWindows; std::list m_lLayerPopups; + std::list m_lXDGPopups; void startCompositor(); @@ -70,6 +71,7 @@ public: CWindow* windowFloatingFromCursor(); SMonitor* getMonitorFromOutput(wlr_output*); SLayerSurface* getLayerForPopup(SLayerPopup*); + CWindow* getWindowForPopup(wlr_xdg_popup*); private: void initAllSignals(); diff --git a/src/Window.hpp b/src/Window.hpp index c1c0dfb0..66ef93c9 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -13,6 +13,7 @@ public: DYNLISTENER(destroyWindow); DYNLISTENER(setTitleWindow); DYNLISTENER(fullscreenWindow); + DYNLISTENER(newPopupXDG); union { wlr_xdg_surface* xdg; diff --git a/src/events/Events.cpp b/src/events/Events.cpp index 583d52aa..8191f295 100644 --- a/src/events/Events.cpp +++ b/src/events/Events.cpp @@ -321,7 +321,7 @@ void createNewPopup(wlr_xdg_popup* popup, void* parent, bool parentIsLayer) { const auto PLAYER = g_pCompositor->getLayerForPopup(PNEWPOPUP); const auto PMONITOR = g_pCompositor->getMonitorFromOutput(PLAYER->layerSurface->output); - wlr_box box = { .x = -PLAYER->geometry.x, .y = -PLAYER->geometry.y, .width = PMONITOR->vecSize.x, .height = PMONITOR->vecSize.y }; + wlr_box box = {.x = PMONITOR->vecPosition.x, .y = PMONITOR->vecPosition.y, .width = PMONITOR->vecSize.x, .height = PMONITOR->vecSize.y}; wlr_xdg_popup_unconstrain_from_box(PNEWPOPUP->popup, &box); } @@ -379,6 +379,74 @@ void Events::listener_commitPopup(wl_listener* listener, void* data) { } +void createNewPopupXDG(wlr_xdg_popup* popup, void* parent, bool parentIsWindow) { + if (!popup) + return; + + g_pCompositor->m_lXDGPopups.push_back(SXDGPopup()); + const auto PNEWPOPUP = &g_pCompositor->m_lXDGPopups.back(); + + PNEWPOPUP->popup = popup; + if (parentIsWindow) + PNEWPOPUP->parentWindow = (CWindow*)parent; + else { + PNEWPOPUP->parentPopup = (wlr_xdg_popup*)parent; + PNEWPOPUP->parentWindow = g_pCompositor->getWindowForPopup((wlr_xdg_popup*)parent); + } + + + wl_signal_add(&popup->base->events.map, &PNEWPOPUP->listen_mapPopupXDG); + wl_signal_add(&popup->base->events.unmap, &PNEWPOPUP->listen_unmapPopupXDG); + wl_signal_add(&popup->base->events.destroy, &PNEWPOPUP->listen_destroyPopupXDG); + wl_signal_add(&popup->base->events.new_popup, &PNEWPOPUP->listen_newPopupFromPopupXDG); + + const auto PMONITOR = g_pCompositor->getMonitorFromID(PNEWPOPUP->parentWindow->m_iMonitorID); + + wlr_box box = {.x = PMONITOR->vecPosition.x, .y = PMONITOR->vecPosition.y, .width = PMONITOR->vecSize.x, .height = PMONITOR->vecSize.y}; + + wlr_xdg_popup_unconstrain_from_box(PNEWPOPUP->popup, &box); +} + +void Events::listener_newPopupXDG(wl_listener* listener, void* data) { + CWindow* PWINDOW = wl_container_of(listener, PWINDOW, listen_newPopupXDG); + + const auto WLRPOPUP = (wlr_xdg_popup*)data; + + createNewPopupXDG(WLRPOPUP, PWINDOW, true); + + Debug::log(LOG, "New layer popup created from XDG window %x -> %s", PWINDOW, PWINDOW->m_szTitle.c_str()); +} + +void Events::listener_newPopupFromPopupXDG(wl_listener* listener, void* data) { + SXDGPopup* PPOPUP = wl_container_of(listener, PPOPUP, listen_newPopupFromPopupXDG); + + const auto WLRPOPUP = (wlr_xdg_popup*)data; + + createNewPopupXDG(WLRPOPUP, PPOPUP, true); + + Debug::log(LOG, "New layer popup created from XDG popup %x -> %s", PPOPUP, PPOPUP->parentWindow->m_szTitle.c_str()); +} + +void Events::listener_mapPopupXDG(wl_listener* listener, void* data) { + +} + +void Events::listener_unmapPopupXDG(wl_listener* listener, void* data) { + +} + +void Events::listener_destroyPopupXDG(wl_listener* listener, void* data) { + SXDGPopup* PPOPUP = wl_container_of(listener, PPOPUP, listen_destroyPopupXDG); + + wl_list_remove(&PPOPUP->listen_mapPopupXDG.link); + wl_list_remove(&PPOPUP->listen_unmapPopupXDG.link); + wl_list_remove(&PPOPUP->listen_destroyPopupXDG.link); + + g_pCompositor->m_lXDGPopups.remove(*PPOPUP); + + Debug::log(LOG, "Destroyed popup XDG %x", PPOPUP); +} + // ------------------------------------------------------------ // // __ _______ _ _ _____ ______ _______ // // \ \ / /_ _| \ | | __ \ / __ \ \ / / ____| // diff --git a/src/events/Events.hpp b/src/events/Events.hpp index 9a1a9cb1..9ac805fe 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -26,6 +26,7 @@ namespace Events { LISTENER(unmapPopupXDG); LISTENER(destroyPopupXDG); LISTENER(commitPopupXDG); + LISTENER(newPopupFromPopupXDG); // Surface XDG (window) LISTENER(newXDGSurface); diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 6aef68d1..8d7dcede 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -3,6 +3,7 @@ #include "../events/Events.hpp" #include "../defines.hpp" #include "../../wlr-layer-shell-unstable-v1-protocol.h" +#include "../Window.hpp" struct SLayerSurface { wlr_layer_surface_v1* layerSurface; @@ -61,4 +62,20 @@ struct SLayerPopup { bool operator==(const SLayerPopup& rhs) { return popup == rhs.popup; } +}; + +struct SXDGPopup { + CWindow* parentWindow = nullptr; + wlr_xdg_popup* parentPopup = nullptr; + wlr_xdg_popup* popup = nullptr; + + DYNLISTENER(newPopupFromPopupXDG); + DYNLISTENER(destroyPopupXDG); + DYNLISTENER(mapPopupXDG); + DYNLISTENER(unmapPopupXDG); + + // For the list lookup + bool operator==(const SXDGPopup& rhs) { + return popup == rhs.popup; + } }; \ No newline at end of file