mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-23 04:29:48 +01:00
Don't damage surfaces coming from not rendered windows
This commit is contained in:
parent
471654d791
commit
970018248f
6 changed files with 53 additions and 10 deletions
|
@ -134,7 +134,7 @@ void Events::listener_mapPopupXDG(void* owner, void* data) {
|
||||||
|
|
||||||
Debug::log(LOG, "New XDG Popup mapped at %d %d", (int)PPOPUP->lx, (int)PPOPUP->ly);
|
Debug::log(LOG, "New XDG Popup mapped at %d %d", (int)PPOPUP->lx, (int)PPOPUP->ly);
|
||||||
|
|
||||||
PPOPUP->pSurfaceTree = SubsurfaceTree::createTreeRoot(PPOPUP->popup->base->surface, addPopupGlobalCoords, PPOPUP);
|
PPOPUP->pSurfaceTree = SubsurfaceTree::createTreeRoot(PPOPUP->popup->base->surface, addPopupGlobalCoords, PPOPUP, PPOPUP->parentWindow);
|
||||||
|
|
||||||
Debug::log(LOG, "XDG Popup got assigned a surfaceTreeNode %x", PPOPUP->pSurfaceTree);
|
Debug::log(LOG, "XDG Popup got assigned a surfaceTreeNode %x", PPOPUP->pSurfaceTree);
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
if (!PWINDOW->m_bNoFocus)
|
if (!PWINDOW->m_bNoFocus)
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
|
|
||||||
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW);
|
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW, PWINDOW);
|
||||||
|
|
||||||
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,13 @@ void addSurfaceGlobalOffset(SSurfaceTreeNode* node, int* lx, int* ly) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SSurfaceTreeNode* createTree(wlr_surface* pSurface) {
|
SSurfaceTreeNode* createTree(wlr_surface* pSurface, CWindow* pWindow) {
|
||||||
SubsurfaceTree::surfaceTreeNodes.push_back(SSurfaceTreeNode());
|
SubsurfaceTree::surfaceTreeNodes.push_back(SSurfaceTreeNode());
|
||||||
|
|
||||||
const auto PNODE = &SubsurfaceTree::surfaceTreeNodes.back();
|
const auto PNODE = &SubsurfaceTree::surfaceTreeNodes.back();
|
||||||
|
|
||||||
PNODE->pSurface = pSurface;
|
PNODE->pSurface = pSurface;
|
||||||
|
PNODE->pWindowOwner = pWindow;
|
||||||
|
|
||||||
PNODE->hyprListener_newSubsurface.initCallback(&pSurface->events.new_subsurface, &Events::listener_newSubsurfaceNode, PNODE, "SurfaceTreeNode");
|
PNODE->hyprListener_newSubsurface.initCallback(&pSurface->events.new_subsurface, &Events::listener_newSubsurfaceNode, PNODE, "SurfaceTreeNode");
|
||||||
PNODE->hyprListener_commit.initCallback(&pSurface->events.commit, &Events::listener_commitSubsurface, PNODE, "SurfaceTreeNode");
|
PNODE->hyprListener_commit.initCallback(&pSurface->events.commit, &Events::listener_commitSubsurface, PNODE, "SurfaceTreeNode");
|
||||||
|
@ -42,16 +43,21 @@ SSurfaceTreeNode* createTree(wlr_surface* pSurface) {
|
||||||
return PNODE;
|
return PNODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSurfaceTreeNode* createSubsurfaceNode(SSurfaceTreeNode* pParent, SSubsurface* pSubsurface, wlr_surface* surface) {
|
SSurfaceTreeNode* createSubsurfaceNode(SSurfaceTreeNode* pParent, SSubsurface* pSubsurface, wlr_surface* surface, CWindow* pWindow) {
|
||||||
const auto PNODE = createTree(surface);
|
const auto PNODE = createTree(surface, pWindow);
|
||||||
PNODE->pParent = pParent;
|
PNODE->pParent = pParent;
|
||||||
PNODE->pSubsurface = pSubsurface;
|
PNODE->pSubsurface = pSubsurface;
|
||||||
|
|
||||||
|
Debug::log(LOG, "Creating a subsurface Node! (pWindow: %x)", pWindow);
|
||||||
|
|
||||||
return PNODE;
|
return PNODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSurfaceTreeNode* SubsurfaceTree::createTreeRoot(wlr_surface* pSurface, applyGlobalOffsetFn fn, void* data) {
|
SSurfaceTreeNode* SubsurfaceTree::createTreeRoot(wlr_surface* pSurface, applyGlobalOffsetFn fn, void* data, CWindow* pWindow) {
|
||||||
const auto PNODE = createTree(pSurface);
|
const auto PNODE = createTree(pSurface, pWindow);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Creating a surfaceTree Root! (pWindow: %x)", pWindow);
|
||||||
|
|
||||||
PNODE->offsetfn = fn;
|
PNODE->offsetfn = fn;
|
||||||
PNODE->globalOffsetData = data;
|
PNODE->globalOffsetData = data;
|
||||||
|
|
||||||
|
@ -120,6 +126,8 @@ void Events::listener_newSubsurfaceNode(void* owner, void* data) {
|
||||||
PNEWSUBSURFACE->hyprListener_unmap.initCallback(&PSUBSURFACE->events.unmap, &Events::listener_unmapSubsurface, PNEWSUBSURFACE, "Subsurface");
|
PNEWSUBSURFACE->hyprListener_unmap.initCallback(&PSUBSURFACE->events.unmap, &Events::listener_unmapSubsurface, PNEWSUBSURFACE, "Subsurface");
|
||||||
PNEWSUBSURFACE->hyprListener_destroy.initCallback(&PSUBSURFACE->events.destroy, &Events::listener_destroySubsurface, PNEWSUBSURFACE, "Subsurface");
|
PNEWSUBSURFACE->hyprListener_destroy.initCallback(&PSUBSURFACE->events.destroy, &Events::listener_destroySubsurface, PNEWSUBSURFACE, "Subsurface");
|
||||||
|
|
||||||
|
PNEWSUBSURFACE->pWindowOwner = pNode->pWindowOwner;
|
||||||
|
|
||||||
wlr_subsurface* existingWlrSubsurface;
|
wlr_subsurface* existingWlrSubsurface;
|
||||||
wl_list_for_each(existingWlrSubsurface, &PSUBSURFACE->surface->current.subsurfaces_below, current.link) {
|
wl_list_for_each(existingWlrSubsurface, &PSUBSURFACE->surface->current.subsurfaces_below, current.link) {
|
||||||
listener_newSubsurfaceNode(pNode, existingWlrSubsurface);
|
listener_newSubsurfaceNode(pNode, existingWlrSubsurface);
|
||||||
|
@ -134,7 +142,7 @@ void Events::listener_mapSubsurface(void* owner, void* data) {
|
||||||
|
|
||||||
Debug::log(LOG, "Subsurface %x mapped", subsurface->pSubsurface);
|
Debug::log(LOG, "Subsurface %x mapped", subsurface->pSubsurface);
|
||||||
|
|
||||||
subsurface->pChild = createSubsurfaceNode(subsurface->pParent, subsurface, subsurface->pSubsurface->surface);
|
subsurface->pChild = createSubsurfaceNode(subsurface->pParent, subsurface, subsurface->pSubsurface->surface, subsurface->pWindowOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_unmapSubsurface(void* owner, void* data) {
|
void Events::listener_unmapSubsurface(void* owner, void* data) {
|
||||||
|
@ -162,6 +170,14 @@ void Events::listener_unmapSubsurface(void* owner, void* data) {
|
||||||
void Events::listener_commitSubsurface(void* owner, void* data) {
|
void Events::listener_commitSubsurface(void* owner, void* data) {
|
||||||
SSurfaceTreeNode* pNode = (SSurfaceTreeNode*)owner;
|
SSurfaceTreeNode* pNode = (SSurfaceTreeNode*)owner;
|
||||||
|
|
||||||
|
// no damaging if it's not visible
|
||||||
|
if (!g_pHyprRenderer->shouldRenderWindow(pNode->pWindowOwner)) {
|
||||||
|
if (g_pConfigManager->getInt("debug:log_damage"))
|
||||||
|
Debug::log(LOG, "Refusing to commit damage from %x because it's invisible.", pNode->pWindowOwner);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int lx = 0, ly = 0;
|
int lx = 0, ly = 0;
|
||||||
|
|
||||||
addSurfaceGlobalOffset(pNode, &lx, &ly);
|
addSurfaceGlobalOffset(pNode, &lx, &ly);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
struct SSubsurface;
|
struct SSubsurface;
|
||||||
|
class CWindow;
|
||||||
|
|
||||||
typedef void (*applyGlobalOffsetFn)(void *, int *, int *);
|
typedef void (*applyGlobalOffsetFn)(void *, int *, int *);
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ struct SSurfaceTreeNode {
|
||||||
|
|
||||||
applyGlobalOffsetFn offsetfn;
|
applyGlobalOffsetFn offsetfn;
|
||||||
void *globalOffsetData;
|
void *globalOffsetData;
|
||||||
|
CWindow* pWindowOwner = nullptr;
|
||||||
|
|
||||||
bool operator==(const SSurfaceTreeNode& rhs) {
|
bool operator==(const SSurfaceTreeNode& rhs) {
|
||||||
return pSurface == rhs.pSurface;
|
return pSurface == rhs.pSurface;
|
||||||
|
@ -37,13 +39,15 @@ struct SSubsurface {
|
||||||
DYNLISTENER(unmap);
|
DYNLISTENER(unmap);
|
||||||
DYNLISTENER(destroy);
|
DYNLISTENER(destroy);
|
||||||
|
|
||||||
|
CWindow* pWindowOwner = nullptr;
|
||||||
|
|
||||||
bool operator==(const SSubsurface& rhs) {
|
bool operator==(const SSubsurface& rhs) {
|
||||||
return pSubsurface == rhs.pSubsurface;
|
return pSubsurface == rhs.pSubsurface;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace SubsurfaceTree {
|
namespace SubsurfaceTree {
|
||||||
SSurfaceTreeNode* createTreeRoot(wlr_surface*, applyGlobalOffsetFn, void*);
|
SSurfaceTreeNode* createTreeRoot(wlr_surface*, applyGlobalOffsetFn, void*, CWindow* pWindow = nullptr);
|
||||||
void destroySurfaceTree(SSurfaceTreeNode*);
|
void destroySurfaceTree(SSurfaceTreeNode*);
|
||||||
|
|
||||||
inline std::list<SSurfaceTreeNode> surfaceTreeNodes;
|
inline std::list<SSurfaceTreeNode> surfaceTreeNodes;
|
||||||
|
|
|
@ -31,7 +31,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
|
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
|
bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
|
||||||
wlr_box geometry = pWindow->getFullWindowBoundingBox();
|
wlr_box geometry = pWindow->getFullWindowBoundingBox();
|
||||||
|
|
||||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry))
|
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry))
|
||||||
|
@ -52,6 +52,27 @@ bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
||||||
|
|
||||||
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||||
|
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == m.ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (m.specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
||||||
CWindow* pWorkspaceWindow = nullptr;
|
CWindow* pWorkspaceWindow = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ public:
|
||||||
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
||||||
void damageMonitor(SMonitor*);
|
void damageMonitor(SMonitor*);
|
||||||
void applyMonitorRule(SMonitor*, SMonitorRule*, bool force = false);
|
void applyMonitorRule(SMonitor*, SMonitorRule*, bool force = false);
|
||||||
|
bool shouldRenderWindow(CWindow*, SMonitor*);
|
||||||
|
bool shouldRenderWindow(CWindow*);
|
||||||
|
|
||||||
DAMAGETRACKINGMODES damageTrackingModeFromStr(const std::string&);
|
DAMAGETRACKINGMODES damageTrackingModeFromStr(const std::string&);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue