wayland/core: move to new impl (#6268)
* wayland/core/dmabuf: move to new impl it's the final countdown
This commit is contained in:
parent
c31d9ef417
commit
6967a31450
147 changed files with 5388 additions and 2226 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#include "../Compositor.hpp"
|
||||
#include "../events/Events.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
|
||||
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
|
|
@ -9,6 +10,8 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
|||
|
||||
CMonitor* pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
|
||||
|
||||
pLS->surface->assign(resource->surface.lock(), pLS);
|
||||
|
||||
if (!pMonitor) {
|
||||
Debug::log(ERR, "New LS has no monitor??");
|
||||
return pLS;
|
||||
|
|
@ -39,8 +42,6 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
|||
|
||||
pLS->alpha.setValueAndWarp(0.f);
|
||||
|
||||
pLS->surface.assign(resource->surface, pLS);
|
||||
|
||||
Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)resource.get(), resource->layerNamespace, (int)pLS->layer, pMonitor->szName);
|
||||
|
||||
return pLS;
|
||||
|
|
@ -58,13 +59,16 @@ CLayerSurface::CLayerSurface(SP<CLayerShellResource> resource_) : layerSurface(r
|
|||
listeners.map = layerSurface->events.map.registerListener([this](std::any d) { onMap(); });
|
||||
listeners.unmap = layerSurface->events.unmap.registerListener([this](std::any d) { onUnmap(); });
|
||||
listeners.destroy = layerSurface->events.destroy.registerListener([this](std::any d) { onDestroy(); });
|
||||
|
||||
surface = CWLSurface::create();
|
||||
}
|
||||
|
||||
CLayerSurface::~CLayerSurface() {
|
||||
if (!g_pHyprOpenGL)
|
||||
return;
|
||||
|
||||
surface.unassign();
|
||||
if (surface)
|
||||
surface->unassign();
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); });
|
||||
}
|
||||
|
|
@ -105,7 +109,8 @@ void CLayerSurface::onDestroy() {
|
|||
|
||||
readyToDelete = true;
|
||||
layerSurface.reset();
|
||||
surface.unassign();
|
||||
if (surface)
|
||||
surface->unassign();
|
||||
}
|
||||
|
||||
void CLayerSurface::onMap() {
|
||||
|
|
@ -126,7 +131,7 @@ void CLayerSurface::onMap() {
|
|||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
|
||||
wlr_surface_send_enter(surface.wlr(), PMONITOR->output);
|
||||
surface->resource()->enter(PMONITOR->self.lock());
|
||||
|
||||
if (layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
|
||||
g_pInputManager->m_dExclusiveLSes.push_back(self);
|
||||
|
|
@ -139,10 +144,10 @@ void CLayerSurface::onMap() {
|
|||
// TODO: use the new superb really very cool grab
|
||||
g_pSeatManager->setGrab(nullptr);
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
g_pCompositor->focusSurface(surface.wlr());
|
||||
g_pCompositor->focusSurface(surface->resource());
|
||||
|
||||
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y);
|
||||
g_pSeatManager->setPointerFocus(surface.wlr(), LOCAL);
|
||||
g_pSeatManager->setPointerFocus(surface->resource(), LOCAL);
|
||||
g_pInputManager->m_bEmptyFocusCursorSet = false;
|
||||
}
|
||||
|
||||
|
|
@ -160,8 +165,8 @@ void CLayerSurface::onMap() {
|
|||
g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", szNamespace});
|
||||
EMIT_HOOK_EVENT("openLayer", self.lock());
|
||||
|
||||
g_pCompositor->setPreferredScaleForSurface(surface.wlr(), PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(surface.wlr(), PMONITOR->transform);
|
||||
g_pCompositor->setPreferredScaleForSurface(surface->resource(), PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(surface->resource(), PMONITOR->transform);
|
||||
}
|
||||
|
||||
void CLayerSurface::onUnmap() {
|
||||
|
|
@ -173,7 +178,7 @@ void CLayerSurface::onUnmap() {
|
|||
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
||||
|
||||
if (!g_pInputManager->m_dExclusiveLSes.empty())
|
||||
g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->layerSurface->surface);
|
||||
g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->surface->resource());
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
|
||||
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||
|
|
@ -197,9 +202,9 @@ void CLayerSurface::onUnmap() {
|
|||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
|
||||
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == layerSurface->surface;
|
||||
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
|
||||
|
||||
surface = nullptr;
|
||||
surface.reset();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
|
@ -208,11 +213,11 @@ void CLayerSurface::onUnmap() {
|
|||
if (WASLASTFOCUS) {
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
|
||||
Vector2D surfaceCoords;
|
||||
PHLLS pFoundLayerSurface;
|
||||
wlr_surface* foundSurface = nullptr;
|
||||
Vector2D surfaceCoords;
|
||||
PHLLS pFoundLayerSurface;
|
||||
SP<CWLSurfaceResource> foundSurface = nullptr;
|
||||
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
g_pCompositor->m_pLastFocus.reset();
|
||||
|
||||
// find LS-es to focus
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
|
||||
|
|
@ -236,8 +241,8 @@ void CLayerSurface::onUnmap() {
|
|||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.width,
|
||||
(int)layerSurface->surface->current.height};
|
||||
geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.size.x,
|
||||
(int)layerSurface->surface->current.size.y};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
g_pInputManager->sendMotionEventsToFocused();
|
||||
|
|
@ -284,12 +289,12 @@ void CLayerSurface::onCommit() {
|
|||
position = Vector2D(geometry.x, geometry.y);
|
||||
|
||||
// update geom if it changed
|
||||
if (layerSurface->surface->current.scale == 1 && PMONITOR->scale != 1.f && layerSurface->surface->current.viewport.has_dst) {
|
||||
if (layerSurface->surface->current.scale == 1 && PMONITOR->scale != 1.f && layerSurface->surface->current.viewport.hasDestination) {
|
||||
// fractional scaling. Dirty hack.
|
||||
geometry = {geometry.x, geometry.y, (int)(layerSurface->surface->current.viewport.dst_width), (int)(layerSurface->surface->current.viewport.dst_height)};
|
||||
geometry = {geometry.pos(), layerSurface->surface->current.viewport.destination};
|
||||
} else {
|
||||
// this is because some apps like e.g. rofi-lbonn can't fucking use the protocol correctly.
|
||||
geometry = {geometry.x, geometry.y, (int)layerSurface->surface->current.width, (int)layerSurface->surface->current.height};
|
||||
geometry = {geometry.pos(), layerSurface->surface->current.size};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,10 +313,10 @@ void CLayerSurface::onCommit() {
|
|||
|
||||
if (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained
|
||||
&& !keyboardExclusive && mapped) {
|
||||
g_pCompositor->focusSurface(layerSurface->surface);
|
||||
g_pCompositor->focusSurface(surface->resource());
|
||||
|
||||
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y);
|
||||
g_pSeatManager->setPointerFocus(layerSurface->surface, LOCAL);
|
||||
g_pSeatManager->setPointerFocus(surface->resource(), LOCAL);
|
||||
g_pInputManager->m_bEmptyFocusCursorSet = false;
|
||||
} else if (!layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) {
|
||||
g_pInputManager->refocus();
|
||||
|
|
@ -319,10 +324,10 @@ void CLayerSurface::onCommit() {
|
|||
|
||||
keyboardExclusive = layerSurface->current.interactivity;
|
||||
|
||||
g_pHyprRenderer->damageSurface(layerSurface->surface, position.x, position.y);
|
||||
g_pHyprRenderer->damageSurface(surface->resource(), position.x, position.y);
|
||||
|
||||
g_pCompositor->setPreferredScaleForSurface(layerSurface->surface, PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(layerSurface->surface, PMONITOR->transform);
|
||||
g_pCompositor->setPreferredScaleForSurface(surface->resource(), PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(surface->resource(), PMONITOR->transform);
|
||||
}
|
||||
|
||||
void CLayerSurface::applyRules() {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class CLayerSurface {
|
|||
|
||||
bool keyboardExclusive = false;
|
||||
|
||||
CWLSurface surface;
|
||||
SP<CWLSurface> surface;
|
||||
|
||||
bool mapped = false;
|
||||
uint32_t layer = 0;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../Compositor.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include <ranges>
|
||||
|
||||
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
|
||||
|
|
@ -14,7 +15,8 @@ CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) {
|
|||
}
|
||||
|
||||
CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pParent(pOwner), m_pResource(popup) {
|
||||
m_sWLSurface.assign(popup->surface->surface, this);
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
m_pWLSurface->assign(popup->surface->surface.lock(), this);
|
||||
|
||||
m_pLayerOwner = pOwner->m_pLayerOwner;
|
||||
m_pWindowOwner = pOwner->m_pWindowOwner;
|
||||
|
|
@ -26,7 +28,8 @@ CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pParent(pOwner),
|
|||
}
|
||||
|
||||
CPopup::~CPopup() {
|
||||
m_sWLSurface.unassign();
|
||||
if (m_pWLSurface)
|
||||
m_pWLSurface->unassign();
|
||||
}
|
||||
|
||||
void CPopup::initAllSignals() {
|
||||
|
|
@ -69,14 +72,14 @@ void CPopup::onMap() {
|
|||
if (m_bMapped)
|
||||
return;
|
||||
|
||||
m_bMapped = true;
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
m_bMapped = true;
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
|
||||
const auto COORDS = coordsGlobal();
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(COORDS);
|
||||
|
||||
CBox box;
|
||||
wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr());
|
||||
box.applyFromWlr().translate(COORDS).expand(4);
|
||||
CBox box = m_pWLSurface->resource()->extends();
|
||||
box.translate(COORDS).expand(4);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
m_vLastPos = coordsRelativeToParent();
|
||||
|
|
@ -87,7 +90,7 @@ void CPopup::onMap() {
|
|||
|
||||
//unconstrain();
|
||||
sendScale();
|
||||
wlr_surface_send_enter(m_pResource->surface->surface, PMONITOR->output);
|
||||
m_pResource->surface->surface->enter(PMONITOR->self.lock());
|
||||
|
||||
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
|
||||
|
|
@ -103,12 +106,12 @@ void CPopup::onUnmap() {
|
|||
return;
|
||||
}
|
||||
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
|
||||
const auto COORDS = coordsGlobal();
|
||||
|
||||
CBox box;
|
||||
wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr());
|
||||
box.applyFromWlr().translate(COORDS).expand(4);
|
||||
CBox box = m_pWLSurface->resource()->extends();
|
||||
box.translate(COORDS).expand(4);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
m_pSubsurfaceHead.reset();
|
||||
|
|
@ -143,7 +146,7 @@ void CPopup::onCommit(bool ignoreSiblings) {
|
|||
}
|
||||
|
||||
if (!m_pWindowOwner.expired() && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) {
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
|
||||
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
|
||||
if (*PLOGDAMAGE)
|
||||
|
|
@ -157,11 +160,10 @@ void CPopup::onCommit(bool ignoreSiblings) {
|
|||
const auto COORDS = coordsGlobal();
|
||||
const auto COORDSLOCAL = coordsRelativeToParent();
|
||||
|
||||
if (m_vLastSize != Vector2D{m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height} || m_bRequestedReposition ||
|
||||
m_vLastPos != COORDSLOCAL) {
|
||||
if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
|
||||
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
box = {COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
|
|
@ -171,7 +173,7 @@ void CPopup::onCommit(bool ignoreSiblings) {
|
|||
if (!ignoreSiblings && m_pSubsurfaceHead)
|
||||
m_pSubsurfaceHead->recheckDamageForSubsurfaces();
|
||||
|
||||
g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
|
||||
g_pHyprRenderer->damageSurface(m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
||||
|
||||
m_bRequestedReposition = false;
|
||||
|
||||
|
|
@ -211,7 +213,7 @@ Vector2D CPopup::coordsRelativeToParent() {
|
|||
|
||||
while (current->m_pParent && current->m_pResource) {
|
||||
|
||||
offset += {current->m_sWLSurface.wlr()->current.dx, current->m_sWLSurface.wlr()->current.dy};
|
||||
offset += current->m_pWLSurface->resource()->current.offset;
|
||||
offset += current->m_pResource->geometry.pos();
|
||||
|
||||
current = current->m_pParent;
|
||||
|
|
@ -260,9 +262,9 @@ Vector2D CPopup::size() {
|
|||
|
||||
void CPopup::sendScale() {
|
||||
if (!m_pWindowOwner.expired())
|
||||
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner->m_pWLSurface.m_fLastScale);
|
||||
g_pCompositor->setPreferredScaleForSurface(m_pWLSurface->resource(), m_pWindowOwner->m_pWLSurface->m_fLastScale);
|
||||
else if (!m_pLayerOwner.expired())
|
||||
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner->surface.m_fLastScale);
|
||||
g_pCompositor->setPreferredScaleForSurface(m_pWLSurface->resource(), m_pLayerOwner->surface->m_fLastScale);
|
||||
else
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
@ -318,9 +320,8 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
|||
return p;
|
||||
} else {
|
||||
const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{};
|
||||
const auto REGION = CRegion{&p->m_sWLSurface.wlr()->current.input}
|
||||
.intersect(CBox{{}, {p->m_sWLSurface.wlr()->current.width, p->m_sWLSurface.wlr()->current.height}})
|
||||
.translate(p->coordsGlobal() + offset);
|
||||
const auto REGION =
|
||||
CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset);
|
||||
if (REGION.containsPoint(globalCoords))
|
||||
return p;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class CPopup {
|
|||
CPopup* at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||
|
||||
//
|
||||
CWLSurface m_sWLSurface;
|
||||
SP<CWLSurface> m_pWLSurface;
|
||||
|
||||
private:
|
||||
// T1 owners, each popup has to have one of these
|
||||
|
|
|
|||
|
|
@ -2,29 +2,31 @@
|
|||
#include "../events/Events.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
|
||||
static void onNewSubsurface(void* owner, void* data);
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/core/Subcompositor.hpp"
|
||||
|
||||
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) {
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pOwner->m_pWLSurface.wlr());
|
||||
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pOwner->m_sWLSurface.wlr());
|
||||
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
|
||||
m_sWLSurface.assign(pSubsurface->surface, this);
|
||||
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pSubsurface->surface);
|
||||
initExistingSubsurfaces(pSubsurface->surface.lock());
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
|
||||
m_sWLSurface.assign(pSubsurface->surface, this);
|
||||
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pSubsurface->surface);
|
||||
initExistingSubsurfaces(pSubsurface->surface.lock());
|
||||
}
|
||||
|
||||
CSubsurface::~CSubsurface() {
|
||||
|
|
@ -33,52 +35,27 @@ CSubsurface::~CSubsurface() {
|
|||
if (!m_pSubsurface)
|
||||
return;
|
||||
|
||||
m_pSubsurface->data = nullptr;
|
||||
|
||||
hyprListener_commitSubsurface.removeCallback();
|
||||
hyprListener_destroySubsurface.removeCallback();
|
||||
}
|
||||
|
||||
static void onNewSubsurface(void* owner, void* data) {
|
||||
const auto PSUBSURFACE = (CSubsurface*)owner;
|
||||
PSUBSURFACE->onNewSubsurface((wlr_subsurface*)data);
|
||||
}
|
||||
|
||||
static void onDestroySubsurface(void* owner, void* data) {
|
||||
const auto PSUBSURFACE = (CSubsurface*)owner;
|
||||
PSUBSURFACE->onDestroy();
|
||||
}
|
||||
|
||||
static void onCommitSubsurface(void* owner, void* data) {
|
||||
const auto PSUBSURFACE = (CSubsurface*)owner;
|
||||
PSUBSURFACE->onCommit();
|
||||
}
|
||||
|
||||
static void onMapSubsurface(void* owner, void* data) {
|
||||
const auto PSUBSURFACE = (CSubsurface*)owner;
|
||||
PSUBSURFACE->onMap();
|
||||
}
|
||||
|
||||
static void onUnmapSubsurface(void* owner, void* data) {
|
||||
const auto PSUBSURFACE = (CSubsurface*)owner;
|
||||
PSUBSURFACE->onUnmap();
|
||||
}
|
||||
|
||||
void CSubsurface::initSignals() {
|
||||
if (m_pSubsurface) {
|
||||
m_pSubsurface->data = this;
|
||||
hyprListener_commitSubsurface.initCallback(&m_pSubsurface->surface->events.commit, &onCommitSubsurface, this, "CSubsurface");
|
||||
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_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface");
|
||||
listeners.commitSubsurface = m_pSubsurface->surface->events.commit.registerListener([this](std::any d) { onCommit(); });
|
||||
listeners.destroySubsurface = m_pSubsurface->events.destroy.registerListener([this](std::any d) { onDestroy(); });
|
||||
listeners.mapSubsurface = m_pSubsurface->surface->events.map.registerListener([this](std::any d) { onMap(); });
|
||||
listeners.unmapSubsurface = m_pSubsurface->surface->events.unmap.registerListener([this](std::any d) { onUnmap(); });
|
||||
listeners.newSubsurface =
|
||||
m_pSubsurface->surface->events.newSubsurface.registerListener([this](std::any d) { onNewSubsurface(std::any_cast<SP<CWLSubsurfaceResource>>(d)); });
|
||||
} else {
|
||||
if (!m_pWindowParent.expired())
|
||||
hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
|
||||
if (m_pWindowParent)
|
||||
listeners.newSubsurface = m_pWindowParent->m_pWLSurface->resource()->events.newSubsurface.registerListener(
|
||||
[this](std::any d) { onNewSubsurface(std::any_cast<SP<CWLSubsurfaceResource>>(d)); });
|
||||
else if (m_pPopupParent)
|
||||
hyprListener_newSubsurface.initCallback(&m_pPopupParent->m_sWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
|
||||
listeners.newSubsurface = m_pPopupParent->m_pWLSurface->resource()->events.newSubsurface.registerListener(
|
||||
[this](std::any d) { onNewSubsurface(std::any_cast<SP<CWLSubsurfaceResource>>(d)); });
|
||||
else
|
||||
RASSERT(false, "CSubsurface::initSignals empty subsurface");
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,21 +70,21 @@ void CSubsurface::checkSiblingDamage() {
|
|||
continue;
|
||||
|
||||
const auto COORDS = n->coordsGlobal();
|
||||
g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y, SCALE);
|
||||
g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y, SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
void CSubsurface::recheckDamageForSubsurfaces() {
|
||||
for (auto& n : m_vChildren) {
|
||||
const auto COORDS = n->coordsGlobal();
|
||||
g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y);
|
||||
g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
||||
}
|
||||
}
|
||||
|
||||
void CSubsurface::onCommit() {
|
||||
// no damaging if it's not visible
|
||||
if (!m_pWindowParent.expired() && (!m_pWindowParent->m_bIsMapped || !m_pWindowParent->m_pWorkspace->m_bVisible)) {
|
||||
m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
|
||||
m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||
|
||||
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
|
||||
if (*PLOGDAMAGE)
|
||||
|
|
@ -117,7 +94,7 @@ void CSubsurface::onCommit() {
|
|||
|
||||
const auto COORDS = coordsGlobal();
|
||||
|
||||
g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
|
||||
g_pHyprRenderer->damageSurface(m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
||||
|
||||
if (m_pPopupParent)
|
||||
m_pPopupParent->recheckTree();
|
||||
|
|
@ -127,10 +104,10 @@ void CSubsurface::onCommit() {
|
|||
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
|
||||
checkSiblingDamage();
|
||||
|
||||
if (m_vLastSize != Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}) {
|
||||
if (m_vLastSize != m_pWLSurface->resource()->current.size) {
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
|
||||
m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||
box = {COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
}
|
||||
|
|
@ -149,20 +126,21 @@ void CSubsurface::onDestroy() {
|
|||
std::erase_if(m_pParent->m_vChildren, [this](const auto& other) { return other.get() == this; });
|
||||
}
|
||||
|
||||
void CSubsurface::onNewSubsurface(wlr_subsurface* pSubsurface) {
|
||||
void CSubsurface::onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface) {
|
||||
CSubsurface* PSUBSURFACE = nullptr;
|
||||
|
||||
if (!m_pWindowParent.expired())
|
||||
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get();
|
||||
else if (m_pPopupParent)
|
||||
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
|
||||
PSUBSURFACE->m_pParent = this;
|
||||
|
||||
ASSERT(PSUBSURFACE);
|
||||
|
||||
PSUBSURFACE->m_pParent = this;
|
||||
}
|
||||
|
||||
void CSubsurface::onMap() {
|
||||
m_vLastSize = {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
|
||||
m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||
|
||||
const auto COORDS = coordsGlobal();
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
|
|
@ -179,7 +157,7 @@ void CSubsurface::onUnmap() {
|
|||
box.expand(4);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
if (m_sWLSurface.wlr() == g_pCompositor->m_pLastFocus)
|
||||
if (m_pWLSurface->resource() == g_pCompositor->m_pLastFocus)
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
|
|
@ -188,19 +166,9 @@ void CSubsurface::onUnmap() {
|
|||
}
|
||||
|
||||
Vector2D CSubsurface::coordsRelativeToParent() {
|
||||
Vector2D offset;
|
||||
|
||||
CSubsurface* current = this;
|
||||
|
||||
while (current->m_pParent) {
|
||||
|
||||
offset += {current->m_sWLSurface.wlr()->current.dx, current->m_sWLSurface.wlr()->current.dy};
|
||||
offset += {current->m_pSubsurface->current.x, current->m_pSubsurface->current.y};
|
||||
|
||||
current = current->m_pParent;
|
||||
}
|
||||
|
||||
return offset;
|
||||
if (!m_pSubsurface)
|
||||
return {};
|
||||
return m_pSubsurface->posRelativeToParent();
|
||||
}
|
||||
|
||||
Vector2D CSubsurface::coordsGlobal() {
|
||||
|
|
@ -214,18 +182,16 @@ Vector2D CSubsurface::coordsGlobal() {
|
|||
return coords;
|
||||
}
|
||||
|
||||
void CSubsurface::initExistingSubsurfaces(wlr_surface* pSurface) {
|
||||
wlr_subsurface* wlrSubsurface;
|
||||
wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_below, current.link) {
|
||||
::onNewSubsurface(this, wlrSubsurface);
|
||||
}
|
||||
wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_above, current.link) {
|
||||
::onNewSubsurface(this, wlrSubsurface);
|
||||
void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
|
||||
for (auto& s : pSurface->subsurfaces) {
|
||||
if (!s || s->surface->hlSurface /* already assigned */)
|
||||
continue;
|
||||
onNewSubsurface(s.lock());
|
||||
}
|
||||
}
|
||||
|
||||
Vector2D CSubsurface::size() {
|
||||
return {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
|
||||
return m_pWLSurface->resource()->current.size;
|
||||
}
|
||||
|
||||
bool CSubsurface::visible() {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "WLSurface.hpp"
|
||||
|
||||
class CPopup;
|
||||
class CWLSubsurfaceResource;
|
||||
|
||||
class CSubsurface {
|
||||
public:
|
||||
|
|
@ -13,8 +14,8 @@ class CSubsurface {
|
|||
CSubsurface(CPopup* pOwner);
|
||||
|
||||
// real nodes
|
||||
CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner);
|
||||
CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner);
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner);
|
||||
|
||||
~CSubsurface();
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ class CSubsurface {
|
|||
|
||||
void onCommit();
|
||||
void onDestroy();
|
||||
void onNewSubsurface(wlr_subsurface* pSubsurface);
|
||||
void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
|
||||
|
|
@ -37,12 +38,18 @@ class CSubsurface {
|
|||
DYNLISTENER(destroySubsurface);
|
||||
DYNLISTENER(commitSubsurface);
|
||||
DYNLISTENER(newSubsurface);
|
||||
DYNLISTENER(mapSubsurface);
|
||||
DYNLISTENER(unmapSubsurface);
|
||||
|
||||
wlr_subsurface* m_pSubsurface = nullptr;
|
||||
CWLSurface m_sWLSurface;
|
||||
Vector2D m_vLastSize = {};
|
||||
struct {
|
||||
CHyprSignalListener destroySubsurface;
|
||||
CHyprSignalListener commitSubsurface;
|
||||
CHyprSignalListener mapSubsurface;
|
||||
CHyprSignalListener unmapSubsurface;
|
||||
CHyprSignalListener newSubsurface;
|
||||
} listeners;
|
||||
|
||||
WP<CWLSubsurfaceResource> m_pSubsurface;
|
||||
SP<CWLSurface> m_pWLSurface;
|
||||
Vector2D m_vLastSize = {};
|
||||
|
||||
// if nullptr, means it's a dummy node
|
||||
CSubsurface* m_pParent = nullptr;
|
||||
|
|
@ -55,6 +62,6 @@ class CSubsurface {
|
|||
bool m_bInert = false;
|
||||
|
||||
void initSignals();
|
||||
void initExistingSubsurfaces(wlr_surface* pSurface);
|
||||
void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
|
||||
void checkSiblingDamage();
|
||||
};
|
||||
|
|
@ -1,36 +1,37 @@
|
|||
#include "WLSurface.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
|
||||
void CWLSurface::assign(wlr_surface* pSurface) {
|
||||
m_pWLRSurface = pSurface;
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
|
||||
m_pResource = pSurface;
|
||||
init();
|
||||
m_bInert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(wlr_surface* pSurface, PHLWINDOW pOwner) {
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, PHLWINDOW pOwner) {
|
||||
m_pWindowOwner = pOwner;
|
||||
m_pWLRSurface = pSurface;
|
||||
m_pResource = pSurface;
|
||||
init();
|
||||
m_bInert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(wlr_surface* pSurface, PHLLS pOwner) {
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, PHLLS pOwner) {
|
||||
m_pLayerOwner = pOwner;
|
||||
m_pWLRSurface = pSurface;
|
||||
m_pResource = pSurface;
|
||||
init();
|
||||
m_bInert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(wlr_surface* pSurface, CSubsurface* pOwner) {
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, CSubsurface* pOwner) {
|
||||
m_pSubsurfaceOwner = pOwner;
|
||||
m_pWLRSurface = pSurface;
|
||||
m_pResource = pSurface;
|
||||
init();
|
||||
m_bInert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(wlr_surface* pSurface, CPopup* pOwner) {
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, CPopup* pOwner) {
|
||||
m_pPopupOwner = pOwner;
|
||||
m_pWLRSurface = pSurface;
|
||||
m_pResource = pSurface;
|
||||
init();
|
||||
m_bInert = false;
|
||||
}
|
||||
|
|
@ -44,20 +45,23 @@ CWLSurface::~CWLSurface() {
|
|||
}
|
||||
|
||||
bool CWLSurface::exists() const {
|
||||
return m_pWLRSurface;
|
||||
return m_pResource;
|
||||
}
|
||||
|
||||
wlr_surface* CWLSurface::wlr() const {
|
||||
return m_pWLRSurface;
|
||||
SP<CWLSurfaceResource> CWLSurface::resource() const {
|
||||
return m_pResource.lock();
|
||||
}
|
||||
|
||||
bool CWLSurface::small() const {
|
||||
if (!validMapped(m_pWindowOwner) || !exists())
|
||||
return false;
|
||||
|
||||
if (!m_pResource->current.buffer)
|
||||
return false;
|
||||
|
||||
const auto O = m_pWindowOwner.lock();
|
||||
|
||||
return O->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || O->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1;
|
||||
return O->m_vReportedSize.x > m_pResource->current.buffer->size.x + 1 || O->m_vReportedSize.y > m_pResource->current.buffer->size.y + 1;
|
||||
}
|
||||
|
||||
Vector2D CWLSurface::correctSmallVec() const {
|
||||
|
|
@ -71,29 +75,28 @@ Vector2D CWLSurface::correctSmallVec() const {
|
|||
}
|
||||
|
||||
Vector2D CWLSurface::getViewporterCorrectedSize() const {
|
||||
if (!exists())
|
||||
if (!exists() || !m_pResource->current.buffer)
|
||||
return {};
|
||||
|
||||
return m_pWLRSurface->current.viewport.has_dst ? Vector2D{m_pWLRSurface->current.viewport.dst_width, m_pWLRSurface->current.viewport.dst_height} :
|
||||
Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height};
|
||||
return m_pResource->current.viewport.hasDestination ? m_pResource->current.viewport.destination : m_pResource->current.buffer->size;
|
||||
}
|
||||
|
||||
CRegion CWLSurface::logicalDamage() const {
|
||||
CRegion damage{&m_pWLRSurface->buffer_damage};
|
||||
damage.transform(m_pWLRSurface->current.transform, m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height);
|
||||
damage.scale(1.0 / m_pWLRSurface->current.scale);
|
||||
if (!m_pResource->current.buffer)
|
||||
return {};
|
||||
|
||||
CRegion damage = m_pResource->accumulateCurrentBufferDamage();
|
||||
damage.transform(m_pResource->current.transform, m_pResource->current.buffer->size.x, m_pResource->current.buffer->size.y);
|
||||
damage.scale(1.0 / m_pResource->current.scale);
|
||||
|
||||
const auto VPSIZE = getViewporterCorrectedSize();
|
||||
const auto CORRECTVEC = correctSmallVec();
|
||||
|
||||
if (m_pWLRSurface->current.viewport.has_src) {
|
||||
damage.intersect(CBox{std::floor(m_pWLRSurface->current.viewport.src.x), std::floor(m_pWLRSurface->current.viewport.src.y),
|
||||
std::ceil(m_pWLRSurface->current.viewport.src.width), std::ceil(m_pWLRSurface->current.viewport.src.height)});
|
||||
}
|
||||
if (m_pResource->current.viewport.hasSource)
|
||||
damage.intersect(m_pResource->current.viewport.source);
|
||||
|
||||
const auto SCALEDSRCSIZE = m_pWLRSurface->current.viewport.has_src ?
|
||||
Vector2D{m_pWLRSurface->current.viewport.src.width, m_pWLRSurface->current.viewport.src.height} * m_pWLRSurface->current.scale :
|
||||
Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height};
|
||||
const auto SCALEDSRCSIZE =
|
||||
m_pResource->current.viewport.hasSource ? m_pResource->current.viewport.source.size() * m_pResource->current.scale : m_pResource->current.buffer->size;
|
||||
|
||||
damage.scale({VPSIZE.x / SCALEDSRCSIZE.x, VPSIZE.y / SCALEDSRCSIZE.y});
|
||||
damage.translate(CORRECTVEC);
|
||||
|
|
@ -102,48 +105,38 @@ CRegion CWLSurface::logicalDamage() const {
|
|||
}
|
||||
|
||||
void CWLSurface::destroy() {
|
||||
if (!m_pWLRSurface)
|
||||
if (!m_pResource)
|
||||
return;
|
||||
|
||||
events.destroy.emit();
|
||||
|
||||
m_pConstraint.reset();
|
||||
|
||||
hyprListener_destroy.removeCallback();
|
||||
hyprListener_commit.removeCallback();
|
||||
m_pWLRSurface->data = nullptr;
|
||||
listeners.destroy.reset();
|
||||
m_pResource->hlSurface.reset();
|
||||
m_pWindowOwner.reset();
|
||||
m_pLayerOwner.reset();
|
||||
m_pPopupOwner = nullptr;
|
||||
m_pSubsurfaceOwner = nullptr;
|
||||
m_bInert = true;
|
||||
|
||||
if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface)
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf == this)
|
||||
if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf && g_pHyprRenderer->m_sLastCursorData.surf->get() == this)
|
||||
g_pHyprRenderer->m_sLastCursorData.surf.reset();
|
||||
|
||||
m_pWLRSurface = nullptr;
|
||||
m_pResource.reset();
|
||||
|
||||
Debug::log(LOG, "CWLSurface {:x} called destroy()", (uintptr_t)this);
|
||||
}
|
||||
|
||||
static void onCommit(void* owner, void* data) {
|
||||
const auto SURF = (CWLSurface*)owner;
|
||||
SURF->onCommit();
|
||||
}
|
||||
|
||||
void CWLSurface::init() {
|
||||
if (!m_pWLRSurface)
|
||||
if (!m_pResource)
|
||||
return;
|
||||
|
||||
RASSERT(!m_pWLRSurface->data, "Attempted to duplicate CWLSurface ownership!");
|
||||
RASSERT(!m_pResource->hlSurface, "Attempted to duplicate CWLSurface ownership!");
|
||||
|
||||
m_pWLRSurface->data = this;
|
||||
m_pResource->hlSurface = self.lock();
|
||||
|
||||
hyprListener_destroy.initCallback(
|
||||
&m_pWLRSurface->events.destroy, [&](void* owner, void* data) { destroy(); }, this, "CWLSurface");
|
||||
hyprListener_commit.initCallback(&m_pWLRSurface->events.commit, ::onCommit, this, "CWLSurface");
|
||||
listeners.destroy = m_pResource->events.destroy.registerListener([this](std::any d) { destroy(); });
|
||||
|
||||
Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this);
|
||||
}
|
||||
|
|
@ -188,10 +181,6 @@ void CWLSurface::appendConstraint(WP<CPointerConstraint> constraint) {
|
|||
m_pConstraint = constraint;
|
||||
}
|
||||
|
||||
void CWLSurface::onCommit() {
|
||||
;
|
||||
}
|
||||
|
||||
SP<CPointerConstraint> CWLSurface::constraint() {
|
||||
return m_pConstraint.lock();
|
||||
}
|
||||
|
|
@ -207,3 +196,9 @@ bool CWLSurface::visible() {
|
|||
return m_pSubsurfaceOwner->visible();
|
||||
return true; // non-desktop, we don't know much.
|
||||
}
|
||||
|
||||
SP<CWLSurface> CWLSurface::fromResource(SP<CWLSurfaceResource> pSurface) {
|
||||
if (!pSurface)
|
||||
return nullptr;
|
||||
return pSurface->hlSurface.lock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,33 +7,37 @@
|
|||
class CSubsurface;
|
||||
class CPopup;
|
||||
class CPointerConstraint;
|
||||
class CWLSurfaceResource;
|
||||
|
||||
class CWLSurface {
|
||||
public:
|
||||
CWLSurface() = default;
|
||||
static SP<CWLSurface> create() {
|
||||
auto p = SP<CWLSurface>(new CWLSurface);
|
||||
p->self = p;
|
||||
return p;
|
||||
}
|
||||
~CWLSurface();
|
||||
|
||||
// anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD
|
||||
void assign(wlr_surface* pSurface);
|
||||
void assign(wlr_surface* pSurface, PHLWINDOW pOwner);
|
||||
void assign(wlr_surface* pSurface, PHLLS pOwner);
|
||||
void assign(wlr_surface* pSurface, CSubsurface* pOwner);
|
||||
void assign(wlr_surface* pSurface, CPopup* pOwner);
|
||||
void assign(SP<CWLSurfaceResource> pSurface);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, PHLWINDOW pOwner);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, PHLLS pOwner);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, CSubsurface* pOwner);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, CPopup* pOwner);
|
||||
void unassign();
|
||||
|
||||
CWLSurface(const CWLSurface&) = delete;
|
||||
CWLSurface(CWLSurface&&) = delete;
|
||||
CWLSurface& operator=(const CWLSurface&) = delete;
|
||||
CWLSurface& operator=(CWLSurface&&) = delete;
|
||||
CWLSurface(const CWLSurface&) = delete;
|
||||
CWLSurface(CWLSurface&&) = delete;
|
||||
CWLSurface& operator=(const CWLSurface&) = delete;
|
||||
CWLSurface& operator=(CWLSurface&&) = delete;
|
||||
|
||||
wlr_surface* wlr() const;
|
||||
bool exists() const;
|
||||
bool small() const; // means surface is smaller than the requested size
|
||||
Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
|
||||
Vector2D getViewporterCorrectedSize() const;
|
||||
CRegion logicalDamage() const;
|
||||
void onCommit();
|
||||
bool visible();
|
||||
SP<CWLSurfaceResource> resource() const;
|
||||
bool exists() const;
|
||||
bool small() const; // means surface is smaller than the requested size
|
||||
Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
|
||||
Vector2D getViewporterCorrectedSize() const;
|
||||
CRegion logicalDamage() const;
|
||||
bool visible();
|
||||
|
||||
// getters for owners.
|
||||
PHLWINDOW getWindow();
|
||||
|
|
@ -55,31 +59,27 @@ class CWLSurface {
|
|||
wl_output_transform m_eLastTransform = (wl_output_transform)-1;
|
||||
|
||||
//
|
||||
CWLSurface& operator=(wlr_surface* pSurface) {
|
||||
CWLSurface& operator=(SP<CWLSurfaceResource> pSurface) {
|
||||
destroy();
|
||||
m_pWLRSurface = pSurface;
|
||||
m_pResource = pSurface;
|
||||
init();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CWLSurface& other) const {
|
||||
return other.wlr() == wlr();
|
||||
return other.resource() == resource();
|
||||
}
|
||||
|
||||
bool operator==(const wlr_surface* other) const {
|
||||
return other == wlr();
|
||||
bool operator==(const SP<CWLSurfaceResource> other) const {
|
||||
return other == resource();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return exists();
|
||||
}
|
||||
|
||||
static CWLSurface* surfaceFromWlr(wlr_surface* pSurface) {
|
||||
if (!pSurface)
|
||||
return nullptr;
|
||||
return (CWLSurface*)pSurface->data;
|
||||
}
|
||||
static SP<CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
|
||||
|
||||
// used by the alpha-modifier protocol
|
||||
float m_pAlphaModifier = 1.F;
|
||||
|
|
@ -88,15 +88,19 @@ class CWLSurface {
|
|||
CSignal destroy;
|
||||
} events;
|
||||
|
||||
WP<CWLSurface> self;
|
||||
|
||||
private:
|
||||
bool m_bInert = true;
|
||||
CWLSurface() = default;
|
||||
|
||||
wlr_surface* m_pWLRSurface = nullptr;
|
||||
bool m_bInert = true;
|
||||
|
||||
PHLWINDOWREF m_pWindowOwner;
|
||||
PHLLSREF m_pLayerOwner;
|
||||
CPopup* m_pPopupOwner = nullptr;
|
||||
CSubsurface* m_pSubsurfaceOwner = nullptr;
|
||||
WP<CWLSurfaceResource> m_pResource;
|
||||
|
||||
PHLWINDOWREF m_pWindowOwner;
|
||||
PHLLSREF m_pLayerOwner;
|
||||
CPopup* m_pPopupOwner = nullptr;
|
||||
CSubsurface* m_pSubsurfaceOwner = nullptr;
|
||||
|
||||
//
|
||||
WP<CPointerConstraint> m_pConstraint;
|
||||
|
|
@ -105,8 +109,9 @@ class CWLSurface {
|
|||
void init();
|
||||
bool desktopComponent();
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(commit);
|
||||
struct {
|
||||
CHyprSignalListener destroy;
|
||||
} listeners;
|
||||
|
||||
friend class CPointerConstraint;
|
||||
};
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include "../config/ConfigValue.hpp"
|
||||
#include "../managers/TokenManager.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../xwayland/XWayland.hpp"
|
||||
|
||||
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
||||
|
|
@ -51,12 +52,14 @@ PHLWINDOW CWindow::create(SP<CXDGSurfaceResource> resource) {
|
|||
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
||||
|
||||
pWindow->m_pWLSurface.assign(pWindow->m_pXDGSurface->surface, pWindow);
|
||||
pWindow->m_pWLSurface->assign(pWindow->m_pXDGSurface->surface.lock(), pWindow);
|
||||
|
||||
return pWindow;
|
||||
}
|
||||
|
||||
CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
|
||||
listeners.map = m_pXDGSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
|
||||
listeners.ack = m_pXDGSurface->events.ack.registerListener([this](std::any d) { onAck(std::any_cast<uint32_t>(d)); });
|
||||
listeners.unmap = m_pXDGSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
|
||||
|
|
@ -67,6 +70,8 @@ CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) {
|
|||
}
|
||||
|
||||
CWindow::CWindow(SP<CXWaylandSurface> surface) : m_pXWaylandSurface(surface) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
|
||||
listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
|
||||
listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
|
||||
listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
|
||||
|
|
@ -83,7 +88,7 @@ CWindow::CWindow(SP<CXWaylandSurface> surface) : m_pXWaylandSurface(surface) {
|
|||
|
||||
CWindow::~CWindow() {
|
||||
if (g_pCompositor->m_pLastWindow.lock().get() == this) {
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
g_pCompositor->m_pLastFocus.reset();
|
||||
g_pCompositor->m_pLastWindow.reset();
|
||||
}
|
||||
|
||||
|
|
@ -124,12 +129,12 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
|
|||
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
|
||||
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
||||
|
||||
if (m_pWLSurface.exists() && !m_bIsX11 && m_pPopupHead) {
|
||||
if (m_pWLSurface->exists() && !m_bIsX11 && m_pPopupHead) {
|
||||
CBox surfaceExtents = {0, 0, 0, 0};
|
||||
// TODO: this could be better, perhaps make a getFullWindowRegion?
|
||||
m_pPopupHead->breadthfirst(
|
||||
[](CPopup* popup, void* data) {
|
||||
if (!popup->m_sWLSurface.wlr())
|
||||
if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource())
|
||||
return;
|
||||
|
||||
CBox* pSurfaceExtents = (CBox*)data;
|
||||
|
|
@ -151,11 +156,11 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
|
|||
if (-surfaceExtents.y > maxExtents.topLeft.y)
|
||||
maxExtents.topLeft.y = -surfaceExtents.y;
|
||||
|
||||
if (surfaceExtents.x + surfaceExtents.width > m_pWLSurface.wlr()->current.width + maxExtents.bottomRight.x)
|
||||
maxExtents.bottomRight.x = surfaceExtents.x + surfaceExtents.width - m_pWLSurface.wlr()->current.width;
|
||||
if (surfaceExtents.x + surfaceExtents.width > m_pWLSurface->resource()->current.size.x + maxExtents.bottomRight.x)
|
||||
maxExtents.bottomRight.x = surfaceExtents.x + surfaceExtents.width - m_pWLSurface->resource()->current.size.x;
|
||||
|
||||
if (surfaceExtents.y + surfaceExtents.height > m_pWLSurface.wlr()->current.height + maxExtents.bottomRight.y)
|
||||
maxExtents.bottomRight.y = surfaceExtents.y + surfaceExtents.height - m_pWLSurface.wlr()->current.height;
|
||||
if (surfaceExtents.y + surfaceExtents.height > m_pWLSurface->resource()->current.size.y + maxExtents.bottomRight.y)
|
||||
maxExtents.bottomRight.y = surfaceExtents.y + surfaceExtents.height - m_pWLSurface->resource()->current.size.y;
|
||||
}
|
||||
|
||||
return maxExtents;
|
||||
|
|
@ -340,17 +345,7 @@ void CWindow::updateToplevel() {
|
|||
updateSurfaceScaleTransformDetails();
|
||||
}
|
||||
|
||||
void sendEnterIter(wlr_surface* pSurface, int x, int y, void* data) {
|
||||
const auto OUTPUT = (wlr_output*)data;
|
||||
wlr_surface_send_enter(pSurface, OUTPUT);
|
||||
}
|
||||
|
||||
void sendLeaveIter(wlr_surface* pSurface, int x, int y, void* data) {
|
||||
const auto OUTPUT = (wlr_output*)data;
|
||||
wlr_surface_send_leave(pSurface, OUTPUT);
|
||||
}
|
||||
|
||||
void CWindow::updateSurfaceScaleTransformDetails() {
|
||||
void CWindow::updateSurfaceScaleTransformDetails(bool force) {
|
||||
if (!m_bIsMapped || m_bHidden || g_pCompositor->m_bUnsafeState)
|
||||
return;
|
||||
|
||||
|
|
@ -363,26 +358,25 @@ void CWindow::updateSurfaceScaleTransformDetails() {
|
|||
if (!PNEWMONITOR)
|
||||
return;
|
||||
|
||||
if (PNEWMONITOR != PLASTMONITOR) {
|
||||
if (PLASTMONITOR && PLASTMONITOR->m_bEnabled)
|
||||
wlr_surface_for_each_surface(m_pWLSurface.wlr(), sendLeaveIter, PLASTMONITOR->output);
|
||||
if (PNEWMONITOR != PLASTMONITOR || force) {
|
||||
if (PLASTMONITOR && PLASTMONITOR->m_bEnabled && PNEWMONITOR != PLASTMONITOR)
|
||||
m_pWLSurface->resource()->breadthfirst([PLASTMONITOR](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) { s->leave(PLASTMONITOR->self.lock()); }, nullptr);
|
||||
|
||||
wlr_surface_for_each_surface(m_pWLSurface.wlr(), sendEnterIter, PNEWMONITOR->output);
|
||||
m_pWLSurface->resource()->breadthfirst([PNEWMONITOR](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) { s->enter(PNEWMONITOR->self.lock()); }, nullptr);
|
||||
}
|
||||
|
||||
wlr_surface_for_each_surface(
|
||||
m_pWLSurface.wlr(),
|
||||
[](wlr_surface* surf, int x, int y, void* data) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(((CWindow*)data)->m_iMonitorID);
|
||||
m_pWLSurface->resource()->breadthfirst(
|
||||
[this](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
|
||||
const auto PSURFACE = CWLSurface::surfaceFromWlr(surf);
|
||||
const auto PSURFACE = CWLSurface::fromResource(s);
|
||||
if (PSURFACE && PSURFACE->m_fLastScale == PMONITOR->scale)
|
||||
return;
|
||||
|
||||
g_pCompositor->setPreferredScaleForSurface(surf, PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(surf, PMONITOR->transform);
|
||||
g_pCompositor->setPreferredScaleForSurface(s, PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(s, PMONITOR->transform);
|
||||
},
|
||||
this);
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
|
|
@ -568,6 +562,8 @@ void CWindow::onMap() {
|
|||
m_vReportedSize = m_vPendingReportedSize;
|
||||
m_bAnimatingIn = true;
|
||||
|
||||
updateSurfaceScaleTransformDetails(true);
|
||||
|
||||
if (m_bIsX11)
|
||||
return;
|
||||
|
||||
|
|
@ -860,7 +856,7 @@ bool CWindow::hasPopupAt(const Vector2D& pos) {
|
|||
|
||||
CPopup* popup = m_pPopupHead->at(pos);
|
||||
|
||||
return popup && popup->m_sWLSurface.wlr();
|
||||
return popup && popup->m_pWLSurface->resource();
|
||||
}
|
||||
|
||||
void CWindow::applyGroupRules() {
|
||||
|
|
@ -1135,23 +1131,24 @@ bool CWindow::opaque() {
|
|||
|
||||
const auto PWORKSPACE = m_pWorkspace;
|
||||
|
||||
if (m_pWLSurface.small() && !m_pWLSurface.m_bFillIgnoreSmall)
|
||||
if (m_pWLSurface->small() && !m_pWLSurface->m_bFillIgnoreSmall)
|
||||
return false;
|
||||
|
||||
if (PWORKSPACE->m_fAlpha.value() != 1.f)
|
||||
return false;
|
||||
|
||||
if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface)
|
||||
return m_pXWaylandSurface->surface->opaque;
|
||||
if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface && m_pXWaylandSurface->surface->current.buffer)
|
||||
return m_pXWaylandSurface->surface->current.buffer->opaque;
|
||||
|
||||
if (m_pXDGSurface && m_pXDGSurface->surface->opaque)
|
||||
if (!m_pWLSurface->resource() || !m_pWLSurface->resource()->current.buffer)
|
||||
return false;
|
||||
|
||||
// TODO: this is wrong
|
||||
const auto EXTENTS = m_pXDGSurface->surface->current.opaque.getExtents();
|
||||
if (EXTENTS.w >= m_pXDGSurface->surface->current.buffer->size.x && EXTENTS.h >= m_pXDGSurface->surface->current.buffer->size.y)
|
||||
return true;
|
||||
|
||||
const auto EXTENTS = pixman_region32_extents(&m_pXDGSurface->surface->opaque_region);
|
||||
if (EXTENTS->x2 - EXTENTS->x1 >= m_pXDGSurface->surface->current.buffer_width && EXTENTS->y2 - EXTENTS->y1 >= m_pXDGSurface->surface->current.buffer_height)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return m_pWLSurface->resource()->current.buffer->opaque;
|
||||
}
|
||||
|
||||
float CWindow::rounding() {
|
||||
|
|
@ -1282,8 +1279,7 @@ int CWindow::surfacesCount() {
|
|||
return 1;
|
||||
|
||||
int no = 0;
|
||||
wlr_surface_for_each_surface(
|
||||
m_pWLSurface.wlr(), [](wlr_surface* surf, int x, int y, void* data) { *((int*)data) += 1; }, &no);
|
||||
m_pWLSurface->resource()->breadthfirst([](SP<CWLSurfaceResource> r, const Vector2D& offset, void* d) { *((int*)d) += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
|
|
@ -1456,16 +1452,16 @@ void CWindow::onAck(uint32_t serial) {
|
|||
}
|
||||
|
||||
void CWindow::onResourceChangeX11() {
|
||||
if (m_pXWaylandSurface->surface && !m_pWLSurface.wlr())
|
||||
m_pWLSurface.assign(m_pXWaylandSurface->surface, m_pSelf.lock());
|
||||
else if (!m_pXWaylandSurface->surface && m_pWLSurface.wlr())
|
||||
m_pWLSurface.unassign();
|
||||
if (m_pXWaylandSurface->surface && !m_pWLSurface->resource())
|
||||
m_pWLSurface->assign(m_pXWaylandSurface->surface.lock(), m_pSelf.lock());
|
||||
else if (!m_pXWaylandSurface->surface && m_pWLSurface->resource())
|
||||
m_pWLSurface->unassign();
|
||||
|
||||
// update metadata as well,
|
||||
// could be first assoc and we need to catch the class
|
||||
onUpdateMeta();
|
||||
|
||||
Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface.wlr());
|
||||
Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface->resource().get());
|
||||
}
|
||||
|
||||
void CWindow::onX11Configure(CBox box) {
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ class CWindow {
|
|||
public:
|
||||
~CWindow();
|
||||
|
||||
CWLSurface m_pWLSurface;
|
||||
SP<CWLSurface> m_pWLSurface;
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
|
|
@ -396,7 +396,7 @@ class CWindow {
|
|||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||
void removeDecorationByType(eDecorationType);
|
||||
void updateToplevel();
|
||||
void updateSurfaceScaleTransformDetails();
|
||||
void updateSurfaceScaleTransformDetails(bool force = false);
|
||||
void moveToWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW X11TransientFor();
|
||||
void onUnmap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue