Added ability to choose display for notifications to settings.

This commit is contained in:
23rd
2025-09-29 13:12:39 +03:00
parent 54018aec90
commit a2d17f6f3f
13 changed files with 168 additions and 13 deletions
+2
View File
@@ -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";
+9 -2
View File
@@ -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<qint32>(_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);
@@ -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;
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -52,11 +52,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_dialogs.h"
#include <QSvgRenderer>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
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<Ui::RadiobuttonGroup>(
currentIndex);
container->add(
object_ptr<Ui::Radiobutton>(
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<Ui::Radiobutton>(
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);
@@ -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 <QtGui/QWindow>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#if __has_include(<gio/gio.hpp>)
#include <gio/gio.hpp>
@@ -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
@@ -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
@@ -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())