mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-11-12 03:28:20 +08:00
[feat] remember remote display resolutions across connections
This commit is contained in:
1 parent
17b4db25fb
commit
a862bf6b35
15 files changed
+414
-67
No files matched your search
@@ -253,6 +253,8 @@ int SessionDeviceManager::InitializeScreenCapturer() {
|
||||
uint64_t send_errors = 0;
|
||||
for (const std::string &remote_id : connected_remote_ids) {
|
||||
if (owner_.managed_host_frontend_ && remote_id.rfind("lan/", 0) != 0) continue;
|
||||
// Warm/shared capture may already be running for another controller.
|
||||
if (!owner_.DisplayResolutionsReadyForCapture(remote_id)) continue;
|
||||
if (!owner_.preview_subscriptions_.ShouldSend(remote_id, now_time,
|
||||
stream_id)) continue;
|
||||
if (owner_.WithController(
|
||||
@@ -693,6 +695,9 @@ void SessionDeviceManager::PushAudio(const std::string& remote_id,
|
||||
}
|
||||
|
||||
void SessionDeviceManager::UpdateInteractions() {
|
||||
// Restore the previous session's modes and apply the new controller's saved
|
||||
// selections before starting capture or allowing an early input return.
|
||||
owner_.HandleDisplayResolutionChanges();
|
||||
// Release even when pending remote-input cleanup makes this tick return early.
|
||||
UpdateScreenSharingPower();
|
||||
#ifdef _WIN32
|
||||
@@ -720,7 +725,8 @@ void SessionDeviceManager::UpdateInteractions() {
|
||||
|
||||
if (owner_.start_screen_capturer_ && !owner_.screen_capturer_is_started_) {
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (now >= next_capture_start_retry_) {
|
||||
if (now >= next_capture_start_retry_ &&
|
||||
owner_.DisplayResolutionsReadyForCapture()) {
|
||||
next_capture_start_retry_ = now + std::chrono::seconds(1);
|
||||
if (StartScreenCapturer() == 0) {
|
||||
owner_.screen_capturer_is_started_ = true;
|
||||
@@ -799,7 +805,6 @@ void SessionDeviceManager::UpdateInteractions() {
|
||||
}
|
||||
|
||||
owner_.keyboard_.CheckRemoteTimeouts();
|
||||
owner_.HandleDisplayResolutionChanges();
|
||||
}
|
||||
|
||||
void SessionDeviceManager::DrainCapturedKeyboardInput() {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "remote_resolution_store.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <display_resolution_preferences.h>
|
||||
|
||||
#include "common/private_file.h"
|
||||
|
||||
namespace crossdesk {
|
||||
namespace {
|
||||
constexpr std::uintmax_t kMaxStoreBytes = 8 * 1024 * 1024;
|
||||
}
|
||||
|
||||
bool RemoteResolutionStore::Load(const std::filesystem::path &path) {
|
||||
std::lock_guard lock(mutex_);
|
||||
path_ = path;
|
||||
devices_.clear();
|
||||
try {
|
||||
if (!std::filesystem::exists(path_)) return true;
|
||||
if (std::filesystem::file_size(path_) > kMaxStoreBytes) return false;
|
||||
std::ifstream input(path_, std::ios::binary);
|
||||
const auto json = nlohmann::json::parse(input);
|
||||
if (json.at("version") != 1 || !json.at("devices").is_object())
|
||||
return false;
|
||||
for (const auto &[device, values] : json.at("devices").items()) {
|
||||
std::vector<DisplayResolutionPreference> preferences;
|
||||
if (!device.empty() && ReadDisplayResolutionPreferences(values, preferences))
|
||||
devices_.emplace(device, std::move(preferences));
|
||||
}
|
||||
return true;
|
||||
} catch (const std::exception &) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DisplayResolutionPreference>
|
||||
RemoteResolutionStore::Get(const std::string &device) const {
|
||||
std::lock_guard lock(mutex_);
|
||||
const auto found = devices_.find(device);
|
||||
return found == devices_.end() ? std::vector<DisplayResolutionPreference>{}
|
||||
: found->second;
|
||||
}
|
||||
|
||||
bool RemoteResolutionStore::Remember(
|
||||
const std::string &device, const DisplayResolutionPreference &preference) {
|
||||
if (device.empty() || !ValidDisplayResolutionPreference(preference))
|
||||
return false;
|
||||
std::lock_guard lock(mutex_);
|
||||
if (path_.empty()) return false;
|
||||
auto updated = devices_;
|
||||
auto &preferences = updated[device];
|
||||
const auto found = std::find_if(preferences.begin(), preferences.end(),
|
||||
[&](const auto &saved) { return saved.display_key == preference.display_key; });
|
||||
if (found != preferences.end()) {
|
||||
if (found->resolution == preference.resolution) return true;
|
||||
*found = preference;
|
||||
} else {
|
||||
if (preferences.size() >= kMaxResolutionDisplays)
|
||||
preferences.erase(preferences.begin());
|
||||
preferences.push_back(preference);
|
||||
}
|
||||
try {
|
||||
nlohmann::json json{{"version", 1}, {"devices", nlohmann::json::object()}};
|
||||
for (const auto &[id, saved] : updated)
|
||||
json["devices"][id] = DisplayResolutionPreferencesJson(saved);
|
||||
const auto text = json.dump(2);
|
||||
if (text.size() > kMaxStoreBytes) return false;
|
||||
private_file::EnsureDirectory(path_.parent_path());
|
||||
private_file::Write(path_, text);
|
||||
devices_ = std::move(updated);
|
||||
return true;
|
||||
} catch (const std::exception &) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace crossdesk
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2026-11-11
|
||||
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REMOTE_RESOLUTION_STORE_H_
|
||||
#define _REMOTE_RESOLUTION_STORE_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#include <display_resolution.h>
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
class RemoteResolutionStore {
|
||||
public:
|
||||
bool Load(const std::filesystem::path &path);
|
||||
std::vector<DisplayResolutionPreference> Get(const std::string &device) const;
|
||||
bool Remember(const std::string &device,
|
||||
const DisplayResolutionPreference &preference);
|
||||
|
||||
private:
|
||||
mutable std::mutex mutex_;
|
||||
std::filesystem::path path_;
|
||||
std::map<std::string, std::vector<DisplayResolutionPreference>> devices_;
|
||||
};
|
||||
|
||||
} // namespace crossdesk
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user