diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml
index eac8d2781..877faddbe 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -9,7 +9,7 @@
+ Version="2.7.4.0" />
Telegram Desktop
Telegram Messenger LLP
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index daa8c8689..e1d53f467 100644
--- a/Telegram/Resources/winrc/Telegram.rc
+++ b/Telegram/Resources/winrc/Telegram.rc
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,7,3,0
- PRODUCTVERSION 2,7,3,0
+ FILEVERSION 2,7,4,0
+ PRODUCTVERSION 2,7,4,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
- VALUE "FileVersion", "2.7.3.0"
+ VALUE "FileVersion", "2.7.4.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "2.7.3.0"
+ VALUE "ProductVersion", "2.7.4.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc
index f8b1b42be..911963678 100644
--- a/Telegram/Resources/winrc/Updater.rc
+++ b/Telegram/Resources/winrc/Updater.rc
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,7,3,0
- PRODUCTVERSION 2,7,3,0
+ FILEVERSION 2,7,4,0
+ PRODUCTVERSION 2,7,4,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater"
- VALUE "FileVersion", "2.7.3.0"
+ VALUE "FileVersion", "2.7.4.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "2.7.3.0"
+ VALUE "ProductVersion", "2.7.4.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp
index b8c879bb1..f8416d5ac 100644
--- a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp
+++ b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp
@@ -163,14 +163,20 @@ bool BotKeyboard::moderateKeyActivate(int key) {
}
} else if (const auto user = item->history()->peer->asUser()) {
if (user->isBot() && item->from() == user) {
- if (key == Qt::Key_Q) {
+ if (key == Qt::Key_Q || key == Qt::Key_6) {
App::sendBotCommand(user, user, qsl("/translate"));
- } else if (key == Qt::Key_W) {
+ } else if (key == Qt::Key_W || key == Qt::Key_5) {
App::sendBotCommand(user, user, qsl("/eng"));
} else if (key == Qt::Key_3) {
App::sendBotCommand(user, user, qsl("/pattern"));
} else if (key == Qt::Key_4) {
App::sendBotCommand(user, user, qsl("/abuse"));
+ } else if (key == Qt::Key_0 || key == Qt::Key_E) {
+ App::sendBotCommand(user, user, qsl("/undo"));
+ } else if (key == Qt::Key_Plus || key == Qt::Key_QuoteLeft) {
+ App::sendBotCommand(user, user, qsl("/next"));
+ } else if (key == Qt::Key_Period || key == Qt::Key_S) {
+ App::sendBotCommand(user, user, qsl("/stats"));
}
return true;
}
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index 1436fa6db..4468ba310 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -23,7 +23,7 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Kotatogram Desktop"_cs;
constexpr auto AppFile = "Kotatogram"_cs;
-constexpr auto AppVersion = 2007003;
-constexpr auto AppVersionStr = "2.7.3";
+constexpr auto AppVersion = 2007004;
+constexpr auto AppVersionStr = "2.7.4";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp
index 654bf650a..6049c026d 100644
--- a/Telegram/SourceFiles/mainwindow.cpp
+++ b/Telegram/SourceFiles/mainwindow.cpp
@@ -556,13 +556,8 @@ bool MainWindow::doWeMarkAsRead() {
if (!_main || Ui::isLayerShown()) {
return false;
}
- // for tile grid in case other windows have shadows
- // i've seen some windows with >70px shadow margins
- const auto margin = style::ConvertScale(100);
- return Ui::IsContentVisible(
- this,
- inner().marginsRemoved(QMargins(margin, margin, margin, margin)))
- && _main->doWeMarkAsRead();
+ updateIsActive();
+ return isActive() && _main->doWeMarkAsRead();
}
void MainWindow::checkHistoryActivation() {
diff --git a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp
index 14dd4302e..b6b4ee2a8 100644
--- a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp
+++ b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp
@@ -8,8 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/linux/linux_xdp_file_dialog.h"
#include "platform/platform_file_utilities.h"
-#include "platform/linux/linux_desktop_environment.h"
-#include "platform/linux/specific_linux.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_linux_glibmm_helper.h"
#include "storage/localstorage.h"
@@ -642,18 +640,8 @@ rpl::producer<> XDPFileDialog::rejected() {
} // namespace
bool Use(Type type) {
- const auto shouldUse = [&] {
- const auto setting = FileDialogType() <= ImplementationType::XDP;
- const auto forceSetting = FileDialogType() == ImplementationType::XDP;
- const auto confined = InFlatpak() || InSnap();
- const auto notGtkBased = !DesktopEnvironment::IsGtkBased();
-
- return setting && (confined || notGtkBased || forceSetting);
- }();
-
static const auto Version = FileChooserPortalVersion();
-
- return shouldUse
+ return (FileDialogType() <= ImplementationType::XDP)
&& Version.has_value()
&& (type != Type::ReadFolder || *Version >= 3);
}
diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
index 286cd6313..87b1a7059 100644
--- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
@@ -715,23 +715,16 @@ void NotificationData::notificationReplied(
} // namespace
-bool SkipAudio() {
- return Inhibited();
+bool SkipAudioForCustom() {
+ return false;
}
-bool SkipToast() {
- // Do not skip native notifications because of Do not disturb.
- // They respect this setting anyway.
- if ((Core::App().settings().nativeNotifications() && Supported())
- || Enforced()) {
- return false;
- }
-
- return Inhibited();
+bool SkipToastForCustom() {
+ return false;
}
-bool SkipFlashBounce() {
- return Inhibited();
+bool SkipFlashBounceForCustom() {
+ return false;
}
bool Supported() {
@@ -1030,5 +1023,17 @@ void Manager::doClearFromSession(not_null session) {
_private->clearFromSession(session);
}
+bool Manager::doSkipAudio() const {
+ return Inhibited();
+}
+
+bool Manager::doSkipToast() const {
+ return false;
+}
+
+bool Manager::doSkipFlashBounce() const {
+ return Inhibited();
+}
+
} // namespace Notifications
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h
index 2e4d1f4a0..d4becaf7e 100644
--- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h
+++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h
@@ -34,6 +34,9 @@ protected:
void doClearAllFast() override;
void doClearFromHistory(not_null history) override;
void doClearFromSession(not_null session) override;
+ bool doSkipAudio() const override;
+ bool doSkipToast() const override;
+ bool doSkipFlashBounce() const override;
private:
class Private;
diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h
index ee4d9e132..a5f8de982 100644
--- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h
+++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h
@@ -32,6 +32,9 @@ protected:
void doClearFromHistory(not_null history) override;
void doClearFromSession(not_null session) override;
QString accountNameSeparator() override;
+ bool doSkipAudio() const override;
+ bool doSkipToast() const override;
+ bool doSkipFlashBounce() const override;
private:
class Private;
diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm
index 8affa37cb..594d7228f 100644
--- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm
+++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm
@@ -140,23 +140,16 @@ using Manager = Platform::Notifications::Manager;
namespace Platform {
namespace Notifications {
-bool SkipAudio() {
- queryDoNotDisturbState();
- return DoNotDisturbEnabled;
+bool SkipAudioForCustom() {
+ return false;
}
-bool SkipToast() {
- if (Supported()) {
- // Do not skip native notifications because of Do not disturb.
- // They respect this setting anyway.
- return false;
- }
- queryDoNotDisturbState();
- return DoNotDisturbEnabled;
+bool SkipToastForCustom() {
+ return false;
}
-bool SkipFlashBounce() {
- return SkipAudio();
+bool SkipFlashBounceForCustom() {
+ return false;
}
bool Supported() {
@@ -438,5 +431,18 @@ QString Manager::accountNameSeparator() {
return QString::fromUtf8(" \xE2\x86\x92 ");
}
+bool Manager::doSkipAudio() const {
+ queryDoNotDisturbState();
+ return DoNotDisturbEnabled;
+}
+
+bool Manager::doSkipToast() const {
+ return false;
+}
+
+bool Manager::doSkipFlashBounce() const {
+ return doSkipAudio();
+}
+
} // namespace Notifications
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/platform_notifications_manager.h b/Telegram/SourceFiles/platform/platform_notifications_manager.h
index eb3efbddb..8ab482671 100644
--- a/Telegram/SourceFiles/platform/platform_notifications_manager.h
+++ b/Telegram/SourceFiles/platform/platform_notifications_manager.h
@@ -12,9 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform {
namespace Notifications {
-[[nodiscard]] bool SkipAudio();
-[[nodiscard]] bool SkipToast();
-[[nodiscard]] bool SkipFlashBounce();
+[[nodiscard]] bool SkipAudioForCustom();
+[[nodiscard]] bool SkipToastForCustom();
+[[nodiscard]] bool SkipFlashBounceForCustom();
[[nodiscard]] bool Supported();
[[nodiscard]] bool Enforced();
diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp
index 25db6596a..f9b3fd167 100644
--- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp
+++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp
@@ -257,9 +257,188 @@ void Check() {
InitSucceeded = init();
}
+bool QuietHoursEnabled = false;
+DWORD QuietHoursValue = 0;
+
+[[nodiscard]] bool UseQuietHoursRegistryEntry() {
+ static const bool result = [] {
+ // Taken from QSysInfo.
+ OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0,{ '\0' } };
+ if (const auto library = GetModuleHandle(L"ntdll.dll")) {
+ using RtlGetVersionFunction = NTSTATUS(NTAPI*)(LPOSVERSIONINFO);
+ const auto RtlGetVersion = reinterpret_cast(
+ GetProcAddress(library, "RtlGetVersion"));
+ if (RtlGetVersion) {
+ RtlGetVersion(&result);
+ }
+ }
+ // At build 17134 (Redstone 4) the "Quiet hours" was replaced
+ // by "Focus assist" and it looks like it doesn't use registry.
+ return (result.dwMajorVersion == 10
+ && result.dwMinorVersion == 0
+ && result.dwBuildNumber < 17134);
+ }();
+ return result;
+}
+
+// Thanks https://stackoverflow.com/questions/35600128/get-windows-quiet-hours-from-win32-or-c-sharp-api
+void QueryQuietHours() {
+ if (!UseQuietHoursRegistryEntry()) {
+ // There are quiet hours in Windows starting from Windows 8.1
+ // But there were several reports about the notifications being shut
+ // down according to the registry while no quiet hours were enabled.
+ // So we try this method only starting with Windows 10.
+ return;
+ }
+
+ LPCWSTR lpKeyName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Notifications\\Settings";
+ LPCWSTR lpValueName = L"NOC_GLOBAL_SETTING_TOASTS_ENABLED";
+ HKEY key;
+ auto result = RegOpenKeyEx(HKEY_CURRENT_USER, lpKeyName, 0, KEY_READ, &key);
+ if (result != ERROR_SUCCESS) {
+ return;
+ }
+
+ DWORD value = 0, type = 0, size = sizeof(value);
+ result = RegQueryValueEx(key, lpValueName, 0, &type, (LPBYTE)&value, &size);
+ RegCloseKey(key);
+
+ auto quietHoursEnabled = (result == ERROR_SUCCESS) && (value == 0);
+ if (QuietHoursEnabled != quietHoursEnabled) {
+ QuietHoursEnabled = quietHoursEnabled;
+ QuietHoursValue = value;
+ LOG(("Quiet hours changed, entry value: %1").arg(value));
+ } else if (QuietHoursValue != value) {
+ QuietHoursValue = value;
+ LOG(("Quiet hours value changed, was value: %1, entry value: %2").arg(QuietHoursValue).arg(value));
+ }
+}
+
+bool FocusAssistBlocks = false;
+
+// Thanks https://www.withinrafael.com/2019/09/19/determine-if-your-app-is-in-a-focus-assist-profiles-priority-list/
+void QueryFocusAssist() {
+ ComPtr quietHoursSettings;
+ auto hr = CoCreateInstance(
+ CLSID_QuietHoursSettings,
+ nullptr,
+ CLSCTX_LOCAL_SERVER,
+ IID_PPV_ARGS(&quietHoursSettings));
+ if (!SUCCEEDED(hr) || !quietHoursSettings) {
+ return;
+ }
+
+ auto profileId = LPWSTR{};
+ const auto guardProfileId = gsl::finally([&] {
+ if (profileId) CoTaskMemFree(profileId);
+ });
+ hr = quietHoursSettings->get_UserSelectedProfile(&profileId);
+ if (!SUCCEEDED(hr) || !profileId) {
+ return;
+ }
+ const auto profileName = QString::fromWCharArray(profileId);
+ if (profileName.endsWith(".alarmsonly", Qt::CaseInsensitive)) {
+ if (!FocusAssistBlocks) {
+ LOG(("Focus Assist: Alarms Only."));
+ FocusAssistBlocks = true;
+ }
+ return;
+ } else if (!profileName.endsWith(".priorityonly", Qt::CaseInsensitive)) {
+ if (!profileName.endsWith(".unrestricted", Qt::CaseInsensitive)) {
+ LOG(("Focus Assist Warning: Unknown profile '%1'"
+ ).arg(profileName));
+ }
+ if (FocusAssistBlocks) {
+ LOG(("Focus Assist: Unrestricted."));
+ FocusAssistBlocks = false;
+ }
+ return;
+ }
+ const auto appUserModelId = std::wstring(AppUserModelId::getId());
+ auto blocked = true;
+ const auto guard = gsl::finally([&] {
+ if (FocusAssistBlocks != blocked) {
+ LOG(("Focus Assist: %1, AppUserModelId: %2, Blocks: %3"
+ ).arg(profileName
+ ).arg(QString::fromStdWString(appUserModelId)
+ ).arg(Logs::b(blocked)));
+ FocusAssistBlocks = blocked;
+ }
+ });
+
+ ComPtr profile;
+ hr = quietHoursSettings->GetProfile(profileId, &profile);
+ if (!SUCCEEDED(hr) || !profile) {
+ return;
+ }
+
+ UINT32 count = 0;
+ auto apps = (LPWSTR*)nullptr;
+ const auto guardApps = gsl::finally([&] {
+ if (apps) CoTaskMemFree(apps);
+ });
+ hr = profile->GetAllowedApps(&count, &apps);
+ if (!SUCCEEDED(hr) || !apps) {
+ return;
+ }
+ for (UINT32 i = 0; i < count; i++) {
+ auto app = apps[i];
+ const auto guardApp = gsl::finally([&] {
+ if (app) CoTaskMemFree(app);
+ });
+ if (app == appUserModelId) {
+ blocked = false;
+ }
+ }
+}
+
+QUERY_USER_NOTIFICATION_STATE UserNotificationState = QUNS_ACCEPTS_NOTIFICATIONS;
+
+void QueryUserNotificationState() {
+ if (Dlls::SHQueryUserNotificationState != nullptr) {
+ QUERY_USER_NOTIFICATION_STATE state;
+ if (SUCCEEDED(Dlls::SHQueryUserNotificationState(&state))) {
+ UserNotificationState = state;
+ }
+ }
+}
+
+static constexpr auto kQuerySettingsEachMs = 1000;
+crl::time LastSettingsQueryMs = 0;
+
+void QuerySystemNotificationSettings() {
+ auto ms = crl::now();
+ if (LastSettingsQueryMs > 0 && ms <= LastSettingsQueryMs + kQuerySettingsEachMs) {
+ return;
+ }
+ LastSettingsQueryMs = ms;
+ QueryQuietHours();
+ QueryFocusAssist();
+ QueryUserNotificationState();
+}
+
} // namespace
#endif // !__MINGW32__
+bool SkipAudioForCustom() {
+ QuerySystemNotificationSettings();
+
+ return (UserNotificationState == QUNS_NOT_PRESENT)
+ || (UserNotificationState == QUNS_PRESENTATION_MODE)
+ || Global::ScreenIsLocked();
+}
+
+bool SkipToastForCustom() {
+ QuerySystemNotificationSettings();
+
+ return (UserNotificationState == QUNS_PRESENTATION_MODE)
+ || (UserNotificationState == QUNS_RUNNING_D3D_FULL_SCREEN);
+}
+
+bool SkipFlashBounceForCustom() {
+ return SkipToastForCustom();
+}
+
bool Supported() {
#ifndef __MINGW32__
if (!Checked) {
@@ -627,201 +806,23 @@ void Manager::onAfterNotificationActivated(
not_null window) {
_private->afterNotificationActivated(id, window);
}
+
+bool Manager::doSkipAudio() const {
+ return SkipAudioForCustom()
+ || QuietHoursEnabled
+ || FocusAssistBlocks;
+}
+
+bool Manager::doSkipToast() const {
+ return false;
+}
+
+bool Manager::doSkipFlashBounce() const {
+ return SkipFlashBounceForCustom()
+ || QuietHoursEnabled
+ || FocusAssistBlocks;
+}
#endif // !__MINGW32__
-namespace {
-
-bool QuietHoursEnabled = false;
-DWORD QuietHoursValue = 0;
-
-[[nodiscard]] bool UseQuietHoursRegistryEntry() {
- static const bool result = [] {
- // Taken from QSysInfo.
- OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0,{ '\0' } };
- if (const auto library = GetModuleHandle(L"ntdll.dll")) {
- using RtlGetVersionFunction = NTSTATUS(NTAPI*)(LPOSVERSIONINFO);
- const auto RtlGetVersion = reinterpret_cast(
- GetProcAddress(library, "RtlGetVersion"));
- if (RtlGetVersion) {
- RtlGetVersion(&result);
- }
- }
- // At build 17134 (Redstone 4) the "Quiet hours" was replaced
- // by "Focus assist" and it looks like it doesn't use registry.
- return (result.dwMajorVersion == 10
- && result.dwMinorVersion == 0
- && result.dwBuildNumber < 17134);
- }();
- return result;
-}
-
-// Thanks https://stackoverflow.com/questions/35600128/get-windows-quiet-hours-from-win32-or-c-sharp-api
-void QueryQuietHours() {
- if (!UseQuietHoursRegistryEntry()) {
- // There are quiet hours in Windows starting from Windows 8.1
- // But there were several reports about the notifications being shut
- // down according to the registry while no quiet hours were enabled.
- // So we try this method only starting with Windows 10.
- return;
- }
-
- LPCWSTR lpKeyName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Notifications\\Settings";
- LPCWSTR lpValueName = L"NOC_GLOBAL_SETTING_TOASTS_ENABLED";
- HKEY key;
- auto result = RegOpenKeyEx(HKEY_CURRENT_USER, lpKeyName, 0, KEY_READ, &key);
- if (result != ERROR_SUCCESS) {
- return;
- }
-
- DWORD value = 0, type = 0, size = sizeof(value);
- result = RegQueryValueEx(key, lpValueName, 0, &type, (LPBYTE)&value, &size);
- RegCloseKey(key);
-
- auto quietHoursEnabled = (result == ERROR_SUCCESS) && (value == 0);
- if (QuietHoursEnabled != quietHoursEnabled) {
- QuietHoursEnabled = quietHoursEnabled;
- QuietHoursValue = value;
- LOG(("Quiet hours changed, entry value: %1").arg(value));
- } else if (QuietHoursValue != value) {
- QuietHoursValue = value;
- LOG(("Quiet hours value changed, was value: %1, entry value: %2").arg(QuietHoursValue).arg(value));
- }
-}
-
-bool FocusAssistBlocks = false;
-
-// Thanks https://www.withinrafael.com/2019/09/19/determine-if-your-app-is-in-a-focus-assist-profiles-priority-list/
-void QueryFocusAssist() {
- ComPtr quietHoursSettings;
- auto hr = CoCreateInstance(
- CLSID_QuietHoursSettings,
- nullptr,
- CLSCTX_LOCAL_SERVER,
- IID_PPV_ARGS(&quietHoursSettings));
- if (!SUCCEEDED(hr) || !quietHoursSettings) {
- return;
- }
-
- auto profileId = LPWSTR{};
- const auto guardProfileId = gsl::finally([&] {
- if (profileId) CoTaskMemFree(profileId);
- });
- hr = quietHoursSettings->get_UserSelectedProfile(&profileId);
- if (!SUCCEEDED(hr) || !profileId) {
- return;
- }
- const auto profileName = QString::fromWCharArray(profileId);
- if (profileName.endsWith(".alarmsonly", Qt::CaseInsensitive)) {
- if (!FocusAssistBlocks) {
- LOG(("Focus Assist: Alarms Only."));
- FocusAssistBlocks = true;
- }
- return;
- } else if (!profileName.endsWith(".priorityonly", Qt::CaseInsensitive)) {
- if (!profileName.endsWith(".unrestricted", Qt::CaseInsensitive)) {
- LOG(("Focus Assist Warning: Unknown profile '%1'"
- ).arg(profileName));
- }
- if (FocusAssistBlocks) {
- LOG(("Focus Assist: Unrestricted."));
- FocusAssistBlocks = false;
- }
- return;
- }
- const auto appUserModelId = std::wstring(AppUserModelId::getId());
- auto blocked = true;
- const auto guard = gsl::finally([&] {
- if (FocusAssistBlocks != blocked) {
- LOG(("Focus Assist: %1, AppUserModelId: %2, Blocks: %3"
- ).arg(profileName
- ).arg(QString::fromStdWString(appUserModelId)
- ).arg(Logs::b(blocked)));
- FocusAssistBlocks = blocked;
- }
- });
-
- ComPtr profile;
- hr = quietHoursSettings->GetProfile(profileId, &profile);
- if (!SUCCEEDED(hr) || !profile) {
- return;
- }
-
- UINT32 count = 0;
- auto apps = (LPWSTR*)nullptr;
- const auto guardApps = gsl::finally([&] {
- if (apps) CoTaskMemFree(apps);
- });
- hr = profile->GetAllowedApps(&count, &apps);
- if (!SUCCEEDED(hr) || !apps) {
- return;
- }
- for (UINT32 i = 0; i < count; i++) {
- auto app = apps[i];
- const auto guardApp = gsl::finally([&] {
- if (app) CoTaskMemFree(app);
- });
- if (app == appUserModelId) {
- blocked = false;
- }
- }
-}
-
-QUERY_USER_NOTIFICATION_STATE UserNotificationState = QUNS_ACCEPTS_NOTIFICATIONS;
-
-void QueryUserNotificationState() {
- if (Dlls::SHQueryUserNotificationState != nullptr) {
- QUERY_USER_NOTIFICATION_STATE state;
- if (SUCCEEDED(Dlls::SHQueryUserNotificationState(&state))) {
- UserNotificationState = state;
- }
- }
-}
-
-static constexpr auto kQuerySettingsEachMs = 1000;
-crl::time LastSettingsQueryMs = 0;
-
-void QuerySystemNotificationSettings() {
- auto ms = crl::now();
- if (LastSettingsQueryMs > 0 && ms <= LastSettingsQueryMs + kQuerySettingsEachMs) {
- return;
- }
- LastSettingsQueryMs = ms;
- QueryQuietHours();
- QueryFocusAssist();
- QueryUserNotificationState();
-}
-
-} // namespace
-
-bool SkipAudio() {
- QuerySystemNotificationSettings();
-
- if (UserNotificationState == QUNS_NOT_PRESENT
- || UserNotificationState == QUNS_PRESENTATION_MODE
- || QuietHoursEnabled
- || FocusAssistBlocks
- || Global::ScreenIsLocked()) {
- return true;
- }
- return false;
-}
-
-bool SkipToast() {
- QuerySystemNotificationSettings();
-
- if (UserNotificationState == QUNS_PRESENTATION_MODE
- || UserNotificationState == QUNS_RUNNING_D3D_FULL_SCREEN
- //|| UserNotificationState == QUNS_BUSY
- || QuietHoursEnabled
- || FocusAssistBlocks) {
- return true;
- }
- return false;
-}
-
-bool SkipFlashBounce() {
- return SkipToast();
-}
-
} // namespace Notifications
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.h b/Telegram/SourceFiles/platform/win/notifications_manager_win.h
index b86a30221..be37f9ff4 100644
--- a/Telegram/SourceFiles/platform/win/notifications_manager_win.h
+++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.h
@@ -39,6 +39,9 @@ protected:
void onAfterNotificationActivated(
NotificationId id,
not_null window) override;
+ bool doSkipAudio() const override;
+ bool doSkipToast() const override;
+ bool doSkipFlashBounce() const override;
private:
class Private;
diff --git a/Telegram/SourceFiles/ui/widgets/separate_panel.cpp b/Telegram/SourceFiles/ui/widgets/separate_panel.cpp
index 69e67fdce..ccc7559e8 100644
--- a/Telegram/SourceFiles/ui/widgets/separate_panel.cpp
+++ b/Telegram/SourceFiles/ui/widgets/separate_panel.cpp
@@ -356,11 +356,35 @@ QRect SeparatePanel::innerGeometry() const {
void SeparatePanel::initGeometry(QSize size) {
const auto active = QApplication::activeWindow();
- const auto center = !active
- ? QGuiApplication::primaryScreen()->geometry().center()
- : (active->isVisible() && active->isActiveWindow())
- ? active->geometry().center()
- : active->windowHandle()->screen()->geometry().center();
+ const auto available = !active
+ ? QGuiApplication::primaryScreen()->availableGeometry()
+ : active->windowHandle()->screen()->availableGeometry();
+ const auto parentGeometry = (active
+ && active->isVisible()
+ && active->isActiveWindow())
+ ? active->geometry()
+ : available;
+
+ auto center = parentGeometry.center();
+ if (size.height() > available.height()) {
+ size = QSize(size.width(), available.height());
+ }
+ if (center.x() + size.width() / 2
+ > available.x() + available.width()) {
+ center.setX(
+ available.x() + available.width() - size.width() / 2);
+ }
+ if (center.x() - size.width() / 2 < available.x()) {
+ center.setX(available.x() + size.width() / 2);
+ }
+ if (center.y() + size.height() / 2
+ > available.y() + available.height()) {
+ center.setY(
+ available.y() + available.height() - size.height() / 2);
+ }
+ if (center.y() - size.height() / 2 < available.y()) {
+ center.setY(available.y() + size.height() / 2);
+ }
_useTransparency = Ui::Platform::TranslucentWindowsSupported(center);
_padding = _useTransparency
? st::callShadow.extend
diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp
index 8e4d95bfb..3e8372cc8 100644
--- a/Telegram/SourceFiles/window/notifications_manager.cpp
+++ b/Telegram/SourceFiles/window/notifications_manager.cpp
@@ -140,6 +140,8 @@ System::SkipState System::skipNotification(
}
void System::schedule(not_null item) {
+ Expects(_manager != nullptr);
+
const auto history = item->history();
const auto skip = skipNotification(item);
if (skip.value == SkipState::Skip) {
@@ -169,7 +171,7 @@ void System::schedule(not_null item) {
_whenAlerts[history].emplace(when, notifyBy);
}
if (Core::App().settings().desktopNotify()
- && !Platform::Notifications::SkipToast()) {
+ && !_manager->skipToast()) {
auto &whenMap = _whenMaps[history];
if (whenMap.find(item->id) == whenMap.end()) {
whenMap.emplace(item->id, when);
@@ -393,7 +395,7 @@ void System::showNext() {
}
const auto &settings = Core::App().settings();
if (alert) {
- if (settings.flashBounceNotify() && !Platform::Notifications::SkipFlashBounce()) {
+ if (settings.flashBounceNotify() && !_manager->skipFlashBounce()) {
if (const auto window = Core::App().activeWindow()) {
if (const auto handle = window->widget()->windowHandle()) {
handle->alert(kSystemAlertDuration);
@@ -401,7 +403,7 @@ void System::showNext() {
}
}
}
- if (settings.soundNotify() && !Platform::Notifications::SkipAudio()) {
+ if (settings.soundNotify() && !_manager->skipAudio()) {
ensureSoundCreated();
_soundTrack->playOnce();
Media::Player::mixer()->suppressAll(_soundTrack->getLengthMs());
@@ -409,7 +411,7 @@ void System::showNext() {
}
}
- if (_waiters.empty() || !settings.desktopNotify() || Platform::Notifications::SkipToast()) {
+ if (_waiters.empty() || !settings.desktopNotify() || _manager->skipToast()) {
if (nextAlert) {
_waitTimer.callOnce(nextAlert - ms);
}
diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h
index 83c8ad347..8c0d338cf 100644
--- a/Telegram/SourceFiles/window/notifications_manager.h
+++ b/Telegram/SourceFiles/window/notifications_manager.h
@@ -202,6 +202,16 @@ public:
[[nodiscard]] virtual ManagerType type() const = 0;
+ [[nodiscard]] bool skipAudio() const {
+ return doSkipAudio();
+ }
+ [[nodiscard]] bool skipToast() const {
+ return doSkipToast();
+ }
+ [[nodiscard]] bool skipFlashBounce() const {
+ return doSkipFlashBounce();
+ }
+
virtual ~Manager() = default;
protected:
@@ -218,6 +228,9 @@ protected:
virtual void doClearFromItem(not_null item) = 0;
virtual void doClearFromHistory(not_null history) = 0;
virtual void doClearFromSession(not_null session) = 0;
+ virtual bool doSkipAudio() const = 0;
+ virtual bool doSkipToast() const = 0;
+ virtual bool doSkipFlashBounce() const = 0;
[[nodiscard]] virtual bool forceHideDetails() const {
return false;
}
@@ -298,6 +311,15 @@ protected:
}
void doClearFromSession(not_null session) override {
}
+ bool doSkipAudio() const {
+ return false;
+ }
+ bool doSkipToast() const {
+ return false;
+ }
+ bool doSkipFlashBounce() const {
+ return false;
+ }
};
diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp
index 13dce6768..a61129c79 100644
--- a/Telegram/SourceFiles/window/notifications_manager_default.cpp
+++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp
@@ -404,6 +404,18 @@ void Manager::doClearFromItem(not_null item) {
}
}
+bool Manager::doSkipAudio() const {
+ return Platform::Notifications::SkipAudioForCustom();
+}
+
+bool Manager::doSkipToast() const {
+ return Platform::Notifications::SkipToastForCustom();
+}
+
+bool Manager::doSkipFlashBounce() const {
+ return Platform::Notifications::SkipFlashBounceForCustom();
+}
+
void Manager::doUpdateAll() {
for_const (auto ¬ification, _notifications) {
notification->updateNotifyDisplay();
diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h
index 68d7c9614..19a6a98c0 100644
--- a/Telegram/SourceFiles/window/notifications_manager_default.h
+++ b/Telegram/SourceFiles/window/notifications_manager_default.h
@@ -76,6 +76,9 @@ private:
void doClearFromHistory(not_null history) override;
void doClearFromSession(not_null session) override;
void doClearFromItem(not_null item) override;
+ bool doSkipAudio() const;
+ bool doSkipToast() const;
+ bool doSkipFlashBounce() const;
void showNextFromQueue();
void unlinkFromShown(Notification *remove);
diff --git a/Telegram/build/version b/Telegram/build/version
index 559ba17ac..40699aa9c 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,7 +1,7 @@
-AppVersion 2007003
+AppVersion 2007004
AppVersionStrMajor 2.7
-AppVersionStrSmall 2.7.3
-AppVersionStr 2.7.3
+AppVersionStrSmall 2.7.4
+AppVersionStr 2.7.4
BetaChannel 0
AlphaVersion 0
-AppVersionOriginal 2.7.3
+AppVersionOriginal 2.7.4
diff --git a/changelog.txt b/changelog.txt
index 52e7e7ea5..7ac8ce48c 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,9 @@
+2.7.4 (28.04.21)
+
+- Fix crash in viewing an invoice after a payment is made.
+- Respect Focus Assist only for native notifications.
+- Mark messages as read only in active window.
+
2.7.3 (27.04.21)
- Fix crash on some versions of Linux.
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 427371560..d1f580742 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -148,7 +148,7 @@ parts:
prime: [-./*]
desktop-qt5:
- source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
+ source: https://github.com/desktop-app/snapcraft-desktop-helpers.git
source-subdir: qt
plugin: make
make-parameters: ["FLAVOR=qt5"]