diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 4ecea9c6ef..9963d241ac 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1448,6 +1448,13 @@ PRIVATE numbers.txt ) +if (APPLE AND NOT build_macstore) + nice_target_sources(Telegram ${res_loc} + PRIVATE + qrc/telegram/mac_icons.qrc + ) +endif() + if (WIN32) # message(${CMAKE_GENERATOR}) # mt.exe -manifest "${res_loc}/winrc/Telegram.manifest" "-inputresource:\"$\";#1" "-outputresource:\"$\";#1" >NUL diff --git a/Telegram/Resources/art/icon_round512@2x.png b/Telegram/Resources/art/icon_round512@2x.png new file mode 100644 index 0000000000..8f7b1098bd Binary files /dev/null and b/Telegram/Resources/art/icon_round512@2x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 81d54f23d6..26977a32de 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -497,6 +497,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_open_system_settings" = "Open Settings"; "lng_settings_add_sendto" = "Place Telegram in \"Send to\" menu"; "lng_settings_mac_warn_before_quit" = "Show warning before quitting with {text}"; +"lng_settings_mac_round_icon" = "Round application icon"; "lng_settings_experimental" = "Experimental settings"; "lng_settings_experimental_about" = "Warning! Those are experimental settings. Some may not work. Others may break the app. Any of them may disappear in the next version without a trace. Use at your own risk."; diff --git a/Telegram/Resources/qrc/telegram/mac_icons.qrc b/Telegram/Resources/qrc/telegram/mac_icons.qrc new file mode 100644 index 0000000000..977b0c8ed4 --- /dev/null +++ b/Telegram/Resources/qrc/telegram/mac_icons.qrc @@ -0,0 +1,5 @@ + + + ../../art/icon_round512@2x.png + + diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index b6f6b3cc39..d3699c01aa 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -1653,16 +1653,27 @@ void Application::quitDelayed() { } } +void Application::refreshApplicationIcon() { + const auto session = (domain().started() && domain().active().sessionExists()) + ? &domain().active().session() + : nullptr; + refreshApplicationIcon(session); +} + +void Application::refreshApplicationIcon(Main::Session *session) { + const auto support = session && session->supportMode(); + Shortcuts::ToggleSupportShortcuts(support); + Platform::SetApplicationIcon(Window::CreateIcon( + session, + Platform::IsMac())); +} + void Application::startShortcuts() { Shortcuts::Start(); _domain->activeSessionChanges( ) | rpl::start_with_next([=](Main::Session *session) { - const auto support = session && session->supportMode(); - Shortcuts::ToggleSupportShortcuts(support); - Platform::SetApplicationIcon(Window::CreateIcon( - session, - Platform::IsMac())); + refreshApplicationIcon(session); }, _lifetime); Shortcuts::Requests( diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index 963275e74f..ef7671150f 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -304,6 +304,7 @@ public: // Sandbox interface. void postponeCall(FnMut &&callable); void refreshGlobalProxy(); + void refreshApplicationIcon(); void quitPreventFinished(); @@ -349,6 +350,7 @@ private: void enumerateWindows( Fn)> callback) const; void processCreatedWindow(not_null window); + void refreshApplicationIcon(Main::Session *session); friend void QuitAttempt(); void quitDelayed(); diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index 4421029685..78e2851b33 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -198,7 +198,8 @@ QByteArray Settings::serialize() const { + sizeof(quint64) + sizeof(qint32) * 3 + Serialize::bytearraySize(mediaViewPosition) - + sizeof(qint32); + + sizeof(qint32) + + sizeof(quint64); auto result = QByteArray(); result.reserve(size); @@ -331,7 +332,8 @@ QByteArray Settings::serialize() const { << qint32(_windowTitleContent.current().hideAccountName ? 1 : 0) << qint32(_windowTitleContent.current().hideTotalUnread ? 1 : 0) << mediaViewPosition - << qint32(_ignoreBatterySaving.current() ? 1 : 0); + << qint32(_ignoreBatterySaving.current() ? 1 : 0) + << quint64(_macRoundIconDigest.value_or(0)); } return result; } @@ -436,6 +438,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { qint32 hideTotalUnread = _windowTitleContent.current().hideTotalUnread ? 1 : 0; QByteArray mediaViewPosition; qint32 ignoreBatterySaving = _ignoreBatterySaving.current() ? 1 : 0; + quint64 macRoundIconDigest = _macRoundIconDigest.value_or(0); stream >> themesAccentColors; if (!stream.atEnd()) { @@ -667,6 +670,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) { if (!stream.atEnd()) { stream >> ignoreBatterySaving; } + if (!stream.atEnd()) { + stream >> macRoundIconDigest; + } if (stream.status() != QDataStream::Ok) { LOG(("App Error: " "Bad data for Core::Settings::constructFromSerialized()")); @@ -864,6 +870,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { } } _ignoreBatterySaving = (ignoreBatterySaving == 1); + _macRoundIconDigest = macRoundIconDigest ? macRoundIconDigest : std::optional(); } QString Settings::getSoundPath(const QString &key) const { diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index eb3df53fde..5b5af6a39d 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -786,6 +786,12 @@ public: void setIgnoreBatterySavingValue(bool value) { _ignoreBatterySaving = value; } + void setMacRoundIconDigest(std::optional value) { + _macRoundIconDigest = value; + } + [[nodiscard]] std::optional macRoundIconDigest() const { + return _macRoundIconDigest; + } [[nodiscard]] static bool ThirdColumnByDefault(); [[nodiscard]] static float64 DefaultDialogsWidthRatio(); @@ -910,6 +916,7 @@ private: bool _rememberedDeleteMessageOnlyForYou = false; WindowPosition _mediaViewPosition = { .maximized = 2 }; rpl::variable _ignoreBatterySaving = false; + std::optional _macRoundIconDigest; bool _tabbedReplacedWithInfo = false; // per-window rpl::event_stream _tabbedReplacedWithInfoValue; // per-window diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index 6eda219960..7e33d5c944 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -852,6 +852,10 @@ void NewVersionLaunched(int oldVersion) { } } +QImage DefaultApplicationIcon() { + return Window::Logo(); +} + namespace ThirdParty { void start() { diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.mm b/Telegram/SourceFiles/platform/mac/specific_mac.mm index aeb6706b81..0602158101 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac.mm +++ b/Telegram/SourceFiles/platform/mac/specific_mac.mm @@ -36,6 +36,51 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include +namespace { + +[[nodiscard]] QImage ImageFromNS(NSImage *icon) { + CGImageRef image = [icon CGImageForProposedRect:NULL context:nil hints:nil]; + + const int width = CGImageGetWidth(image); + const int height = CGImageGetHeight(image); + auto result = QImage(width, height, QImage::Format_ARGB32_Premultiplied); + result.fill(Qt::transparent); + + CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + CGBitmapInfo info = CGBitmapInfo(kCGImageAlphaPremultipliedFirst) | kCGBitmapByteOrder32Host; + CGContextRef context = CGBitmapContextCreate( + result.bits(), + width, + height, + 8, + result.bytesPerLine(), + space, + info); + + CGRect rect = CGRectMake(0, 0, width, height); + CGContextDrawImage(context, rect, image); + + CFRelease(space); + CFRelease(context); + + return result; +} + +[[nodiscard]] QImage ResolveBundleIconDefault() { + NSString *path = [[NSBundle mainBundle] bundlePath]; + NSString *icon = [path stringByAppendingString:@"/Contents/Resources/Icon.icns"]; + NSImage *image = [[NSImage alloc] initWithContentsOfFile:icon]; + if (!image) { + return Window::Logo(); + } + + auto result = ImageFromNS(image); + [image release]; + return result; +} + +} // namespace + QString psAppDataPath() { return objc_appDataPath(); } @@ -188,6 +233,11 @@ bool AutostartSkip() { void NewVersionLaunched(int oldVersion) { } +QImage DefaultApplicationIcon() { + static auto result = ResolveBundleIconDefault(); + return result; +} + bool PreventsQuit(Core::QuitReason reason) { // Thanks Chromium, see // chromium.org/developers/design-documents/confirm-to-quit-experiment diff --git a/Telegram/SourceFiles/platform/platform_specific.h b/Telegram/SourceFiles/platform/platform_specific.h index 7b35e7af35..794f4428b6 100644 --- a/Telegram/SourceFiles/platform/platform_specific.h +++ b/Telegram/SourceFiles/platform/platform_specific.h @@ -47,6 +47,8 @@ bool SkipTaskbarSupported(); void WriteCrashDumpDetails(); void NewVersionLaunched(int oldVersion); +[[nodiscard]] QImage DefaultApplicationIcon(); + [[nodiscard]] bool PreventsQuit(Core::QuitReason reason); [[nodiscard]] std::optional IsDarkMode(); diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp index 0892b67a0e..6dc19d35be 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.cpp +++ b/Telegram/SourceFiles/platform/win/specific_win.cpp @@ -651,6 +651,10 @@ void NewVersionLaunched(int oldVersion) { } } +QImage DefaultApplicationIcon() { + return Window::Logo(); +} + } // namespace Platform void psSendToMenu(bool send, bool silent) { diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp index 4c6ef22844..418c39bbd9 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced.cpp @@ -20,11 +20,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_utilities.h" // Ui::Text::ToUpper #include "ui/text/format_values.h" #include "ui/boxes/single_choice_box.h" +#include "ui/painter.h" #include "boxes/connection_box.h" #include "boxes/about_box.h" #include "ui/boxes/confirm_box.h" #include "platform/platform_specific.h" #include "ui/platform/ui_platform_window.h" +#include "base/platform/base_platform_custom_app_icon.h" #include "base/platform/base_platform_info.h" #include "window/window_controller.h" #include "window/window_session_controller.h" @@ -52,6 +54,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #endif // !TDESKTOP_DISABLE_SPELLCHECK namespace Settings { +namespace { + +[[nodiscard]] const QImage &IconMacRound() { + static const auto result = QImage(u":/gui/art/icon_round512@2x.png"_q); + return result; +} + +} // namespace void SetupConnectionType( not_null controller, @@ -528,6 +538,32 @@ void SetupSystemIntegrationContent( Core::App().settings().setMacWarnBeforeQuit(checked); Core::App().saveSettingsDelayed(); }, warnBeforeQuit->lifetime()); + +#ifndef OS_MAC_STORE + const auto enabled = [] { + const auto digest = base::Platform::CurrentCustomAppIconDigest(); + return digest && (Core::App().settings().macRoundIconDigest() == digest); + }; + const auto roundIcon = addCheckbox( + tr::lng_settings_mac_round_icon(), + enabled()); + roundIcon->checkedChanges( + ) | rpl::filter([=](bool checked) { + return (checked != enabled()); + }) | rpl::start_with_next([=](bool checked) { + const auto digest = checked + ? base::Platform::SetCustomAppIcon(IconMacRound()) + : std::optional(); + if (!checked) { + base::Platform::ClearCustomAppIcon(); + } + Window::OverrideApplicationIcon(checked ? IconMacRound() : QImage()); + Core::App().refreshApplicationIcon(); + Core::App().settings().setMacRoundIconDigest(digest); + Core::App().saveSettings(); + }, roundIcon->lifetime()); +#endif // OS_MAC_STORE + #else // Q_OS_MAC const auto closeToTaskbar = addSlidingCheckbox( tr::lng_settings_close_to_taskbar(), diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 3fa20cb60e..e3227363e6 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -64,6 +64,11 @@ using Core::WindowPosition; return { skipx, skipy }; } +[[nodiscard]] QImage &OverridenIcon() { + static auto result = QImage(); + return result; +} + } // namespace const QImage &Logo() { @@ -123,12 +128,19 @@ void ConvertIconToBlack(QImage &image) { } } +void OverrideApplicationIcon(QImage image) { + OverridenIcon() = std::move(image); +} + QIcon CreateOfficialIcon(Main::Session *session) { const auto support = (session && session->supportMode()); if (!support) { return QIcon(); } - auto image = Logo(); + auto overriden = OverridenIcon(); + auto image = overriden.isNull() + ? Platform::DefaultApplicationIcon() + : overriden; ConvertIconToBlack(image); return QIcon(Ui::PixmapFromImage(std::move(image))); } diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index d5f87d16eb..a6c1ac275d 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -37,6 +37,7 @@ struct TermsLock; [[nodiscard]] const QImage &Logo(); [[nodiscard]] const QImage &LogoNoMargin(); +void OverrideApplicationIcon(QImage image); [[nodiscard]] QIcon CreateIcon( Main::Session *session = nullptr, bool returnNullIfDefault = false); diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128.png index fc96863ef6..36d300faa2 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128@2x.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128@2x.png index 7943dd19df..cbb2420d32 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128@2x.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon128@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16.png index 561369d2b2..0ba4967982 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16@2x.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16@2x.png index f220a885bb..71066360e0 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16@2x.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon16@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256.png index 8c4abee16d..38f1c1f4f4 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256@2x.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256@2x.png index d096c2bd0a..10d4b1b360 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256@2x.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon256@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32.png index cff6368944..ca84cd0e7c 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32@2x.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32@2x.png index 22b468746a..53f70ab9cd 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32@2x.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon32@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512.png index cdf2fdab5d..7af9b445d0 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512.png differ diff --git a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512@2x.png b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512@2x.png index 7c1560fe63..708cfb8cc2 100644 Binary files a/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512@2x.png and b/Telegram/Telegram/Images.xcassets/AppIcon.appiconset/icon512@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128.png index fc96863ef6..36d300faa2 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128@2x.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128@2x.png index 7943dd19df..cbb2420d32 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128@2x.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_128x128@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16.png index 561369d2b2..0ba4967982 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16@2x.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16@2x.png index f220a885bb..71066360e0 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16@2x.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_16x16@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256.png index 8c4abee16d..38f1c1f4f4 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256@2x.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256@2x.png index d096c2bd0a..10d4b1b360 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256@2x.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_256x256@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32.png index cff6368944..ca84cd0e7c 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32@2x.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32@2x.png index 22b468746a..53f70ab9cd 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32@2x.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_32x32@2x.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512.png index cdf2fdab5d..7af9b445d0 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512.png differ diff --git a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512@2x.png b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512@2x.png index 7c1560fe63..708cfb8cc2 100644 Binary files a/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512@2x.png and b/Telegram/Telegram/Images.xcassets/Icon.iconset/icon_512x512@2x.png differ