mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-22 19:49:49 +01:00
monitor: avoid dangling references to old monitors being undestroyed
ref #7414
This commit is contained in:
parent
272d904870
commit
c86db7bbb0
5 changed files with 19 additions and 33 deletions
|
@ -2935,7 +2935,7 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) {
|
|||
|
||||
void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
|
||||
// add it to real
|
||||
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>());
|
||||
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>(output));
|
||||
if (std::string("HEADLESS-1") == output->name) {
|
||||
g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get();
|
||||
output->name = "FALLBACK"; // we are allowed to do this :)
|
||||
|
@ -2944,7 +2944,6 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
|
|||
Debug::log(LOG, "New output with name {}", output->name);
|
||||
|
||||
PNEWMONITOR->szName = output->name;
|
||||
PNEWMONITOR->output = output;
|
||||
PNEWMONITOR->self = PNEWMONITOR;
|
||||
const bool FALLBACK = g_pCompositor->m_pUnsafeOutput ? output == g_pCompositor->m_pUnsafeOutput->output : false;
|
||||
PNEWMONITOR->ID = FALLBACK ? MONITOR_INVALID : g_pCompositor->getNextAvailableMonitorID(output->name);
|
||||
|
|
|
@ -27,7 +27,6 @@ namespace Events {
|
|||
|
||||
// Monitor part 2 the sequel
|
||||
DYNLISTENFUNC(monitorFrame);
|
||||
DYNLISTENFUNC(monitorDestroy);
|
||||
DYNLISTENFUNC(monitorStateRequest);
|
||||
DYNLISTENFUNC(monitorDamage);
|
||||
DYNLISTENFUNC(monitorNeedsFrame);
|
||||
|
|
|
@ -85,31 +85,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
}
|
||||
}
|
||||
|
||||
void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||
CMonitor* pMonitor = (CMonitor*)owner;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||
if (m->output == pMonitor->output) {
|
||||
pMonitor = m.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pMonitor)
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "Destroy called for monitor {}", pMonitor->szName);
|
||||
|
||||
pMonitor->onDisconnect(true);
|
||||
|
||||
pMonitor->output = nullptr;
|
||||
pMonitor->m_bRenderingInitPassed = false;
|
||||
|
||||
Debug::log(LOG, "Removing monitor {} from realMonitors", pMonitor->szName);
|
||||
|
||||
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == pMonitor; });
|
||||
}
|
||||
|
||||
void Events::listener_monitorNeedsFrame(void* owner, void* data) {
|
||||
const auto PMONITOR = (CMonitor*)owner;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ int ratHandler(void* data) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
CMonitor::CMonitor() : state(this) {
|
||||
CMonitor::CMonitor(SP<Aquamarine::IOutput> output_) : state(this), output(output_) {
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -40,16 +40,29 @@ void CMonitor::onConnect(bool noRule) {
|
|||
outTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
|
||||
}
|
||||
|
||||
listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
|
||||
listeners.destroy = output->events.destroy.registerListener([this](std::any d) { Events::listener_monitorDestroy(this, nullptr); });
|
||||
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
|
||||
listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
|
||||
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
|
||||
listeners.needsFrame =
|
||||
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
|
||||
|
||||
listeners.presented = output->events.present.registerListener([this](std::any d) {
|
||||
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
|
||||
PROTO::presentation->onPresented(this, E.when, E.refresh, E.seq, E.flags);
|
||||
});
|
||||
|
||||
listeners.destroy = output->events.destroy.registerListener([this](std::any d) {
|
||||
Debug::log(LOG, "Destroy called for monitor {}", szName);
|
||||
|
||||
onDisconnect(true);
|
||||
|
||||
output = nullptr;
|
||||
m_bRenderingInitPassed = false;
|
||||
|
||||
Debug::log(LOG, "Removing monitor {} from realMonitors", szName);
|
||||
|
||||
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == this; });
|
||||
});
|
||||
|
||||
listeners.state = output->events.state.registerListener([this](std::any d) {
|
||||
auto E = std::any_cast<Aquamarine::IOutput::SStateEvent>(d);
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class CMonitorState {
|
|||
|
||||
class CMonitor {
|
||||
public:
|
||||
CMonitor();
|
||||
CMonitor(SP<Aquamarine::IOutput> output);
|
||||
~CMonitor();
|
||||
|
||||
Vector2D vecPosition = Vector2D(-1, -1); // means unset
|
||||
|
|
Loading…
Reference in a new issue