summaryrefslogtreecommitdiff
path: root/src/protocols
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2026-02-20 22:31:59 +0000
committerGitHub <noreply@github.com>2026-02-20 22:31:59 +0000
commitd91952c555085758117f1eb360d4ace120ee5d65 (patch)
tree7bcf2d3b9454b075c0fc68b09f3c33e0f27b8a96 /src/protocols
parent8b17a7404b70a5ca2383320167a88e03289f0211 (diff)
wayland/output: return all bound wl_output instances in outputResourceFrom (#13315)
ref https://github.com/hyprwm/Hyprland/discussions/13301
Diffstat (limited to 'src/protocols')
-rw-r--r--src/protocols/ExtWorkspace.cpp7
-rw-r--r--src/protocols/ForeignToplevelWlr.cpp18
-rw-r--r--src/protocols/PresentationTime.cpp7
-rw-r--r--src/protocols/core/Compositor.cpp20
-rw-r--r--src/protocols/core/Output.cpp8
-rw-r--r--src/protocols/core/Output.hpp10
6 files changed, 46 insertions, 24 deletions
diff --git a/src/protocols/ExtWorkspace.cpp b/src/protocols/ExtWorkspace.cpp
index 2af72a4d..876949ba 100644
--- a/src/protocols/ExtWorkspace.cpp
+++ b/src/protocols/ExtWorkspace.cpp
@@ -27,8 +27,11 @@ CExtWorkspaceGroupResource::CExtWorkspaceGroupResource(WP<CExtWorkspaceManagerRe
const auto& output = PROTO::outputs.at(m_monitor->m_name);
- if (auto resource = output->outputResourceFrom(m_resource->client()))
- m_resource->sendOutputEnter(resource->getResource()->resource());
+ if (auto resources = output->outputResourcesFrom(m_resource->client()); !resources.empty()) {
+ for (const auto& r : resources) {
+ m_resource->sendOutputEnter(r->getResource()->resource());
+ }
+ }
m_listeners.outputBound = output->m_events.outputBound.listen([this](const SP<CWLOutputResource>& output) {
if (output->client() == m_resource->client())
diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp
index 5e18483d..89db1ad8 100644
--- a/src/protocols/ForeignToplevelWlr.cpp
+++ b/src/protocols/ForeignToplevelWlr.cpp
@@ -154,17 +154,23 @@ void CForeignToplevelHandleWlr::sendMonitor(PHLMONITOR pMonitor) {
const auto CLIENT = m_resource->client();
if (const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(m_lastMonitorID); PLASTMONITOR && PROTO::outputs.contains(PLASTMONITOR->m_name)) {
- const auto OLDRESOURCE = PROTO::outputs.at(PLASTMONITOR->m_name)->outputResourceFrom(CLIENT);
+ const auto OLDRESOURCES = PROTO::outputs.at(PLASTMONITOR->m_name)->outputResourcesFrom(CLIENT);
- if LIKELY (OLDRESOURCE)
- m_resource->sendOutputLeave(OLDRESOURCE->getResource()->resource());
+ if LIKELY (!OLDRESOURCES.empty()) {
+ for (const auto& r : OLDRESOURCES) {
+ m_resource->sendOutputLeave(r->getResource()->resource());
+ }
+ }
}
if (PROTO::outputs.contains(pMonitor->m_name)) {
- const auto NEWRESOURCE = PROTO::outputs.at(pMonitor->m_name)->outputResourceFrom(CLIENT);
+ const auto NEWRESOURCES = PROTO::outputs.at(pMonitor->m_name)->outputResourcesFrom(CLIENT);
- if LIKELY (NEWRESOURCE)
- m_resource->sendOutputEnter(NEWRESOURCE->getResource()->resource());
+ if LIKELY (!NEWRESOURCES.empty()) {
+ for (const auto& r : NEWRESOURCES) {
+ m_resource->sendOutputEnter(r->getResource()->resource());
+ }
+ }
}
m_lastMonitorID = pMonitor->m_id;
diff --git a/src/protocols/PresentationTime.cpp b/src/protocols/PresentationTime.cpp
index f1cd42d2..42c0e34c 100644
--- a/src/protocols/PresentationTime.cpp
+++ b/src/protocols/PresentationTime.cpp
@@ -44,8 +44,11 @@ void CPresentationFeedback::sendQueued(WP<CQueuedPresentationData> data, const t
auto client = m_resource->client();
if LIKELY (PROTO::outputs.contains(data->m_monitor->m_name) && data->m_wasPresented) {
- if LIKELY (auto outputResource = PROTO::outputs.at(data->m_monitor->m_name)->outputResourceFrom(client); outputResource)
- m_resource->sendSyncOutput(outputResource->getResource()->resource());
+ if LIKELY (auto outputResources = PROTO::outputs.at(data->m_monitor->m_name)->outputResourcesFrom(client); !outputResources.empty()) {
+ for (const auto& r : outputResources) {
+ m_resource->sendSyncOutput(r->getResource()->resource());
+ }
+ }
}
if (data->m_wasPresented) {
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp
index 7638486f..06f430b9 100644
--- a/src/protocols/core/Compositor.cpp
+++ b/src/protocols/core/Compositor.cpp
@@ -286,16 +286,20 @@ void CWLSurfaceResource::enter(PHLMONITOR monitor) {
return;
}
- auto output = PROTO::outputs.at(monitor->m_name)->outputResourceFrom(m_client);
+ auto outputs = PROTO::outputs.at(monitor->m_name)->outputResourcesFrom(m_client);
- if UNLIKELY (!output || !output->getResource() || !output->getResource()->resource()) {
+ if UNLIKELY (outputs.empty() || std::ranges::all_of(outputs, [](const auto& o) { return !o->getResource() || !o->getResource()->resource(); })) {
LOGM(Log::ERR, "Cannot enter surface {:x} to {}, client hasn't bound the output", (uintptr_t)this, monitor->m_name);
return;
}
m_enteredOutputs.emplace_back(monitor);
- m_resource->sendEnter(output->getResource().get());
+ for (const auto& o : outputs) {
+ if (!o->getResource() || !o->getResource()->resource())
+ continue;
+ m_resource->sendEnter(o->getResource().get());
+ }
m_events.enter.emit(monitor);
}
@@ -303,16 +307,20 @@ void CWLSurfaceResource::leave(PHLMONITOR monitor) {
if UNLIKELY (std::ranges::find(m_enteredOutputs, monitor) == m_enteredOutputs.end())
return;
- auto output = PROTO::outputs.at(monitor->m_name)->outputResourceFrom(m_client);
+ auto outputs = PROTO::outputs.at(monitor->m_name)->outputResourcesFrom(m_client);
- if UNLIKELY (!output) {
+ if UNLIKELY (outputs.empty() || std::ranges::all_of(outputs, [](const auto& o) { return !o->getResource() || !o->getResource()->resource(); })) {
LOGM(Log::ERR, "Cannot leave surface {:x} from {}, client hasn't bound the output", (uintptr_t)this, monitor->m_name);
return;
}
std::erase(m_enteredOutputs, monitor);
- m_resource->sendLeave(output->getResource().get());
+ for (const auto& o : outputs) {
+ if (!o->getResource() || !o->getResource()->resource())
+ continue;
+ m_resource->sendLeave(o->getResource().get());
+ }
m_events.leave.emit(monitor);
}
diff --git a/src/protocols/core/Output.cpp b/src/protocols/core/Output.cpp
index 755470e4..dd9c3166 100644
--- a/src/protocols/core/Output.cpp
+++ b/src/protocols/core/Output.cpp
@@ -117,15 +117,17 @@ void CWLOutputProtocol::destroyResource(CWLOutputResource* resource) {
PROTO::outputs.erase(m_name);
}
-SP<CWLOutputResource> CWLOutputProtocol::outputResourceFrom(wl_client* client) {
+std::vector<SP<CWLOutputResource>> CWLOutputProtocol::outputResourcesFrom(wl_client* client) {
+ std::vector<SP<CWLOutputResource>> ret;
+
for (auto const& r : m_outputs) {
if (r->client() != client)
continue;
- return r;
+ ret.emplace_back(r);
}
- return nullptr;
+ return ret;
}
void CWLOutputProtocol::remove() {
diff --git a/src/protocols/core/Output.hpp b/src/protocols/core/Output.hpp
index d0c6fb13..cf266685 100644
--- a/src/protocols/core/Output.hpp
+++ b/src/protocols/core/Output.hpp
@@ -34,13 +34,13 @@ class CWLOutputProtocol : public IWaylandProtocol {
public:
CWLOutputProtocol(const wl_interface* iface, const int& ver, const std::string& name, PHLMONITOR pMonitor);
- virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
+ virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
- SP<CWLOutputResource> outputResourceFrom(wl_client* client);
- void sendDone();
+ std::vector<SP<CWLOutputResource>> outputResourcesFrom(wl_client* client);
+ void sendDone();
- PHLMONITORREF m_monitor;
- WP<CWLOutputProtocol> m_self;
+ PHLMONITORREF m_monitor;
+ WP<CWLOutputProtocol> m_self;
// will mark the protocol for removal, will be removed when no. of bound outputs is 0 (or when overwritten by a new global)
void remove();