Add a checkbox to disable taskbar flash.

Also add ability to set urgent flag for the window on Linux.

Fixes #223, fixes #897, fixes #906.
This commit is contained in:
John Preston 2020-05-12 14:04:53 +04:00
parent f4f6550d66
commit 6f760d513e
15 changed files with 86 additions and 48 deletions

View File

@ -300,6 +300,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_notifications_position" = "Location on the screen"; "lng_settings_notifications_position" = "Location on the screen";
"lng_settings_notifications_count" = "Notifications count"; "lng_settings_notifications_count" = "Notifications count";
"lng_settings_sound_notify" = "Play sound"; "lng_settings_sound_notify" = "Play sound";
"lng_settings_alert_windows" = "Flash the taskbar icon";
"lng_settings_alert_mac" = "Bounce the dock icon";
"lng_settings_alert_linux" = "Draw attention to the window";
"lng_settings_badge_title" = "Badge counter"; "lng_settings_badge_title" = "Badge counter";
"lng_settings_include_muted" = "Include muted chats in unread count"; "lng_settings_include_muted" = "Include muted chats in unread count";
"lng_settings_count_unread" = "Count unread messages"; "lng_settings_count_unread" = "Count unread messages";

View File

@ -381,7 +381,9 @@ struct Data {
bool VoiceMsgPlaybackDoubled = false; bool VoiceMsgPlaybackDoubled = false;
bool SoundNotify = true; bool SoundNotify = true;
bool DesktopNotify = true; bool DesktopNotify = true;
bool FlashBounceNotify = true;
bool RestoreSoundNotifyFromTray = false; bool RestoreSoundNotifyFromTray = false;
bool RestoreFlashBounceNotifyFromTray = false;
DBINotifyView NotifyView = dbinvShowPreview; DBINotifyView NotifyView = dbinvShowPreview;
bool NativeNotifications = false; bool NativeNotifications = false;
int NotificationsCount = 3; int NotificationsCount = 3;
@ -508,7 +510,9 @@ DefineRefVar(Global, base::Observable<void>, DownloadPathChanged);
DefineVar(Global, bool, VoiceMsgPlaybackDoubled); DefineVar(Global, bool, VoiceMsgPlaybackDoubled);
DefineVar(Global, bool, SoundNotify); DefineVar(Global, bool, SoundNotify);
DefineVar(Global, bool, DesktopNotify); DefineVar(Global, bool, DesktopNotify);
DefineVar(Global, bool, FlashBounceNotify);
DefineVar(Global, bool, RestoreSoundNotifyFromTray); DefineVar(Global, bool, RestoreSoundNotifyFromTray);
DefineVar(Global, bool, RestoreFlashBounceNotifyFromTray);
DefineVar(Global, DBINotifyView, NotifyView); DefineVar(Global, DBINotifyView, NotifyView);
DefineVar(Global, bool, NativeNotifications); DefineVar(Global, bool, NativeNotifications);
DefineVar(Global, int, NotificationsCount); DefineVar(Global, int, NotificationsCount);

View File

@ -210,7 +210,9 @@ DeclareRefVar(base::Observable<void>, DownloadPathChanged);
DeclareVar(bool, VoiceMsgPlaybackDoubled); DeclareVar(bool, VoiceMsgPlaybackDoubled);
DeclareVar(bool, SoundNotify); DeclareVar(bool, SoundNotify);
DeclareVar(bool, DesktopNotify); DeclareVar(bool, DesktopNotify);
DeclareVar(bool, FlashBounceNotify);
DeclareVar(bool, RestoreSoundNotifyFromTray); DeclareVar(bool, RestoreSoundNotifyFromTray);
DeclareVar(bool, RestoreFlashBounceNotifyFromTray);
DeclareVar(DBINotifyView, NotifyView); DeclareVar(DBINotifyView, NotifyView);
DeclareVar(bool, NativeNotifications); DeclareVar(bool, NativeNotifications);
DeclareVar(int, NotificationsCount); DeclareVar(int, NotificationsCount);

View File

@ -40,6 +40,7 @@ void PrepareSupportMode() {
Global::SetDesktopNotify(false); Global::SetDesktopNotify(false);
Global::SetSoundNotify(false); Global::SetSoundNotify(false);
Global::SetFlashBounceNotify(false);
Auth().settings().autoDownload() = Full::FullDisabled(); Auth().settings().autoDownload() = Full::FullDisabled();
Local::writeUserSettings(); Local::writeUserSettings();
} }

View File

@ -757,7 +757,8 @@ void MainWindow::toggleDisplayNotifyFromTray() {
return; return;
} }
bool soundNotifyChanged = false; auto soundNotifyChanged = false;
auto flashBounceNotifyChanged = false;
Global::SetDesktopNotify(!Global::DesktopNotify()); Global::SetDesktopNotify(!Global::DesktopNotify());
if (Global::DesktopNotify()) { if (Global::DesktopNotify()) {
if (Global::RestoreSoundNotifyFromTray() && !Global::SoundNotify()) { if (Global::RestoreSoundNotifyFromTray() && !Global::SoundNotify()) {
@ -765,6 +766,12 @@ void MainWindow::toggleDisplayNotifyFromTray() {
Global::SetRestoreSoundNotifyFromTray(false); Global::SetRestoreSoundNotifyFromTray(false);
soundNotifyChanged = true; soundNotifyChanged = true;
} }
if (Global::RestoreFlashBounceNotifyFromTray()
&& !Global::FlashBounceNotify()) {
Global::SetFlashBounceNotify(true);
Global::SetRestoreFlashBounceNotifyFromTray(false);
flashBounceNotifyChanged = true;
}
} else { } else {
if (Global::SoundNotify()) { if (Global::SoundNotify()) {
Global::SetSoundNotify(false); Global::SetSoundNotify(false);
@ -773,13 +780,23 @@ void MainWindow::toggleDisplayNotifyFromTray() {
} else { } else {
Global::SetRestoreSoundNotifyFromTray(false); Global::SetRestoreSoundNotifyFromTray(false);
} }
if (Global::FlashBounceNotify()) {
Global::SetFlashBounceNotify(false);
Global::SetRestoreFlashBounceNotifyFromTray(true);
flashBounceNotifyChanged = true;
} else {
Global::SetRestoreFlashBounceNotifyFromTray(false);
}
} }
Local::writeUserSettings(); Local::writeUserSettings();
account().session().notifications().settingsChanged().notify( using Change = Window::Notifications::ChangeType;
Window::Notifications::ChangeType::DesktopEnabled); auto &changes = account().session().notifications().settingsChanged();
changes.notify(Change::DesktopEnabled);
if (soundNotifyChanged) { if (soundNotifyChanged) {
account().session().notifications().settingsChanged().notify( changes.notify(Change::SoundEnabled);
Window::Notifications::ChangeType::SoundEnabled); }
if (flashBounceNotifyChanged) {
changes.notify(Change::FlashBounceEnabled);
} }
} }

View File

@ -457,15 +457,11 @@ bool SkipAudio() {
} }
bool SkipToast() { bool SkipToast() {
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION return SkipAudio();
if (Supported() }
&& GetCapabilities().contains(qsl("inhibitions"))
&& !InhibitedNotSupported) {
return Inhibited();
}
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
return false; bool SkipFlashBounce() {
return SkipAudio();
} }
bool Supported() { bool Supported() {

View File

@ -19,9 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform { namespace Platform {
namespace Notifications { namespace Notifications {
inline void FlashBounce() {
}
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION #ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
class NotificationData : public QObject { class NotificationData : public QObject {
Q_OBJECT Q_OBJECT

View File

@ -13,9 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform { namespace Platform {
namespace Notifications { namespace Notifications {
bool SkipAudio();
bool SkipToast();
class Manager : public Window::Notifications::NativeManager, public base::has_weak_ptr { class Manager : public Window::Notifications::NativeManager, public base::has_weak_ptr {
public: public:
Manager(Window::Notifications::System *system); Manager(Window::Notifications::System *system);

View File

@ -143,6 +143,10 @@ bool SkipToast() {
return DoNotDisturbEnabled; return DoNotDisturbEnabled;
} }
bool SkipFlashBounce() {
return SkipAudio();
}
bool Supported() { bool Supported() {
return Platform::IsMac10_8OrGreater(); return Platform::IsMac10_8OrGreater();
} }
@ -154,10 +158,6 @@ std::unique_ptr<Window::Notifications::Manager> Create(Window::Notifications::Sy
return nullptr; return nullptr;
} }
void FlashBounce() {
[NSApp requestUserAttention:NSInformationalRequest];
}
class Manager::Private : public QObject, private base::Subscriber { class Manager::Private : public QObject, private base::Subscriber {
public: public:
Private(Manager *manager); Private(Manager *manager);

View File

@ -12,12 +12,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform { namespace Platform {
namespace Notifications { namespace Notifications {
bool SkipAudio(); [[nodiscard]] bool SkipAudio();
bool SkipToast(); [[nodiscard]] bool SkipToast();
[[nodiscard]] bool SkipFlashBounce();
bool Supported(); [[nodiscard]] bool Supported();
std::unique_ptr<Window::Notifications::Manager> Create(Window::Notifications::System *system); [[nodiscard]] std::unique_ptr<Window::Notifications::Manager> Create(
void FlashBounce(); Window::Notifications::System *system);
} // namespace Notifications } // namespace Notifications
} // namespace Platform } // namespace Platform

View File

@ -321,21 +321,6 @@ std::unique_ptr<Window::Notifications::Manager> Create(Window::Notifications::Sy
return nullptr; return nullptr;
} }
void FlashBounce() {
auto window = App::wnd();
if (!window || GetForegroundWindow() == window->psHwnd()) {
return;
}
FLASHWINFO info;
info.cbSize = sizeof(info);
info.hwnd = window->psHwnd();
info.dwFlags = FLASHW_ALL;
info.dwTimeout = 0;
info.uCount = 1;
FlashWindowEx(&info);
}
class Manager::Private { class Manager::Private {
public: public:
using Type = Window::Notifications::CachedUserpics::Type; using Type = Window::Notifications::CachedUserpics::Type;
@ -723,5 +708,9 @@ bool SkipToast() {
return false; return false;
} }
bool SkipFlashBounce() {
return SkipToast();
}
} // namespace Notifications } // namespace Notifications
} // namespace Platform } // namespace Platform

View File

@ -568,6 +568,13 @@ void SetupNotificationsContent(
const auto sound = addCheckbox( const auto sound = addCheckbox(
tr::lng_settings_sound_notify(tr::now), tr::lng_settings_sound_notify(tr::now),
Global::SoundNotify()); Global::SoundNotify());
const auto flashbounce = addCheckbox(
(Platform::IsWindows()
? tr::lng_settings_alert_windows
: Platform::IsMac()
? tr::lng_settings_alert_mac
: tr::lng_settings_alert_linux)(tr::now),
Global::FlashBounceNotify());
AddSkip(container, st::settingsCheckboxesSkip); AddSkip(container, st::settingsCheckboxesSkip);
AddDivider(container); AddDivider(container);
@ -714,6 +721,14 @@ void SetupNotificationsContent(
changed(Change::SoundEnabled); changed(Change::SoundEnabled);
}, sound->lifetime()); }, sound->lifetime());
flashbounce->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != Global::FlashBounceNotify());
}) | rpl::start_with_next([=](bool checked) {
Global::SetFlashBounceNotify(checked);
changed(Change::FlashBounceEnabled);
}, flashbounce->lifetime());
muted->checkedChanges( muted->checkedChanges(
) | rpl::filter([=](bool checked) { ) | rpl::filter([=](bool checked) {
return (checked != session->settings().includeMutedCounter()); return (checked != session->settings().includeMutedCounter());
@ -743,6 +758,8 @@ void SetupNotificationsContent(
preview->toggle(name->entity()->checked(), anim::type::normal); preview->toggle(name->entity()->checked(), anim::type::normal);
} else if (change == Change::SoundEnabled) { } else if (change == Change::SoundEnabled) {
sound->setChecked(Global::SoundNotify()); sound->setChecked(Global::SoundNotify());
} else if (change == Change::FlashBounceEnabled) {
flashbounce->setChecked(Global::FlashBounceNotify());
} }
}, desktop->lifetime()); }, desktop->lifetime());

View File

@ -649,7 +649,7 @@ enum {
dbiSendKeyOld = 0x05, dbiSendKeyOld = 0x05,
dbiAutoStart = 0x06, dbiAutoStart = 0x06,
dbiStartMinimized = 0x07, dbiStartMinimized = 0x07,
dbiSoundNotify = 0x08, dbiSoundFlashBounceNotify = 0x08,
dbiWorkMode = 0x09, dbiWorkMode = 0x09,
dbiSeenTrayTooltip = 0x0a, dbiSeenTrayTooltip = 0x0a,
dbiDesktopNotify = 0x0b, dbiDesktopNotify = 0x0b,
@ -1189,12 +1189,13 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
anim::SetDisabled(disabled == 1); anim::SetDisabled(disabled == 1);
} break; } break;
case dbiSoundNotify: { case dbiSoundFlashBounceNotify: {
qint32 v; qint32 v;
stream >> v; stream >> v;
if (!_checkStreamStatus(stream)) return false; if (!_checkStreamStatus(stream)) return false;
Global::SetSoundNotify(v == 1); Global::SetSoundNotify((v & 0x01) == 0x01);
Global::SetFlashBounceNotify((v & 0x02) == 0x00);
} break; } break;
case dbiAutoDownloadOld: { case dbiAutoDownloadOld: {
@ -2202,6 +2203,9 @@ void _writeUserSettings() {
} }
size += sizeof(quint32) + Serialize::bytearraySize(callSettings); size += sizeof(quint32) + Serialize::bytearraySize(callSettings);
const auto soundFlashBounce = (Global::SoundNotify() ? 0x01 : 0x00)
| (Global::FlashBounceNotify() ? 0x00 : 0x02);
EncryptedDescriptor data(size); EncryptedDescriptor data(size);
data.stream data.stream
<< quint32(dbiTileBackground) << quint32(dbiTileBackground)
@ -2209,7 +2213,7 @@ void _writeUserSettings() {
<< qint32(Window::Theme::Background()->tileNight() ? 1 : 0); << qint32(Window::Theme::Background()->tileNight() ? 1 : 0);
data.stream << quint32(dbiAdaptiveForWide) << qint32(Global::AdaptiveForWide() ? 1 : 0); data.stream << quint32(dbiAdaptiveForWide) << qint32(Global::AdaptiveForWide() ? 1 : 0);
data.stream << quint32(dbiAutoLock) << qint32(Global::AutoLock()); data.stream << quint32(dbiAutoLock) << qint32(Global::AutoLock());
data.stream << quint32(dbiSoundNotify) << qint32(Global::SoundNotify()); data.stream << quint32(dbiSoundFlashBounceNotify) << qint32(soundFlashBounce);
data.stream << quint32(dbiDesktopNotify) << qint32(Global::DesktopNotify()); data.stream << quint32(dbiDesktopNotify) << qint32(Global::DesktopNotify());
data.stream << quint32(dbiNotifyView) << qint32(Global::NotifyView()); data.stream << quint32(dbiNotifyView) << qint32(Global::NotifyView());
data.stream << quint32(dbiNativeNotifications) << qint32(Global::NativeNotifications()); data.stream << quint32(dbiNativeNotifications) << qint32(Global::NativeNotifications());

View File

@ -27,6 +27,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "facades.h" #include "facades.h"
#include "app.h" #include "app.h"
#include <QtGui/QWindow>
namespace Window { namespace Window {
namespace Notifications { namespace Notifications {
namespace { namespace {
@ -290,7 +292,14 @@ void System::showNext() {
} }
} }
if (alert) { if (alert) {
Platform::Notifications::FlashBounce(); if (Global::FlashBounceNotify() && !Platform::Notifications::SkipFlashBounce()) {
if (const auto widget = App::wnd()) {
if (const auto window = widget->windowHandle()) {
window->alert(0);
// (window, SLOT(_q_clearAlert())); in the future.
}
}
}
if (Global::SoundNotify() && !Platform::Notifications::SkipAudio()) { if (Global::SoundNotify() && !Platform::Notifications::SkipAudio()) {
ensureSoundCreated(); ensureSoundCreated();
_soundTrack->playOnce(); _soundTrack->playOnce();

View File

@ -32,6 +32,7 @@ namespace Notifications {
enum class ChangeType { enum class ChangeType {
SoundEnabled, SoundEnabled,
FlashBounceEnabled,
IncludeMuted, IncludeMuted,
CountMessages, CountMessages,
DesktopEnabled, DesktopEnabled,