summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-02-29 14:26:02 +0000
committerVaxry <vaxry@vaxry.net>2024-02-29 14:26:02 +0000
commit2e111c8cf97d391c25fc6263660271fab605ece1 (patch)
treed0e38817bb633457a87eabae0fa109533937199f /src
parentb39dcfa497f84486569bf862092dfcfadbfd8747 (diff)
xdg: rewrite entire popup implementation
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp9
-rw-r--r--src/Compositor.hpp2
-rw-r--r--src/Window.cpp8
-rw-r--r--src/Window.hpp5
-rw-r--r--src/desktop/Popup.cpp225
-rw-r--r--src/desktop/Popup.hpp69
-rw-r--r--src/desktop/Subsurface.cpp51
-rw-r--r--src/desktop/Subsurface.hpp8
-rw-r--r--src/events/Events.hpp11
-rw-r--r--src/events/Layers.cpp6
-rw-r--r--src/events/Popups.cpp269
-rw-r--r--src/events/Windows.cpp7
-rw-r--r--src/helpers/WLClasses.hpp32
13 files changed, 358 insertions, 344 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 48ac0e1c..150dbfaa 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -1120,15 +1120,6 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) {
return true;
}
-CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) {
- for (auto& p : m_vXDGPopups) {
- if (p->popup == popup)
- return p->parentWindow;
- }
-
- return nullptr;
-}
-
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<std::unique_ptr<SLayerSurface>>* layerSurfaces, Vector2D* sCoords,
SLayerSurface** ppLayerSurfaceFound) {
for (auto& ls : *layerSurfaces | std::views::reverse) {
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 92573669..e9edae04 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -93,7 +93,6 @@ class CCompositor {
std::vector<std::shared_ptr<CMonitor>> m_vMonitors;
std::vector<std::shared_ptr<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
std::vector<std::unique_ptr<CWindow>> m_vWindows;
- std::vector<std::unique_ptr<SXDGPopup>> m_vXDGPopups;
std::vector<std::unique_ptr<CWorkspace>> m_vWorkspaces;
std::vector<CWindow*> m_vWindowsFadingOut;
std::vector<SLayerSurface*> m_vSurfacesFadingOut;
@@ -142,7 +141,6 @@ class CCompositor {
Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*);
CMonitor* getMonitorFromOutput(wlr_output*);
CMonitor* getRealMonitorFromOutput(wlr_output*);
- CWindow* getWindowForPopup(wlr_xdg_popup*);
CWindow* getWindowFromSurface(wlr_surface*);
CWindow* getWindowFromHandle(uint32_t);
CWindow* getWindowFromZWLRHandle(wl_resource*);
diff --git a/src/Window.cpp b/src/Window.cpp
index f1484cb0..6742be60 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -472,7 +472,11 @@ void CWindow::onUnmap() {
g_pCompositor->updateWorkspaceWindows(m_iWorkspaceID);
+ if (m_bIsX11)
+ return;
+
m_pSubsurfaceHead.reset();
+ m_pPopupHead.reset();
}
void CWindow::onMap() {
@@ -519,7 +523,11 @@ void CWindow::onMap() {
break;
}
+ if (m_bIsX11)
+ return;
+
m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
+ m_pPopupHead = std::make_unique<CPopup>(this);
}
void CWindow::onBorderAngleAnimEnd(void* ptr) {
diff --git a/src/Window.hpp b/src/Window.hpp
index 476cb1c5..f4809d11 100644
--- a/src/Window.hpp
+++ b/src/Window.hpp
@@ -8,6 +8,7 @@
#include "config/ConfigDataValues.hpp"
#include "helpers/Vector2D.hpp"
#include "desktop/WLSurface.hpp"
+#include "desktop/Popup.hpp"
#include "macros.hpp"
#include "managers/XWaylandManager.hpp"
@@ -193,7 +194,6 @@ class CWindow {
DYNLISTENER(setTitleWindow);
DYNLISTENER(setGeometryX11U);
DYNLISTENER(fullscreenWindow);
- DYNLISTENER(newPopupXDG);
DYNLISTENER(requestMove);
DYNLISTENER(requestMinimize);
DYNLISTENER(requestMaximize);
@@ -278,8 +278,9 @@ class CWindow {
// bitfield eSuppressEvents
uint64_t m_eSuppressedEvents = SUPPRESS_NONE;
- // for the subsurface tree
+ // desktop components
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
+ std::unique_ptr<CPopup> m_pPopupHead;
// Animated border
CGradientValueData m_cRealBorderColor = {0};
diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp
new file mode 100644
index 00000000..a4b63826
--- /dev/null
+++ b/src/desktop/Popup.cpp
@@ -0,0 +1,225 @@
+#include "Popup.hpp"
+
+CPopup::CPopup(CWindow* pOwner) : m_pWindowOwner(pOwner) {
+ initAllSignals();
+}
+
+CPopup::CPopup(SLayerSurface* pOwner) : m_pLayerOwner(pOwner) {
+ initAllSignals();
+}
+
+CPopup::CPopup(wlr_xdg_popup* popup, CPopup* pOwner) : m_pParent(pOwner), m_pWLR(popup) {
+ m_pWLR->base->data = this;
+ m_sWLSurface.assign(popup->base->surface);
+
+ m_pLayerOwner = pOwner->m_pLayerOwner;
+ m_pWindowOwner = pOwner->m_pWindowOwner;
+
+ m_vLastSize = {m_pWLR->current.geometry.width, m_pWLR->current.geometry.height};
+ unconstrain();
+
+ initAllSignals();
+}
+
+CPopup::~CPopup() {
+ m_sWLSurface.unassign();
+ if (m_pWLR)
+ m_pWLR->base->data = nullptr;
+
+ hyprListener_commitPopup.removeCallback();
+ hyprListener_repositionPopup.removeCallback();
+ hyprListener_mapPopup.removeCallback();
+ hyprListener_unmapPopup.removeCallback();
+ hyprListener_newPopup.removeCallback();
+ hyprListener_destroyPopup.removeCallback();
+}
+
+static void onNewPopup(void* owner, void* data) {
+ const auto POPUP = (CPopup*)owner;
+ POPUP->onNewPopup((wlr_xdg_popup*)data);
+}
+
+static void onMapPopup(void* owner, void* data) {
+ const auto POPUP = (CPopup*)owner;
+ POPUP->onMap();
+}
+
+static void onDestroyPopup(void* owner, void* data) {
+ const auto POPUP = (CPopup*)owner;
+ POPUP->onDestroy();
+}
+
+static void onUnmapPopup(void* owner, void* data) {
+ const auto POPUP = (CPopup*)owner;
+ POPUP->onUnmap();
+}
+
+static void onCommitPopup(void* owner, void* data) {
+ const auto POPUP = (CPopup*)owner;
+ POPUP->onCommit();
+}
+
+static void onRepositionPopup(void* owner, void* data) {
+ const auto POPUP = (CPopup*)owner;
+ POPUP->onReposition();
+}
+
+void CPopup::initAllSignals() {
+
+ if (!m_pWLR) {
+ if (m_pWindowOwner)
+ hyprListener_newPopup.initCallback(&m_pWindowOwner->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head");
+ else if (m_pLayerOwner)
+ hyprListener_newPopup.initCallback(&m_pLayerOwner->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head");
+ else
+ ASSERT(false);
+
+ return;
+ }
+
+ hyprListener_repositionPopup.initCallback(&m_pWLR->events.reposition, ::onRepositionPopup, this, "CPopup");
+ hyprListener_destroyPopup.initCallback(&m_pWLR->events.destroy, ::onDestroyPopup, this, "CPopup");
+ hyprListener_mapPopup.initCallback(&m_sWLSurface.wlr()->events.map, ::onMapPopup, this, "CPopup");
+ hyprListener_unmapPopup.initCallback(&m_sWLSurface.wlr()->events.unmap, ::onUnmapPopup, this, "CPopup");
+ hyprListener_commitPopup.initCallback(&m_sWLSurface.wlr()->events.commit, ::onCommitPopup, this, "CPopup");
+ hyprListener_newPopup.initCallback(&m_pWLR->base->events.new_popup, ::onNewPopup, this, "CPopup");
+}
+
+void CPopup::onNewPopup(wlr_xdg_popup* popup) {
+ const auto POPUP = m_vChildren.emplace_back(std::make_unique<CPopup>(popup, this)).get();
+ Debug::log(LOG, "New popup at wlr {:x} and hl {:x}", (uintptr_t)popup, (uintptr_t)POPUP);
+}
+
+void CPopup::onDestroy() {
+ m_bInert = true;
+
+ if (!m_pParent)
+ return; // head node
+
+ std::erase_if(m_pParent->m_vChildren, [this](const auto& other) { return other.get() == this; });
+}
+
+void CPopup::onMap() {
+ m_vLastSize = {m_pWLR->current.geometry.width, m_pWLR->current.geometry.height};
+ const auto COORDS = coordsGlobal();
+
+ CBox box = {COORDS, m_vLastSize};
+ g_pHyprRenderer->damageBox(&box);
+
+ m_vLastPos = coordsRelativeToParent();
+
+ g_pInputManager->simulateMouseMovement();
+
+ m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
+
+ unconstrain();
+}
+
+void CPopup::onUnmap() {
+ m_vLastSize = {m_pWLR->current.geometry.width, m_pWLR->current.geometry.height};
+ const auto COORDS = coordsGlobal();
+
+ CBox box = {COORDS, m_vLastSize};
+ g_pHyprRenderer->damageBox(&box);
+
+ m_pSubsurfaceHead.reset();
+
+ g_pInputManager->simulateMouseMovement();
+}
+
+void CPopup::onCommit() {
+ if (m_pWLR->base->initial_commit) {
+ wlr_xdg_surface_schedule_configure(m_pWLR->base);
+ return;
+ }
+
+ const auto COORDS = coordsGlobal();
+ const auto COORDSLOCAL = coordsRelativeToParent();
+
+ if (m_vLastSize != Vector2D{m_pWLR->current.geometry.width, m_pWLR->current.geometry.height} || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
+ CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
+ g_pHyprRenderer->damageBox(&box);
+ m_vLastSize = {m_pWLR->current.geometry.width, m_pWLR->current.geometry.height};
+ box = {COORDS, m_vLastSize};
+ g_pHyprRenderer->damageBox(&box);
+
+ m_vLastPos = COORDSLOCAL;
+ }
+
+ m_pSubsurfaceHead->recheckDamageForSubsurfaces();
+
+ g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
+
+ m_bRequestedReposition = false;
+}
+
+void CPopup::onReposition() {
+ Debug::log(LOG, "Popup {:x} requests reposition", (uintptr_t)this);
+
+ m_bRequestedReposition = true;
+
+ m_vLastPos = coordsRelativeToParent();
+
+ unconstrain();
+}
+
+void CPopup::unconstrain() {
+ const auto COORDS = t1ParentCoords();
+ const auto PMONITOR = g_pCompositor->getMonitorFromVector(COORDS);
+
+ if (!PMONITOR)
+ return;
+
+ CBox box = {PMONITOR->vecPosition.x - COORDS.x, PMONITOR->vecPosition.y - COORDS.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
+ wlr_xdg_popup_unconstrain_from_box(m_pWLR, box.pWlr());
+}
+
+Vector2D CPopup::coordsRelativeToParent() {
+ Vector2D offset;
+
+ CPopup* current = this;
+
+ while (current->m_pParent) {
+
+ offset += {current->m_sWLSurface.wlr()->current.dx, current->m_sWLSurface.wlr()->current.dy};
+ offset += {current->m_pWLR->current.geometry.x, current->m_pWLR->current.geometry.y};
+
+ current = current->m_pParent;
+ }
+
+ return offset;
+}
+
+Vector2D CPopup::coordsGlobal() {
+ return localToGlobal(coordsRelativeToParent());
+}
+
+Vector2D CPopup::localToGlobal(const Vector2D& rel) {
+ return t1ParentCoords() + rel;
+}
+
+Vector2D CPopup::t1ParentCoords() {
+ if (m_pWindowOwner)
+ return m_pWindowOwner->m_vRealPosition.vec();
+ if (m_pLayerOwner)
+ return m_pLayerOwner->realPosition.vec();
+
+ ASSERT(false);
+ return {};
+}
+
+void CPopup::recheckTree() {
+ CPopup* curr = this;
+ while (curr->m_pParent) {
+ curr = curr->m_pParent;
+ }
+
+ curr->recheckChildrenRecursive();
+}
+
+void CPopup::recheckChildrenRecursive() {
+ for (auto& c : m_vChildren) {
+ c->onCommit();
+ c->recheckChildrenRecursive();
+ }
+} \ No newline at end of file
diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp
new file mode 100644
index 00000000..8279f7ed
--- /dev/null
+++ b/src/desktop/Popup.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <vector>
+#include <memory>
+#include "Subsurface.hpp"
+
+struct SLayerSurface;
+
+class CPopup {
+ public:
+ // dummy head nodes
+ CPopup(CWindow* pOwner);
+ CPopup(SLayerSurface* pOwner);
+
+ // real nodes
+ CPopup(wlr_xdg_popup* popup, CPopup* pOwner);
+
+ ~CPopup();
+
+ Vector2D coordsRelativeToParent();
+ Vector2D coordsGlobal();
+
+ void onNewPopup(wlr_xdg_popup* popup);
+ void onDestroy();
+ void onMap();
+ void onUnmap();
+ void onCommit();
+ void onReposition();
+
+ void recheckTree();
+
+ CWLSurface m_sWLSurface;
+
+ private:
+ // T1 owners, each popup has to have one of these
+ CWindow* m_pWindowOwner = nullptr;
+ SLayerSurface* m_pLayerOwner = nullptr;
+
+ // T2 owners
+ CPopup* m_pParent = nullptr;
+
+ wlr_xdg_popup* m_pWLR = nullptr;
+
+ Vector2D m_vLastSize = {};
+ Vector2D m_vLastPos = {};
+
+ bool m_bRequestedReposition = false;
+
+ bool m_bInert = false;
+
+ //
+ std::vector<std::unique_ptr<CPopup>> m_vChildren;
+ std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
+
+ // signals
+ DYNLISTENER(newPopup);
+ DYNLISTENER(destroyPopup);
+ DYNLISTENER(mapPopup);
+ DYNLISTENER(unmapPopup);
+ DYNLISTENER(commitPopup);
+ DYNLISTENER(repositionPopup);
+
+ void initAllSignals();
+ void unconstrain();
+ void recheckChildrenRecursive();
+
+ Vector2D localToGlobal(const Vector2D& rel);
+ Vector2D t1ParentCoords();
+}; \ No newline at end of file
diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp
index 0923e9cc..dde8d532 100644
--- a/src/desktop/Subsurface.cpp
+++ b/src/desktop/Subsurface.cpp
@@ -16,12 +16,30 @@ CSubsurface::CSubsurface(CWindow* pOwner) : m_pWindowParent(pOwner) {
}
}
+CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
+ initSignals();
+
+ wlr_subsurface* wlrSubsurface;
+ wl_list_for_each(wlrSubsurface, &pOwner->m_sWLSurface.wlr()->current.subsurfaces_below, current.link) {
+ ::onNewSubsurface(this, wlrSubsurface);
+ }
+ wl_list_for_each(wlrSubsurface, &pOwner->m_sWLSurface.wlr()->current.subsurfaces_above, current.link) {
+ ::onNewSubsurface(this, wlrSubsurface);
+ }
+}
+
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
m_sWLSurface.assign(pSubsurface->surface);
initSignals();
initExistingSubsurfaces();
}
+CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
+ m_sWLSurface.assign(pSubsurface->surface);
+ initSignals();
+ initExistingSubsurfaces();
+}
+
CSubsurface::~CSubsurface() {
hyprListener_newSubsurface.removeCallback();
@@ -30,11 +48,6 @@ CSubsurface::~CSubsurface() {
hyprListener_commitSubsurface.removeCallback();
hyprListener_destroySubsurface.removeCallback();
-
- const auto COORDS = coordsGlobal();
-
- CBox box = {COORDS, m_vLastSize};
- g_pHyprRenderer->damageBox(&box);
}
static void onNewSubsurface(void* owner, void* data) {
@@ -68,10 +81,12 @@ void CSubsurface::initSignals() {
hyprListener_destroySubsurface.initCallback(&m_pSubsurface->events.destroy, &onDestroySubsurface, this, "CSubsurface");
hyprListener_newSubsurface.initCallback(&m_pSubsurface->surface->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface");
hyprListener_mapSubsurface.initCallback(&m_pSubsurface->surface->events.map, &onMapSubsurface, this, "CSubsurface");
- hyprListener_newSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface");
+ hyprListener_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface");
} else {
if (m_pWindowParent)
- hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface");
+ hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
+ else if (m_pPopupParent)
+ hyprListener_newSubsurface.initCallback(&m_pPopupParent->m_sWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
else
RASSERT(false, "CSubsurface::initSignals empty subsurface");
}
@@ -93,11 +108,9 @@ void CSubsurface::checkSiblingDamage() {
}
void CSubsurface::recheckDamageForSubsurfaces() {
- const double SCALE = m_pWindowParent && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
-
for (auto& n : m_vChildren) {
const auto COORDS = n->coordsGlobal();
- g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y, SCALE);
+ g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y);
}
}
@@ -112,11 +125,14 @@ void CSubsurface::onCommit() {
return;
}
- const auto COORDS = coordsGlobal();
+ const auto COORDS = coordsGlobal();
- const double SCALE = m_pWindowParent && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
+ g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
- g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y, SCALE);
+ if (m_pPopupParent)
+ m_pPopupParent->recheckTree();
+ if (m_pWindowParent) // I hate you firefox why are you doing this
+ m_pWindowParent->m_pPopupHead->recheckTree();
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
checkSiblingDamage();
@@ -130,9 +146,6 @@ void CSubsurface::onCommit() {
}
if (m_pWindowParent) {
- if (m_pWindowParent->m_bIsX11)
- m_pWindowParent->m_vReportedSize = m_pWindowParent->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged.
-
// tearing: if solitary, redraw it. This still might be a single surface window
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_pWindowParent->m_iMonitorID);
if (PMONITOR && PMONITOR->solitaryClient == m_pWindowParent && m_pWindowParent->canBeTorn() && PMONITOR->tearingState.canTear &&
@@ -155,6 +168,8 @@ void CSubsurface::onDestroy() {
// destroy children
m_vChildren.clear();
+ m_bInert = true;
+
if (!m_pSubsurface)
return; // dummy node, nothing to do, it's the parent dying
@@ -167,6 +182,8 @@ void CSubsurface::onNewSubsurface(wlr_subsurface* pSubsurface) {
if (m_pWindowParent)
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent)).get();
+ else if (m_pPopupParent)
+ PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
PSUBSURFACE->m_pParent = this;
ASSERT(PSUBSURFACE);
@@ -220,6 +237,8 @@ Vector2D CSubsurface::coordsGlobal() {
if (m_pWindowParent)
coords += m_pWindowParent->m_vRealPosition.vec();
+ else if (m_pPopupParent)
+ coords += m_pPopupParent->coordsGlobal();
return coords;
}
diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp
index 22692192..a8babd70 100644
--- a/src/desktop/Subsurface.hpp
+++ b/src/desktop/Subsurface.hpp
@@ -5,15 +5,17 @@
#include "WLSurface.hpp"
class CWindow;
-struct SXDGPopup;
+class CPopup;
class CSubsurface {
public:
// root dummy nodes
CSubsurface(CWindow* pOwner);
+ CSubsurface(CPopup* pOwner);
// real nodes
CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner);
+ CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner);
~CSubsurface();
@@ -29,7 +31,6 @@ class CSubsurface {
void recheckDamageForSubsurfaces();
private:
-
DYNLISTENER(destroySubsurface);
DYNLISTENER(commitSubsurface);
DYNLISTENER(newSubsurface);
@@ -44,9 +45,12 @@ class CSubsurface {
CSubsurface* m_pParent = nullptr;
CWindow* m_pWindowParent = nullptr;
+ CPopup* m_pPopupParent = nullptr;
std::vector<std::unique_ptr<CSubsurface>> m_vChildren;
+ bool m_bInert = false;
+
void initSignals();
void initExistingSubsurfaces();
void checkSiblingDamage();
diff --git a/src/events/Events.hpp b/src/events/Events.hpp
index 980142a0..69faf6c1 100644
--- a/src/events/Events.hpp
+++ b/src/events/Events.hpp
@@ -22,17 +22,6 @@ namespace Events {
DYNLISTENFUNC(unmapLayerSurface);
DYNLISTENFUNC(commitLayerSurface);
- // Popups
- DYNLISTENFUNC(newPopup); // LayerSurface
-
- DYNLISTENFUNC(newPopupXDG);
- DYNLISTENFUNC(mapPopupXDG);
- DYNLISTENFUNC(unmapPopupXDG);
- DYNLISTENFUNC(destroyPopupXDG);
- DYNLISTENFUNC(commitPopupXDG);
- DYNLISTENFUNC(newPopupFromPopupXDG);
- DYNLISTENFUNC(repositionPopupXDG);
-
// Surface XDG (window)
LISTENER(newXDGToplevel);
LISTENER(activateXDG);
diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp
index 5e9de8b4..7dbcc7b1 100644
--- a/src/events/Layers.cpp
+++ b/src/events/Layers.cpp
@@ -46,7 +46,6 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
layerSurface->hyprListener_destroyLayerSurface.initCallback(&WLRLAYERSURFACE->events.destroy, &Events::listener_destroyLayerSurface, layerSurface, "layerSurface");
layerSurface->hyprListener_mapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.map, &Events::listener_mapLayerSurface, layerSurface, "layerSurface");
layerSurface->hyprListener_unmapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.unmap, &Events::listener_unmapLayerSurface, layerSurface, "layerSurface");
- layerSurface->hyprListener_newPopup.initCallback(&WLRLAYERSURFACE->events.new_popup, &Events::listener_newPopup, layerSurface, "layerSurface");
layerSurface->layerSurface = WLRLAYERSURFACE;
layerSurface->layer = WLRLAYERSURFACE->current.layer;
@@ -87,7 +86,6 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
layersurface->hyprListener_destroyLayerSurface.removeCallback();
layersurface->hyprListener_mapLayerSurface.removeCallback();
layersurface->hyprListener_unmapLayerSurface.removeCallback();
- layersurface->hyprListener_newPopup.removeCallback();
// rearrange to fix the reserved areas
if (PMONITOR) {
@@ -113,6 +111,8 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
layersurface->keyboardExclusive = layersurface->layerSurface->current.keyboard_interactive;
layersurface->surface = layersurface->layerSurface->surface;
+ layersurface->popupHead = std::make_unique<CPopup>(layersurface);
+
// fix if it changed its mon
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
@@ -184,6 +184,8 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
std::erase(g_pInputManager->m_dExclusiveLSes, layersurface);
+ layersurface->popupHead.reset();
+
if (!g_pInputManager->m_dExclusiveLSes.empty())
g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->layerSurface->surface);
diff --git a/src/events/Popups.cpp b/src/events/Popups.cpp
deleted file mode 100644
index ca1787f5..00000000
--- a/src/events/Popups.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-#include "Events.hpp"
-
-#include "../Compositor.hpp"
-#include "../helpers/WLClasses.hpp"
-#include "../managers/input/InputManager.hpp"
-#include "../render/Renderer.hpp"
-
-// --------------------------------------------- //
-// _____ ____ _____ _ _ _____ _____ //
-// | __ \ / __ \| __ \| | | | __ \ / ____| //
-// | |__) | | | | |__) | | | | |__) | (___ //
-// | ___/| | | | ___/| | | | ___/ \___ \ //
-// | | | |__| | | | |__| | | ____) | //
-// |_| \____/|_| \____/|_| |_____/ //
-// //
-// --------------------------------------------- //
-
-void addPopupGlobalCoords(void* pPopup, int* x, int* y) {
- SXDGPopup* const PPOPUP = (SXDGPopup*)pPopup;
-
- auto curPopup = PPOPUP;
-
- int px = 0;
- int py = 0;
-
- while (true) {
- px += curPopup->popup->current.geometry.x;
- py += curPopup->popup->current.geometry.y;
-
- if (curPopup == PPOPUP && PPOPUP->parentWindow) {
- px -= curPopup->popup->base->current.geometry.x;
- py -= curPopup->popup->base->current.geometry.y;
- }
-
- if (curPopup->popup && !curPopup->parentPopup && !curPopup->parentWindow) {
- const auto EXTENTSSURFACE = pixman_region32_extents(&curPopup->popup->base->surface->input_region);
- px -= EXTENTSSURFACE->x1;
- py -= EXTENTSSURFACE->y1;
- }
-
- if (curPopup->parentPopup) {
- curPopup = curPopup->parentPopup;
- } else {
- break;
- }
- }
-
- px += PPOPUP->lx;
- py += PPOPUP->ly;
-
- *x += px;
- *y += py;
-}
-
-void createNewPopup(wlr_xdg_popup* popup, SXDGPopup* pHyprPopup) {
- pHyprPopup->popup = popup;
-
- pHyprPopup->hyprListener_destroyPopupXDG.initCallback(&popup->events.destroy, &Events::listener_destroyPopupXDG, pHyprPopup, "HyprPopup");
- pHyprPopup->hyprListener_mapPopupXDG.initCallback(&popup->base->surface->events.map, &Events::listener_mapPopupXDG, pHyprPopup, "HyprPopup");
- pHyprPopup->hyprListener_unmapPopupXDG.initCallback(&popup->base->surface->events.unmap, &Events::listener_unmapPopupXDG, pHyprPopup, "HyprPopup");
- pHyprPopup->hyprListener_newPopupFromPopupXDG.initCallback(&popup->base->events.new_popup, &Events::listener_newPopupFromPopupXDG, pHyprPopup, "HyprPopup");
- pHyprPopup->hyprListener_commitPopupXDG.initCallback(&popup->base->surface->events.commit, &Events::listener_commitPopupXDG, pHyprPopup, "HyprPopup");
- pHyprPopup->hyprListener_repositionPopupXDG.initCallback(&popup->events.reposition, &Events::listener_repositionPopupXDG, pHyprPopup, "HyprPopup");
-
- const auto PMONITOR = g_pCompositor->m_pLastMonitor;
-
- CBox box = {PMONITOR->vecPosition.x - pHyprPopup->lx, PMONITOR->vecPosition.y - pHyprPopup->ly, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
-
- wlr_xdg_popup_unconstrain_from_box(popup, box.pWlr());
-
- pHyprPopup->monitor = PMONITOR;
-
- Debug::log(LOG, "Popup: Unconstrained from lx ly: {:j5}, pHyprPopup lx ly: {:.5f} {:.5f}", PMONITOR->vecPosition, (float)pHyprPopup->lx, (float)pHyprPopup->ly);
-}
-
-void Events::listener_newPopup(void* owner, void* data) {
- SLayerSurface* layersurface = (SLayerSurface*)owner;
-
- ASSERT(layersurface);
-
- Debug::log(LOG, "New layer popup created from surface {:x}", (uintptr_t)layersurface);
-
- const auto WLRPOPUP = (wlr_xdg_popup*)data;
-
- const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
-
- const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
-
- PNEWPOPUP->popup = WLRPOPUP;
- PNEWPOPUP->lx = layersurface->position.x;
- PNEWPOPUP->ly = layersurface->position.y;
- PNEWPOPUP->monitor = PMONITOR;
- PNEWPOPUP->parentLS = layersurface;
- createNewPopup(WLRPOPUP, PNEWPOPUP);
-}
-
-void Events::listener_newPopupXDG(void* owner, void* data) {
- CWindow* PWINDOW = (CWindow*)owner;
-
- ASSERT(PWINDOW);
-
- if (!PWINDOW->m_bIsMapped)
- return;
-
- Debug::log(LOG, "New layer popup created from XDG window {}", PWINDOW);
-
- const auto WLRPOPUP = (wlr_xdg_popup*)data;
-
- const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
-
- const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
-
- PNEWPOPUP->popup = WLRPOPUP;
- PNEWPOPUP->lx = PWINDOW->m_vRealPosition.goalv().x;
- PNEWPOPUP->ly = PWINDOW->m_vRealPosition.goalv().y;
- PNEWPOPUP->parentWindow = PWINDOW;
- PNEWPOPUP->monitor = PMONITOR;
- createNewPopup(WLRPOPUP, PNEWPOPUP);
-}
-
-void Events::listener_newPopupFromPopupXDG(void* owner, void* data) {
- SXDGPopup* PPOPUP = (SXDGPopup*)owner;
-
- ASSERT(PPOPUP);
-
- if (PPOPUP->parentWindow)
- Debug::log(LOG, "New popup created from XDG Window popup {:x} -> {}", (uintptr_t)PPOPUP, PPOPUP->parentWindow);
- else
- Debug::log(LOG, "New popup created from Non-Window popup {:x}", (uintptr_t)PPOPUP);
-
- const auto WLRPOPUP = (wlr_xdg_popup*)data;
-
- const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
-
- PNEWPOPUP->popup = WLRPOPUP;
- PNEWPOPUP->parentPopup = PPOPUP;
- PNEWPOPUP->lx = PPOPUP->lx;
- PNEWPOPUP->ly = PPOPUP->ly;
- PNEWPOPUP->parentWindow = PPOPUP->parentWindow;
- PNEWPOPUP->monitor = PPOPUP->monitor;
-
- createNewPopup(WLRPOPUP, PNEWPOPUP);
-}
-
-void Events::listener_mapPopupXDG(void* owner, void* data) {
- SXDGPopup* PPOPUP = (SXDGPopup*)owner;
-
- ASSERT(PPOPUP);
-
- Debug::log(LOG, "New XDG Popup mapped at {} {}", (int)PPOPUP->lx, (int)PPOPUP->ly);
-
- if (PPOPUP->parentWindow)
- PPOPUP->parentWindow->m_lPopupSurfaces.emplace_back(PPOPUP->popup->base->surface);
- else if (PPOPUP->parentLS)
- PPOPUP->parentLS->popupSurfaces.emplace_back(PPOPUP->popup->base->surface);
-
- //PPOPUP->pSurfaceTree = SubsurfaceTree::createTreeRoot(PPOPUP->popup->base->surface, addPopupGlobalCoords, PPOPUP, PPOPUP->parentWindow);
-
- int lx = 0, ly = 0;
- addPopupGlobalCoords(PPOPUP, &lx, &ly);
-
- CBox extents;
- wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
- extents.applyFromWlr();
-
- g_pHyprRenderer->damageBox(lx - extents.x, ly - extents.y, extents.width + 2, extents.height + 2);
-
- if (PPOPUP->monitor) {
- g_pCompositor->setPreferredScaleForSurface(PPOPUP->popup->base->surface, PPOPUP->monitor->scale);
- g_pCompositor->setPreferredTransformForSurface(PPOPUP->popup->base->surface, PPOPUP->monitor->transform);
- }
-
- // Debug::log(LOG, "XDG Popup got assigned a surfaceTreeNode {:x}", (uintptr_t)PPOPUP->pSurfaceTree);
-}
-
-void Events::listener_repositionPopupXDG(void* owner, void* data) {
- SXDGPopup* PPOPUP = (SXDGPopup*)owner;
-
- Debug::log(LOG, "XDG Popup {:x} asks for a reposition", (uintptr_t)PPOPUP);
-
- int lx = 0, ly = 0;
- addPopupGlobalCoords(PPOPUP, &lx, &ly);
-
- CBox extents;
- wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
- extents.applyFromWlr();
-
- PPOPUP->lastPos = {lx - extents.x, ly - extents.y};
- PPOPUP->repositionRequested = true;
-
- const auto PMONITOR = g_pCompositor->m_pLastMonitor;
-
- CBox box = {PMONITOR->vecPosition.x - lx + PPOPUP->popup->current.geometry.x, PMONITOR->vecPosition.y - ly + PPOPUP->popup->current.geometry.y, PMONITOR->vecSize.x,
- PMONITOR->vecSize.y};
- wlr_xdg_popup_unconstrain_from_box(PPOPUP->popup, box.pWlr());
-}
-
-void Events::listener_unmapPopupXDG(void* owner, void* data) {
- SXDGPopup* PPOPUP = (SXDGPopup*)owner;
- Debug::log(LOG, "XDG Popup unmapped");
-
- ASSERT(PPOPUP);
-
- if (PPOPUP->popup->base->surface == g_pCompositor->m_pLastFocus)
- g_pInputManager->releaseAllMouseButtons();
-
- // SubsurfaceTree::destroySurfaceTree(PPOPUP->pSurfaceTree);
-
- int lx = 0, ly = 0;
- addPopupGlobalCoords(PPOPUP, &lx, &ly);
-
- CBox extents;
- wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
- extents.applyFromWlr();
-
- g_pHyprRenderer->damageBox(lx - extents.x, ly - extents.y, extents.width + 2, extents.height + 2);
-
- if (PPOPUP->parentWindow)
- std::erase(PPOPUP->parentWindow->m_lPopupSurfaces, PPOPUP->popup->base->surface);
- else if (PPOPUP->parentLS)
- std::erase(PPOPUP->parentLS->popupSurfaces, PPOPUP->popup->base->surface);
-
- // PPOPUP->pSurfaceTree = nullptr;
-
- g_pInputManager->simulateMouseMovement(); // to focus and return back to an appropriate surface
-}
-
-void Events::listener_commitPopupXDG(void* owner, void* data) {
- SXDGPopup* PPOPUP = (SXDGPopup*)owner;
-
- if (PPOPUP->popup->base->initial_commit) {
- wlr_xdg_surface_schedule_configure(PPOPUP->popup->base);
- return;
- }
-
- if (g_pCompositor->windowValidMapped(PPOPUP->parentWindow)) {
- PPOPUP->lx = PPOPUP->parentWindow->m_vRealPosition.vec().x;
- PPOPUP->ly = PPOPUP->parentWindow->m_vRealPosition.vec().y;
- }
-
- int lx = 0, ly = 0;
- addPopupGlobalCoords(PPOPUP, &lx, &ly);
-
- CBox extents;
- wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
- extents.applyFromWlr();
-
- if (PPOPUP->repositionRequested)
- g_pHyprRenderer->damageBox(PPOPUP->lastPos.x, PPOPUP->lastPos.y, extents.width + 2, extents.height + 2);
-
- PPOPUP->repositionRequested = false;
-
- g_pHyprRenderer->damageSurface(PPOPUP->popup->base->surface, lx, ly);
-}
-
-void Events::listener_destroyPopupXDG(void* owner, void* data) {
- SXDGPopup* PPOPUP = (SXDGPopup*)owner;
-
- ASSERT(PPOPUP);
-
- Debug::log(LOG, "Destroyed popup XDG {:x}", (uintptr_t)PPOPUP);
-
- // if (PPOPUP->pSurfaceTree) {
- // SubsurfaceTree::destroySurfaceTree(PPOPUP->pSurfaceTree);
- // PPOPUP->pSurfaceTree = nullptr;
- // }
-
- std::erase_if(g_pCompositor->m_vXDGPopups, [&](std::unique_ptr<SXDGPopup>& el) { return el.get() == PPOPUP; });
-}
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index 162415b4..34a34cbd 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -488,7 +488,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (!PWINDOW->m_bIsX11) {
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XDG Window Late");
- PWINDOW->hyprListener_newPopupXDG.initCallback(&PWINDOW->m_uSurface.xdg->events.new_popup, &Events::listener_newPopupXDG, PWINDOW, "XDG Window Late");
PWINDOW->hyprListener_requestMaximize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_maximize, &Events::listener_requestMaximize, PWINDOW,
"XDG Window Late");
PWINDOW->hyprListener_requestMinimize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_minimize, &Events::listener_requestMinimize, PWINDOW,
@@ -681,7 +680,6 @@ void Events::listener_unmapWindow(void* owner, void* data) {
if (!PWINDOW->m_bIsX11) {
Debug::log(LOG, "Unregistered late callbacks XDG");
PWINDOW->hyprListener_setTitleWindow.removeCallback();
- PWINDOW->hyprListener_newPopupXDG.removeCallback();
PWINDOW->hyprListener_requestMaximize.removeCallback();
PWINDOW->hyprListener_requestMinimize.removeCallback();
PWINDOW->hyprListener_requestMove.removeCallback();
@@ -833,7 +831,10 @@ void Events::listener_commitWindow(void* owner, void* data) {
g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y,
PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
- PWINDOW->m_pSubsurfaceHead->recheckDamageForSubsurfaces();
+ if (!PWINDOW->m_bIsX11) {
+ PWINDOW->m_pSubsurfaceHead->recheckDamageForSubsurfaces();
+ PWINDOW->m_pPopupHead->recheckTree();
+ }
if (PWINDOW->m_bIsX11 || !PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen)
return;
diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp
index e536c3d2..624625af 100644
--- a/src/helpers/WLClasses.hpp
+++ b/src/helpers/WLClasses.hpp
@@ -5,6 +5,7 @@
#include "wlr-layer-shell-unstable-v1-protocol.h"
#include "../Window.hpp"
#include "../desktop/Subsurface.hpp"
+#include "../desktop/Popup.hpp"
#include "AnimatedVariable.hpp"
#include "../desktop/WLSurface.hpp"
#include "Region.hpp"
@@ -31,13 +32,14 @@ struct SLayerSurface {
bool keyboardExclusive = false;
CWLSurface surface;
- std::list<CWLSurface> popupSurfaces;
+
+ // desktop components
+ std::unique_ptr<CPopup> popupHead;
DYNLISTENER(destroyLayerSurface);
DYNLISTENER(mapLayerSurface);
DYNLISTENER(unmapLayerSurface);
DYNLISTENER(commitLayerSurface);
- DYNLISTENER(newPopup);
CBox geometry = {0, 0, 0, 0};
Vector2D position;
@@ -199,32 +201,6 @@ struct SConstraint {
class CMonitor;
-struct SXDGPopup {
- CWindow* parentWindow = nullptr;
- SLayerSurface* parentLS = nullptr;
- SXDGPopup* parentPopup = nullptr;
- wlr_xdg_popup* popup = nullptr;
- CMonitor* monitor = nullptr;
-
- DYNLISTENER(newPopupFromPopupXDG);
- DYNLISTENER(destroyPopupXDG);
- DYNLISTENER(mapPopupXDG);
- DYNLISTENER(unmapPopupXDG);
- DYNLISTENER(commitPopupXDG);
- DYNLISTENER(repositionPopupXDG);
-
- double lx;
- double ly;
-
- Vector2D lastPos = {};
- bool repositionRequested = false;
-
- // For the list lookup
- bool operator==(const SXDGPopup& rhs) const {
- return popup == rhs.popup;
- }
-};
-
struct SSeat {
wlr_seat* seat = nullptr;
wl_client* exclusiveClient = nullptr;