mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-29 13:47:47 +00:00
Updated TDesktop sources to 2.7.4
This commit is contained in:
commit
351e7c290d
@ -9,7 +9,7 @@
|
|||||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||||
ProcessorArchitecture="ARCHITECTURE"
|
ProcessorArchitecture="ARCHITECTURE"
|
||||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||||
Version="2.7.3.0" />
|
Version="2.7.4.0" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>Telegram Desktop</DisplayName>
|
<DisplayName>Telegram Desktop</DisplayName>
|
||||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||||
|
@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,7,3,0
|
FILEVERSION 2,7,4,0
|
||||||
PRODUCTVERSION 2,7,3,0
|
PRODUCTVERSION 2,7,4,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -62,10 +62,10 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||||
VALUE "FileDescription", "Telegram Desktop"
|
VALUE "FileDescription", "Telegram Desktop"
|
||||||
VALUE "FileVersion", "2.7.3.0"
|
VALUE "FileVersion", "2.7.4.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "2.7.3.0"
|
VALUE "ProductVersion", "2.7.4.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,7,3,0
|
FILEVERSION 2,7,4,0
|
||||||
PRODUCTVERSION 2,7,3,0
|
PRODUCTVERSION 2,7,4,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -53,10 +53,10 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||||
VALUE "FileVersion", "2.7.3.0"
|
VALUE "FileVersion", "2.7.4.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "2.7.3.0"
|
VALUE "ProductVersion", "2.7.4.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -163,14 +163,20 @@ bool BotKeyboard::moderateKeyActivate(int key) {
|
|||||||
}
|
}
|
||||||
} else if (const auto user = item->history()->peer->asUser()) {
|
} else if (const auto user = item->history()->peer->asUser()) {
|
||||||
if (user->isBot() && item->from() == user) {
|
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"));
|
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"));
|
App::sendBotCommand(user, user, qsl("/eng"));
|
||||||
} else if (key == Qt::Key_3) {
|
} else if (key == Qt::Key_3) {
|
||||||
App::sendBotCommand(user, user, qsl("/pattern"));
|
App::sendBotCommand(user, user, qsl("/pattern"));
|
||||||
} else if (key == Qt::Key_4) {
|
} else if (key == Qt::Key_4) {
|
||||||
App::sendBotCommand(user, user, qsl("/abuse"));
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
|
|||||||
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
|
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
|
||||||
constexpr auto AppName = "Kotatogram Desktop"_cs;
|
constexpr auto AppName = "Kotatogram Desktop"_cs;
|
||||||
constexpr auto AppFile = "Kotatogram"_cs;
|
constexpr auto AppFile = "Kotatogram"_cs;
|
||||||
constexpr auto AppVersion = 2007003;
|
constexpr auto AppVersion = 2007004;
|
||||||
constexpr auto AppVersionStr = "2.7.3";
|
constexpr auto AppVersionStr = "2.7.4";
|
||||||
constexpr auto AppBetaVersion = false;
|
constexpr auto AppBetaVersion = false;
|
||||||
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
||||||
|
@ -556,13 +556,8 @@ bool MainWindow::doWeMarkAsRead() {
|
|||||||
if (!_main || Ui::isLayerShown()) {
|
if (!_main || Ui::isLayerShown()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// for tile grid in case other windows have shadows
|
updateIsActive();
|
||||||
// i've seen some windows with >70px shadow margins
|
return isActive() && _main->doWeMarkAsRead();
|
||||||
const auto margin = style::ConvertScale(100);
|
|
||||||
return Ui::IsContentVisible(
|
|
||||||
this,
|
|
||||||
inner().marginsRemoved(QMargins(margin, margin, margin, margin)))
|
|
||||||
&& _main->doWeMarkAsRead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::checkHistoryActivation() {
|
void MainWindow::checkHistoryActivation() {
|
||||||
|
@ -8,8 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "platform/linux/linux_xdp_file_dialog.h"
|
#include "platform/linux/linux_xdp_file_dialog.h"
|
||||||
|
|
||||||
#include "platform/platform_file_utilities.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/base_platform_info.h"
|
||||||
#include "base/platform/linux/base_linux_glibmm_helper.h"
|
#include "base/platform/linux/base_linux_glibmm_helper.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
@ -642,18 +640,8 @@ rpl::producer<> XDPFileDialog::rejected() {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool Use(Type type) {
|
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();
|
static const auto Version = FileChooserPortalVersion();
|
||||||
|
return (FileDialogType() <= ImplementationType::XDP)
|
||||||
return shouldUse
|
|
||||||
&& Version.has_value()
|
&& Version.has_value()
|
||||||
&& (type != Type::ReadFolder || *Version >= 3);
|
&& (type != Type::ReadFolder || *Version >= 3);
|
||||||
}
|
}
|
||||||
|
@ -715,23 +715,16 @@ void NotificationData::notificationReplied(
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool SkipAudio() {
|
bool SkipAudioForCustom() {
|
||||||
return Inhibited();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipToast() {
|
bool SkipToastForCustom() {
|
||||||
// Do not skip native notifications because of Do not disturb.
|
return false;
|
||||||
// They respect this setting anyway.
|
|
||||||
if ((Core::App().settings().nativeNotifications() && Supported())
|
|
||||||
|| Enforced()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Inhibited();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipFlashBounce() {
|
bool SkipFlashBounceForCustom() {
|
||||||
return Inhibited();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Supported() {
|
bool Supported() {
|
||||||
@ -1030,5 +1023,17 @@ void Manager::doClearFromSession(not_null<Main::Session*> session) {
|
|||||||
_private->clearFromSession(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 Notifications
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
@ -34,6 +34,9 @@ protected:
|
|||||||
void doClearAllFast() override;
|
void doClearAllFast() override;
|
||||||
void doClearFromHistory(not_null<History*> history) override;
|
void doClearFromHistory(not_null<History*> history) override;
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||||
|
bool doSkipAudio() const override;
|
||||||
|
bool doSkipToast() const override;
|
||||||
|
bool doSkipFlashBounce() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
@ -32,6 +32,9 @@ protected:
|
|||||||
void doClearFromHistory(not_null<History*> history) override;
|
void doClearFromHistory(not_null<History*> history) override;
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||||
QString accountNameSeparator() override;
|
QString accountNameSeparator() override;
|
||||||
|
bool doSkipAudio() const override;
|
||||||
|
bool doSkipToast() const override;
|
||||||
|
bool doSkipFlashBounce() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
@ -140,23 +140,16 @@ using Manager = Platform::Notifications::Manager;
|
|||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
|
|
||||||
bool SkipAudio() {
|
bool SkipAudioForCustom() {
|
||||||
queryDoNotDisturbState();
|
return false;
|
||||||
return DoNotDisturbEnabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipToast() {
|
bool SkipToastForCustom() {
|
||||||
if (Supported()) {
|
return false;
|
||||||
// Do not skip native notifications because of Do not disturb.
|
|
||||||
// They respect this setting anyway.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
queryDoNotDisturbState();
|
|
||||||
return DoNotDisturbEnabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipFlashBounce() {
|
bool SkipFlashBounceForCustom() {
|
||||||
return SkipAudio();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Supported() {
|
bool Supported() {
|
||||||
@ -438,5 +431,18 @@ QString Manager::accountNameSeparator() {
|
|||||||
return QString::fromUtf8(" \xE2\x86\x92 ");
|
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 Notifications
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
@ -12,9 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
|
|
||||||
[[nodiscard]] bool SkipAudio();
|
[[nodiscard]] bool SkipAudioForCustom();
|
||||||
[[nodiscard]] bool SkipToast();
|
[[nodiscard]] bool SkipToastForCustom();
|
||||||
[[nodiscard]] bool SkipFlashBounce();
|
[[nodiscard]] bool SkipFlashBounceForCustom();
|
||||||
|
|
||||||
[[nodiscard]] bool Supported();
|
[[nodiscard]] bool Supported();
|
||||||
[[nodiscard]] bool Enforced();
|
[[nodiscard]] bool Enforced();
|
||||||
|
@ -257,9 +257,188 @@ void Check() {
|
|||||||
InitSucceeded = init();
|
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<RtlGetVersionFunction>(
|
||||||
|
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<IQuietHoursSettings> 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<IQuietHoursProfile> 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
|
} // namespace
|
||||||
#endif // !__MINGW32__
|
#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() {
|
bool Supported() {
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
if (!Checked) {
|
if (!Checked) {
|
||||||
@ -627,201 +806,23 @@ void Manager::onAfterNotificationActivated(
|
|||||||
not_null<Window::SessionController*> window) {
|
not_null<Window::SessionController*> window) {
|
||||||
_private->afterNotificationActivated(id, 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__
|
#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<RtlGetVersionFunction>(
|
|
||||||
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<IQuietHoursSettings> 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<IQuietHoursProfile> 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 Notifications
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
@ -39,6 +39,9 @@ protected:
|
|||||||
void onAfterNotificationActivated(
|
void onAfterNotificationActivated(
|
||||||
NotificationId id,
|
NotificationId id,
|
||||||
not_null<Window::SessionController*> window) override;
|
not_null<Window::SessionController*> window) override;
|
||||||
|
bool doSkipAudio() const override;
|
||||||
|
bool doSkipToast() const override;
|
||||||
|
bool doSkipFlashBounce() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
@ -356,11 +356,35 @@ QRect SeparatePanel::innerGeometry() const {
|
|||||||
|
|
||||||
void SeparatePanel::initGeometry(QSize size) {
|
void SeparatePanel::initGeometry(QSize size) {
|
||||||
const auto active = QApplication::activeWindow();
|
const auto active = QApplication::activeWindow();
|
||||||
const auto center = !active
|
const auto available = !active
|
||||||
? QGuiApplication::primaryScreen()->geometry().center()
|
? QGuiApplication::primaryScreen()->availableGeometry()
|
||||||
: (active->isVisible() && active->isActiveWindow())
|
: active->windowHandle()->screen()->availableGeometry();
|
||||||
? active->geometry().center()
|
const auto parentGeometry = (active
|
||||||
: active->windowHandle()->screen()->geometry().center();
|
&& 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);
|
_useTransparency = Ui::Platform::TranslucentWindowsSupported(center);
|
||||||
_padding = _useTransparency
|
_padding = _useTransparency
|
||||||
? st::callShadow.extend
|
? st::callShadow.extend
|
||||||
|
@ -140,6 +140,8 @@ System::SkipState System::skipNotification(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void System::schedule(not_null<HistoryItem*> item) {
|
void System::schedule(not_null<HistoryItem*> item) {
|
||||||
|
Expects(_manager != nullptr);
|
||||||
|
|
||||||
const auto history = item->history();
|
const auto history = item->history();
|
||||||
const auto skip = skipNotification(item);
|
const auto skip = skipNotification(item);
|
||||||
if (skip.value == SkipState::Skip) {
|
if (skip.value == SkipState::Skip) {
|
||||||
@ -169,7 +171,7 @@ void System::schedule(not_null<HistoryItem*> item) {
|
|||||||
_whenAlerts[history].emplace(when, notifyBy);
|
_whenAlerts[history].emplace(when, notifyBy);
|
||||||
}
|
}
|
||||||
if (Core::App().settings().desktopNotify()
|
if (Core::App().settings().desktopNotify()
|
||||||
&& !Platform::Notifications::SkipToast()) {
|
&& !_manager->skipToast()) {
|
||||||
auto &whenMap = _whenMaps[history];
|
auto &whenMap = _whenMaps[history];
|
||||||
if (whenMap.find(item->id) == whenMap.end()) {
|
if (whenMap.find(item->id) == whenMap.end()) {
|
||||||
whenMap.emplace(item->id, when);
|
whenMap.emplace(item->id, when);
|
||||||
@ -393,7 +395,7 @@ void System::showNext() {
|
|||||||
}
|
}
|
||||||
const auto &settings = Core::App().settings();
|
const auto &settings = Core::App().settings();
|
||||||
if (alert) {
|
if (alert) {
|
||||||
if (settings.flashBounceNotify() && !Platform::Notifications::SkipFlashBounce()) {
|
if (settings.flashBounceNotify() && !_manager->skipFlashBounce()) {
|
||||||
if (const auto window = Core::App().activeWindow()) {
|
if (const auto window = Core::App().activeWindow()) {
|
||||||
if (const auto handle = window->widget()->windowHandle()) {
|
if (const auto handle = window->widget()->windowHandle()) {
|
||||||
handle->alert(kSystemAlertDuration);
|
handle->alert(kSystemAlertDuration);
|
||||||
@ -401,7 +403,7 @@ void System::showNext() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (settings.soundNotify() && !Platform::Notifications::SkipAudio()) {
|
if (settings.soundNotify() && !_manager->skipAudio()) {
|
||||||
ensureSoundCreated();
|
ensureSoundCreated();
|
||||||
_soundTrack->playOnce();
|
_soundTrack->playOnce();
|
||||||
Media::Player::mixer()->suppressAll(_soundTrack->getLengthMs());
|
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) {
|
if (nextAlert) {
|
||||||
_waitTimer.callOnce(nextAlert - ms);
|
_waitTimer.callOnce(nextAlert - ms);
|
||||||
}
|
}
|
||||||
|
@ -202,6 +202,16 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] virtual ManagerType type() const = 0;
|
[[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;
|
virtual ~Manager() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -218,6 +228,9 @@ protected:
|
|||||||
virtual void doClearFromItem(not_null<HistoryItem*> item) = 0;
|
virtual void doClearFromItem(not_null<HistoryItem*> item) = 0;
|
||||||
virtual void doClearFromHistory(not_null<History*> history) = 0;
|
virtual void doClearFromHistory(not_null<History*> history) = 0;
|
||||||
virtual void doClearFromSession(not_null<Main::Session*> session) = 0;
|
virtual void doClearFromSession(not_null<Main::Session*> session) = 0;
|
||||||
|
virtual bool doSkipAudio() const = 0;
|
||||||
|
virtual bool doSkipToast() const = 0;
|
||||||
|
virtual bool doSkipFlashBounce() const = 0;
|
||||||
[[nodiscard]] virtual bool forceHideDetails() const {
|
[[nodiscard]] virtual bool forceHideDetails() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -298,6 +311,15 @@ protected:
|
|||||||
}
|
}
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override {
|
void doClearFromSession(not_null<Main::Session*> session) override {
|
||||||
}
|
}
|
||||||
|
bool doSkipAudio() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool doSkipToast() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool doSkipFlashBounce() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -404,6 +404,18 @@ void Manager::doClearFromItem(not_null<HistoryItem*> 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() {
|
void Manager::doUpdateAll() {
|
||||||
for_const (auto ¬ification, _notifications) {
|
for_const (auto ¬ification, _notifications) {
|
||||||
notification->updateNotifyDisplay();
|
notification->updateNotifyDisplay();
|
||||||
|
@ -76,6 +76,9 @@ private:
|
|||||||
void doClearFromHistory(not_null<History*> history) override;
|
void doClearFromHistory(not_null<History*> history) override;
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||||
void doClearFromItem(not_null<HistoryItem*> item) override;
|
void doClearFromItem(not_null<HistoryItem*> item) override;
|
||||||
|
bool doSkipAudio() const;
|
||||||
|
bool doSkipToast() const;
|
||||||
|
bool doSkipFlashBounce() const;
|
||||||
|
|
||||||
void showNextFromQueue();
|
void showNextFromQueue();
|
||||||
void unlinkFromShown(Notification *remove);
|
void unlinkFromShown(Notification *remove);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
AppVersion 2007003
|
AppVersion 2007004
|
||||||
AppVersionStrMajor 2.7
|
AppVersionStrMajor 2.7
|
||||||
AppVersionStrSmall 2.7.3
|
AppVersionStrSmall 2.7.4
|
||||||
AppVersionStr 2.7.3
|
AppVersionStr 2.7.4
|
||||||
BetaChannel 0
|
BetaChannel 0
|
||||||
AlphaVersion 0
|
AlphaVersion 0
|
||||||
AppVersionOriginal 2.7.3
|
AppVersionOriginal 2.7.4
|
||||||
|
@ -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)
|
2.7.3 (27.04.21)
|
||||||
|
|
||||||
- Fix crash on some versions of Linux.
|
- Fix crash on some versions of Linux.
|
||||||
|
@ -148,7 +148,7 @@ parts:
|
|||||||
prime: [-./*]
|
prime: [-./*]
|
||||||
|
|
||||||
desktop-qt5:
|
desktop-qt5:
|
||||||
source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
|
source: https://github.com/desktop-app/snapcraft-desktop-helpers.git
|
||||||
source-subdir: qt
|
source-subdir: qt
|
||||||
plugin: make
|
plugin: make
|
||||||
make-parameters: ["FLAVOR=qt5"]
|
make-parameters: ["FLAVOR=qt5"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user