Import theme from roblox and fix x11

vkAcquireNextImageKHR(): A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully. (VK_SUBOPTIMAL_KHR) (1000001003)
This commit is contained in:
komaruworld committed 2026-08-31 21:42:35 +03:00
1 parent d5f9c91358
commit 035c7fe1d4
19 files changed
+244 -31

No files matched your search

+62
View File
@@ -341,6 +341,68 @@ PlatformCacheMigrationResult MigratePlatformProfileCaches(
return result;
}
RobloxThemeCacheResult ReadRobloxThemeCache(
const std::filesystem::path& app_storage_file,
std::int64_t authenticated_user_id) {
RobloxThemeCacheResult result;
if (!app_storage_file.is_absolute() || authenticated_user_id < -1) {
result.error = "Roblox theme cache path or user ID is invalid";
return result;
}
const JsonReadResult storage = ReadJson(app_storage_file);
if (storage.status == ReadStatus::kInvalid) {
result.error = storage.error;
return result;
}
if (storage.status == ReadStatus::kMissing) {
return result;
}
const auto read_theme = [&result](const nlohmann::json& value,
std::string_view name) {
if (!value.is_string()) {
result.error = std::string(name) + " is not a string";
return;
}
const std::string& theme = value.get_ref<const std::string&>();
if (theme != "dark" && theme != "light") {
result.error = std::string(name) + " must be dark or light";
return;
}
result.dark_theme = theme == "dark";
};
if (authenticated_user_id >= 0) {
const auto encoded_device_themes = storage.value.find("DeviceLevelTheme");
if (encoded_device_themes != storage.value.end()) {
if (!encoded_device_themes->is_string()) {
result.error = "Roblox DeviceLevelTheme is not an encoded object";
return result;
}
const nlohmann::json device_themes = nlohmann::json::parse(
encoded_device_themes->get_ref<const std::string&>(), nullptr, false,
true);
if (device_themes.is_discarded() || !device_themes.is_object()) {
result.error = "Roblox DeviceLevelTheme encoding is invalid";
return result;
}
const auto account_theme =
device_themes.find(std::to_string(authenticated_user_id));
if (account_theme != device_themes.end()) {
read_theme(*account_theme, "Roblox account theme");
return result;
}
}
}
const auto authenticated_theme = storage.value.find("AuthenticatedTheme");
if (authenticated_theme != storage.value.end()) {
read_theme(*authenticated_theme, "Roblox authenticated theme");
}
return result;
}
bool ApplyRobloxThemeCacheOverride(
const std::filesystem::path& app_storage_file,
std::int64_t authenticated_user_id, bool dark_theme, std::string* error) {
+10 -3
View File
@@ -206,13 +206,18 @@ bool DecodePolicy(const nlohmann::json& encoded, nlohmann::json* policy) {
DesktopAppPolicyResult ApplyDesktopAppPolicy(
const std::filesystem::path& app_storage_file,
const std::filesystem::path& default_policy_file,
std::int64_t authenticated_user_id) {
std::int64_t authenticated_user_id, std::string_view theme_mode) {
DesktopAppPolicyResult result;
if (!app_storage_file.is_absolute() || !default_policy_file.is_absolute() ||
authenticated_user_id < -1) {
result.error = "desktop app-policy paths or user ID are invalid";
authenticated_user_id < -1 ||
(theme_mode != "roblox" && theme_mode != "system" &&
theme_mode != "light" && theme_mode != "dark")) {
result.error = "desktop app-policy paths, user ID, or theme are invalid";
return result;
}
const std::string forced_theme =
theme_mode == "light" || theme_mode == "dark" ? std::string(theme_mode)
: std::string();
JsonReadResult storage =
ReadJsonObject(app_storage_file, "Roblox appStorage");
@@ -259,6 +264,7 @@ DesktopAppPolicyResult ApplyDesktopAppPolicy(
return result;
}
NormalizeDesktopLayout(&policy);
policy["ForceTheme"] = forced_theme;
entry.value() = policy.dump();
if (!template_policy.is_object()) {
template_policy = policy;
@@ -289,6 +295,7 @@ DesktopAppPolicyResult ApplyDesktopAppPolicy(
}
template_policy = fallback.value;
NormalizeDesktopLayout(&template_policy);
template_policy["ForceTheme"] = forced_theme;
}
const std::string encoded_policy = template_policy.dump();
+2 -1
View File
@@ -185,7 +185,8 @@ RuntimeConfig RuntimeConfig::FromEnvironment(const Environment& environment) {
config.window_.high_dpi = ReadBoolean(environment, "MOCKTAIL_WIN_HIGH_DPI",
config.window_.high_dpi,
&config.window_.high_dpi_valid);
config.theme_mode_ = environment.GetOr("MOCKTAIL_THEME", "system");
config.theme_mode_ =
environment.GetOr("MOCKTAIL_THEME", config.theme_mode_);
const std::optional<std::string> configured_device =
environment.Get("MOCKTAIL_DEVICE_PROFILE");
const bool has_explicit_device =
+3 -1
View File
@@ -50,7 +50,9 @@ runtime:
# roblox_library: /absolute/path/to/libroblox.so
appearance:
theme: system
# String (default: roblox): use Roblox's saved account theme. Supported
# overrides: dark, light, or system (follow the desktop color scheme).
theme: roblox
graphics:
# String (default: direct-vulkan): graphics backend. Use opengl on hardware
+3 -2
View File
@@ -301,8 +301,9 @@ bool ValidateAndMap(const ValueMap& yaml, ValueMap* environment,
(*environment)["ROBLOX_LIB_PATH"] = *library;
}
if (const auto theme = value("appearance.theme"); theme.has_value()) {
if (*theme != "system" && *theme != "light" && *theme != "dark") {
*error = "appearance.theme must be system, light, or dark";
if (*theme != "roblox" && *theme != "system" && *theme != "light" &&
*theme != "dark") {
*error = "appearance.theme must be roblox, system, light, or dark";
return false;
}
(*environment)["MOCKTAIL_THEME"] = *theme;