protocols/outputMgmt: fix wlr-randr by defering success event until monitor reloads (#12236)
wlr-randr disconnects immediately after receiving success event, but before applying the monitor configuration. This causes the state to be lost when performMonitorReload() is called. By postponing the success event until the call of the hook monitorLayoutChanged we ensure the configuration to remain valid during the reload process.
This commit is contained in:
parent
522edc8712
commit
06b37c3907
2 changed files with 30 additions and 2 deletions
|
|
@ -28,6 +28,8 @@ COutputManager::COutputManager(SP<CZwlrOutputManagerV1> resource_) : m_resource(
|
|||
PROTO::outputManagement->m_configurations.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
RESOURCE->m_self = RESOURCE;
|
||||
});
|
||||
|
||||
// send all heads at start
|
||||
|
|
@ -335,7 +337,7 @@ COutputConfiguration::COutputConfiguration(SP<CZwlrOutputConfigurationV1> resour
|
|||
const auto SUCCESS = applyTestConfiguration(false);
|
||||
|
||||
if (SUCCESS)
|
||||
m_resource->sendSucceeded();
|
||||
PROTO::outputManagement->m_pendingConfigurationSuccessEvents.emplace_back(m_self);
|
||||
else
|
||||
m_resource->sendFailed();
|
||||
|
||||
|
|
@ -576,7 +578,10 @@ bool COutputConfigurationHead::good() {
|
|||
}
|
||||
|
||||
COutputManagementProtocol::COutputManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
static auto P = g_pHookSystem->hookDynamic("monitorLayoutChanged", [this](void* self, SCallbackInfo& info, std::any param) { this->updateAllOutputs(); });
|
||||
static auto P = g_pHookSystem->hookDynamic("monitorLayoutChanged", [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
updateAllOutputs();
|
||||
sendPendingSuccessEvents();
|
||||
});
|
||||
}
|
||||
|
||||
void COutputManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
|
|
@ -647,3 +652,19 @@ SP<SWlrManagerSavedOutputState> COutputManagementProtocol::getOutputStateFor(PHL
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void COutputManagementProtocol::sendPendingSuccessEvents() {
|
||||
if (m_pendingConfigurationSuccessEvents.empty())
|
||||
return;
|
||||
|
||||
LOGM(LOG, "Sending {} pending configuration success events", m_pendingConfigurationSuccessEvents.size());
|
||||
|
||||
for (auto const& config : m_pendingConfigurationSuccessEvents) {
|
||||
if (!config)
|
||||
continue;
|
||||
|
||||
config->m_resource->sendSucceeded();
|
||||
}
|
||||
|
||||
m_pendingConfigurationSuccessEvents.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,8 +141,12 @@ class COutputConfiguration {
|
|||
SP<CZwlrOutputConfigurationV1> m_resource;
|
||||
std::vector<WP<COutputConfigurationHead>> m_heads;
|
||||
WP<COutputManager> m_owner;
|
||||
WP<COutputConfiguration> m_self;
|
||||
|
||||
bool applyTestConfiguration(bool test);
|
||||
|
||||
friend class COutputManagementProtocol;
|
||||
friend class COutputManager;
|
||||
};
|
||||
|
||||
class COutputManagementProtocol : public IWaylandProtocol {
|
||||
|
|
@ -154,6 +158,8 @@ class COutputManagementProtocol : public IWaylandProtocol {
|
|||
// doesn't have to return one
|
||||
SP<SWlrManagerSavedOutputState> getOutputStateFor(PHLMONITOR pMonitor);
|
||||
|
||||
void sendPendingSuccessEvents();
|
||||
|
||||
private:
|
||||
void destroyResource(COutputManager* resource);
|
||||
void destroyResource(COutputHead* resource);
|
||||
|
|
@ -169,6 +175,7 @@ class COutputManagementProtocol : public IWaylandProtocol {
|
|||
std::vector<SP<COutputMode>> m_modes;
|
||||
std::vector<SP<COutputConfiguration>> m_configurations;
|
||||
std::vector<SP<COutputConfigurationHead>> m_configurationHeads;
|
||||
std::vector<WP<COutputConfiguration>> m_pendingConfigurationSuccessEvents;
|
||||
|
||||
SP<COutputHead> headFromResource(wl_resource* r);
|
||||
SP<COutputMode> modeFromResource(wl_resource* r);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue