diff --git a/Telegram/Resources/colors.palette b/Telegram/Resources/colors.palette index 41f036e6bd..668888f2e8 100644 --- a/Telegram/Resources/colors.palette +++ b/Telegram/Resources/colors.palette @@ -49,7 +49,7 @@ lightButtonFgOver: lightButtonFg; menuIconFg: #a8a8a8; menuIconFgOver: #999999; -// custom title bar for Windows +// custom title bar for Windows and macOS titleBg: windowOverBg; titleShadow: #00000003; titleButtonFg: #ababab; @@ -57,6 +57,8 @@ titleButtonBgOver: #e5e5e5; titleButtonFgOver: #9a9a9a; titleButtonCloseBgOver: #e81123; titleButtonCloseFgOver: #ffffff; +titleFgActive: #3e3c3e; +titleFg: #acacac; // tray icon trayCounterBg: #f23c34; diff --git a/Telegram/Resources/sample.tdesktop-theme b/Telegram/Resources/sample.tdesktop-theme index 7db210cc7d..da0b103bf2 100644 --- a/Telegram/Resources/sample.tdesktop-theme +++ b/Telegram/Resources/sample.tdesktop-theme @@ -51,6 +51,8 @@ titleButtonBgOver: #e5e5e5; titleButtonFgOver: #9a9a9a; titleButtonCloseBgOver: #e81123; titleButtonCloseFgOver: #ffffff; +titleFgActive: #3e3c3e; +titleFg: #acacac; trayCounterBg: #f23c34; trayCounterBgMute: #888888; trayCounterFg: #ffffff; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 35e199cbff..e7e6650310 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -103,7 +103,6 @@ MainWindow::MainWindow() { Notify::unreadCounterUpdated(); } }); - subscribe(Global::RefUnreadCounterUpdate(), [this] { updateUnreadCounter(); }); resize(st::windowDefaultWidth, st::windowDefaultHeight); @@ -388,12 +387,6 @@ void MainWindow::setupMain(const MTPUser *self) { updateConnectingStatus(); } -void MainWindow::updateUnreadCounter() { - if (!Global::started() || App::quitting()) return; - - psUpdateCounter(); -} - void MainWindow::showSettings() { if (_passcode) return; diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index a40ca68b48..c6d032f8a9 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -216,7 +216,6 @@ private slots: void onWindowActiveChanged(); private: - void updateUnreadCounter(); void showConnecting(const QString &text, const QString &reconnect = QString()); void hideConnecting(); diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index 4ce43c0369..824005b5cb 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -43,8 +43,6 @@ public: void psRefreshTaskbarIcon() { } - void psUpdateCounter(); - bool psHasNativeNotifications(); virtual QImage iconWithCounter(int size, int count, const style::color &bg, const style::color &fg, bool smallIcon) = 0; @@ -61,6 +59,7 @@ public slots: protected: void initHook() override; + void unreadCounterChangedHook() override; bool psHasTrayIcon() const; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index e2e6340988..da0490c5c4 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -45,10 +45,6 @@ public: bool psFilterNativeEvent(void *event); - bool eventFilter(QObject *obj, QEvent *evt) override; - - void psUpdateCounter(); - bool psHasNativeNotifications() { return !(QSysInfo::macVersion() < QSysInfo::MV_10_8); } @@ -80,8 +76,12 @@ private slots: void onHideAfterFullScreen(); protected: + bool eventFilter(QObject *obj, QEvent *evt) override; + void stateChangedHook(Qt::WindowState state) override; void initHook() override; + void titleVisibilityChangedHook() override; + void unreadCounterChangedHook() override; QImage psTrayIcon(bool selected = false) const; bool psHasTrayIcon() const { @@ -105,6 +105,8 @@ protected: private: void createGlobalMenu(); + void updateTitleCounter(); + void updateIconCounters(); friend class Private; std_::unique_ptr _private; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 3e0851c9dc..1a8a56a230 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -169,11 +169,11 @@ void MainWindow::Private::initCustomTitle(NSWindow *window, NSView *view) { } void MainWindow::Private::willEnterFullScreen() { - _public->setTitleVisibility(false); + _public->setTitleVisible(false); } void MainWindow::Private::willExitFullScreen() { - _public->setTitleVisibility(true); + _public->setTitleVisible(true); } void MainWindow::Private::enableShadow(WId winId) { @@ -243,6 +243,10 @@ void MainWindow::initHook() { } } +void MainWindow::titleVisibilityChangedHook() { + updateTitleCounter(); +} + void MainWindow::onHideAfterFullScreen() { hide(); } @@ -269,7 +273,7 @@ void MainWindow::psSetupTrayIcon() { connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleTray(QSystemTrayIcon::ActivationReason)), Qt::UniqueConnection); App::wnd()->updateTrayMenu(); } - psUpdateCounter(); + updateIconCounters(); trayIcon->show(); } @@ -323,10 +327,17 @@ void _placeCounter(QImage &img, int size, int count, const style::color &bg, con p.drawText(size - w - d - skip, size - f->height + f->ascent - skip, cnt); } -void MainWindow::psUpdateCounter() { - int32 counter = App::histories().unreadBadge(); +void MainWindow::updateTitleCounter() { + setWindowTitle(titleVisible() ? QString() : titleText()); +} - setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); +void MainWindow::unreadCounterChangedHook() { + updateTitleCounter(); + updateIconCounters(); +} + +void MainWindow::updateIconCounters() { + auto counter = App::histories().unreadBadge(); QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); _private->setWindowBadge(counter ? cnt : QString()); diff --git a/Telegram/SourceFiles/platform/mac/window_title_mac.h b/Telegram/SourceFiles/platform/mac/window_title_mac.h index 6409888e3e..3ccdfe3b73 100644 --- a/Telegram/SourceFiles/platform/mac/window_title_mac.h +++ b/Telegram/SourceFiles/platform/mac/window_title_mac.h @@ -28,16 +28,20 @@ class PlainShadow; namespace Platform { -class TitleWidget : public Window::TitleWidget { +class MainWindow; + +class TitleWidget : public Window::TitleWidget, private base::Subscriber { public: - TitleWidget(QWidget *parent, int height); + TitleWidget(MainWindow *parent, int height); protected: void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *e) override; + void mouseDoubleClickEvent(QMouseEvent *e) override; private: ChildWidget _shadow; + QFont _font; }; diff --git a/Telegram/SourceFiles/platform/mac/window_title_mac.mm b/Telegram/SourceFiles/platform/mac/window_title_mac.mm index 4927d0cb19..8d6c84311f 100644 --- a/Telegram/SourceFiles/platform/mac/window_title_mac.mm +++ b/Telegram/SourceFiles/platform/mac/window_title_mac.mm @@ -27,26 +27,62 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Platform { -TitleWidget::TitleWidget(QWidget *parent, int height) : Window::TitleWidget(parent) +TitleWidget::TitleWidget(MainWindow *parent, int height) : Window::TitleWidget(parent) , _shadow(this, st::titleShadow) { setAttribute(Qt::WA_OpaquePaintEvent); resize(width(), height); + +#ifndef OS_MAC_OLD + QStringList families = { qsl(".SF NS Text"), qsl("Helvetica Neue") }; + for (auto family : families) { + _font.setFamily(family); + if (QFontInfo(_font).family() == _font.family()) { + break; + } + } +#endif // OS_MAC_OLD + + if (QFontInfo(_font).family() == _font.family()) { + _font.setPixelSize((height * 15) / 24); + } else { + _font = st::normalFont; + } + + subscribe(Global::RefUnreadCounterUpdate(), [this] { update(); }); } void TitleWidget::paintEvent(QPaintEvent *e) { - Painter(this).fillRect(rect(), st::titleBg); + Painter p(this); + + p.fillRect(rect(), st::titleBg); + + p.setPen(isActiveWindow() ? st::titleFgActive : st::titleFg); + p.setFont(_font); + + p.drawText(rect(), static_cast(parentWidget())->titleText(), style::al_center); } void TitleWidget::resizeEvent(QResizeEvent *e) { _shadow->setGeometry(0, height() - st::lineWidth, width(), st::lineWidth); } +void TitleWidget::mouseDoubleClickEvent(QMouseEvent *e) { + auto window = parentWidget(); + if (window->windowState() == Qt::WindowMaximized) { + window->setWindowState(Qt::WindowNoState); + } else { + window->setWindowState(Qt::WindowMaximized); + } +} + Window::TitleWidget *CreateTitleWidget(QWidget *parent) { +#ifndef OS_MAC_OLD if (auto window = qobject_cast(parent)) { if (auto height = window->getCustomTitleHeight()) { - return new TitleWidget(parent, height); + return new TitleWidget(window, height); } } +#endif // !OS_MAC_OLD return nullptr; } diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index 7124be4132..bd128bf19a 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -683,7 +683,7 @@ void MainWindow::psSetupTrayIcon() { connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(showFromTray())); App::wnd()->updateTrayMenu(); } - psUpdateCounter(); + updateIconCounters(); trayIcon->show(); } @@ -723,7 +723,12 @@ void MainWindow::psUpdateWorkmode() { } } -void MainWindow::psUpdateCounter() { +void MainWindow::unreadCounterChangedHook() { + setWindowTitle(titleText()); + updateIconCounters(); +} + +void MainWindow::updateIconCounters() { auto counter = App::histories().unreadBadge(); auto muted = App::histories().unreadOnlyMuted(); @@ -746,7 +751,6 @@ void MainWindow::psUpdateCounter() { trayIcon->setIcon(forTrayIcon); } - setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); psDestroyIcons(); ps_iconSmall = createHIconFromQIcon(iconSmall, iconSizeSmall.width(), iconSizeSmall.height()); ps_iconBig = createHIconFromQIcon(iconBig, iconSizeBig.width(), iconSizeBig.height()); diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index 36ae6ef2a3..4a00efd6e0 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -50,8 +50,6 @@ public: void psRefreshTaskbarIcon(); - void psUpdateCounter(); - bool psHasNativeNotifications(); virtual QImage iconWithCounter(int size, int count, const style::color &bg, const style::color &fg, bool smallIcon) = 0; @@ -93,6 +91,7 @@ public slots: protected: void initHook() override; int32 screenNameChecksum(const QString &name) const override; + void unreadCounterChangedHook() override; bool psHasTrayIcon() const { return trayIcon; @@ -110,6 +109,8 @@ protected: QTimer psUpdatedPositionTimer; private: + void updateIconCounters(); + void psDestroyIcons(); static UINT _taskbarCreatedMsgId; diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 8a0fb16cba..3dec77fd9c 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -30,7 +30,8 @@ namespace Window { MainWindow::MainWindow() : QWidget() , _positionUpdatedTimer(this) -, _body(this) { +, _body(this) +, _titleText(qsl("Telegram")) { subscribe(Theme::Background(), [this](const Theme::BackgroundUpdate &data) { using Type = Theme::BackgroundUpdate::Type; if (data.type == Type::TestingTheme || data.type == Type::RevertingTheme || data.type == Type::ApplyingTheme) { @@ -39,6 +40,7 @@ MainWindow::MainWindow() : QWidget() } } }); + subscribe(Global::RefUnreadCounterUpdate(), [this] { updateUnreadCounter(); }); } void MainWindow::init() { @@ -105,11 +107,16 @@ void MainWindow::positionUpdated() { _positionUpdatedTimer->start(SaveWindowPositionTimeout); } -void MainWindow::setTitleVisibility(bool visible) { +bool MainWindow::titleVisible() const { + return _title && !_title->isHidden(); +} + +void MainWindow::setTitleVisible(bool visible) { if (_title && (_title->isHidden() == visible)) { _title->setVisible(visible); updateControlsGeometry(); } + titleVisibilityChangedHook(); } int32 MainWindow::screenNameChecksum(const QString &name) const { @@ -134,6 +141,15 @@ void MainWindow::updateControlsGeometry() { _body->setGeometry(0, bodyTop, width(), height() - bodyTop); } +void MainWindow::updateUnreadCounter() { + if (!Global::started() || App::quitting()) return; + + auto counter = App::histories().unreadBadge(); + _titleText = (counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"); + + unreadCounterChangedHook(); +} + void MainWindow::savePosition(Qt::WindowState state) { if (state == Qt::WindowActive) state = windowHandle()->windowState(); if (state == Qt::WindowMinimized || !positionInited()) return; diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index 594bf2dd27..1e3f11f9b6 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -40,7 +40,11 @@ public: } void positionUpdated(); - void setTitleVisibility(bool visible); + bool titleVisible() const; + void setTitleVisible(bool visible); + QString titleText() const { + return _titleText; + } virtual void closeWithoutDestroy(); @@ -61,6 +65,12 @@ protected: virtual void stateChangedHook(Qt::WindowState state) { } + virtual void titleVisibilityChangedHook() { + } + + virtual void unreadCounterChangedHook() { + } + // This one is overriden in Windows for historical reasons. virtual int32 screenNameChecksum(const QString &name) const; @@ -73,6 +83,7 @@ private slots: private: void updateControlsGeometry(); + void updateUnreadCounter(); void initSize(); ChildObject _positionUpdatedTimer; @@ -81,6 +92,8 @@ private: ChildWidget _title = { nullptr }; ChildWidget _body; + QString _titleText; + }; } // namespace Window