Skip to content

Commit

Permalink
add dark title bar support on windows (#1288)
Browse files Browse the repository at this point in the history
  • Loading branch information
chirag-droid authored Feb 14, 2024
1 parent 4a525fd commit 10dfd8d
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
4 changes: 4 additions & 0 deletions library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ else ()
$<BUILD_INTERFACE:${F3D_SOURCE_DIR}/external/nlohmann_json>)
endif ()

if (WIN32)
target_link_libraries(libf3d PRIVATE Dwmapi)
endif()

set_target_properties(libf3d PROPERTIES
CXX_STANDARD 17
CXX_VISIBILITY_PRESET hidden
Expand Down
96 changes: 96 additions & 0 deletions library/src/window_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
#include <vtkExternalOpenGLRenderWindow.h>
#endif

#ifdef _WIN32
#include <Windows.h>
#include <dwmapi.h>

#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif

constexpr auto IMMERSIVE_DARK_MODE_SUPPORTED_SINCE = 19041;
#endif

namespace f3d::detail
{
class window_impl::internals
Expand All @@ -44,6 +55,90 @@ class window_impl::internals
return this->CachePath;
}

#if _WIN32
/**
* Helper function to detect if the
* Windows Build Number is equal or greater to a number
*/
static bool IsWindowsBuildNumberOrGreater(int buildNumber)
{
std::string value{};
bool result = vtksys::SystemTools::ReadRegistryValue(
"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion;CurrentBuildNumber",
value);

if (result == true)
{
try
{
return std::stoi(value) >= buildNumber;
}
catch (const std::invalid_argument& e)
{
f3d::log::debug("Error parsing CurrentBuildNumber", e.what());
}
}
else
{
f3d::log::debug("Error opening registry key.");
}

return false;
}

/**
* Helper function to fetch a DWORD from windows registry.
*
* @param hKey A handle to an open registry key
* @param subKey The path of registry key relative to 'hKey'
* @param value The name of the registry value
* @param dWord Variable to store the result in
*/
static bool ReadRegistryDWord(
HKEY hKey, const std::wstring& subKey, const std::wstring& value, DWORD& dWord)
{
DWORD dataSize = sizeof(DWORD);
LONG result = RegGetValueW(
hKey, subKey.c_str(), value.c_str(), RRF_RT_REG_DWORD, nullptr, &dWord, &dataSize);

return result == ERROR_SUCCESS;
}

/**
* Helper function to detect user theme
*/
static bool IsWindowsInDarkMode()
{
std::wstring subKey(L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");

DWORD value{};

if (ReadRegistryDWord(HKEY_CURRENT_USER, subKey, L"AppsUseLightTheme", value))
{
return value == 0;
}

if (ReadRegistryDWord(HKEY_CURRENT_USER, subKey, L"SystemUsesLightTheme", value))
{
return value == 0;
}

return false;
}
#endif

void UpdateTheme() const
{
#ifdef _WIN32
if (this->IsWindowsBuildNumberOrGreater(IMMERSIVE_DARK_MODE_SUPPORTED_SINCE))
{
HWND hwnd = static_cast<HWND>(this->RenWin->GetGenericWindowId());
BOOL useDarkMode = this->IsWindowsInDarkMode();
DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &useDarkMode, sizeof(useDarkMode));
}
#endif
}

std::unique_ptr<camera_impl> Camera;
vtkSmartPointer<vtkRenderWindow> RenWin;
vtkNew<vtkF3DRendererWithColoring> Renderer;
Expand Down Expand Up @@ -214,6 +309,7 @@ void window_impl::Initialize(bool withColoring)
{
this->Internals->WithColoring = withColoring;
this->Internals->Renderer->Initialize(this->Internals->Options.getAsString("scene.up-direction"));
this->Internals->UpdateTheme();
this->Internals->Initialized = true;
}

Expand Down

0 comments on commit 10dfd8d

Please sign in to comment.