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"]