Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ jobs:
# Doxygen from Ubuntu is too old, need Doxygen >= 1.10
DOCS=OFF
else
DOCS=ON
DOCS=OFF
fi

cmake \
Expand Down
20 changes: 17 additions & 3 deletions src/common/include/display_device/settings_manager_interface.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,20 @@ namespace display_device {
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Outcome values when trying to revert settings.
*/
enum class RevertResult {
Ok, ///< Settings were reverted successfully
ApiTemporarilyUnavailable, ///< API is temporarily unavailable
TopologyIsInvalid, ///< Topology is invalid
SwitchingTopologyFailed, ///< Switching topology has failed
RevertingPrimaryDeviceFailed, ///< Reverting primary device failed
RevertingDisplayModesFailed, ///< Reverting display modes failed
RevertingHdrStatesFailed, ///< Reverting HDR states failed
PersistenceSaveFailed, ///< Persistence save failed
};

/**
* @brief Default virtual destructor.
*/
Expand DownExpand Up@@ -79,7 +93,7 @@ namespace display_device {
* const auto result = iface->revertSettings();
* @examples_end
*/
[[nodiscard]] virtual bool
[[nodiscard]] virtual RevertResult
revertSettings() = 0;

/**
Expand All@@ -94,11 +108,11 @@ namespace display_device {
* auto result = iface->applySettings(config);
* if (result == ApplyResult::Ok) {
* // Wait for some time
* if (!iface->revertSettings()) {
* if (iface->revertSettings() != RevertResult::Ok) {
* // Wait for user input
* const bool user_wants_reset { true };
* if (user_wants_reset) {
* result = iface->resetPersistence();
* iface->resetPersistence();
* }
* }
* }
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ namespace display_device {
applySettings(const SingleDisplayConfiguration &config) override;

/** For details @see SettingsManagerInterface::revertSettings */
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertSettings() override;

/** For details @see SettingsManagerInterface::resetPersistence */
Expand DownExpand Up@@ -107,11 +107,11 @@ namespace display_device {
* @param current_topology Topology before this method is called.
* @param system_settings_touched Indicates whether a "write" operation could have been performed on the OS.
* @param switched_topology [Optional] Indicates whether the current topology was switched to revert settings.
* @returns True on success, false otherwise.
* @returns Result enum indicating success or failure.
* @warning The method assumes that the caller will ensure restoring the topology
* in case of a failure!
*/
[[nodiscard]] bool
[[nodiscard]] RevertResult
revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology = nullptr);

std::shared_ptr<WinDisplayDeviceInterface> m_dd_api;
Expand Down
14 changes: 6 additions & 8 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@
*/
namespace display_device::win_utils {
/**
* @brief Get all the device its in the topology.
* @brief Get all the device ids in the topology.
* @param topology Topology to be "flattened".
* @return Device ids found in the topology.
* @examples
Expand All@@ -29,18 +29,16 @@ namespace display_device::win_utils {
flattenTopology(const ActiveTopology &topology);

/**
* @brief Remove all unavailable devices from the topology.
* @brief Create extended topology from all the available devices.
* @param win_dd Interface for interacting with the OS.
* @param topology Topology to be stripped.
* @return Topology with only available devices.
* @return Extended topology with all the available devices.
* @examples
* const WinDisplayDeviceInterface* iface = getIface(...);
* const ActiveTopology topology { { "DeviceId1", "DeviceId2" }, { "DeviceId3" } };
* const auto stripped_topology { stripTopologyOfUnavailableDevices(*iface, topology) };
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand DownExpand Up@@ -86,7 +84,7 @@ namespace display_device::win_utils {

/**
* @brief Compute new topology from arbitrary data.
* @param device_prep Specify how to to compute the new topology.
* @param device_prep Specify how to compute the new topology.
* @param configuring_primary_devices Specify whether the `device_to_configure` was unspecified (primary device was selected).
* @param device_to_configure Main device to be configured.
* @param additional_devices_to_configure Additional devices that belong to the same group as `device_to_configure`.
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_apply.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ namespace display_device {
if (change_is_needed) {
if (cached_state && !m_dd_api->isTopologyTheSame(cached_state->m_modified.m_topology, new_topology)) {
DD_LOG(warning) << "To apply new display device settings, previous modifications must be undone! Trying to undo them now.";
if (!revertModifiedSettings(topology_before_changes, system_settings_touched)) {
if (revertModifiedSettings(topology_before_changes, system_settings_touched) != RevertResult::Ok) {
DD_LOG(error) << "Failed to apply new configuration, because the previous settings could not be reverted!";
return std::nullopt;
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/settings_manager_general.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ namespace display_device {
bool
SettingsManager::resetPersistence() {
// Trying to revert one more time in case we succeed.
if (revertSettings()) {
if (revertSettings() == RevertResult::Ok) {
return true;
}

Expand Down
44 changes: 22 additions & 22 deletions src/windows/settings_manager_revert.cpp
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/**
* @file src/windows/settings_manager_revert.cpp
* @brief Definitions for the methods for reverting settings in SettingsManager..
* @brief Definitions for the methods for reverting settings in SettingsManager.
*/
// class header include
#include "display_device/windows/settings_manager.h"
Expand All@@ -23,25 +23,25 @@ namespace display_device {
}
} // namespace

bool
SettingsManager::RevertResult
SettingsManager::revertSettings() {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state) {
return true;
return RevertResult::Ok;
}

const auto api_access { m_dd_api->isApiAccessAvailable() };
DD_LOG(info) << "Trying to revert applied display device settings. API is available: " << toJson(api_access);

if (!api_access) {
return false;
return RevertResult::ApiTemporarilyUnavailable;
}

const auto current_topology { m_dd_api->getCurrentTopology() };
if (!m_dd_api->isTopologyValid(current_topology)) {
DD_LOG(error) << "Retrieved current topology is invalid:\n"
<< toJson(current_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

bool system_settings_touched { false };
Expand All@@ -50,8 +50,8 @@ namespace display_device {
win_utils::blankHdrStates(*m_dd_api, m_workarounds.m_hdr_blank_delay);
}
} };
boost::scope::scope_exit topology_prep_guard { [this, &cached_state, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::stripTopologyOfUnavailableDevices(*m_dd_api, cached_state->m_initial.m_topology) };
boost::scope::scope_exit topology_prep_guard { [this, &current_topology, &system_settings_touched]() {
auto topology_to_restore { win_utils::createFullExtendedTopology(*m_dd_api) };
if (!m_dd_api->isTopologyValid(topology_to_restore)) {
topology_to_restore = current_topology;
}
Expand All@@ -66,15 +66,15 @@ namespace display_device {

// We can revert the modified setting independently before playing around with initial topology.
bool switched_to_modified_topology { false };
if (!revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology)) {
if (const auto result = revertModifiedSettings(current_topology, system_settings_touched, &switched_to_modified_topology); result != RevertResult::Ok) {
// Error already logged
return false;
return result;
}

if (!m_dd_api->isTopologyValid(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Trying to revert to an invalid initial topology:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_initial.m_topology) };
Expand All@@ -83,12 +83,12 @@ namespace display_device {
if (need_to_switch_topology && !m_dd_api->setTopology(cached_state->m_initial.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_initial.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}

if (!m_persistence_state->persistState(std::nullopt)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing initial topology changes...";
return false;
return RevertResult::PersistenceSaveFailed;
}

if (m_audio_context_api->isCaptured()) {
Expand All@@ -97,28 +97,28 @@ namespace display_device {

// Disable guards
topology_prep_guard.set_active(false);
return true;
return RevertResult::Ok;
}

bool
SettingsManager::RevertResult
SettingsManager::revertModifiedSettings(const ActiveTopology &current_topology, bool &system_settings_touched, bool *switched_topology) {
const auto &cached_state { m_persistence_state->getState() };
if (!cached_state || !cached_state->m_modified.hasModifications()) {
return true;
return RevertResult::Ok;
}

if (!m_dd_api->isTopologyValid(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Trying to revert modified settings using invalid topology:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::TopologyIsInvalid;
}

const bool is_topology_the_same { m_dd_api->isTopologyTheSame(current_topology, cached_state->m_modified.m_topology) };
system_settings_touched = !is_topology_the_same;
if (!is_topology_the_same && !m_dd_api->setTopology(cached_state->m_modified.m_topology)) {
DD_LOG(error) << "Failed to change topology to:\n"
<< toJson(cached_state->m_modified.m_topology);
return false;
return RevertResult::SwitchingTopologyFailed;
}
if (switched_topology) {
*switched_topology = !is_topology_the_same;
Expand All@@ -135,7 +135,7 @@ namespace display_device {
<< toJson(cached_state->m_modified.m_original_hdr_states);
if (!m_dd_api->setHdrStates(cached_state->m_modified.m_original_hdr_states)) {
// Error already logged
return false;
return RevertResult::RevertingHdrStatesFailed;
}

hdr_guard_fn = win_utils::hdrStateGuardFn(*m_dd_api, current_states);
Expand All@@ -152,7 +152,7 @@ namespace display_device {
if (!m_dd_api->setDisplayModes(cached_state->m_modified.m_original_modes)) {
system_settings_touched = true;
// Error already logged
return false;
return RevertResult::RevertingDisplayModesFailed;
}

// It is possible that the display modes will not actually change even though the "current != new" condition is true.
Expand All@@ -175,7 +175,7 @@ namespace display_device {
DD_LOG(info) << "Trying to change back the original primary device to: " << toJson(cached_state->m_modified.m_original_primary_device);
if (!m_dd_api->setAsPrimary(cached_state->m_modified.m_original_primary_device)) {
// Error already logged
return false;
return RevertResult::RevertingPrimaryDeviceFailed;
}

primary_guard_fn = win_utils::primaryGuardFn(*m_dd_api, current_primary_device);
Expand All@@ -186,13 +186,13 @@ namespace display_device {
cleared_data.m_modified = { cleared_data.m_modified.m_topology };
if (!m_persistence_state->persistState(cleared_data)) {
DD_LOG(error) << "Failed to save reverted settings! Undoing changes to modified topology...";
return false;
return RevertResult::PersistenceSaveFailed;
}

// Disable guards
hdr_guard.set_active(false);
mode_guard.set_active(false);
primary_guard.set_active(false);
return true;
return RevertResult::Ok;
}
} // namespace display_device
11 changes: 8 additions & 3 deletions src/windows/settings_utils.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,19 @@ namespace display_device::win_utils {
}

ActiveTopology
stripTopologyOfUnavailableDevices(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
const auto devices { win_dd.enumAvailableDevices() };
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for stripping topology!";
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
return {};
}

return stripTopology(topology, devices);
ActiveTopology topology;
for (const auto &device : devices) {
topology.push_back({ device.m_device_id });
}

return topology;
}

std::string
Expand Down
4 changes: 2 additions & 2 deletions src/windows/win_api_layer.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -612,12 +612,12 @@ namespace display_device {
return TRUE; }, reinterpret_cast<LPARAM>(&enum_data));

if (!enum_data.m_width) {
DD_LOG(error) << "Failed to get monitor info for " << display_name << "!";
DD_LOG(debug) << "Failed to get monitor info for " << display_name << "!";
return std::nullopt;
}

if (*enum_data.m_width * source_mode.width == 0) {
DD_LOG(error) << "Cannot get display scale for " << display_name << " from a width of 0!";
DD_LOG(debug) << "Cannot get display scale for " << display_name << " from a width of 0!";
return std::nullopt;
}

Expand Down
Loading