diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b8543d48f7..73e88c6ba3 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -522,6 +522,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_use_native_notifications" = "Use native notifications"; "lng_settings_notifications_position" = "Location on the screen"; "lng_settings_notifications_count" = "Notifications count"; +"lng_settings_notifications_display" = "Display for notifications"; +"lng_settings_notifications_display_default" = "Default"; "lng_settings_sound_allowed" = "Allow sound"; "lng_settings_alert_windows" = "Flash the taskbar icon"; "lng_settings_alert_mac" = "Bounce the Dock icon"; diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index aaf7bae18d..e60324915b 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -241,7 +241,8 @@ QByteArray Settings::serialize() const { + sizeof(qint32) * 3 + Serialize::bytearraySize(_tonsiteStorageToken) + sizeof(qint32) * 8 - + sizeof(ushort); + + sizeof(ushort) + + sizeof(qint32); // _notificationsDisplayChecksum auto result = QByteArray(); result.reserve(size); @@ -404,7 +405,8 @@ QByteArray Settings::serialize() const { << qint32(_ivZoom.current()) << qint32(_systemDarkModeEnabled.current() ? 1 : 0) << qint32(_quickDialogAction) - << _notificationsVolume; + << _notificationsVolume + << _notificationsDisplayChecksum; } Ensures(result.size() == size); @@ -435,6 +437,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { qint32 nativeNotifications = _nativeNotifications ? (*_nativeNotifications ? 1 : 2) : 0; qint32 notificationsCount = _notificationsCount; qint32 notificationsCorner = static_cast(_notificationsCorner); + qint32 notificationsDisplayChecksum = _notificationsDisplayChecksum; qint32 autoLock = _autoLock; QString playbackDeviceId = _playbackDeviceId.current(); QString captureDeviceId = _captureDeviceId.current(); @@ -869,6 +872,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) { if (!stream.atEnd()) { stream >> notificationsVolume; } + if (!stream.atEnd()) { + stream >> notificationsDisplayChecksum; + } if (stream.status() != QDataStream::Ok) { LOG(("App Error: " "Bad data for Core::Settings::constructFromSerialized()")); @@ -908,6 +914,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { case ScreenCorner::BottomRight: case ScreenCorner::BottomLeft: _notificationsCorner = uncheckedNotificationsCorner; break; } + _notificationsDisplayChecksum = notificationsDisplayChecksum; _includeMutedCounter = (includeMutedCounter == 1); _includeMutedCounterFolders = (includeMutedCounterFolders == 1); _countUnreadMessages = (countUnreadMessages == 1); diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index 9ee26fea74..0a78d2c22c 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -241,6 +241,12 @@ public: void setNotificationsCorner(ScreenCorner corner) { _notificationsCorner = corner; } + [[nodiscard]] int32 notificationsDisplayChecksum() const { + return _notificationsDisplayChecksum; + } + void setNotificationsDisplayChecksum(int32 checksum) { + _notificationsDisplayChecksum = checksum; + } [[nodiscard]] bool includeMutedCounter() const { return _includeMutedCounter; } @@ -988,6 +994,7 @@ private: bool _skipToastsInFocus = false; int _notificationsCount = 3; ScreenCorner _notificationsCorner = ScreenCorner::BottomRight; + int32 _notificationsDisplayChecksum = 0; bool _includeMutedCounter = true; bool _includeMutedCounterFolders = true; bool _countUnreadMessages = true; diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index f70a8959fd..4115d7def1 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -539,4 +539,16 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *evt) { MainWindow::~MainWindow() { } +int32 ScreenNameChecksum(const QString &name) { + return Window::DefaultScreenNameChecksum(name); +} + +int32 ScreenNameChecksum(const QScreen *screen) { + return ScreenNameChecksum(screen->name()); +} + +QString ScreenDisplayLabel(const QScreen *screen) { + return screen ? screen->name() : QString(); +} + } // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index 4ef98ba773..4a5ba8f7fa 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -63,8 +63,9 @@ private: }; -[[nodiscard]] inline int32 ScreenNameChecksum(const QString &name) { - return Window::DefaultScreenNameChecksum(name); -} +[[nodiscard]] int32 ScreenNameChecksum(const QString &name); +[[nodiscard]] int32 ScreenNameChecksum(const QScreen *screen); + +[[nodiscard]] QString ScreenDisplayLabel(const QScreen *screen); } // namespace Platform diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index 63ed4009b3..890639f1e2 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -93,8 +93,9 @@ private: }; -[[nodiscard]] inline int32 ScreenNameChecksum(const QString &name) { - return Window::DefaultScreenNameChecksum(name); -} +[[nodiscard]] int32 ScreenNameChecksum(const QString &name); +[[nodiscard]] int32 ScreenNameChecksum(const QScreen *screen); + +[[nodiscard]] QString ScreenDisplayLabel(const QScreen *screen); } // namespace Platform diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 5b26fefb9d..f301749453 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -675,4 +675,16 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *evt) { MainWindow::~MainWindow() { } +int32 ScreenNameChecksum(const QString &name) { + return Window::DefaultScreenNameChecksum(name); +} + +int32 ScreenNameChecksum(const QScreen *screen) { + return ScreenNameChecksum(screen->name()); +} + +QString ScreenDisplayLabel(const QScreen *screen) { + return screen ? screen->name() : QString(); +} + } // namespace diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index ede58134f4..61ef7cdc2f 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -724,4 +724,12 @@ int32 ScreenNameChecksum(const QString &name) { return base::crc32(buffer, sizeof(buffer)); } +int32 ScreenNameChecksum(const QScreen *screen) { + return ScreenNameChecksum(screen->name()); +} + +QString ScreenDisplayLabel(const QScreen *screen) { + return screen ? screen->name() : QString(); +} + } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index 9f4884467e..95f9d52da6 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -106,5 +106,8 @@ private: }; [[nodiscard]] int32 ScreenNameChecksum(const QString &name); +[[nodiscard]] int32 ScreenNameChecksum(const QScreen *screen); + +[[nodiscard]] QString ScreenDisplayLabel(const QScreen *screen); } // namespace Platform diff --git a/Telegram/SourceFiles/settings/settings_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp index e0ca4c1bf3..b42ae02ec0 100644 --- a/Telegram/SourceFiles/settings/settings_notifications.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications.cpp @@ -52,11 +52,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_dialogs.h" #include +#include +#include namespace Settings { namespace { constexpr auto kMaxNotificationsCount = 5; +constexpr auto kDefaultDisplayIndex = -1; [[nodiscard]] int CurrentCount() { return std::clamp( @@ -542,7 +545,8 @@ void NotificationsCount::setOverCorner(ScreenCorner corner) { samples[i]->showFast(); } if (samplesNeeded > samplesLeave) { - auto r = _controller->widget()->desktopRect(); + const auto r = Window::Notifications::NotificationDisplayRect( + &_controller->window()); auto isLeft = Core::Settings::IsLeftCorner(_overCorner); auto isTop = Core::Settings::IsTopCorner(_overCorner); auto sampleLeft = (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX); @@ -887,6 +891,79 @@ void SetupAdvancedNotifications( }, skipInFocus->lifetime()); } + const auto screens = QGuiApplication::screens(); + if (screens.size() > 1) { + Ui::AddSkip(container, st::settingsCheckboxesSkip); + Ui::AddDivider(container); + Ui::AddSkip(container, st::settingsCheckboxesSkip); + Ui::AddSubsectionTitle( + container, + tr::lng_settings_notifications_display()); + + const auto currentChecksum + = Core::App().settings().notificationsDisplayChecksum(); + auto currentIndex = (currentChecksum == 0) + ? kDefaultDisplayIndex + : 0; + for (auto i = 0; i < screens.size(); ++i) { + if (Platform::ScreenNameChecksum(screens[i]) == currentChecksum) { + currentIndex = i; + break; + } + } + + const auto group = std::make_shared( + currentIndex); + + container->add( + object_ptr( + container, + group, + kDefaultDisplayIndex, + tr::lng_settings_notifications_display_default(tr::now), + st::settingsSendType), + st::settingsSendTypePadding); + + for (auto i = 0; i < screens.size(); ++i) { + const auto &screen = screens[i]; + const auto name = Platform::ScreenDisplayLabel(screen); + const auto geometry = screen->geometry(); + const auto resolution = QString::number(geometry.width()) + + QChar(0x00D7) + + QString::number(geometry.height()); + const auto label = name.isEmpty() + ? QString("Display (%1)").arg(resolution) + : QString("%1 (%2)").arg(name).arg(resolution); + container->add( + object_ptr( + container, + group, + i, + label, + st::settingsSendType), + st::settingsSendTypePadding); + } + group->setChangedCallback([=](int selectedIndex) { + if (selectedIndex == kDefaultDisplayIndex) { + Core::App().settings().setNotificationsDisplayChecksum(0); + Core::App().saveSettings(); + Core::App().notifications().notifySettingsChanged( + ChangeType::Corner); + } else { + const auto screens = QGuiApplication::screens(); + if (selectedIndex >= 0 && selectedIndex < screens.size()) { + const auto checksum = Platform::ScreenNameChecksum( + screens[selectedIndex]); + Core::App().settings().setNotificationsDisplayChecksum( + checksum); + Core::App().saveSettings(); + Core::App().notifications().notifySettingsChanged( + ChangeType::Corner); + } + } + }); + } + Ui::AddSkip(container, st::settingsCheckboxesSkip); Ui::AddDivider(container); Ui::AddSkip(container, st::settingsCheckboxesSkip); diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index e69cb49b03..affd4badc9 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -40,8 +40,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "main/main_session_settings.h" #include "ui/text/text_utilities.h" +#include "platform/platform_specific.h" #include +#include +#include #if __has_include() #include @@ -1479,5 +1482,27 @@ QString WrapFromScheduled(const QString &text) { return QString::fromUtf8("\xF0\x9F\x93\x85 ") + text; } +QRect NotificationDisplayRect(Window::Controller *controller) { + const auto displayChecksum + = Core::App().settings().notificationsDisplayChecksum(); + + auto screen = (QScreen*)(nullptr); + if (displayChecksum) { + using namespace Platform; + for (const auto candidateScreen : QGuiApplication::screens()) { + if (ScreenNameChecksum(candidateScreen) == displayChecksum) { + screen = candidateScreen; + break; + } + } + } + + return screen + ? screen->availableGeometry() + : controller + ? controller->widget()->desktopRect() + : QGuiApplication::primaryScreen()->availableGeometry(); +} + } // namespace Notifications } // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index 4e7fb064a0..1e84c3a63a 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -42,6 +42,7 @@ class Track; } // namespace Media::Audio namespace Window { +class Controller; class SessionController; } // namespace Window @@ -468,4 +469,6 @@ protected: [[nodiscard]] QString WrapFromScheduled(const QString &text); +[[nodiscard]] QRect NotificationDisplayRect(Window::Controller *controller); + } // namespace Window::Notifications diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 441f97eae3..bd4e46042a 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -51,10 +51,7 @@ namespace { [[nodiscard]] QPoint notificationStartPosition() { const auto corner = Core::App().settings().notificationsCorner(); - const auto window = Core::App().activePrimaryWindow(); - const auto r = window - ? window->widget()->desktopRect() - : QGuiApplication::primaryScreen()->availableGeometry(); + const auto r = NotificationDisplayRect(Core::App().activePrimaryWindow()); const auto isLeft = Core::Settings::IsLeftCorner(corner); const auto isTop = Core::Settings::IsTopCorner(corner); const auto x = (isLeft == rtl())