xdg-shell: move to new impl
This commit is contained in:
parent
121d3a7213
commit
0cfdde3d1a
24 changed files with 1352 additions and 421 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#include "../config/ConfigValue.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include <ranges>
|
||||
|
||||
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
|
||||
|
|
@ -12,14 +13,13 @@ CPopup::CPopup(PHLLS 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, this);
|
||||
CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pParent(pOwner), m_pResource(popup) {
|
||||
m_sWLSurface.assign(popup->surface->surface, this);
|
||||
|
||||
m_pLayerOwner = pOwner->m_pLayerOwner;
|
||||
m_pWindowOwner = pOwner->m_pWindowOwner;
|
||||
|
||||
m_vLastSize = {m_pWLR->current.geometry.width, m_pWLR->current.geometry.height};
|
||||
m_vLastSize = popup->surface->current.geometry.size();
|
||||
unconstrain();
|
||||
|
||||
initAllSignals();
|
||||
|
|
@ -27,71 +27,32 @@ CPopup::CPopup(wlr_xdg_popup* popup, CPopup* pOwner) : m_pParent(pOwner), m_pWLR
|
|||
|
||||
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_pResource) {
|
||||
if (!m_pWindowOwner.expired())
|
||||
hyprListener_newPopup.initCallback(&m_pWindowOwner->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head");
|
||||
listeners.newPopup = m_pWindowOwner->m_pXDGSurface->events.newPopup.registerListener([this](std::any d) { this->onNewPopup(std::any_cast<SP<CXDGPopupResource>>(d)); });
|
||||
else if (!m_pLayerOwner.expired())
|
||||
listeners.newPopup = m_pLayerOwner->layerSurface->events.newPopup.registerListener([this](std::any d) { this->onNewPopup(std::any_cast<wlr_xdg_popup*>(d)); });
|
||||
listeners.newPopup = m_pLayerOwner->layerSurface->events.newPopup.registerListener([this](std::any d) { this->onNewPopup(std::any_cast<SP<CXDGPopupResource>>(d)); });
|
||||
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");
|
||||
listeners.reposition = m_pResource->events.reposition.registerListener([this](std::any d) { this->onReposition(); });
|
||||
listeners.map = m_pResource->surface->events.map.registerListener([this](std::any d) { this->onMap(); });
|
||||
listeners.unmap = m_pResource->surface->events.unmap.registerListener([this](std::any d) { this->onUnmap(); });
|
||||
listeners.destroy = m_pResource->surface->events.destroy.registerListener([this](std::any d) { this->onDestroy(); });
|
||||
listeners.commit = m_pResource->surface->events.commit.registerListener([this](std::any d) { this->onCommit(); });
|
||||
listeners.newPopup = m_pResource->surface->events.newPopup.registerListener([this](std::any d) { this->onNewPopup(std::any_cast<SP<CXDGPopupResource>>(d)); });
|
||||
}
|
||||
|
||||
void CPopup::onNewPopup(wlr_xdg_popup* popup) {
|
||||
void CPopup::onNewPopup(SP<CXDGPopupResource> 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);
|
||||
Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP);
|
||||
}
|
||||
|
||||
void CPopup::onDestroy() {
|
||||
|
|
@ -104,7 +65,7 @@ void CPopup::onDestroy() {
|
|||
}
|
||||
|
||||
void CPopup::onMap() {
|
||||
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
const auto COORDS = coordsGlobal();
|
||||
|
||||
CBox box;
|
||||
|
|
@ -126,7 +87,9 @@ void CPopup::onMap() {
|
|||
}
|
||||
|
||||
void CPopup::onUnmap() {
|
||||
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
|
||||
if (!m_pResource || !m_pResource->surface)
|
||||
return;
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
const auto COORDS = coordsGlobal();
|
||||
|
||||
CBox box;
|
||||
|
|
@ -140,16 +103,27 @@ void CPopup::onUnmap() {
|
|||
|
||||
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
|
||||
|
||||
// damage all children
|
||||
breadthfirst(
|
||||
[this](CPopup* p, void* data) {
|
||||
if (!p->m_pResource)
|
||||
return;
|
||||
|
||||
auto box = CBox{p->coordsGlobal(), p->size()};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CPopup::onCommit(bool ignoreSiblings) {
|
||||
if (m_pWLR->base->initial_commit) {
|
||||
wlr_xdg_surface_schedule_configure(m_pWLR->base);
|
||||
if (m_pResource->surface->initialCommit) {
|
||||
m_pResource->surface->scheduleConfigure();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_pWindowOwner.expired() && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) {
|
||||
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
|
||||
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
|
||||
if (*PLOGDAMAGE)
|
||||
|
|
@ -157,16 +131,17 @@ void CPopup::onCommit(bool ignoreSiblings) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!m_pWLR->base->surface->mapped)
|
||||
if (!m_pResource->surface->mapped)
|
||||
return;
|
||||
|
||||
const auto COORDS = coordsGlobal();
|
||||
const auto COORDSLOCAL = coordsRelativeToParent();
|
||||
|
||||
if (m_vLastSize != Vector2D{m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height} || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
|
||||
if (m_vLastSize != Vector2D{m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height} || m_bRequestedReposition ||
|
||||
m_vLastPos != COORDSLOCAL) {
|
||||
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
|
||||
m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
|
||||
box = {COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
|
|
@ -202,20 +177,25 @@ void CPopup::unconstrain() {
|
|||
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());
|
||||
m_pResource->applyPositioning(box, COORDS - PMONITOR->vecPosition);
|
||||
wlr_surface_send_enter(m_pResource->surface->surface, PMONITOR->output);
|
||||
}
|
||||
|
||||
Vector2D CPopup::coordsRelativeToParent() {
|
||||
Vector2D offset;
|
||||
|
||||
CPopup* current = this;
|
||||
if (!m_pResource)
|
||||
return {};
|
||||
|
||||
offset -= {m_pWLR->base->current.geometry.x, m_pWLR->base->current.geometry.y};
|
||||
CPopup* current = this;
|
||||
offset -= current->m_pResource->surface->current.geometry.pos();
|
||||
|
||||
while (current->m_pParent) {
|
||||
offset -= m_pResource->surface->current.geometry.pos();
|
||||
|
||||
while (current->m_pParent && current->m_pResource) {
|
||||
|
||||
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};
|
||||
offset += current->m_pResource->geometry.pos();
|
||||
|
||||
current = current->m_pParent;
|
||||
}
|
||||
|
|
@ -309,7 +289,7 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
|||
breadthfirst([](CPopup* popup, void* data) { ((std::vector<CPopup*>*)data)->push_back(popup); }, &popups);
|
||||
|
||||
for (auto& p : popups | std::views::reverse) {
|
||||
if (!p->m_pWLR)
|
||||
if (!p->m_pResource)
|
||||
continue;
|
||||
|
||||
if (!allowsInput) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
#include "Subsurface.hpp"
|
||||
#include "../helpers/signal/Listener.hpp"
|
||||
|
||||
class CXDGPopupResource;
|
||||
|
||||
class CPopup {
|
||||
public:
|
||||
// dummy head nodes
|
||||
|
|
@ -12,7 +14,7 @@ class CPopup {
|
|||
CPopup(PHLLS pOwner);
|
||||
|
||||
// real nodes
|
||||
CPopup(wlr_xdg_popup* popup, CPopup* pOwner);
|
||||
CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner);
|
||||
|
||||
~CPopup();
|
||||
|
||||
|
|
@ -21,7 +23,7 @@ class CPopup {
|
|||
|
||||
Vector2D size();
|
||||
|
||||
void onNewPopup(wlr_xdg_popup* popup);
|
||||
void onNewPopup(SP<CXDGPopupResource> popup);
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
|
|
@ -45,31 +47,28 @@ class CPopup {
|
|||
PHLLSREF m_pLayerOwner;
|
||||
|
||||
// T2 owners
|
||||
CPopup* m_pParent = nullptr;
|
||||
CPopup* m_pParent = nullptr;
|
||||
|
||||
wlr_xdg_popup* m_pWLR = nullptr;
|
||||
WP<CXDGPopupResource> m_pResource;
|
||||
|
||||
Vector2D m_vLastSize = {};
|
||||
Vector2D m_vLastPos = {};
|
||||
Vector2D m_vLastSize = {};
|
||||
Vector2D m_vLastPos = {};
|
||||
|
||||
bool m_bRequestedReposition = false;
|
||||
bool m_bRequestedReposition = false;
|
||||
|
||||
bool m_bInert = 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);
|
||||
|
||||
struct {
|
||||
CHyprSignalListener newPopup;
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
CHyprSignalListener reposition;
|
||||
} listeners;
|
||||
|
||||
void initAllSignals();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "../config/ConfigValue.hpp"
|
||||
#include <any>
|
||||
#include "../managers/TokenManager.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
|
||||
PHLWINDOW CWindow::create() {
|
||||
PHLWINDOW pWindow = SP<CWindow>(new CWindow);
|
||||
|
|
@ -27,6 +28,39 @@ PHLWINDOW CWindow::create() {
|
|||
return pWindow;
|
||||
}
|
||||
|
||||
PHLWINDOW CWindow::create(SP<CXDGSurfaceResource> resource) {
|
||||
PHLWINDOW pWindow = SP<CWindow>(new CWindow(resource));
|
||||
|
||||
pWindow->m_pSelf = pWindow;
|
||||
resource->toplevel->window = pWindow;
|
||||
|
||||
pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER);
|
||||
pWindow->m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER);
|
||||
pWindow->m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
||||
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
||||
|
||||
pWindow->m_pWLSurface.assign(pWindow->m_pXDGSurface->surface, pWindow);
|
||||
|
||||
return pWindow;
|
||||
}
|
||||
|
||||
CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) {
|
||||
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); });
|
||||
listeners.destroy = m_pXDGSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
|
||||
listeners.commit = m_pXDGSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
|
||||
listeners.updateState = m_pXDGSurface->toplevel->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
|
||||
listeners.updateMetadata = m_pXDGSurface->toplevel->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
|
||||
}
|
||||
|
||||
CWindow::CWindow() {
|
||||
;
|
||||
}
|
||||
|
|
@ -74,21 +108,24 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
|
|||
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
|
||||
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
||||
|
||||
if (m_pWLSurface.exists() && !m_bIsX11) {
|
||||
if (m_pWLSurface.exists() && !m_bIsX11 && m_pPopupHead) {
|
||||
CBox surfaceExtents = {0, 0, 0, 0};
|
||||
// TODO: this could be better, perhaps make a getFullWindowRegion?
|
||||
wlr_xdg_surface_for_each_popup_surface(
|
||||
m_uSurface.xdg,
|
||||
[](wlr_surface* surf, int sx, int sy, void* data) {
|
||||
m_pPopupHead->breadthfirst(
|
||||
[](CPopup* popup, void* data) {
|
||||
if (!popup->m_sWLSurface.wlr())
|
||||
return;
|
||||
|
||||
CBox* pSurfaceExtents = (CBox*)data;
|
||||
if (sx < pSurfaceExtents->x)
|
||||
pSurfaceExtents->x = sx;
|
||||
if (sy < pSurfaceExtents->y)
|
||||
pSurfaceExtents->y = sy;
|
||||
if (sx + surf->current.width > pSurfaceExtents->width)
|
||||
pSurfaceExtents->width = sx + surf->current.width - pSurfaceExtents->x;
|
||||
if (sy + surf->current.height > pSurfaceExtents->height)
|
||||
pSurfaceExtents->height = sy + surf->current.height - pSurfaceExtents->y;
|
||||
CBox surf = CBox{popup->coordsRelativeToParent(), popup->size()};
|
||||
if (surf.x < pSurfaceExtents->x)
|
||||
pSurfaceExtents->x = surf.x;
|
||||
if (surf.y < pSurfaceExtents->y)
|
||||
pSurfaceExtents->y = surf.y;
|
||||
if (surf.x + surf.w > pSurfaceExtents->width)
|
||||
pSurfaceExtents->width = surf.x + surf.w - pSurfaceExtents->x;
|
||||
if (surf.y + surf.h > pSurfaceExtents->height)
|
||||
pSurfaceExtents->height = surf.y + surf.h - pSurfaceExtents->y;
|
||||
},
|
||||
&surfaceExtents);
|
||||
|
||||
|
|
@ -258,10 +295,10 @@ bool CWindow::checkInputOnDecos(const eInputType type, const Vector2D& mouseCoor
|
|||
pid_t CWindow::getPID() {
|
||||
pid_t PID = -1;
|
||||
if (!m_bIsX11) {
|
||||
if (!m_uSurface.xdg)
|
||||
if (!m_pXDGSurface || !m_pXDGSurface->owner /* happens at unmap */)
|
||||
return -1;
|
||||
|
||||
wl_client_get_credentials(wl_resource_get_client(m_uSurface.xdg->resource), &PID, nullptr, nullptr);
|
||||
wl_client_get_credentials(m_pXDGSurface->owner->client(), &PID, nullptr, nullptr);
|
||||
} else {
|
||||
if (!m_uSurface.xwayland)
|
||||
return -1;
|
||||
|
|
@ -511,8 +548,8 @@ void CWindow::onMap() {
|
|||
|
||||
g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf);
|
||||
|
||||
hyprListener_unmapWindow.initCallback(m_bIsX11 ? &m_uSurface.xwayland->surface->events.unmap : &m_uSurface.xdg->surface->events.unmap, &Events::listener_unmapWindow, this,
|
||||
"CWindow");
|
||||
if (m_bIsX11)
|
||||
hyprListener_unmapWindow.initCallback(&m_uSurface.xwayland->surface->events.unmap, &Events::listener_unmapWindow, this, "CWindow");
|
||||
|
||||
m_vReportedSize = m_vPendingReportedSize;
|
||||
m_bAnimatingIn = true;
|
||||
|
|
@ -793,26 +830,14 @@ bool CWindow::isInCurvedCorner(double x, double y) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void findExtensionForVector2D(wlr_surface* surface, int x, int y, void* data) {
|
||||
const auto DATA = (SExtensionFindingData*)data;
|
||||
|
||||
CBox box = {DATA->origin.x + x, DATA->origin.y + y, surface->current.width, surface->current.height};
|
||||
|
||||
if (box.containsPoint(DATA->vec))
|
||||
*DATA->found = surface;
|
||||
}
|
||||
|
||||
// checks if the wayland window has a popup at pos
|
||||
bool CWindow::hasPopupAt(const Vector2D& pos) {
|
||||
if (m_bIsX11)
|
||||
return false;
|
||||
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
Vector2D origin = m_vRealPosition.value();
|
||||
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||
wlr_xdg_surface_for_each_popup_surface(m_uSurface.xdg, findExtensionForVector2D, &data);
|
||||
CPopup* popup = m_pPopupHead->at(pos);
|
||||
|
||||
return resultSurf;
|
||||
return popup && popup->m_sWLSurface.wlr();
|
||||
}
|
||||
|
||||
void CWindow::applyGroupRules() {
|
||||
|
|
@ -1096,11 +1121,11 @@ bool CWindow::opaque() {
|
|||
if (m_bIsX11)
|
||||
return !m_uSurface.xwayland->has_alpha;
|
||||
|
||||
if (m_uSurface.xdg->surface->opaque)
|
||||
if (m_pXDGSurface->surface->opaque)
|
||||
return true;
|
||||
|
||||
const auto EXTENTS = pixman_region32_extents(&m_uSurface.xdg->surface->opaque_region);
|
||||
if (EXTENTS->x2 - EXTENTS->x1 >= m_uSurface.xdg->surface->current.buffer_width && EXTENTS->y2 - EXTENTS->y1 >= m_uSurface.xdg->surface->current.buffer_height)
|
||||
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;
|
||||
|
|
@ -1162,10 +1187,10 @@ void CWindow::setSuspended(bool suspend) {
|
|||
if (suspend == m_bSuspended)
|
||||
return;
|
||||
|
||||
if (m_bIsX11)
|
||||
if (m_bIsX11 || !m_pXDGSurface->toplevel)
|
||||
return;
|
||||
|
||||
wlr_xdg_toplevel_set_suspended(m_uSurface.xdg->toplevel, suspend);
|
||||
m_pXDGSurface->toplevel->setSuspeneded(suspend);
|
||||
m_bSuspended = suspend;
|
||||
}
|
||||
|
||||
|
|
@ -1221,12 +1246,21 @@ void CWindow::onWorkspaceAnimUpdate() {
|
|||
}
|
||||
|
||||
int CWindow::popupsCount() {
|
||||
if (m_bIsX11)
|
||||
return 0;
|
||||
|
||||
int no = -1;
|
||||
m_pPopupHead->breadthfirst([](CPopup* p, void* d) { *((int*)d) += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
int CWindow::surfacesCount() {
|
||||
if (m_bIsX11)
|
||||
return 1;
|
||||
|
||||
int no = 0;
|
||||
wlr_xdg_surface_for_each_popup_surface(
|
||||
m_uSurface.xdg, [](wlr_surface* s, int x, int y, void* data) { *(int*)data += 1; }, &no);
|
||||
wlr_surface_for_each_surface(
|
||||
m_pWLSurface.wlr(), [](wlr_surface* surf, int x, int y, void* data) { *((int*)data) += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
|
|
@ -1278,6 +1312,9 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
|
|||
}
|
||||
|
||||
void CWindow::activate(bool force) {
|
||||
if (g_pCompositor->m_pLastWindow == m_pSelf)
|
||||
return;
|
||||
|
||||
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)this)});
|
||||
|
|
@ -1295,3 +1332,98 @@ void CWindow::activate(bool force) {
|
|||
g_pCompositor->focusWindow(m_pSelf.lock());
|
||||
g_pCompositor->warpCursorTo(middle());
|
||||
}
|
||||
|
||||
void CWindow::onUpdateState() {
|
||||
if (!m_pXDGSurface)
|
||||
return;
|
||||
|
||||
if (m_pXDGSurface->toplevel->state.requestsFullscreen) {
|
||||
bool fs = m_pXDGSurface->toplevel->state.requestsFullscreen.value();
|
||||
|
||||
if (fs != m_bIsFullscreen && m_pXDGSurface->mapped)
|
||||
g_pCompositor->setWindowFullscreen(m_pSelf.lock(), fs, FULLSCREEN_FULL);
|
||||
|
||||
if (!m_pXDGSurface->mapped)
|
||||
m_bWantsInitialFullscreen = fs;
|
||||
}
|
||||
|
||||
if (m_pXDGSurface->toplevel->state.requestsMaximize) {
|
||||
bool fs = m_pXDGSurface->toplevel->state.requestsMaximize.value();
|
||||
|
||||
if (fs != m_bIsFullscreen && m_pXDGSurface->mapped)
|
||||
g_pCompositor->setWindowFullscreen(m_pSelf.lock(), fs, FULLSCREEN_MAXIMIZED);
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::onUpdateMeta() {
|
||||
const auto NEWTITLE = fetchTitle();
|
||||
|
||||
if (m_szTitle != NEWTITLE) {
|
||||
m_szTitle = NEWTITLE;
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"windowtitle", std::format("{:x}", (uintptr_t)this)});
|
||||
EMIT_HOOK_EVENT("windowTitle", m_pSelf.lock());
|
||||
|
||||
if (m_pSelf == g_pCompositor->m_pLastWindow) { // if it's the active, let's post an event to update others
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", m_szClass + "," + m_szTitle});
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", std::format("{:x}", (uintptr_t)this)});
|
||||
EMIT_HOOK_EVENT("activeWindow", m_pSelf.lock());
|
||||
}
|
||||
|
||||
updateDynamicRules();
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(m_pSelf.lock());
|
||||
updateToplevel();
|
||||
|
||||
Debug::log(LOG, "Window {:x} set title to {}", (uintptr_t)this, m_szTitle);
|
||||
}
|
||||
|
||||
const auto NEWCLASS = fetchClass();
|
||||
if (m_szClass != NEWCLASS) {
|
||||
m_szClass = NEWCLASS;
|
||||
|
||||
if (m_pSelf == g_pCompositor->m_pLastWindow) { // if it's the active, let's post an event to update others
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", m_szClass + "," + m_szTitle});
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", std::format("{:x}", (uintptr_t)this)});
|
||||
EMIT_HOOK_EVENT("activeWindow", m_pSelf.lock());
|
||||
}
|
||||
|
||||
updateDynamicRules();
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(m_pSelf.lock());
|
||||
updateToplevel();
|
||||
|
||||
Debug::log(LOG, "Window {:x} set class to {}", (uintptr_t)this, m_szClass);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CWindow::fetchTitle() {
|
||||
if (!m_bIsX11) {
|
||||
if (m_pXDGSurface && m_pXDGSurface->toplevel)
|
||||
return m_pXDGSurface->toplevel->state.title;
|
||||
} else {
|
||||
if (m_uSurface.xwayland && m_uSurface.xwayland->title)
|
||||
return m_uSurface.xwayland->title;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string CWindow::fetchClass() {
|
||||
if (!m_bIsX11) {
|
||||
if (m_pXDGSurface && m_pXDGSurface->toplevel)
|
||||
return m_pXDGSurface->toplevel->state.appid;
|
||||
} else {
|
||||
if (m_uSurface.xwayland && m_uSurface.xwayland->_class)
|
||||
return m_uSurface.xwayland->_class;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void CWindow::onAck(uint32_t serial) {
|
||||
const auto SERIAL = std::find_if(m_vPendingSizeAcks.rbegin(), m_vPendingSizeAcks.rend(), [serial](const auto& e) { return e.first == serial; });
|
||||
|
||||
if (SERIAL == m_vPendingSizeAcks.rend())
|
||||
return;
|
||||
|
||||
m_pPendingSizeAck = *SERIAL;
|
||||
std::erase_if(m_vPendingSizeAcks, [&](const auto& el) { return el.first <= SERIAL->first; });
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
#include "DesktopTypes.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
|
||||
class CXDGSurfaceResource;
|
||||
|
||||
enum eIdleInhibitMode {
|
||||
IDLEINHIBIT_NONE = 0,
|
||||
IDLEINHIBIT_ALWAYS,
|
||||
|
|
@ -196,9 +198,12 @@ struct SInitialWorkspaceToken {
|
|||
|
||||
class CWindow {
|
||||
public:
|
||||
static PHLWINDOW create(SP<CXDGSurfaceResource>);
|
||||
// xwl
|
||||
static PHLWINDOW create();
|
||||
|
||||
private:
|
||||
CWindow(SP<CXDGSurfaceResource> resource);
|
||||
CWindow();
|
||||
|
||||
public:
|
||||
|
|
@ -233,9 +238,9 @@ class CWindow {
|
|||
} events;
|
||||
|
||||
union {
|
||||
wlr_xdg_surface* xdg;
|
||||
wlr_xwayland_surface* xwayland;
|
||||
} m_uSurface;
|
||||
WP<CXDGSurfaceResource> m_pXDGSurface;
|
||||
|
||||
// this is the position and size of the "bounding box"
|
||||
Vector2D m_vPosition = Vector2D(0, 0);
|
||||
|
|
@ -271,6 +276,7 @@ class CWindow {
|
|||
bool m_bWasMaximized = false;
|
||||
uint64_t m_iMonitorID = -1;
|
||||
std::string m_szTitle = "";
|
||||
std::string m_szClass = "";
|
||||
std::string m_szInitialTitle = "";
|
||||
std::string m_szInitialClass = "";
|
||||
PHLWORKSPACE m_pWorkspace;
|
||||
|
|
@ -385,7 +391,7 @@ class CWindow {
|
|||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) {
|
||||
return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize &&
|
||||
return m_pXDGSurface == rhs.m_pXDGSurface && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize &&
|
||||
m_bFadingOut == rhs.m_bFadingOut;
|
||||
}
|
||||
|
||||
|
|
@ -424,6 +430,7 @@ class CWindow {
|
|||
int workspaceID();
|
||||
bool onSpecialWorkspace();
|
||||
void activate(bool force = false);
|
||||
int surfacesCount();
|
||||
|
||||
int getRealBorderSize();
|
||||
void updateSpecialRenderData();
|
||||
|
|
@ -450,6 +457,13 @@ class CWindow {
|
|||
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
||||
void setAnimationsToMove();
|
||||
void onWorkspaceAnimUpdate();
|
||||
void onUpdateState();
|
||||
void onUpdateMeta();
|
||||
std::string fetchTitle();
|
||||
std::string fetchClass();
|
||||
|
||||
// listeners
|
||||
void onAck(uint32_t serial);
|
||||
|
||||
//
|
||||
std::unordered_map<std::string, std::string> getEnv();
|
||||
|
|
@ -457,6 +471,17 @@ class CWindow {
|
|||
//
|
||||
PHLWINDOWREF m_pSelf;
|
||||
|
||||
// make private once we move listeners to inside CWindow
|
||||
struct {
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener ack;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener updateState;
|
||||
CHyprSignalListener updateMetadata;
|
||||
} listeners;
|
||||
|
||||
private:
|
||||
// For hidden windows and stuff
|
||||
bool m_bHidden = false;
|
||||
|
|
@ -520,7 +545,7 @@ struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
|
|||
if (formatMonitor)
|
||||
std::format_to(out, ", monitor: {}", w->m_iMonitorID);
|
||||
if (formatClass)
|
||||
std::format_to(out, ", class: {}", g_pXWaylandManager->getAppIDClass(w));
|
||||
std::format_to(out, ", class: {}", w->m_szClass);
|
||||
return std::format_to(out, "]");
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue