Compare commits

..

15 Commits

Author SHA1 Message Date
John Preston
9c9fc9e881 Version 2.7.4: Fix build for macOS. 2021-04-28 14:08:02 +04:00
John Preston
1d089366ff Version 2.7.4.
- 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.
2021-04-28 13:16:01 +04:00
John Preston
fe40464e33 Force separate panel into the screen geometry. 2021-04-28 13:16:00 +04:00
John Preston
728b1efb9a Respect Focus Assist only for native notifications.
Fixes #16215.
2021-04-28 11:20:39 +04:00
John Preston
175f3d7a38 Use our fork of 'snapcraft-desktop-helpers'. 2021-04-28 10:46:03 +04:00
Stepan Skryabin
ae1fb8841a Update supported operating systems 2021-04-28 09:39:58 +03:00
Ilya Fedin
16ba20f898 Prefer portal file dialog in all environments 2021-04-28 09:39:20 +03:00
Daniil
d8ffc114d3 Revert number keys check 2021-04-28 09:38:23 +03:00
Daniil
23bd76a8dd Expand moderating mode some more
Revert key check, since number keys stopped working if bot have 
Add missing commands since last PR, also add keys to respect both keypad and regular keyboard users.
2021-04-28 09:38:23 +03:00
John Preston
d85981cca0 Revert "Check if the window is not overlapped when is not active"
This reverts commit 6b1bc1e845.

Fixes #16188. Maybe add an option later.
2021-04-28 10:36:15 +04:00
Ilya Fedin
7b466e0643 Take shadow into account when saving/restoring window geometry 2021-04-28 10:13:54 +04:00
John Preston
d984c5924d Fix crash in invoice view.
Fixes #16210.
2021-04-27 22:18:35 +04:00
23rd
cfa3352caf Added NuGet to Github CI for Windows. 2021-04-27 21:16:26 +03:00
Ilya Fedin
05d2fc819c Bind path to WebkitWebProcess 2021-04-27 17:44:41 +03:00
Ilya Fedin
cb930a89ce Silence ServiceUnknown and Disconnected errors for native notifications 2021-04-27 17:44:16 +03:00
26 changed files with 378 additions and 278 deletions

View File

@@ -114,6 +114,11 @@ jobs:
- name: Choco installs.
run: choco install --no-progress -y nasm yasm jom ninja
- name: NuGet sources.
run: |
nuget sources Disable -Name "Microsoft Visual Studio Offline Packages"
nuget sources Add -Source https://api.nuget.org/v3/index.json & exit 0
- name: Patches.
shell: bash
run: |
@@ -279,6 +284,10 @@ jobs:
msbuild -m opus.sln /property:Configuration=Debug /property:Platform="Win32"
msbuild -m opus.sln /property:Configuration=Release /property:Platform="Win32"
echo "Workaround for FFmpeg."
copy Win32\Release\m.lib Win32\Release\ssp.lib
copy Win32\Release\m.lib Win32\Debug\ssp.lib
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v2

View File

@@ -15,7 +15,8 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
The latest version is available for
* [Windows 7 and above](https://telegram.org/dl/desktop/win) ([portable](https://telegram.org/dl/desktop/win_portable))
* [Windows 7 and above (64 bit)](https://telegram.org/dl/desktop/win64) ([portable](https://telegram.org/dl/desktop/win64_portable))
* [Windows 7 and above (32 bit)](https://telegram.org/dl/desktop/win) ([portable](https://telegram.org/dl/desktop/win_portable))
* [macOS 10.12 and above](https://telegram.org/dl/desktop/mac)
* [Linux static build for 64 bit](https://telegram.org/dl/desktop/linux)
* [Snap](https://snapcraft.io/telegram-desktop)

View File

@@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.7.3.0" />
Version="2.7.4.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>

View File

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

View File

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

View File

@@ -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;
}

View File

@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Telegram Desktop"_cs;
constexpr auto AppFile = "Telegram"_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;

View File

@@ -557,13 +557,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() {

View File

@@ -196,7 +196,7 @@ void FormSummary::setupControls() {
_1 + _2 < _3));
rpl::merge(
_submit->widthValue(),
(_submit ? _submit->widthValue() : rpl::single(0)),
_cancel->widthValue()
) | rpl::skip(2) | rpl::start_with_next([=] {
updateControlsGeometry();

View File

@@ -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) {
static const auto ShouldUse = [&] {
const auto envVar = qEnvironmentVariableIsSet("TDESKTOP_USE_PORTAL");
const auto confined = InFlatpak() || InSnap();
const auto notGtkBased = !DesktopEnvironment::IsGtkBased();
return confined || notGtkBased || envVar;
}();
static const auto Version = FileChooserPortalVersion();
return ShouldUse
&& Version.has_value()
return Version.has_value()
&& (type != Type::ReadFolder || *Version >= 3);
}

View File

@@ -60,8 +60,17 @@ void StartServiceAsync(
try {
result(); // get the error if any
} catch (const Glib::Error &e) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
static const auto NotSupportedErrors = {
"org.freedesktop.DBus.Error.ServiceUnknown",
};
const auto errorName =
Gio::DBus::ErrorUtils::get_remote_error(e);
if (!ranges::contains(NotSupportedErrors, errorName)) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
}
} catch (const std::exception &e) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
@@ -72,9 +81,7 @@ void StartServiceAsync(
cancellable);
return;
} catch (const Glib::Error &e) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
} catch (...) {
}
crl::on_main([=] { callback(); });
@@ -708,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() {
@@ -1023,5 +1023,17 @@ void Manager::doClearFromSession(not_null<Main::Session*> 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

View File

@@ -34,6 +34,9 @@ protected:
void doClearAllFast() override;
void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override;
bool doSkipAudio() const override;
bool doSkipToast() const override;
bool doSkipFlashBounce() const override;
private:
class Private;

View File

@@ -32,6 +32,9 @@ protected:
void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override;
QString accountNameSeparator() override;
bool doSkipAudio() const override;
bool doSkipToast() const override;
bool doSkipFlashBounce() const override;
private:
class Private;

View File

@@ -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

View File

@@ -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();

View File

@@ -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<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
#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::SessionController*> 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<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 Platform

View File

@@ -39,6 +39,9 @@ protected:
void onAfterNotificationActivated(
NotificationId id,
not_null<Window::SessionController*> window) override;
bool doSkipAudio() const override;
bool doSkipToast() const override;
bool doSkipFlashBounce() const override;
private:
class Private;

View File

@@ -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

View File

@@ -461,6 +461,7 @@ void MainWindow::recountGeometryConstraints() {
}
void MainWindow::initSize() {
updateShadowSize();
updateMinimumSize();
if (initSizeFromSystem()) {
@@ -562,6 +563,7 @@ void MainWindow::initSize() {
}
maximized = position.maximized;
}
geometry += _padding;
DEBUG_LOG(("Window Pos: Setting first %1, %2, %3, %4").arg(geometry.x()).arg(geometry.y()).arg(geometry.width()).arg(geometry.height()));
setGeometry(geometry);
}
@@ -679,7 +681,7 @@ void MainWindow::savePosition(Qt::WindowState state) {
realPosition.maximized = 1;
DEBUG_LOG(("Window Pos: Saving maximized position."));
} else {
auto r = geometry();
auto r = geometry().marginsRemoved(_padding);
realPosition.x = r.x();
realPosition.y = r.y();
realPosition.w = r.width() - (_rightColumn ? _rightColumn->width() : 0);

View File

@@ -138,6 +138,8 @@ System::SkipState System::skipNotification(
}
void System::schedule(not_null<HistoryItem*> item) {
Expects(_manager != nullptr);
const auto history = item->history();
const auto skip = skipNotification(item);
if (skip.value == SkipState::Skip) {
@@ -167,7 +169,7 @@ void System::schedule(not_null<HistoryItem*> 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);
@@ -391,7 +393,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);
@@ -399,7 +401,7 @@ void System::showNext() {
}
}
}
if (settings.soundNotify() && !Platform::Notifications::SkipAudio()) {
if (settings.soundNotify() && !_manager->skipAudio()) {
ensureSoundCreated();
_soundTrack->playOnce();
Media::Player::mixer()->suppressAll(_soundTrack->getLengthMs());
@@ -407,7 +409,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);
}

View File

@@ -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<HistoryItem*> item) = 0;
virtual void doClearFromHistory(not_null<History*> history) = 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 {
return false;
}
@@ -298,6 +311,15 @@ protected:
}
void doClearFromSession(not_null<Main::Session*> session) override {
}
bool doSkipAudio() const override {
return false;
}
bool doSkipToast() const override {
return false;
}
bool doSkipFlashBounce() const override {
return false;
}
};

View File

@@ -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() {
for_const (auto &notification, _notifications) {
notification->updateNotifyDisplay();

View File

@@ -76,6 +76,9 @@ private:
void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override;
void doClearFromItem(not_null<HistoryItem*> item) override;
bool doSkipAudio() const override;
bool doSkipToast() const override;
bool doSkipFlashBounce() const override;
void showNextFromQueue();
void unlinkFromShown(Notification *remove);

View File

@@ -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

View File

@@ -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.

View File

@@ -69,6 +69,8 @@ layout:
bind: $SNAP/usr/share/alsa
/usr/share/X11:
bind: $SNAP/usr/share/X11
/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/webkit2gtk-4.0:
bind: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/webkit2gtk-4.0
parts:
telegram:
@@ -155,7 +157,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"]