mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
One more attempt to fix DND on macOS.
This commit is contained in:
parent
1eff68813d
commit
32e650548f
12 changed files with 228 additions and 102 deletions
|
@ -794,16 +794,16 @@ void NotificationData::notificationReplied(
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool SkipAudioForCustom() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkipToastForCustom() {
|
bool SkipToastForCustom() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipFlashBounceForCustom() {
|
void MaybePlaySoundForCustom(Fn<void()> playSound) {
|
||||||
return false;
|
playSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaybeFlashBounceForCustom(Fn<void()> flashBounce) {
|
||||||
|
flashBounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitForInputForCustom() {
|
bool WaitForInputForCustom() {
|
||||||
|
@ -917,10 +917,7 @@ public:
|
||||||
void clearFromHistory(not_null<History*> history);
|
void clearFromHistory(not_null<History*> history);
|
||||||
void clearFromSession(not_null<Main::Session*> session);
|
void clearFromSession(not_null<Main::Session*> session);
|
||||||
void clearNotification(NotificationId id);
|
void clearNotification(NotificationId id);
|
||||||
|
void invokeIfNotInhibited(Fn<void()> callback);
|
||||||
[[nodiscard]] bool inhibited() const {
|
|
||||||
return _inhibited;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Private();
|
~Private();
|
||||||
|
|
||||||
|
@ -1154,6 +1151,12 @@ void Manager::Private::clearNotification(NotificationId id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::Private::invokeIfNotInhibited(Fn<void()> callback) {
|
||||||
|
if (!_inhibited) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Manager::Private::~Private() {
|
Manager::Private::~Private() {
|
||||||
clearAll();
|
clearAll();
|
||||||
|
|
||||||
|
@ -1215,16 +1218,16 @@ void Manager::doClearFromSession(not_null<Main::Session*> session) {
|
||||||
_private->clearFromSession(session);
|
_private->clearFromSession(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::doSkipAudio() const {
|
|
||||||
return _private->inhibited();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::doSkipToast() const {
|
bool Manager::doSkipToast() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::doSkipFlashBounce() const {
|
void Manager::doMaybePlaySound(Fn<void()> playSound) {
|
||||||
return _private->inhibited();
|
_private->invokeIfNotInhibited(std::move(playSound));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::doMaybeFlashBounce(Fn<void()> flashBounce) {
|
||||||
|
_private->invokeIfNotInhibited(std::move(flashBounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Notifications
|
} // namespace Notifications
|
||||||
|
|
|
@ -33,9 +33,9 @@ protected:
|
||||||
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
void doClearFromTopic(not_null<Data::ForumTopic*> topic) 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 doSkipToast() const override;
|
||||||
bool doSkipFlashBounce() const override;
|
void doMaybePlaySound(Fn<void()> playSound) override;
|
||||||
|
void doMaybeFlashBounce(Fn<void()> flashBounce) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
|
|
@ -13,16 +13,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
|
|
||||||
bool SkipAudioForCustom() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkipToastForCustom() {
|
bool SkipToastForCustom() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipFlashBounceForCustom() {
|
void MaybePlaySoundForCustom(Fn<void()> playSound) {
|
||||||
return false;
|
playSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaybeFlashBounceForCustom(Fn<void()> flashBounce) {
|
||||||
|
flashBounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitForInputForCustom() {
|
bool WaitForInputForCustom() {
|
||||||
|
|
|
@ -34,9 +34,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 doSkipToast() const override;
|
||||||
bool doSkipFlashBounce() const override;
|
void doMaybePlaySound(Fn<void()> playSound) override;
|
||||||
|
void doMaybeFlashBounce(Fn<void()> flashBounce) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
|
|
@ -27,17 +27,34 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static constexpr auto kQuerySettingsEachMs = 1000;
|
constexpr auto kQuerySettingsEachMs = crl::time(1000);
|
||||||
auto DoNotDisturbEnabled = false;
|
|
||||||
auto LastSettingsQueryMs = 0;
|
crl::time LastSettingsQueryMs/* = 0*/;
|
||||||
|
bool DoNotDisturbEnabled/* = false*/;
|
||||||
|
|
||||||
|
[[nodiscard]] bool ShouldQuerySettings() {
|
||||||
|
const auto now = crl::now();
|
||||||
|
if (LastSettingsQueryMs > 0 && now <= LastSettingsQueryMs + kQuerySettingsEachMs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LastSettingsQueryMs = now;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QString LibraryPath() {
|
||||||
|
static const auto result = [] {
|
||||||
|
NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
|
||||||
|
return url
|
||||||
|
? QString::fromUtf8([[url path] fileSystemRepresentation])
|
||||||
|
: QString();
|
||||||
|
}();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void queryDoNotDisturbState() {
|
void queryDoNotDisturbState() {
|
||||||
auto ms = crl::now();
|
if (!ShouldQuerySettings()) {
|
||||||
if (LastSettingsQueryMs > 0 && ms <= LastSettingsQueryMs + kQuerySettingsEachMs) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LastSettingsQueryMs = ms;
|
|
||||||
|
|
||||||
Boolean isKeyValid;
|
Boolean isKeyValid;
|
||||||
const auto doNotDisturb = CFPreferencesGetAppBooleanValue(
|
const auto doNotDisturb = CFPreferencesGetAppBooleanValue(
|
||||||
CFSTR("doNotDisturb"),
|
CFSTR("doNotDisturb"),
|
||||||
|
@ -151,16 +168,16 @@ using Manager = Platform::Notifications::Manager;
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
|
|
||||||
bool SkipAudioForCustom() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkipToastForCustom() {
|
bool SkipToastForCustom() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipFlashBounceForCustom() {
|
void MaybePlaySoundForCustom(Fn<void()> playSound) {
|
||||||
return false;
|
playSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaybeFlashBounceForCustom(Fn<void()> flashBounce) {
|
||||||
|
flashBounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitForInputForCustom() {
|
bool WaitForInputForCustom() {
|
||||||
|
@ -207,6 +224,8 @@ public:
|
||||||
void clearFromSession(not_null<Main::Session*> session);
|
void clearFromSession(not_null<Main::Session*> session);
|
||||||
void updateDelegate();
|
void updateDelegate();
|
||||||
|
|
||||||
|
void invokeIfNotFocused(Fn<void()> callback);
|
||||||
|
|
||||||
~Private();
|
~Private();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -214,6 +233,7 @@ private:
|
||||||
void putClearTask(Task task);
|
void putClearTask(Task task);
|
||||||
|
|
||||||
void clearingThreadLoop();
|
void clearingThreadLoop();
|
||||||
|
void checkFocusState();
|
||||||
|
|
||||||
const uint64 _managerId = 0;
|
const uint64 _managerId = 0;
|
||||||
QString _managerIdString;
|
QString _managerIdString;
|
||||||
|
@ -249,6 +269,14 @@ private:
|
||||||
ClearFinish>;
|
ClearFinish>;
|
||||||
std::vector<ClearTask> _clearingTasks;
|
std::vector<ClearTask> _clearingTasks;
|
||||||
|
|
||||||
|
QProcess _dnd;
|
||||||
|
QProcess _focus;
|
||||||
|
std::vector<Fn<void()>> _focusedCallbacks;
|
||||||
|
bool _waitingDnd = false;
|
||||||
|
bool _waitingFocus = false;
|
||||||
|
bool _focused = false;
|
||||||
|
bool _processesInited = false;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -457,6 +485,70 @@ void Manager::Private::updateDelegate() {
|
||||||
[center setDelegate:_delegate];
|
[center setDelegate:_delegate];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::Private::invokeIfNotFocused(Fn<void()> callback) {
|
||||||
|
if (!Platform::IsMac11_0OrGreater()) {
|
||||||
|
queryDoNotDisturbState();
|
||||||
|
if (!DoNotDisturbEnabled) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
} else if (Platform::IsMacStoreBuild() || LibraryPath().isEmpty()) {
|
||||||
|
callback();
|
||||||
|
} else if (!_focusedCallbacks.empty()) {
|
||||||
|
_focusedCallbacks.push_back(std::move(callback));
|
||||||
|
} else if (!ShouldQuerySettings()) {
|
||||||
|
if (!_focused) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!_processesInited) {
|
||||||
|
_processesInited = true;
|
||||||
|
QObject::connect(&_dnd, &QProcess::finished, [=] {
|
||||||
|
_waitingDnd = false;
|
||||||
|
checkFocusState();
|
||||||
|
});
|
||||||
|
QObject::connect(&_focus, &QProcess::finished, [=] {
|
||||||
|
_waitingFocus = false;
|
||||||
|
checkFocusState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const auto start = [](QProcess &process, QString keys) {
|
||||||
|
auto arguments = QStringList()
|
||||||
|
<< "-extract"
|
||||||
|
<< keys
|
||||||
|
<< "raw"
|
||||||
|
<< "-o"
|
||||||
|
<< "-"
|
||||||
|
<< "--"
|
||||||
|
<< (LibraryPath() + "/Preferences/com.apple.controlcenter.plist");
|
||||||
|
DEBUG_LOG(("Focus Check: Started %1.").arg(u"plutil"_q + arguments.join(' ')));
|
||||||
|
process.start(u"plutil"_q, arguments);
|
||||||
|
};
|
||||||
|
_focusedCallbacks.push_back(std::move(callback));
|
||||||
|
_waitingFocus = _waitingDnd = true;
|
||||||
|
start(_focus, u"NSStatusItem Visible FocusModes"_q);
|
||||||
|
start(_dnd, u"NSStatusItem Visible DoNotDisturb"_q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::Private::checkFocusState() {
|
||||||
|
if (_waitingFocus || _waitingDnd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto istrue = [](QProcess &process) {
|
||||||
|
const auto output = process.readAllStandardOutput();
|
||||||
|
DEBUG_LOG(("Focus Check: %1").arg(output));
|
||||||
|
const auto result = (output.trimmed() == u"true"_q);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
_focused = istrue(_focus) || istrue(_dnd);
|
||||||
|
auto callbacks = base::take(_focusedCallbacks);
|
||||||
|
if (!_focused) {
|
||||||
|
for (const auto &callback : callbacks) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Manager::Private::~Private() {
|
Manager::Private::~Private() {
|
||||||
if (_clearingThread.joinable()) {
|
if (_clearingThread.joinable()) {
|
||||||
putClearTask(ClearFinish());
|
putClearTask(ClearFinish());
|
||||||
|
@ -517,17 +609,16 @@ 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 {
|
bool Manager::doSkipToast() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::doSkipFlashBounce() const {
|
void Manager::doMaybePlaySound(Fn<void()> playSound) {
|
||||||
return doSkipAudio();
|
_private->invokeIfNotFocused(std::move(playSound));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::doMaybeFlashBounce(Fn<void()> flashBounce) {
|
||||||
|
_private->invokeIfNotFocused(std::move(flashBounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Notifications
|
} // namespace Notifications
|
||||||
|
|
|
@ -12,9 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
|
|
||||||
[[nodiscard]] bool SkipAudioForCustom();
|
|
||||||
[[nodiscard]] bool SkipToastForCustom();
|
[[nodiscard]] bool SkipToastForCustom();
|
||||||
[[nodiscard]] bool SkipFlashBounceForCustom();
|
void MaybePlaySoundForCustom(Fn<void()> playSound);
|
||||||
|
void MaybeFlashBounceForCustom(Fn<void()> flashBounce);
|
||||||
[[nodiscard]] bool WaitForInputForCustom();
|
[[nodiscard]] bool WaitForInputForCustom();
|
||||||
|
|
||||||
[[nodiscard]] bool Supported();
|
[[nodiscard]] bool Supported();
|
||||||
|
|
|
@ -53,6 +53,19 @@ namespace Notifications {
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kQuerySettingsEachMs = 1000;
|
||||||
|
|
||||||
|
crl::time LastSettingsQueryMs/* = 0*/;
|
||||||
|
|
||||||
|
[[nodiscard]] bool ShouldQuerySettings() {
|
||||||
|
const auto now = crl::now();
|
||||||
|
if (LastSettingsQueryMs > 0 && now <= LastSettingsQueryMs + kQuerySettingsEachMs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LastSettingsQueryMs = now;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::wstring NotificationTemplate(
|
[[nodiscard]] std::wstring NotificationTemplate(
|
||||||
QString id,
|
QString id,
|
||||||
Window::Notifications::Manager::DisplayOptions options) {
|
Window::Notifications::Manager::DisplayOptions options) {
|
||||||
|
@ -333,24 +346,16 @@ void QueryUserNotificationState() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto kQuerySettingsEachMs = 1000;
|
|
||||||
crl::time LastSettingsQueryMs = 0;
|
|
||||||
|
|
||||||
void QuerySystemNotificationSettings() {
|
void QuerySystemNotificationSettings() {
|
||||||
auto ms = crl::now();
|
if (!ShouldQuerySettings()) {
|
||||||
if (LastSettingsQueryMs > 0 && ms <= LastSettingsQueryMs + kQuerySettingsEachMs) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LastSettingsQueryMs = ms;
|
|
||||||
QueryQuietHours();
|
QueryQuietHours();
|
||||||
QueryFocusAssist();
|
QueryFocusAssist();
|
||||||
QueryUserNotificationState();
|
QueryUserNotificationState();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
bool SkipSoundForCustom() {
|
||||||
#endif // !__MINGW32__
|
|
||||||
|
|
||||||
bool SkipAudioForCustom() {
|
|
||||||
QuerySystemNotificationSettings();
|
QuerySystemNotificationSettings();
|
||||||
|
|
||||||
return (UserNotificationState == QUNS_NOT_PRESENT)
|
return (UserNotificationState == QUNS_NOT_PRESENT)
|
||||||
|
@ -358,6 +363,19 @@ bool SkipAudioForCustom() {
|
||||||
|| Core::App().screenIsLocked();
|
|| Core::App().screenIsLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SkipFlashBounceForCustom() {
|
||||||
|
return SkipToastForCustom();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
#endif // !__MINGW32__
|
||||||
|
|
||||||
|
void MaybePlaySoundForCustom(Fn<void()> playSound) {
|
||||||
|
if (!SkipSoundForCustom()) {
|
||||||
|
playSound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SkipToastForCustom() {
|
bool SkipToastForCustom() {
|
||||||
QuerySystemNotificationSettings();
|
QuerySystemNotificationSettings();
|
||||||
|
|
||||||
|
@ -365,8 +383,10 @@ bool SkipToastForCustom() {
|
||||||
|| (UserNotificationState == QUNS_RUNNING_D3D_FULL_SCREEN);
|
|| (UserNotificationState == QUNS_RUNNING_D3D_FULL_SCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipFlashBounceForCustom() {
|
void MaybeFlashBounceForCustom(Fn<void()> flashBounce) {
|
||||||
return SkipToastForCustom();
|
if (!SkipFlashBounceForCustom()) {
|
||||||
|
flashBounce();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitForInputForCustom() {
|
bool WaitForInputForCustom() {
|
||||||
|
@ -942,20 +962,26 @@ void Manager::onAfterNotificationActivated(
|
||||||
_private->afterNotificationActivated(id, window);
|
_private->afterNotificationActivated(id, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::doSkipAudio() const {
|
|
||||||
return SkipAudioForCustom()
|
|
||||||
|| QuietHoursEnabled
|
|
||||||
|| FocusAssistBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::doSkipToast() const {
|
bool Manager::doSkipToast() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::doSkipFlashBounce() const {
|
void Manager::doMaybePlaySound(Fn<void()> playSound) {
|
||||||
return SkipFlashBounceForCustom()
|
const auto skip = SkipSoundForCustom()
|
||||||
|| QuietHoursEnabled
|
|| QuietHoursEnabled
|
||||||
|| FocusAssistBlocks;
|
|| FocusAssistBlocks;
|
||||||
|
if (!skip) {
|
||||||
|
playSound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::doMaybeFlashBounce(Fn<void()> flashBounce) {
|
||||||
|
const auto skip = SkipFlashBounceForCustom()
|
||||||
|
|| QuietHoursEnabled
|
||||||
|
|| FocusAssistBlocks;
|
||||||
|
if (!skip) {
|
||||||
|
flashBounce();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // !__MINGW32__
|
#endif // !__MINGW32__
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,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 doSkipToast() const override;
|
||||||
bool doSkipFlashBounce() const override;
|
void doMaybePlaySound(Fn<void()> playSound) override;
|
||||||
|
void doMaybeFlashBounce(Fn<void()> flashBounce) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
|
|
@ -574,22 +574,28 @@ void System::showNext() {
|
||||||
}
|
}
|
||||||
const auto &settings = Core::App().settings();
|
const auto &settings = Core::App().settings();
|
||||||
if (alertThread) {
|
if (alertThread) {
|
||||||
if (settings.flashBounceNotify() && !_manager->skipFlashBounce()) {
|
if (settings.flashBounceNotify()) {
|
||||||
const auto peer = alertThread->peer();
|
const auto peer = alertThread->peer();
|
||||||
if (const auto window = Core::App().windowFor(peer)) {
|
if (const auto window = Core::App().windowFor(peer)) {
|
||||||
if (const auto handle = window->widget()->windowHandle()) {
|
if (const auto controller = window->sessionController()) {
|
||||||
handle->alert(kSystemAlertDuration);
|
_manager->maybeFlashBounce(crl::guard(controller, [=] {
|
||||||
// (handle, SLOT(_q_clearAlert())); in the future.
|
if (const auto handle = window->widget()->windowHandle()) {
|
||||||
|
handle->alert(kSystemAlertDuration);
|
||||||
|
// (handle, SLOT(_q_clearAlert())); in the future.
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (settings.soundNotify() && !_manager->skipAudio()) {
|
if (settings.soundNotify()) {
|
||||||
const auto track = lookupSound(
|
const auto owner = &alertThread->owner();
|
||||||
&alertThread->owner(),
|
const auto id = owner->notifySettings().sound(alertThread).id;
|
||||||
alertThread->owner().notifySettings().sound(alertThread).id);
|
_manager->maybePlaySound(crl::guard(&owner->session(), [=] {
|
||||||
track->playOnce();
|
const auto track = lookupSound(owner, id);
|
||||||
Media::Player::mixer()->suppressAll(track->getLengthMs());
|
track->playOnce();
|
||||||
Media::Player::mixer()->scheduleFaderCallback();
|
Media::Player::mixer()->suppressAll(track->getLengthMs());
|
||||||
|
Media::Player::mixer()->scheduleFaderCallback();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,14 +337,14 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] virtual ManagerType type() const = 0;
|
[[nodiscard]] virtual ManagerType type() const = 0;
|
||||||
|
|
||||||
[[nodiscard]] bool skipAudio() const {
|
|
||||||
return doSkipAudio();
|
|
||||||
}
|
|
||||||
[[nodiscard]] bool skipToast() const {
|
[[nodiscard]] bool skipToast() const {
|
||||||
return doSkipToast();
|
return doSkipToast();
|
||||||
}
|
}
|
||||||
[[nodiscard]] bool skipFlashBounce() const {
|
void maybePlaySound(Fn<void()> playSound) {
|
||||||
return doSkipFlashBounce();
|
doMaybePlaySound(std::move(playSound));
|
||||||
|
}
|
||||||
|
void maybeFlashBounce(Fn<void()> flashBounce) {
|
||||||
|
doMaybeFlashBounce(std::move(flashBounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Manager() = default;
|
virtual ~Manager() = default;
|
||||||
|
@ -362,9 +362,9 @@ protected:
|
||||||
virtual void doClearFromTopic(not_null<Data::ForumTopic*> topic) = 0;
|
virtual void doClearFromTopic(not_null<Data::ForumTopic*> topic) = 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;
|
[[nodiscard]] virtual bool doSkipToast() const = 0;
|
||||||
virtual bool doSkipToast() const = 0;
|
virtual void doMaybePlaySound(Fn<void()> playSound) = 0;
|
||||||
virtual bool doSkipFlashBounce() const = 0;
|
virtual void doMaybeFlashBounce(Fn<void()> flashBounce) = 0;
|
||||||
[[nodiscard]] virtual bool forceHideDetails() const {
|
[[nodiscard]] virtual bool forceHideDetails() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -445,14 +445,14 @@ protected:
|
||||||
}
|
}
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override {
|
void doClearFromSession(not_null<Main::Session*> session) override {
|
||||||
}
|
}
|
||||||
bool doSkipAudio() const override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool doSkipToast() const override {
|
bool doSkipToast() const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool doSkipFlashBounce() const override {
|
void doMaybePlaySound(Fn<void()> playSound) override {
|
||||||
return false;
|
playSound();
|
||||||
|
}
|
||||||
|
void doMaybeFlashBounce(Fn<void()> flashBounce) override {
|
||||||
|
flashBounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -445,16 +445,16 @@ void Manager::doClearFromItem(not_null<HistoryItem*> item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::doSkipAudio() const {
|
|
||||||
return Platform::Notifications::SkipAudioForCustom();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::doSkipToast() const {
|
bool Manager::doSkipToast() const {
|
||||||
return Platform::Notifications::SkipToastForCustom();
|
return Platform::Notifications::SkipToastForCustom();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::doSkipFlashBounce() const {
|
void Manager::doMaybePlaySound(Fn<void()> playSound) {
|
||||||
return Platform::Notifications::SkipFlashBounceForCustom();
|
Platform::Notifications::MaybePlaySoundForCustom(std::move(playSound));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::doMaybeFlashBounce(Fn<void()> flashBounce) {
|
||||||
|
Platform::Notifications::MaybeFlashBounceForCustom(std::move(flashBounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::doUpdateAll() {
|
void Manager::doUpdateAll() {
|
||||||
|
|
|
@ -73,9 +73,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 override;
|
|
||||||
bool doSkipToast() const override;
|
bool doSkipToast() const override;
|
||||||
bool doSkipFlashBounce() const override;
|
void doMaybePlaySound(Fn<void()> playSound) override;
|
||||||
|
void doMaybeFlashBounce(Fn<void()> flashBounce) override;
|
||||||
|
|
||||||
void showNextFromQueue();
|
void showNextFromQueue();
|
||||||
void unlinkFromShown(Notification *remove);
|
void unlinkFromShown(Notification *remove);
|
||||||
|
|
Loading…
Add table
Reference in a new issue