[feat] remember remote display resolutions across connections

This commit is contained in:
dijunkun
2026-11-11 14:14:00 +08:00
parent 17b4db25fb
commit a862bf6b35
15 changed files with 414 additions and 67 deletions
+15 -1
View File
@@ -52,6 +52,20 @@ struct DisplayResolutionChange {
bool accepted = false;
};
// Persist the native identity, never the display's position in a session.
struct DisplayResolutionPreference {
std::string display_key;
DisplayResolution resolution;
};
inline bool ValidDisplayResolutionPreference(
const DisplayResolutionPreference &preference) {
return !preference.display_key.empty() &&
preference.display_key.size() <= 1024 &&
preference.display_key.find('\0') == std::string::npos &&
ValidDisplayResolution(preference.resolution);
}
inline bool SupportsDisplayResolution(const DisplayResolutionInfo &display,
const DisplayResolutionChange &change) {
return display.display_id == change.display_id &&
@@ -62,4 +76,4 @@ inline bool SupportsDisplayResolution(const DisplayResolutionInfo &display,
} // namespace crossdesk
#endif
#endif
@@ -0,0 +1,58 @@
/*
* @Author: DI JUNKUN
* @Date: 2026-11-11
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _DISPLAY_RESOLUTION_PREFERENCES_H_
#define _DISPLAY_RESOLUTION_PREFERENCES_H_
#include <nlohmann/json.hpp>
#include "display_resolution.h"
namespace crossdesk {
inline nlohmann::json DisplayResolutionPreferencesJson(
const std::vector<DisplayResolutionPreference> &preferences) {
auto result = nlohmann::json::array();
for (const auto &preference : preferences)
result.push_back({{"display_key", preference.display_key},
{"width", preference.resolution.width},
{"height", preference.resolution.height}});
return result;
}
inline bool ReadDisplayResolutionPreferences(
const nlohmann::json &values,
std::vector<DisplayResolutionPreference> &result) {
std::vector<DisplayResolutionPreference> parsed;
if (!values.is_array() || values.size() > kMaxResolutionDisplays)
return false;
try {
for (const auto &value : values) {
const auto &width = value.at("width");
const auto &height = value.at("height");
if (!width.is_number_integer() || !height.is_number_integer() ||
width < 1 || width > 32768 || height < 1 || height > 32768)
return false;
DisplayResolutionPreference preference{
value.at("display_key").get<std::string>(),
{width.get<int>(), height.get<int>()}};
if (!ValidDisplayResolutionPreference(preference) ||
std::any_of(parsed.begin(), parsed.end(), [&](const auto &existing) {
return existing.display_key == preference.display_key;
}))
return false;
parsed.push_back(std::move(preference));
}
} catch (const nlohmann::json::exception &) {
return false;
}
result = std::move(parsed);
return true;
}
} // namespace crossdesk
#endif
+2
View File
@@ -223,6 +223,8 @@ struct RemoteAction {
// Optional host information extension, also returned with resolution status.
std::vector<DisplayResolutionInfo> display_resolutions;
DisplayResolutionChange resolution_change;
// Controller preferences sent with its initial host information.
std::vector<DisplayResolutionPreference> preferred_display_resolutions;
std::string to_json() const;
bool from_json(const std::string& json_string);