mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 15:17:07 +02:00
Add 'respect system dark mode' checkbox.
This commit is contained in:
parent
c24da4c3df
commit
8c4e8212cd
26 changed files with 298 additions and 151 deletions
Telegram
Resources/langs
SourceFiles
|
@ -434,6 +434,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_settings_sensitive_disable_filtering" = "Disable filtering";
|
||||
"lng_settings_sensitive_about" = "Display sensitive media in public channels on all your Telegram devices.";
|
||||
|
||||
"lng_settings_auto_night_mode" = "Auto-Night mode";
|
||||
"lng_settings_auto_night_enabled" = "Match the system settings";
|
||||
"lng_settings_auto_night_warning" = "You have enabled auto-night mode. If you want to change the dark mode settings, you'll need to disable it first.";
|
||||
"lng_settings_auto_night_disable" = "Disable";
|
||||
|
||||
"lng_settings_spellchecker" = "Spell checker";
|
||||
"lng_settings_system_spellchecker" = "Use system spell checker";
|
||||
"lng_settings_custom_spellchecker" = "Use spell checker";
|
||||
|
|
|
@ -212,25 +212,9 @@ void Application::run() {
|
|||
Ui::InitTextOptions();
|
||||
Ui::Emoji::Init();
|
||||
startEmojiImageLoader();
|
||||
startSystemDarkModeViewer();
|
||||
Media::Player::start(_audio.get());
|
||||
|
||||
const auto darkModeChanged = [] {
|
||||
const auto darkMode = Core::App().settings().systemDarkMode();
|
||||
const auto darkModeEnabled = Core::App().settings().systemDarkModeEnabled();
|
||||
if (darkModeEnabled
|
||||
&& darkMode.has_value()
|
||||
&& (*darkMode != Window::Theme::IsNightMode())) {
|
||||
Window::Theme::ToggleNightMode();
|
||||
Window::Theme::KeepApplied();
|
||||
}
|
||||
};
|
||||
|
||||
Core::App().settings().systemDarkModeChanges(
|
||||
) | rpl::start_with_next(darkModeChanged, _lifetime);
|
||||
|
||||
Core::App().settings().systemDarkModeEnabledChanges(
|
||||
) | rpl::start_with_next(darkModeChanged, _lifetime);
|
||||
|
||||
style::ShortAnimationPlaying(
|
||||
) | rpl::start_with_next([=](bool playing) {
|
||||
if (playing) {
|
||||
|
@ -250,10 +234,10 @@ void Application::run() {
|
|||
QMimeDatabase().mimeTypeForName(qsl("text/plain"));
|
||||
|
||||
_window = std::make_unique<Window::Controller>();
|
||||
|
||||
_domain->activeChanges(
|
||||
) | rpl::start_with_next([=](not_null<Main::Account*> account) {
|
||||
_window->showAccount(account);
|
||||
Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
|
||||
}, _window->widget()->lifetime());
|
||||
|
||||
QCoreApplication::instance()->installEventFilter(this);
|
||||
|
@ -267,16 +251,8 @@ void Application::run() {
|
|||
|
||||
// Depend on activeWindow() for now :(
|
||||
startShortcuts();
|
||||
|
||||
App::initMedia();
|
||||
|
||||
const auto state = _domain->start(QByteArray());
|
||||
if (state == Storage::StartResult::IncorrectPasscode) {
|
||||
Global::SetLocalPasscode(true);
|
||||
Global::RefLocalPasscodeChanged().notify();
|
||||
lockByPasscode();
|
||||
DEBUG_LOG(("Application Info: passcode needed..."));
|
||||
}
|
||||
startDomain();
|
||||
|
||||
_window->widget()->show();
|
||||
|
||||
|
@ -298,6 +274,47 @@ void Application::run() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::startDomain() {
|
||||
const auto state = _domain->start(QByteArray());
|
||||
if (state != Storage::StartResult::IncorrectPasscodeLegacy) {
|
||||
// In case of non-legacy passcoded app all global settings are ready.
|
||||
startSettingsAndBackground();
|
||||
}
|
||||
if (state != Storage::StartResult::Success) {
|
||||
Global::SetLocalPasscode(true);
|
||||
Global::RefLocalPasscodeChanged().notify();
|
||||
lockByPasscode();
|
||||
DEBUG_LOG(("Application Info: passcode needed..."));
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startSettingsAndBackground() {
|
||||
Local::rewriteSettingsIfNeeded();
|
||||
Window::Theme::Background()->start();
|
||||
checkSystemDarkMode();
|
||||
}
|
||||
|
||||
void Application::checkSystemDarkMode() {
|
||||
const auto maybeDarkMode = _settings.systemDarkMode();
|
||||
const auto darkModeEnabled = _settings.systemDarkModeEnabled();
|
||||
const auto needToSwitch = darkModeEnabled
|
||||
&& maybeDarkMode
|
||||
&& (*maybeDarkMode != Window::Theme::IsNightMode());
|
||||
if (needToSwitch) {
|
||||
Window::Theme::ToggleNightMode();
|
||||
Window::Theme::KeepApplied();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startSystemDarkModeViewer() {
|
||||
rpl::merge(
|
||||
_settings.systemDarkModeChanges() | rpl::to_empty,
|
||||
_settings.systemDarkModeEnabledChanges() | rpl::to_empty
|
||||
) | rpl::start_with_next([=] {
|
||||
checkSystemDarkMode();
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
auto Application::prepareEmojiSourceImages()
|
||||
-> std::shared_ptr<Ui::Emoji::UniversalImages> {
|
||||
const auto &images = Ui::Emoji::SourceImages();
|
||||
|
|
|
@ -140,6 +140,7 @@ public:
|
|||
[[nodiscard]] QWidget *getFileDialogParent();
|
||||
void notifyFileDialogShown(bool shown);
|
||||
[[nodiscard]] QWidget *getModalParent();
|
||||
void checkSystemDarkMode();
|
||||
|
||||
// Media view interface.
|
||||
void checkMediaViewActivation();
|
||||
|
@ -161,6 +162,7 @@ public:
|
|||
return _logoNoMargin;
|
||||
}
|
||||
|
||||
void startSettingsAndBackground();
|
||||
[[nodiscard]] Settings &settings() {
|
||||
return _settings;
|
||||
}
|
||||
|
@ -290,7 +292,9 @@ private:
|
|||
-> std::shared_ptr<Ui::Emoji::UniversalImages>;
|
||||
void startLocalStorage();
|
||||
void startShortcuts();
|
||||
void startDomain();
|
||||
void startEmojiImageLoader();
|
||||
void startSystemDarkModeViewer();
|
||||
|
||||
void stateChanged(Qt::ApplicationState state);
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ Domain::Domain(const QString &dataName)
|
|||
, _local(std::make_unique<Storage::Domain>(this, dataName)) {
|
||||
_active.changes(
|
||||
) | rpl::take(1) | rpl::start_with_next([] {
|
||||
Local::rewriteSettingsIfNeeded();
|
||||
// In case we had a legacy passcoded app we start settings here.
|
||||
Core::App().startSettingsAndBackground();
|
||||
|
||||
Core::App().notifications().createManager();
|
||||
}, _lifetime);
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ void MainWindow::initHook() {
|
|||
|| QSystemTrayIcon::isSystemTrayAvailable();
|
||||
|
||||
LOG(("System tray available: %1").arg(Logs::b(trayAvailable)));
|
||||
cSetSupportTray(trayAvailable);
|
||||
Platform::SetTrayIconSupported(trayAvailable);
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
auto sniWatcher = new QDBusServiceWatcher(
|
||||
|
@ -591,9 +591,9 @@ void MainWindow::onSNIOwnerChanged(
|
|||
const auto trayAvailable = SNIAvailable
|
||||
|| QSystemTrayIcon::isSystemTrayAvailable();
|
||||
|
||||
cSetSupportTray(trayAvailable);
|
||||
Platform::SetTrayIconSupported(trayAvailable);
|
||||
|
||||
if (cSupportTray()) {
|
||||
if (trayAvailable) {
|
||||
psSetupTrayIcon();
|
||||
} else {
|
||||
LOG(("System tray is not available."));
|
||||
|
@ -654,9 +654,9 @@ void MainWindow::psSetupTrayIcon() {
|
|||
}
|
||||
|
||||
void MainWindow::workmodeUpdated(DBIWorkMode mode) {
|
||||
if (!cSupportTray()) return;
|
||||
|
||||
if (mode == dbiwmWindowOnly) {
|
||||
if (!Platform::TrayIconSupported()) {
|
||||
return;
|
||||
} else if (mode == dbiwmWindowOnly) {
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
if (_sniTrayIcon) {
|
||||
_sniTrayIcon->setContextMenu(0);
|
||||
|
|
|
@ -69,6 +69,8 @@ constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
|
|||
|
||||
QStringList PlatformThemes;
|
||||
|
||||
bool IsTrayIconSupported = true;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
void PortalAutostart(bool autostart, bool silent = false) {
|
||||
QVariantMap options;
|
||||
|
@ -871,8 +873,7 @@ std::optional<crl::time> LastUserInputTime() {
|
|||
|
||||
std::optional<bool> IsDarkMode() {
|
||||
#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
if (Libs::GtkSettingSupported()
|
||||
&& Libs::GtkLoaded()) {
|
||||
if (Libs::GtkSettingSupported() && Libs::GtkLoaded()) {
|
||||
if (Libs::gtk_check_version != nullptr
|
||||
&& !Libs::gtk_check_version(3, 0, 0)
|
||||
&& Libs::GtkSetting<gboolean>("gtk-application-prefer-dark-theme")) {
|
||||
|
@ -897,6 +898,14 @@ bool AutostartSupported() {
|
|||
return !InSnap();
|
||||
}
|
||||
|
||||
bool TrayIconSupported() {
|
||||
return IsTrayIconSupported;
|
||||
}
|
||||
|
||||
void SetTrayIconSupported(bool supported) {
|
||||
IsTrayIconSupported = supported;
|
||||
}
|
||||
|
||||
void FallbackFontConfigCheckBegin() {
|
||||
if (!CheckFontConfigCrash()) {
|
||||
return;
|
||||
|
|
|
@ -47,6 +47,7 @@ void FallbackFontConfigCheckBegin();
|
|||
void FallbackFontConfigCheckEnd();
|
||||
|
||||
bool GtkClipboardSupported();
|
||||
void SetTrayIconSupported(bool supported);
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
|
|
|
@ -40,6 +40,14 @@ inline bool StartSystemResize(QWindow *window, Qt::Edges edges) {
|
|||
return false;
|
||||
}
|
||||
|
||||
inline bool AutostartSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TrayIconSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
inline void start() {
|
||||
|
|
|
@ -263,10 +263,6 @@ void IgnoreApplicationActivationRightNow() {
|
|||
objc_ignoreApplicationActivationRightNow();
|
||||
}
|
||||
|
||||
bool AutostartSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
void psNewVersion() {
|
||||
|
|
|
@ -48,6 +48,7 @@ bool OpenSystemSettings(SystemSettingsType type);
|
|||
|
||||
void IgnoreApplicationActivationRightNow();
|
||||
bool AutostartSupported();
|
||||
bool TrayIconSupported();
|
||||
QImage GetImageFromClipboard();
|
||||
bool StartSystemMove(QWindow *window);
|
||||
bool StartSystemResize(QWindow *window, Qt::Edges edges);
|
||||
|
|
|
@ -384,27 +384,34 @@ std::optional<crl::time> LastUserInputTime() {
|
|||
}
|
||||
|
||||
std::optional<bool> IsDarkMode() {
|
||||
if (QOperatingSystemVersion::current()
|
||||
< QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 17763)) {
|
||||
static const auto kSystemVersion = QOperatingSystemVersion::current();
|
||||
static const auto kDarkModeAddedVersion = QOperatingSystemVersion(
|
||||
QOperatingSystemVersion::Windows,
|
||||
10,
|
||||
0,
|
||||
17763);
|
||||
static const auto kSupported = (kSystemVersion >= kDarkModeAddedVersion);
|
||||
if (!kSupported) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
LPCWSTR lpKeyName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
||||
LPCWSTR lpValueName = L"AppsUseLightTheme";
|
||||
HKEY key;
|
||||
auto result = RegOpenKeyEx(HKEY_CURRENT_USER, lpKeyName, 0, KEY_READ, &key);
|
||||
const auto keyName = L""
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
||||
const auto valueName = L"AppsUseLightTheme";
|
||||
auto key = HKEY();
|
||||
auto result = RegOpenKeyEx(HKEY_CURRENT_USER, keyName, 0, KEY_READ, &key);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
DWORD value = 0, type = 0, size = sizeof(value);
|
||||
result = RegQueryValueEx(key, lpValueName, 0, &type, (LPBYTE)&value, &size);
|
||||
result = RegQueryValueEx(key, valueName, 0, &type, (LPBYTE)&value, &size);
|
||||
RegCloseKey(key);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return value == 0;
|
||||
return (value == 0);
|
||||
}
|
||||
|
||||
bool AutostartSupported() {
|
||||
|
|
|
@ -40,6 +40,10 @@ inline bool StartSystemResize(QWindow *window, Qt::Edges edges) {
|
|||
return false;
|
||||
}
|
||||
|
||||
inline bool TrayIconSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
void start();
|
||||
|
|
|
@ -42,7 +42,6 @@ bool gUseFreeType = false;
|
|||
bool gAutoUpdate = true;
|
||||
TWindowPos gWindowPos;
|
||||
LaunchMode gLaunchMode = LaunchModeNormal;
|
||||
bool gSupportTray = true;
|
||||
bool gSeenTrayTooltip = false;
|
||||
bool gRestartingUpdate = false, gRestarting = false, gRestartingToSettings = false, gWriteProtected = false;
|
||||
int32 gLastUpdateCheck = 0;
|
||||
|
|
|
@ -79,7 +79,6 @@ struct TWindowPos {
|
|||
int h = 0;
|
||||
};
|
||||
DeclareSetting(TWindowPos, WindowPos);
|
||||
DeclareSetting(bool, SupportTray);
|
||||
DeclareSetting(bool, SeenTrayTooltip);
|
||||
DeclareSetting(bool, RestartingUpdate);
|
||||
DeclareSetting(bool, Restarting);
|
||||
|
|
|
@ -325,11 +325,7 @@ void SetupSpellchecker(
|
|||
#endif // !TDESKTOP_DISABLE_SPELLCHECK
|
||||
}
|
||||
|
||||
bool HasTray() {
|
||||
return cSupportTray() || Platform::IsWindows();
|
||||
}
|
||||
|
||||
void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
|
||||
void SetupSystemIntegrationContent(not_null<Ui::VerticalLayout*> container) {
|
||||
const auto checkbox = [&](const QString &label, bool checked) {
|
||||
return object_ptr<Ui::Checkbox>(
|
||||
container,
|
||||
|
@ -349,65 +345,65 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
|
|||
checkbox(label, checked),
|
||||
st::settingsCheckboxPadding));
|
||||
};
|
||||
if (Platform::TrayIconSupported()) {
|
||||
const auto trayEnabled = [] {
|
||||
const auto workMode = Global::WorkMode().value();
|
||||
return (workMode == dbiwmTrayOnly)
|
||||
|| (workMode == dbiwmWindowAndTray);
|
||||
};
|
||||
const auto tray = addCheckbox(
|
||||
tr::lng_settings_workmode_tray(tr::now),
|
||||
trayEnabled());
|
||||
|
||||
const auto trayEnabled = [] {
|
||||
const auto workMode = Global::WorkMode().value();
|
||||
return (workMode == dbiwmTrayOnly)
|
||||
|| (workMode == dbiwmWindowAndTray);
|
||||
};
|
||||
const auto tray = addCheckbox(
|
||||
tr::lng_settings_workmode_tray(tr::now),
|
||||
trayEnabled());
|
||||
const auto taskbarEnabled = [] {
|
||||
const auto workMode = Global::WorkMode().value();
|
||||
return (workMode == dbiwmWindowOnly)
|
||||
|| (workMode == dbiwmWindowAndTray);
|
||||
};
|
||||
const auto taskbar = Platform::IsWindows()
|
||||
? addCheckbox(
|
||||
tr::lng_settings_workmode_window(tr::now),
|
||||
taskbarEnabled())
|
||||
: nullptr;
|
||||
|
||||
const auto taskbarEnabled = [] {
|
||||
const auto workMode = Global::WorkMode().value();
|
||||
return (workMode == dbiwmWindowOnly)
|
||||
|| (workMode == dbiwmWindowAndTray);
|
||||
};
|
||||
const auto taskbar = Platform::IsWindows()
|
||||
? addCheckbox(
|
||||
tr::lng_settings_workmode_window(tr::now),
|
||||
taskbarEnabled())
|
||||
: nullptr;
|
||||
const auto updateWorkmode = [=] {
|
||||
const auto newMode = tray->checked()
|
||||
? ((!taskbar || taskbar->checked())
|
||||
? dbiwmWindowAndTray
|
||||
: dbiwmTrayOnly)
|
||||
: dbiwmWindowOnly;
|
||||
if ((newMode == dbiwmWindowAndTray || newMode == dbiwmTrayOnly)
|
||||
&& Global::WorkMode().value() != newMode) {
|
||||
cSetSeenTrayTooltip(false);
|
||||
}
|
||||
Global::RefWorkMode().set(newMode);
|
||||
Local::writeSettings();
|
||||
};
|
||||
|
||||
const auto updateWorkmode = [=] {
|
||||
const auto newMode = tray->checked()
|
||||
? ((!taskbar || taskbar->checked())
|
||||
? dbiwmWindowAndTray
|
||||
: dbiwmTrayOnly)
|
||||
: dbiwmWindowOnly;
|
||||
if ((newMode == dbiwmWindowAndTray || newMode == dbiwmTrayOnly)
|
||||
&& Global::WorkMode().value() != newMode) {
|
||||
cSetSeenTrayTooltip(false);
|
||||
}
|
||||
Global::RefWorkMode().set(newMode);
|
||||
Local::writeSettings();
|
||||
};
|
||||
|
||||
tray->checkedChanges(
|
||||
) | rpl::filter([=](bool checked) {
|
||||
return (checked != trayEnabled());
|
||||
}) | rpl::start_with_next([=](bool checked) {
|
||||
if (!checked && taskbar && !taskbar->checked()) {
|
||||
taskbar->setChecked(true);
|
||||
} else {
|
||||
updateWorkmode();
|
||||
}
|
||||
}, tray->lifetime());
|
||||
|
||||
if (taskbar) {
|
||||
taskbar->checkedChanges(
|
||||
tray->checkedChanges(
|
||||
) | rpl::filter([=](bool checked) {
|
||||
return (checked != taskbarEnabled());
|
||||
return (checked != trayEnabled());
|
||||
}) | rpl::start_with_next([=](bool checked) {
|
||||
if (!checked && !tray->checked()) {
|
||||
tray->setChecked(true);
|
||||
if (!checked && taskbar && !taskbar->checked()) {
|
||||
taskbar->setChecked(true);
|
||||
} else {
|
||||
updateWorkmode();
|
||||
}
|
||||
}, taskbar->lifetime());
|
||||
}
|
||||
}, tray->lifetime());
|
||||
|
||||
if (taskbar) {
|
||||
taskbar->checkedChanges(
|
||||
) | rpl::filter([=](bool checked) {
|
||||
return (checked != taskbarEnabled());
|
||||
}) | rpl::start_with_next([=](bool checked) {
|
||||
if (!checked && !tray->checked()) {
|
||||
tray->setChecked(true);
|
||||
} else {
|
||||
updateWorkmode();
|
||||
}
|
||||
}, taskbar->lifetime());
|
||||
}
|
||||
}
|
||||
if (Platform::AllowNativeWindowFrameToggle()) {
|
||||
const auto nativeFrame = addCheckbox(
|
||||
tr::lng_settings_native_frame(tr::now),
|
||||
|
@ -421,7 +417,6 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
|
|||
Core::App().saveSettingsDelayed();
|
||||
}, nativeFrame->lifetime());
|
||||
}
|
||||
|
||||
if (Platform::AutostartSupported()) {
|
||||
const auto minimizedToggled = [] {
|
||||
return cStartMinimized() && !Global::LocalPasscode();
|
||||
|
@ -471,8 +466,7 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
|
|||
}, minimized->lifetime());
|
||||
}
|
||||
|
||||
#ifndef OS_WIN_STORE
|
||||
if (Platform::IsWindows()) {
|
||||
if (Platform::IsWindows() && !Platform::IsWindowsStoreBuild()) {
|
||||
const auto sendto = addCheckbox(
|
||||
tr::lng_settings_add_sendto(tr::now),
|
||||
cSendToMenu());
|
||||
|
@ -486,22 +480,18 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
|
|||
Local::writeSettings();
|
||||
}, sendto->lifetime());
|
||||
}
|
||||
#endif // OS_WIN_STORE
|
||||
}
|
||||
|
||||
void SetupTray(not_null<Ui::VerticalLayout*> container) {
|
||||
if (!HasTray()) {
|
||||
return;
|
||||
}
|
||||
|
||||
void SetupSystemIntegrationOptions(not_null<Ui::VerticalLayout*> container) {
|
||||
auto wrap = object_ptr<Ui::VerticalLayout>(container);
|
||||
SetupTrayContent(wrap.data());
|
||||
SetupSystemIntegrationContent(wrap.data());
|
||||
if (wrap->count() > 0) {
|
||||
container->add(object_ptr<Ui::OverrideMargins>(
|
||||
container,
|
||||
std::move(wrap)));
|
||||
|
||||
container->add(object_ptr<Ui::OverrideMargins>(
|
||||
container,
|
||||
std::move(wrap)));
|
||||
|
||||
AddSkip(container, st::settingsCheckboxesSkip);
|
||||
AddSkip(container, st::settingsCheckboxesSkip);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupAnimations(not_null<Ui::VerticalLayout*> container) {
|
||||
|
@ -539,7 +529,7 @@ void SetupSystemIntegration(
|
|||
)->addClickHandler([=] {
|
||||
showOther(Type::Calls);
|
||||
});
|
||||
SetupTray(container);
|
||||
SetupSystemIntegrationOptions(container);
|
||||
AddSkip(container);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,7 @@ void SetupConnectionType(
|
|||
not_null<Ui::VerticalLayout*> container);
|
||||
bool HasUpdate();
|
||||
void SetupUpdate(not_null<Ui::VerticalLayout*> container);
|
||||
bool HasTray();
|
||||
void SetupTray(not_null<Ui::VerticalLayout*> container);
|
||||
void SetupSystemIntegrationContent(not_null<Ui::VerticalLayout*> container);
|
||||
void SetupAnimations(not_null<Ui::VerticalLayout*> container);
|
||||
|
||||
class Advanced : public Section {
|
||||
|
|
|
@ -982,7 +982,9 @@ void SetupChatBackground(
|
|||
}, adaptive->lifetime());
|
||||
}
|
||||
|
||||
void SetupDefaultThemes(not_null<Ui::VerticalLayout*> container) {
|
||||
void SetupDefaultThemes(
|
||||
not_null<Window::Controller*> window,
|
||||
not_null<Ui::VerticalLayout*> container) {
|
||||
using Type = Window::Theme::EmbeddedType;
|
||||
using Scheme = Window::Theme::EmbeddedScheme;
|
||||
using Check = Window::Theme::CloudListCheck;
|
||||
|
@ -1015,13 +1017,18 @@ void SetupDefaultThemes(not_null<Ui::VerticalLayout*> container) {
|
|||
};
|
||||
const auto currentlyIsCustom = (chosen() == Type(-1))
|
||||
&& !Background()->themeObject().cloud.id;
|
||||
const auto keep = [=] {
|
||||
if (!currentlyIsCustom) {
|
||||
KeepApplied();
|
||||
}
|
||||
};
|
||||
if (IsNightMode() == isNight(scheme)) {
|
||||
ApplyDefaultWithPath(scheme.path);
|
||||
keep();
|
||||
} else {
|
||||
ToggleNightMode(scheme.path);
|
||||
}
|
||||
if (!currentlyIsCustom) {
|
||||
KeepApplied();
|
||||
Window::Theme::ToggleNightModeWithConfirmation(
|
||||
window,
|
||||
[=, path = scheme.path] { ToggleNightMode(path); keep();});
|
||||
}
|
||||
};
|
||||
const auto schemeClicked = [=](
|
||||
|
@ -1163,7 +1170,7 @@ void SetupThemeOptions(
|
|||
AddSubsectionTitle(container, tr::lng_settings_themes());
|
||||
|
||||
AddSkip(container, st::settingsThemesTopSkip);
|
||||
SetupDefaultThemes(container);
|
||||
SetupDefaultThemes(&controller->window(), container);
|
||||
AddSkip(container);
|
||||
}
|
||||
|
||||
|
@ -1260,6 +1267,47 @@ void SetupCloudThemes(
|
|||
wrap->setDuration(0)->toggleOn(list->empty() | rpl::map(!_1));
|
||||
}
|
||||
|
||||
void SetupAutoNightMode(not_null<Ui::VerticalLayout*> container) {
|
||||
if (!Platform::IsDarkModeSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddDivider(container);
|
||||
AddSkip(container, st::settingsPrivacySkip);
|
||||
|
||||
AddSubsectionTitle(container, tr::lng_settings_auto_night_mode());
|
||||
|
||||
auto wrap = object_ptr<Ui::VerticalLayout>(container);
|
||||
const auto autoNight = wrap->add(
|
||||
object_ptr<Ui::Checkbox>(
|
||||
wrap,
|
||||
tr::lng_settings_auto_night_enabled(tr::now),
|
||||
Core::App().settings().systemDarkModeEnabled(),
|
||||
st::settingsCheckbox),
|
||||
st::settingsCheckboxPadding);
|
||||
|
||||
autoNight->checkedChanges(
|
||||
) | rpl::filter([=](bool checked) {
|
||||
return (checked != Core::App().settings().systemDarkModeEnabled());
|
||||
}) | rpl::start_with_next([=](bool checked) {
|
||||
Core::App().settings().setSystemDarkModeEnabled(checked);
|
||||
Core::App().saveSettingsDelayed();
|
||||
}, autoNight->lifetime());
|
||||
|
||||
Core::App().settings().systemDarkModeEnabledChanges(
|
||||
) | rpl::filter([=](bool value) {
|
||||
return (value != autoNight->checked());
|
||||
}) | rpl::start_with_next([=](bool value) {
|
||||
autoNight->setChecked(value);
|
||||
}, autoNight->lifetime());
|
||||
|
||||
container->add(object_ptr<Ui::OverrideMargins>(
|
||||
container,
|
||||
std::move(wrap)));
|
||||
|
||||
AddSkip(container, st::settingsCheckboxesSkip);
|
||||
}
|
||||
|
||||
void SetupSupportSwitchSettings(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<Ui::VerticalLayout*> container) {
|
||||
|
@ -1381,6 +1429,7 @@ void Chat::setupContent(not_null<Window::SessionController*> controller) {
|
|||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||
|
||||
SetupThemeOptions(controller, content);
|
||||
SetupAutoNightMode(content);
|
||||
SetupCloudThemes(controller, content);
|
||||
SetupChatBackground(controller, content);
|
||||
SetupStickersEmoji(controller, content);
|
||||
|
|
|
@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "settings/settings_common.h"
|
||||
|
||||
namespace Window {
|
||||
class Controller;
|
||||
} // namespace Window
|
||||
|
||||
namespace Settings {
|
||||
|
||||
void SetupDataStorage(
|
||||
|
@ -17,7 +21,9 @@ void SetupDataStorage(
|
|||
void SetupAutoDownload(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<Ui::VerticalLayout*> container);
|
||||
void SetupDefaultThemes(not_null<Ui::VerticalLayout*> container);
|
||||
void SetupDefaultThemes(
|
||||
not_null<Window::Controller*> window,
|
||||
not_null<Ui::VerticalLayout*> container);
|
||||
void SetupSupport(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<Ui::VerticalLayout*> container);
|
||||
|
|
|
@ -75,16 +75,14 @@ object_ptr<Ui::RpWidget> CreateIntroSettings(
|
|||
SetupUpdate(result);
|
||||
AddSkip(result);
|
||||
}
|
||||
if (HasTray()) {
|
||||
AddDivider(result);
|
||||
AddSkip(result);
|
||||
SetupTray(result);
|
||||
AddSkip(result);
|
||||
}
|
||||
AddDivider(result);
|
||||
AddSkip(result);
|
||||
SetupSystemIntegrationContent(result);
|
||||
AddSkip(result);
|
||||
AddDivider(result);
|
||||
AddSkip(result);
|
||||
SetupInterfaceScale(result, false);
|
||||
SetupDefaultThemes(result);
|
||||
SetupDefaultThemes(window, result);
|
||||
AddSkip(result);
|
||||
|
||||
if (anim::Disabled()) {
|
||||
|
|
|
@ -140,8 +140,9 @@ void FileLoader::finishWithBytes(const QByteArray &data) {
|
|||
Platform::File::PostprocessDownloaded(
|
||||
QFileInfo(_file).absoluteFilePath());
|
||||
}
|
||||
_session->notifyDownloaderTaskFinished();
|
||||
const auto session = _session;
|
||||
_updates.fire_done();
|
||||
session->notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
QByteArray FileLoader::imageFormat(const QSize &shrinkBox) const {
|
||||
|
|
|
@ -134,7 +134,7 @@ StartResult Account::legacyStart(const QByteArray &passcode) {
|
|||
if (result == ReadMapResult::Failed) {
|
||||
Assert(_localKey == nullptr);
|
||||
} else if (result == ReadMapResult::IncorrectPasscode) {
|
||||
return StartResult::IncorrectPasscode;
|
||||
return StartResult::IncorrectPasscodeLegacy;
|
||||
}
|
||||
clearLegacyFiles();
|
||||
return StartResult::Success;
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Storage {
|
|||
enum class StartResult : uchar {
|
||||
Success,
|
||||
IncorrectPasscode,
|
||||
IncorrectPasscodeLegacy,
|
||||
};
|
||||
|
||||
class Domain final {
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/themes/window_theme_preview.h"
|
||||
#include "window/themes/window_themes_embedded.h"
|
||||
#include "window/themes/window_theme_editor.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "mainwidget.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
|
@ -24,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_account.h" // Account::local.
|
||||
#include "main/main_domain.h" // Domain::activeSessionValue.
|
||||
#include "ui/image/image.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/background_box.h"
|
||||
#include "core/application.h"
|
||||
#include "app.h"
|
||||
|
@ -560,6 +562,8 @@ void ChatBackground::start() {
|
|||
_session = session;
|
||||
checkUploadWallPaper();
|
||||
}, _lifetime);
|
||||
|
||||
Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
|
||||
}
|
||||
|
||||
void ChatBackground::checkUploadWallPaper() {
|
||||
|
@ -1074,6 +1078,14 @@ bool ChatBackground::nightMode() const {
|
|||
void ChatBackground::reapplyWithNightMode(
|
||||
std::optional<QString> themePath,
|
||||
bool newNightMode) {
|
||||
if (!started()) {
|
||||
// We can get here from legacy passcoded state.
|
||||
// In this case Background() is not started yet, because
|
||||
// some settings and the background itself were not read.
|
||||
return;
|
||||
} else if (_nightMode != newNightMode && !nightModeChangeAllowed()) {
|
||||
return;
|
||||
}
|
||||
const auto settingExactTheme = themePath.has_value();
|
||||
const auto nightModeChanged = (newNightMode != _nightMode);
|
||||
const auto oldNightMode = _nightMode;
|
||||
|
@ -1136,6 +1148,14 @@ void ChatBackground::reapplyWithNightMode(
|
|||
}
|
||||
}
|
||||
|
||||
bool ChatBackground::nightModeChangeAllowed() const {
|
||||
const auto &settings = Core::App().settings();
|
||||
const auto allowedToBeAfterChange = settings.systemDarkModeEnabled()
|
||||
? settings.systemDarkMode().value_or(!_nightMode)
|
||||
: !_nightMode;
|
||||
return (_nightMode != allowedToBeAfterChange);
|
||||
}
|
||||
|
||||
void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
|
||||
reapplyWithNightMode(themePath, !_nightMode);
|
||||
}
|
||||
|
@ -1293,6 +1313,28 @@ void ToggleNightMode(const QString &path) {
|
|||
Background()->toggleNightMode(path);
|
||||
}
|
||||
|
||||
void ToggleNightModeWithConfirmation(
|
||||
not_null<Controller*> window,
|
||||
Fn<void()> toggle) {
|
||||
if (Background()->nightModeChangeAllowed()) {
|
||||
toggle();
|
||||
} else {
|
||||
const auto box = std::make_shared<QPointer<ConfirmBox>>();
|
||||
const auto disableAndToggle = [=] {
|
||||
Core::App().settings().setSystemDarkModeEnabled(false);
|
||||
Core::App().saveSettingsDelayed();
|
||||
toggle();
|
||||
if (*box) {
|
||||
(*box)->closeBox();
|
||||
}
|
||||
};
|
||||
*box = window->show(Box<ConfirmBox>(
|
||||
tr::lng_settings_auto_night_warning(tr::now),
|
||||
tr::lng_settings_auto_night_disable(tr::now),
|
||||
disableAndToggle));
|
||||
}
|
||||
}
|
||||
|
||||
void ResetToSomeDefault() {
|
||||
Background()->reapplyWithNightMode(
|
||||
IsNightMode() ? NightThemePath() : QString(),
|
||||
|
|
|
@ -14,6 +14,10 @@ namespace Main {
|
|||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Window {
|
||||
class Controller;
|
||||
} // namespace Window
|
||||
|
||||
namespace Window {
|
||||
namespace Theme {
|
||||
|
||||
|
@ -76,6 +80,9 @@ QString NightThemePath();
|
|||
void SetNightModeValue(bool nightMode);
|
||||
void ToggleNightMode();
|
||||
void ToggleNightMode(const QString &themePath);
|
||||
void ToggleNightModeWithConfirmation(
|
||||
not_null<Controller*> window,
|
||||
Fn<void()> toggle);
|
||||
void ResetToSomeDefault();
|
||||
[[nodiscard]] bool IsNonDefaultBackground();
|
||||
void Revert();
|
||||
|
@ -169,6 +176,7 @@ public:
|
|||
[[nodiscard]] bool tileDay() const;
|
||||
[[nodiscard]] bool tileNight() const;
|
||||
[[nodiscard]] bool isMonoColorImage() const;
|
||||
[[nodiscard]] bool nightModeChangeAllowed() const;
|
||||
|
||||
private:
|
||||
struct AdjustableColor {
|
||||
|
|
|
@ -51,8 +51,6 @@ Controller::~Controller() {
|
|||
}
|
||||
|
||||
void Controller::showAccount(not_null<Main::Account*> account) {
|
||||
Window::Theme::Background()->start();
|
||||
|
||||
_accountLifetime.destroy();
|
||||
_account = account;
|
||||
|
||||
|
|
|
@ -894,10 +894,19 @@ void MainMenu::refreshMenu() {
|
|||
|
||||
_nightThemeAction = std::make_shared<QPointer<QAction>>();
|
||||
auto action = _menu->addAction(tr::lng_menu_night_mode(tr::now), [=] {
|
||||
if (auto action = *_nightThemeAction) {
|
||||
action->setChecked(!action->isChecked());
|
||||
_nightThemeSwitch.callOnce(st::mainMenu.itemToggle.duration);
|
||||
}
|
||||
const auto weak = MakeWeak(this);
|
||||
const auto toggle = [=] {
|
||||
if (!weak) {
|
||||
Window::Theme::ToggleNightMode();
|
||||
Window::Theme::KeepApplied();
|
||||
} else if (auto action = *_nightThemeAction) {
|
||||
action->setChecked(!action->isChecked());
|
||||
_nightThemeSwitch.callOnce(st::mainMenu.itemToggle.duration);
|
||||
}
|
||||
};
|
||||
Window::Theme::ToggleNightModeWithConfirmation(
|
||||
&_controller->window(),
|
||||
toggle);
|
||||
}, &st::mainMenuNightMode, &st::mainMenuNightModeOver);
|
||||
*_nightThemeAction = action;
|
||||
action->setCheckable(true);
|
||||
|
@ -908,12 +917,6 @@ void MainMenu::refreshMenu() {
|
|||
if (darkModeEnabled && darkMode.has_value()) {
|
||||
action->setChecked(*darkMode);
|
||||
}
|
||||
action->setEnabled(!darkModeEnabled || !darkMode.has_value());
|
||||
}, lifetime());
|
||||
Core::App().settings().systemDarkModeEnabledChanges(
|
||||
) | rpl::start_with_next([=](bool darkModeEnabled) {
|
||||
const auto darkMode = Core::App().settings().systemDarkMode();
|
||||
action->setEnabled(!darkModeEnabled || !darkMode.has_value());
|
||||
}, lifetime());
|
||||
_menu->finishAnimating();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue