diff --git a/Telegram/Resources/lang.txt b/Telegram/Resources/lang.txt index 26480a623..a23100c48 100644 --- a/Telegram/Resources/lang.txt +++ b/Telegram/Resources/lang.txt @@ -24,6 +24,7 @@ lng_menu_settings: "Settings"; lng_menu_about: "About"; lng_open_from_tray: "Open Telegram"; +lng_minimize_to_tray: "Minimize to tray"; lng_quit_from_tray: "Quit Telegram"; lng_tray_icon_text: "Telegram is still running here, you can change this from settings page. diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 684bbc6d2..23416f6a3 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -20,15 +20,16 @@ semibold: 'Open Sans Semibold'; fsize: 13px; -spriteFile: ':/gui/art/sprite.png' / 2:':/gui/art/sprite_125x.png' / 3:':/gui/art/sprite_150x.png' / 4:':/gui/art/sprite_200x.png'; // exceptional value for retina -emojisFile: ':/gui/art/emoji.png' / 2:':/gui/art/emoji_125x.png' / 3:':/gui/art/emoji_150x.png' / 4:':/gui/art/emoji_200x.png'; // exceptional value for retina +spriteFile: ':/gui/art/sprite.png' / 2:':/gui/art/sprite_125x.png' / 3:':/gui/art/sprite_150x.png' / 4:':/gui/art/sprite_200x.png'; +emojisFile: ':/gui/art/emoji.png' / 2:':/gui/art/emoji_125x.png' / 3:':/gui/art/emoji_150x.png' / 4:':/gui/art/emoji_200x.png'; emojiImgSize: 18px; // exceptional value for retina emojiSize: 18px; emojiPadding: 0px; -counterBG: #b42f35; -counterMuteBG: #777; +counterBG: #f23c34; +counterMuteBG: #888; counterColor: #fff; +counterMacInvColor: #045fd5; lineWidth: 1px; @@ -941,7 +942,7 @@ historyScroll: flatScroll(scrollDef) { barOverColor: #89a0b4bc; bgOverColor: #89a0b46b; - round: 2px; + round: 0px; width: 12px; deltax: 3px; diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index da9884c6a..2016f7b7c 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -61,6 +61,13 @@ namespace { case 3: if (ev->key() == Qt::Key_F11) _debugState = 4; else if (ev->key() != Qt::Key_F10) _debugState = 0; break; case 4: if (ev->key() == Qt::Key_F12) offerDebug(); if (ev->key() != Qt::Key_F11) _debugState = 0; break; } + + if (cPlatform() == dbipMac && ev->key() == Qt::Key_W && (ev->modifiers() & (Qt::MetaModifier | Qt::ControlModifier))) { + if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) { + App::wnd()->minimizeToTray(); + return true; + } + } } return QObject::eventFilter(o, e); } diff --git a/Telegram/SourceFiles/art/osxtray.png b/Telegram/SourceFiles/art/osxtray.png new file mode 100644 index 000000000..fe7b2b7a4 Binary files /dev/null and b/Telegram/SourceFiles/art/osxtray.png differ diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png index 982030254..56553e2df 100644 Binary files a/Telegram/SourceFiles/art/sprite.png and b/Telegram/SourceFiles/art/sprite.png differ diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png index b18d853e2..de688414b 100644 Binary files a/Telegram/SourceFiles/art/sprite_200x.png and b/Telegram/SourceFiles/art/sprite_200x.png differ diff --git a/Telegram/SourceFiles/gui/contextmenu.cpp b/Telegram/SourceFiles/gui/contextmenu.cpp new file mode 100644 index 000000000..b6fa308fc --- /dev/null +++ b/Telegram/SourceFiles/gui/contextmenu.cpp @@ -0,0 +1,139 @@ +/* + This file is part of Telegram Desktop, + an unofficial desktop messaging app, see https://telegram.org + + Telegram Desktop is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + It is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE + Copyright (c) 2014 John Preston, https://tdesktop.com + */ +#include "stdafx.h" + +#include "contextmenu.h" +#include "flatbutton.h" + +#include "lang.h" + +ContextMenu::ContextMenu(QWidget *parent) : QWidget(parent), +_hiding(false), a_opacity(0) { + resetButtons(); + + setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::Tool | Qt::NoDropShadowWindowHint); + hide(); +} + +FlatButton *ContextMenu::addButton(FlatButton *button) { + button->setParent(this); + + _width = qMax(_width, int(2 * st::dropdownBorder + button->width())); + if (!_buttons.isEmpty()) { + _height += st::dropdownBorder; + } + _height += button->height(); + + _buttons.push_back(button); + + resize(_width, _height); + + return button; +} + +void ContextMenu::resetButtons() { + _width = 2 * st::dropdownBorder; + _height = 2 * st::dropdownBorder; + resize(_width, _height); + for (int32 i = 0, l = _buttons.size(); i < l; ++i) { + delete _buttons[i]; + } + _buttons.clear(); +} + +void ContextMenu::resizeEvent(QResizeEvent *e) { + int32 top = st::dropdownBorder; + for (Buttons::const_iterator i = _buttons.cbegin(), e = _buttons.cend(); i != e; ++i) { + (*i)->move(st::dropdownBorder, top); + top += st::dropdownBorder + (*i)->height(); + } +} + +void ContextMenu::paintEvent(QPaintEvent *e) { + QPainter p(this); + + if (animating()) { + p.setOpacity(a_opacity.current()); + } + + // paint window border + p.fillRect(QRect(0, 0, _width - st::dropdownBorder, st::dropdownBorder), st::dropdownBorderColor->b); + p.fillRect(QRect(_width - st::dropdownBorder, 0, st::dropdownBorder, _height - st::dropdownBorder), st::dropdownBorderColor->b); + p.fillRect(QRect(st::dropdownBorder, _height - st::dropdownBorder, _width - st::dropdownBorder, st::dropdownBorder), st::dropdownBorderColor->b); + p.fillRect(QRect(0, st::dropdownBorder, st::dropdownBorder, _height - st::dropdownBorder), st::dropdownBorderColor->b); + + if (!_buttons.isEmpty()) { // paint separators + int32 top = st::dropdownBorder + _buttons.front()->height(); + p.setPen(st::dropdownBorderColor->p); + for (int32 i = 1, s = _buttons.size(); i < s; ++i) { + p.fillRect(st::dropdownBorder, top, _width - 2 * st::dropdownBorder, st::dropdownBorder, st::dropdownBorderColor->b); + top += st::dropdownBorder + _buttons[i]->height(); + } + } +} + +void ContextMenu::fastHide() { + if (animating()) { + anim::stop(this); + } + a_opacity = anim::fvalue(0, 0); + hide(); +} + +void ContextMenu::adjustButtons() { + for (Buttons::const_iterator i = _buttons.cbegin(), e = _buttons.cend(); i != e; ++i) { + (*i)->setOpacity(a_opacity.current()); + } +} + +void ContextMenu::hideStart() { + _hiding = true; + a_opacity.start(0); + anim::start(this); +} + +void ContextMenu::hideFinish() { + hide(); +} + +void ContextMenu::showStart() { + if (!isHidden() && a_opacity.current() == 1) { + return; + } + _hiding = false; + show(); + a_opacity.start(1); + anim::start(this); +} + +bool ContextMenu::animStep(float64 ms) { + float64 dt = ms / 150; + bool res = true; + if (dt >= 1) { + a_opacity.finish(); + if (_hiding) { + hideFinish(); + } + res = false; + } else { + a_opacity.update(dt, anim::linear); + } + adjustButtons(); + update(); + return res; +} diff --git a/Telegram/SourceFiles/gui/contextmenu.h b/Telegram/SourceFiles/gui/contextmenu.h new file mode 100644 index 000000000..a869404a3 --- /dev/null +++ b/Telegram/SourceFiles/gui/contextmenu.h @@ -0,0 +1,59 @@ +/* + This file is part of Telegram Desktop, + an unofficial desktop messaging app, see https://telegram.org + + Telegram Desktop is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + It is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE + Copyright (c) 2014 John Preston, https://tdesktop.com + */ +#pragma once + +#include + +class FlatButton; + +class ContextMenu : public QWidget, public Animated { + Q_OBJECT + +public: + + ContextMenu(QWidget *parent); + FlatButton *addButton(FlatButton *button); + void resetButtons(); + + void resizeEvent(QResizeEvent *e); + void paintEvent(QPaintEvent *e); + + void fastHide(); + + bool animStep(float64 ms); + +public slots: + + void hideStart(); + void hideFinish(); + + void showStart(); + +private: + + void adjustButtons(); + + typedef QVector Buttons; + Buttons _buttons; + + int32 _width, _height; + bool _hiding; + + anim::fvalue a_opacity; + +}; \ No newline at end of file diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp index 24a0f9bb5..7a90afe92 100644 --- a/Telegram/SourceFiles/pspecific_linux.cpp +++ b/Telegram/SourceFiles/pspecific_linux.cpp @@ -219,7 +219,7 @@ void PsMainWindow::psStateChanged(Qt::WindowState state) { psUpdateSysMenu(state); psUpdateMargins(); // if (state == Qt::WindowMinimized && GetWindowLong(ps_hWnd, GWL_HWNDPARENT)) { -// minimizeToTray(); +// App::wnd()->minimizeToTray(); // } psSavePosition(state); } diff --git a/Telegram/SourceFiles/pspecific_linux.h b/Telegram/SourceFiles/pspecific_linux.h index 88b9fa1d7..230479084 100644 --- a/Telegram/SourceFiles/pspecific_linux.h +++ b/Telegram/SourceFiles/pspecific_linux.h @@ -59,9 +59,6 @@ public: void psUpdateWorkmode(); void psRefreshTaskbarIcon(); - virtual bool minimizeToTray() { - return false; - } bool psPosInited() const { return posInited; @@ -161,7 +158,7 @@ private: }; -void psActivateProcess(uint64 pid); +void psActivateProcess(uint64 pid = 0); QString psLocalServerPrefix(); QString psCurrentCountry(); QString psCurrentLanguage(); diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 18d81396b..6ade07aed 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -65,6 +65,9 @@ void MacPrivate::notifyReplied(unsigned long long peer, const char *str) { PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent), posInited(false), trayIcon(0), trayIconMenu(0), icon256(qsl(":/gui/art/iconround256.png")) { + QImage tray(qsl(":/gui/art/osxtray.png")); + trayImg = tray.copy(0, cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4)); + trayImgSel = tray.copy(tray.width() / (cRetina() ? 2 : 4), cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4)); connect(&psIdleTimer, SIGNAL(timeout()), this, SLOT(psIdleTimeout())); psIdleTimer.setSingleShot(false); } @@ -78,6 +81,10 @@ void PsMainWindow::psNotIdle() const { } } +QImage PsMainWindow::psTrayIcon(bool selected) const { + return selected ? trayImgSel : trayImg; +} + void PsMainWindow::psIdleTimeout() { int64 idleTime = objc_idleTime(); if (idleTime >= 0) { @@ -138,6 +145,41 @@ void PsMainWindow::psUpdateWorkmode() { } } +void _placeCounter(QImage &img, int size, int count, style::color bg, style::color color) { + if (!count) return; + + QPainter p(&img); + QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0')); + int32 cntSize = cnt.size(); + + p.setBrush(bg->b); + p.setPen(Qt::NoPen); + p.setRenderHint(QPainter::Antialiasing); + int32 fontSize, skip; + if (size == 22) { + skip = 1; + fontSize = 8; + } else { + skip = 2; + fontSize = 16; + } + style::font f(fontSize); + int32 w = f->m.width(cnt), d, r; + if (size == 22) { + d = (cntSize < 2) ? 3 : 2; + r = (cntSize < 2) ? 6 : 5; + } else { + d = (cntSize < 2) ? 6 : 5; + r = (cntSize < 2) ? 9 : 11; + } + p.drawRoundedRect(QRect(size - w - d * 2 - skip, size - f->height - skip, w + d * 2, f->height), r, r); + + p.setCompositionMode(QPainter::CompositionMode_Source); + p.setFont(f->f); + p.setPen(color->p); + p.drawText(size - w - d - skip, size - f->height + f->ascent - skip, cnt); +} + void PsMainWindow::psUpdateCounter() { int32 counter = App::histories().unreadFull; @@ -148,10 +190,16 @@ void PsMainWindow::psUpdateCounter() { if (trayIcon) { style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG; - QIcon iconSmall; - iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(16, counter, bg, true))); - iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(32, counter, bg, true))); - trayIcon->setIcon(iconSmall); + QIcon icon; + QImage img(psTrayIcon()), imgsel(psTrayIcon(true)); + img.detach(); + imgsel.detach(); + int32 size = cRetina() ? 44 : 22; + _placeCounter(img, size, counter, bg, st::counterColor); + _placeCounter(imgsel, size, counter, st::white, st::counterMacInvColor); + icon.addPixmap(QPixmap::fromImage(img)); + icon.addPixmap(QPixmap::fromImage(imgsel), QIcon::Selected); + trayIcon->setIcon(icon); } } @@ -255,7 +303,7 @@ void PsMainWindow::psStateChanged(Qt::WindowState state) { psUpdateSysMenu(state); psUpdateMargins(); // if (state == Qt::WindowMinimized && GetWindowLong(ps_hWnd, GWL_HWNDPARENT)) { -// minimizeToTray(); +// App::wnd()->minimizeToTray(); // } psSavePosition(state); } diff --git a/Telegram/SourceFiles/pspecific_mac.h b/Telegram/SourceFiles/pspecific_mac.h index e770211b3..68dc30104 100644 --- a/Telegram/SourceFiles/pspecific_mac.h +++ b/Telegram/SourceFiles/pspecific_mac.h @@ -69,9 +69,6 @@ public: void psUpdateWorkmode(); void psRefreshTaskbarIcon(); - virtual bool minimizeToTray() { - return false; - } bool psPosInited() const { return posInited; @@ -95,13 +92,17 @@ public slots: protected: void psNotIdle() const; + QImage psTrayIcon(bool selected = false) const; bool posInited; QSystemTrayIcon *trayIcon; QMenu *trayIconMenu; QImage icon256; + QImage trayImg, trayImgSel; + virtual void setupTrayIcon() = 0; + virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0; virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; QTimer psUpdatedPositionTimer; @@ -173,7 +174,7 @@ private: }; -void psActivateProcess(uint64 pid); +void psActivateProcess(uint64 pid = 0); QString psLocalServerPrefix(); QString psCurrentCountry(); QString psCurrentLanguage(); diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index c7aef18c7..646b67f97 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -1135,7 +1135,7 @@ void PsMainWindow::psStateChanged(Qt::WindowState state) { psUpdateSysMenu(state); psUpdateMargins(); if (state == Qt::WindowMinimized && GetWindowLong(ps_hWnd, GWL_HWNDPARENT)) { - minimizeToTray(); + App::wnd()->minimizeToTray(); } psSavePosition(state); } @@ -1748,7 +1748,9 @@ namespace { } void psActivateProcess(uint64 pid) { - ::EnumWindows((WNDENUMPROC)_ActivateProcess, (LPARAM)&pid); + if (pid) { + ::EnumWindows((WNDENUMPROC)_ActivateProcess, (LPARAM)&pid); + } } QString psCurrentCountry() { diff --git a/Telegram/SourceFiles/pspecific_wnd.h b/Telegram/SourceFiles/pspecific_wnd.h index cd89bf9d0..46284bee6 100644 --- a/Telegram/SourceFiles/pspecific_wnd.h +++ b/Telegram/SourceFiles/pspecific_wnd.h @@ -1,3 +1,4 @@ + /* This file is part of Telegram Desktop, an unofficial desktop messaging app, see https://telegram.org @@ -57,9 +58,6 @@ public: void psUpdateWorkmode(); void psRefreshTaskbarIcon(); - virtual bool minimizeToTray() { - return false; - } bool psPosInited() const { return posInited; @@ -170,7 +168,7 @@ private: }; -void psActivateProcess(uint64 pid); +void psActivateProcess(uint64 pid = 0); QString psLocalServerPrefix(); QString psCurrentCountry(); QString psCurrentLanguage(); diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index bdc1b0335..1a2951db2 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -21,7 +21,7 @@ extern bool gDebug; inline bool cDebug() { #if defined _DEBUG && !defined Q_OS_MAC return true; -#elif defined _WITH_DEBUG +#elif defined _WITH_DEBUG || (defined _DEBUG && defined Q_OS_MAC) return gDebug; #else return false; diff --git a/Telegram/SourceFiles/stdafx.h b/Telegram/SourceFiles/stdafx.h index 05f1ab58d..b0d0e8cd9 100644 --- a/Telegram/SourceFiles/stdafx.h +++ b/Telegram/SourceFiles/stdafx.h @@ -56,6 +56,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com #include "gui/flatinput.h" #include "gui/flattextarea.h" #include "gui/flatbutton.h" +#include "gui/contextmenu.h" #include "gui/switcher.h" #include "gui/scrollarea.h" #include "gui/images.h" diff --git a/Telegram/SourceFiles/telegram.qrc b/Telegram/SourceFiles/telegram.qrc index 74576d75f..93525b044 100644 --- a/Telegram/SourceFiles/telegram.qrc +++ b/Telegram/SourceFiles/telegram.qrc @@ -19,6 +19,7 @@ art/blank.gif art/iconround256.png art/fonts/DejaVuSans.ttf + art/osxtray.png art/chatcolor1.png diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index a26a2adaf..3fd52fed3 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -624,6 +624,7 @@ void Window::checkHistoryActivation(int state) { if (main && MTP::authedId() && historyIsActive(state)) { main->historyWasRead(); } + QTimer::singleShot(1, this, SLOT(updateTrayMenu())); } void Window::layerHidden() { @@ -740,31 +741,28 @@ bool Window::minimizeToTray() { App::writeConfig(); } if (App::main()) App::main()->setOnline(windowState()); + updateTrayMenu(); return true; } void Window::setupTrayIcon() { if (!trayIcon) { - if (trayIconMenu) trayIconMenu->deleteLater(); - trayIconMenu = new QMenu(this); - trayIconMenu->setFont(QFont("Tahoma")); - QAction *a; - a = trayIconMenu->addAction(lang(lng_open_from_tray), this, SLOT(showFromTray())); - a->setEnabled(true); - a = trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray())); - a->setEnabled(true); - if (trayIcon) trayIcon->deleteLater(); trayIcon = new QSystemTrayIcon(this); +#ifdef Q_OS_MAC + QIcon icon(QPixmap::fromImage(psTrayIcon())); + icon.addPixmap(QPixmap::fromImage(psTrayIcon(true)), QIcon::Selected); +#else + QIcon icon(QPixmap::fromImage(iconLarge())); +#endif - trayIcon->setIcon(QIcon(QPixmap::fromImage(iconLarge()))); - trayIcon->setContextMenu(trayIconMenu); + trayIcon->setIcon(icon); trayIcon->setToolTip(QString::fromStdWString(AppName)); - + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleTray(QSystemTrayIcon::ActivationReason)), Qt::UniqueConnection); if (cPlatform() != dbipMac) { - connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleTray(QSystemTrayIcon::ActivationReason))); connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(showFromTray())); } + updateTrayMenu(); } psUpdateCounter(); @@ -772,6 +770,24 @@ void Window::setupTrayIcon() { psUpdateDelegate(); } +void Window::updateTrayMenu(int windowState) { + bool active = psIsActive(windowState); + if (trayIconMenu) { + trayIconMenu->deleteLater(); + trayIconMenu = 0; + } + if (active || cPlatform() != dbipMac) { + trayIconMenu = new QMenu(this); + trayIconMenu->setFont(QFont("Tahoma")); + QAction *a; + a = trayIconMenu->addAction(lang(active ? lng_minimize_to_tray : lng_open_from_tray), this, active ? SLOT(minimizeToTray()) : SLOT(showFromTray())); + a->setEnabled(true); + a = trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray())); + a->setEnabled(true); + } + trayIcon->setContextMenu(trayIconMenu); +} + void Window::quitFromTray() { App::quit(); } @@ -780,6 +796,7 @@ void Window::activate() { bool wasHidden = !isVisible(); setWindowState(windowState() & ~Qt::WindowMinimized); setVisible(true); + psActivateProcess(); activateWindow(); if (wasHidden) { if (main) { @@ -836,10 +853,12 @@ void Window::showFromTray(QSystemTrayIcon::ActivationReason reason) { setWindowIcon(myIcon); psUpdateCounter(); if (App::main()) App::main()->setOnline(windowState()); + QTimer::singleShot(1, this, SLOT(updateTrayMenu())); } } void Window::toggleTray(QSystemTrayIcon::ActivationReason reason) { + if (trayIconMenu && cPlatform() == dbipMac) return; if (reason != QSystemTrayIcon::Context) { if (psIsActive()) { minimizeToTray(); @@ -1202,6 +1221,43 @@ QImage Window::iconLarge() const { return icon256; } +void Window::placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) { + QPainter p(&img); + + QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 10, 1, 10, QChar('0')); + int32 cntSize = cnt.size(); + + p.setBrush(bg->b); + p.setPen(Qt::NoPen); + p.setRenderHint(QPainter::Antialiasing); + int32 fontSize; + if (size == 16) { + fontSize = 8; + } else if (size == 32) { + fontSize = (cntSize < 2) ? 12 : 12; + } else { + fontSize = (cntSize < 2) ? 22 : 22; + } + style::font f(fontSize); + int32 w = f->m.width(cnt), d, r; + if (size == 16) { + d = (cntSize < 2) ? 2 : 1; + r = (cntSize < 2) ? 4 : 3; + } else if (size == 32) { + d = (cntSize < 2) ? 5 : 2; + r = (cntSize < 2) ? 8 : 7; + } else { + d = (cntSize < 2) ? 9 : 4; + r = (cntSize < 2) ? 16 : 14; + } + p.drawRoundedRect(QRect(shift.x() + size - w - d * 2, shift.y() + size - f->height, w + d * 2, f->height), r, r); + p.setFont(f->f); + + p.setPen(color->p); + + p.drawText(shift.x() + size - w - d, shift.y() + size - f->height + f->ascent, cnt); + +} QImage Window::iconWithCounter(int size, int count, style::color bg, bool smallIcon) { bool layer = false; @@ -1257,40 +1313,7 @@ QImage Window::iconWithCounter(int size, int count, style::color bg, bool smallI if (!count) return img; if (smallIcon) { - QPainter p(&img); - - QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 10, 1, 10, QChar('0')); - int32 cntSize = cnt.size(); - - p.setBrush(bg->b); - p.setPen(Qt::NoPen); - p.setRenderHint(QPainter::Antialiasing); - int32 fontSize; - if (size == 16) { - fontSize = 8; - } else if (size == 32) { - fontSize = (cntSize < 2) ? 12 : ((smallIcon || cntSize < 3) ? 12 : 10); - } else { - fontSize = (cntSize < 2) ? 22 : ((smallIcon || cntSize < 3) ? 22 : 16); - } - style::font f(fontSize); - int32 w = f->m.width(cnt), d, r; - if (size == 16) { - d = (cntSize < 2) ? 2 : 1; - r = (cntSize < 2) ? 4 : 3; - } else if (size == 32) { - d = (cntSize < 2) ? 5 : ((smallIcon || cntSize < 3) ? 2 : 1); - r = (cntSize < 2) ? 8 : ((smallIcon || cntSize < 3) ? 7 : 3); - } else { - d = (cntSize < 2) ? 9 : ((smallIcon || cntSize < 3) ? 4 : 2); - r = (cntSize < 2) ? 16 : ((smallIcon || cntSize < 3) ? 14 : 8); - } - p.drawRoundedRect(QRect(size - w - d * 2, size - f->height, w + d * 2, f->height), r, r); - p.setFont(f->f); - - p.setPen(st::counterColor->p); - - p.drawText(size - w - d, size - f->height + f->ascent, cnt); + placeSmallCounter(img, size, count, bg, QPoint(), st::counterColor); } else { QPainter p(&img); p.drawPixmap(size / 2, size / 2, QPixmap::fromImage(iconWithCounter(-size / 2, count, bg, false))); diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index e1b108ac9..0e90971eb 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -184,8 +184,6 @@ public: bool historyIsActive(int state = -1) const; - bool minimizeToTray(); - void activate(); void noIntro(IntroWidget *was); @@ -234,8 +232,10 @@ public slots: void showSettings(); void layerHidden(); void updateTitleStatus(); + void quitFromTray(); void showFromTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown); + bool minimizeToTray(); void toggleTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown); void onInactiveTimer(); @@ -244,7 +244,8 @@ public slots: void onTempDirClearFailed(); void notifyFire(); - + void updateTrayMenu(int windowState = -1); + signals: void resized(const QSize &size); @@ -257,6 +258,7 @@ protected: private: + void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color); QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon); QImage icon16, icon32, icon64; diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index f7f401310..79c1016f5 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -42,6 +42,8 @@ 0732E4A9199E262300D50FE7 /* overviewwidget.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 0732E4A7199E262300D50FE7 /* overviewwidget.cpp */; }; 0732E4AC199E268A00D50FE7 /* moc_overviewwidget.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 0732E4AB199E268A00D50FE7 /* moc_overviewwidget.cpp */; }; 0749CE69194D723400345D61 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07C3AF24194335ED0016CFF1 /* Images.xcassets */; }; + 074FCB8E19D36851004C6EB2 /* contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB8C19D36851004C6EB2 /* contextmenu.cpp */; }; + 074FCB9119D36E60004C6EB2 /* moc_contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB9019D36E60004C6EB2 /* moc_contextmenu.cpp */; }; 07A69332199277BA0099CB9F /* mediaview.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07A69330199277BA0099CB9F /* mediaview.cpp */; }; 07A6933519927B160099CB9F /* moc_mediaview.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07A6933419927B160099CB9F /* moc_mediaview.cpp */; }; 07C4753B1967DF1C00CAAFE9 /* switcher.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07C475391967DF1C00CAAFE9 /* switcher.cpp */; }; @@ -243,6 +245,9 @@ 0732E4A7199E262300D50FE7 /* overviewwidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = overviewwidget.cpp; path = SourceFiles/overviewwidget.cpp; sourceTree = SOURCE_ROOT; }; 0732E4A8199E262300D50FE7 /* overviewwidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = overviewwidget.h; path = SourceFiles/overviewwidget.h; sourceTree = SOURCE_ROOT; }; 0732E4AB199E268A00D50FE7 /* moc_overviewwidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_overviewwidget.cpp; path = GeneratedFiles/Debug/moc_overviewwidget.cpp; sourceTree = SOURCE_ROOT; }; + 074FCB8C19D36851004C6EB2 /* contextmenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = contextmenu.cpp; path = SourceFiles/gui/contextmenu.cpp; sourceTree = SOURCE_ROOT; }; + 074FCB8D19D36851004C6EB2 /* contextmenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = contextmenu.h; path = SourceFiles/gui/contextmenu.h; sourceTree = SOURCE_ROOT; }; + 074FCB9019D36E60004C6EB2 /* moc_contextmenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_contextmenu.cpp; path = GeneratedFiles/Debug/moc_contextmenu.cpp; sourceTree = SOURCE_ROOT; }; 075EB50EB07CF69FD62FB8DF /* /usr/local/Qt-5.3.1/mkspecs/modules/qt_lib_sql_private.pri */ = {isa = PBXFileReference; lastKnownFileType = text; path = "/usr/local/Qt-5.3.1/mkspecs/modules/qt_lib_sql_private.pri"; sourceTree = ""; }; 0771C4C94B623FC34BF62983 /* intro.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = intro.cpp; path = SourceFiles/intro/intro.cpp; sourceTree = ""; }; 07A69330199277BA0099CB9F /* mediaview.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mediaview.cpp; path = SourceFiles/mediaview.cpp; sourceTree = SOURCE_ROOT; }; @@ -758,6 +763,7 @@ D3FE9C29B6A61D7C3C4B731B /* animation.cpp */, 08A7682548FB7E671FF03822 /* boxshadow.cpp */, 4D55B83DFDFE3D492CDBD27A /* button.cpp */, + 074FCB8C19D36851004C6EB2 /* contextmenu.cpp */, 751C8D0E0BE6D16937B77A2C /* countrycodeinput.cpp */, 3E329D4547CC23585307FA32 /* countryinput.cpp */, B3062303CE8F4EB9325CB3DC /* emoji_config.cpp */, @@ -777,6 +783,7 @@ 85FABD67716E36CD8B3CA4FA /* animation.h */, BDAB6725B830DEE896DC0F55 /* boxshadow.h */, 4604687EBA85611C9E8A9CDF /* button.h */, + 074FCB8D19D36851004C6EB2 /* contextmenu.h */, 60C0061633AC4244EA634B2A /* countrycodeinput.h */, 6868ADA9E9A9801B2BA92B97 /* countryinput.h */, 19618554524B8D928F13940D /* emoji_config.h */, @@ -1016,6 +1023,7 @@ 801973D3334D0FCA849CF485 /* Debug */ = { isa = PBXGroup; children = ( + 074FCB9019D36E60004C6EB2 /* moc_contextmenu.cpp */, 07D703BA19B88FB900C4EED2 /* moc_audio.cpp */, 0732E4AB199E268A00D50FE7 /* moc_overviewwidget.cpp */, 07C4753E1967E37300CAAFE9 /* moc_switcher.cpp */, @@ -1366,6 +1374,7 @@ 68FFEB7CA30BF0149161B809 /* window.cpp in Compile Sources */, 0CB7DE9A54CC9BF86FB7B5CA /* mtp.cpp in Compile Sources */, DF259E9677CC63AF8754032B /* mtpConnection.cpp in Compile Sources */, + 074FCB9119D36E60004C6EB2 /* moc_contextmenu.cpp in Compile Sources */, B6346B66B0A2228A91D8A5D9 /* mtpDC.cpp in Compile Sources */, B8CA3E1E11A7E0E7DF9E1CDE /* mtpFileLoader.cpp in Compile Sources */, 99F0A9B2AFE5ABDCBFC04510 /* mtpRPC.cpp in Compile Sources */, @@ -1387,6 +1396,7 @@ 0A49F3A5DC0680FB31519670 /* phoneinput.cpp in Compile Sources */, ADE99904299B99EB6135E8D9 /* scrollarea.cpp in Compile Sources */, 90085DF442550A0845D5AF37 /* style_core.cpp in Compile Sources */, + 074FCB8E19D36851004C6EB2 /* contextmenu.cpp in Compile Sources */, 3AA6E7264581F82856FB37F7 /* text.cpp in Compile Sources */, FCE6518C548DF7BC82228A4A /* twidget.cpp in Compile Sources */, F91C59BECCE70070B06E8385 /* lang.cpp in Compile Sources */, diff --git a/Telegram/Telegram.xcodeproj/qt_preprocess.mak b/Telegram/Telegram.xcodeproj/qt_preprocess.mak index 03331a2f3..309285533 100644 --- a/Telegram/Telegram.xcodeproj/qt_preprocess.mak +++ b/Telegram/Telegram.xcodeproj/qt_preprocess.mak @@ -38,7 +38,8 @@ compilers: GeneratedFiles/qrc_telegram.cpp GeneratedFiles/Debug/moc_application. GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp\ GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp\ GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp\ - GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp\ + GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp\ + GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp\ GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp\ GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp\ GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp\ @@ -90,9 +91,9 @@ GeneratedFiles/qrc_telegram.cpp: SourceFiles/telegram.qrc \ SourceFiles/art/chatcolor2.png /usr/local/Qt-5.3.1/bin/rcc -name telegram SourceFiles/telegram.qrc -o GeneratedFiles/qrc_telegram.cpp -compiler_moc_header_make_all: GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp +compiler_moc_header_make_all: GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp compiler_moc_header_clean: - -$(DEL_FILE) GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp + -$(DEL_FILE) GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp GeneratedFiles/Debug/moc_application.cpp: ../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalSocket \ ../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalServer \ ../../Libraries/QtStatic/qtbase/include/QtNetwork/QNetworkReply \ @@ -303,6 +304,10 @@ GeneratedFiles/Debug/moc_button.cpp: ../../Libraries/QtStatic/qtbase/include/QtW SourceFiles/gui/button.h /usr/local/Qt-5.3.1/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.3.1/mkspecs/macx-clang -I. -I/usr/local/Qt-5.3.1/include/QtGui/5.3.1/QtGui -I/usr/local/Qt-5.3.1/include/QtCore/5.3.1/QtCore -I/usr/local/Qt-5.3.1/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.3.1/include -I/usr/local/Qt-5.3.1/include/QtMultimedia -I/usr/local/Qt-5.3.1/include/QtWidgets -I/usr/local/Qt-5.3.1/include/QtNetwork -I/usr/local/Qt-5.3.1/include/QtGui -I/usr/local/Qt-5.3.1/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/gui/button.h -o GeneratedFiles/Debug/moc_button.cpp +GeneratedFiles/Debug/moc_contextmenu.cpp: ../../Libraries/QtStatic/qtbase/include/QtWidgets/QWidget \ + SourceFiles/gui/contextmenu.h + /usr/local/Qt-5.3.1/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.3.1/mkspecs/macx-clang -I. -I/usr/local/Qt-5.3.1/include/QtGui/5.3.1/QtGui -I/usr/local/Qt-5.3.1/include/QtCore/5.3.1/QtCore -I/usr/local/Qt-5.3.1/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.3.1/include -I/usr/local/Qt-5.3.1/include/QtMultimedia -I/usr/local/Qt-5.3.1/include/QtWidgets -I/usr/local/Qt-5.3.1/include/QtNetwork -I/usr/local/Qt-5.3.1/include/QtGui -I/usr/local/Qt-5.3.1/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/gui/contextmenu.h -o GeneratedFiles/Debug/moc_contextmenu.cpp + GeneratedFiles/Debug/moc_countrycodeinput.cpp: SourceFiles/gui/flatinput.h \ ../../Libraries/QtStatic/qtbase/include/QtWidgets/QLineEdit \ SourceFiles/style.h \ diff --git a/Telegram/_qt_5_3_1_patch/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/Telegram/_qt_5_3_1_patch/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 537a438b7..17f2df5ca 100755 --- a/Telegram/_qt_5_3_1_patch/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/Telegram/_qt_5_3_1_patch/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -102,7 +102,7 @@ QT_USE_NAMESPACE QCocoaSystemTrayIcon *systray; NSStatusItem *item; QCocoaMenu *menu; - bool menuVisible; + bool menuVisible, iconSelected; QIcon icon; QT_MANGLE_NAMESPACE(QNSImageView) *imageCell; } @@ -124,6 +124,7 @@ QT_USE_NAMESPACE QT_MANGLE_NAMESPACE(QNSStatusItem) *parent; } -(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent; +-(void)updateIconSelection; -(void)menuTrackingDone:(NSNotification*)notification; -(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton; @end @@ -202,13 +203,11 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon) m_sys->item->icon = icon; - const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible; - CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; - const short scale = (hgt - 6) * _devicePixelRatio(); + const short scale = hgt * _devicePixelRatio(); QPixmap pm = m_sys->item->icon.pixmap(QSize(scale, scale), - menuVisible ? QIcon::Selected : QIcon::Normal); + m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal); if (pm.isNull()) { pm = QPixmap(scale, scale); pm.fill(Qt::transparent); @@ -330,24 +329,30 @@ QT_END_NAMESPACE return self; } +-(void)updateIconSelection +{ + CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + const short scale = hgt * _devicePixelRatio(); + QPixmap pm = parent->icon.pixmap(QSize(scale, scale), + parent->iconSelected ? QIcon::Selected : QIcon::Normal); + if (pm.isNull()) { + pm = QPixmap(scale, scale); + pm.fill(Qt::transparent); + } + NSImage *nsaltimage = static_cast(qt_mac_create_nsimage(pm)); + [self setImage: nsaltimage]; + [nsaltimage release]; +} + -(void)menuTrackingDone:(NSNotification*)notification { Q_UNUSED(notification); down = NO; - CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; - const short scale = (hgt - 6) * _devicePixelRatio(); + parent->menuVisible = false; - QPixmap pm = parent->icon.pixmap(QSize(scale, scale), QIcon::Normal); - if (pm.isNull()) { - pm = QPixmap(scale, scale); - pm.fill(Qt::transparent); - } - NSImage *nsaltimage = static_cast(qt_mac_create_nsimage(pm)); - [self setImage: nsaltimage]; - [nsaltimage release]; - - parent->menuVisible = false; + parent->iconSelected = false; + [self updateIconSelection]; [self setNeedsDisplay:YES]; } @@ -358,25 +363,15 @@ QT_END_NAMESPACE int clickCount = [mouseEvent clickCount]; [self setNeedsDisplay:YES]; - CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; - const short scale = (hgt - 6) * _devicePixelRatio(); + parent->iconSelected = (clickCount != 2) && parent->menu; + [self updateIconSelection]; - QPixmap pm = parent->icon.pixmap(QSize(scale, scale), - parent->menuVisible ? QIcon::Selected : QIcon::Normal); - if (pm.isNull()) { - pm = QPixmap(scale, scale); - pm.fill(Qt::transparent); - } - NSImage *nsaltimage = static_cast(qt_mac_create_nsimage(pm)); - [self setImage: nsaltimage]; - [nsaltimage release]; - - if (clickCount == 2) { - [self menuTrackingDone:nil]; - [parent doubleClickSelector:self]; - } else { - [parent triggerSelector:self button:mouseButton]; - } + if (clickCount == 2) { + [self menuTrackingDone:nil]; + [parent doubleClickSelector:self]; + } else { + [parent triggerSelector:self button:mouseButton]; + } } -(void)mouseDown:(NSEvent *)mouseEvent @@ -388,6 +383,9 @@ QT_END_NAMESPACE { Q_UNUSED(mouseEvent); [self menuTrackingDone:nil]; + + parent->iconSelected = false; + [self updateIconSelection]; } - (void)rightMouseDown:(NSEvent *)mouseEvent @@ -399,6 +397,9 @@ QT_END_NAMESPACE { Q_UNUSED(mouseEvent); [self menuTrackingDone:nil]; + + parent->iconSelected = false; + [self updateIconSelection]; } - (void)otherMouseDown:(NSEvent *)mouseEvent @@ -413,7 +414,7 @@ QT_END_NAMESPACE } -(void)drawRect:(NSRect)rect { - [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down]; + [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO]; [super drawRect:rect]; } @end diff --git a/Telegram/_qt_5_3_1_patch/qtbase/src/widgets/util/qsystemtrayicon_qpa.cpp b/Telegram/_qt_5_3_1_patch/qtbase/src/widgets/util/qsystemtrayicon_qpa.cpp new file mode 100644 index 000000000..1e621e48f --- /dev/null +++ b/Telegram/_qt_5_3_1_patch/qtbase/src/widgets/util/qsystemtrayicon_qpa.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsystemtrayicon_p.h" + +#include +#include +#include + +#include +#include + +#ifndef QT_NO_SYSTEMTRAYICON + +QT_BEGIN_NAMESPACE + +QSystemTrayIconPrivate::QSystemTrayIconPrivate() + : qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()) + , visible(false) +{ +} + +QSystemTrayIconPrivate::~QSystemTrayIconPrivate() +{ + delete qpa_sys; +} + +void QSystemTrayIconPrivate::install_sys() +{ + if (qpa_sys) { + qpa_sys->init(); + QObject::connect(qpa_sys, SIGNAL(activated(QPlatformSystemTrayIcon::ActivationReason)), + q_func(), SLOT(_q_emitActivated(QPlatformSystemTrayIcon::ActivationReason))); + QObject::connect(qpa_sys, SIGNAL(messageClicked()), + q_func(), SIGNAL(messageClicked())); + updateMenu_sys(); + updateIcon_sys(); + updateToolTip_sys(); + } +} + +void QSystemTrayIconPrivate::remove_sys() +{ + if (qpa_sys) + qpa_sys->cleanup(); +} + +QRect QSystemTrayIconPrivate::geometry_sys() const +{ + if (qpa_sys) + return qpa_sys->geometry(); + else + return QRect(); +} + +void QSystemTrayIconPrivate::updateIcon_sys() +{ + if (qpa_sys) + qpa_sys->updateIcon(icon); +} + +void QSystemTrayIconPrivate::updateMenu_sys() +{ + if (qpa_sys) { + if (menu) { + if (!menu->platformMenu()) { + QPlatformMenu *platformMenu = qpa_sys->createMenu(); + if (platformMenu) + menu->setPlatformMenu(platformMenu); + } + qpa_sys->updateMenu(menu->platformMenu()); + } else { + qpa_sys->updateMenu(0); + } + } +} + +void QSystemTrayIconPrivate::updateToolTip_sys() +{ + if (qpa_sys) + qpa_sys->updateToolTip(toolTip); +} + +bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys() +{ + QScopedPointer sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()); + if (sys) + return sys->isSystemTrayAvailable(); + else + return false; +} + +bool QSystemTrayIconPrivate::supportsMessages_sys() +{ + QScopedPointer sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()); + if (sys) + return sys->supportsMessages(); + else + return false; +} + +void QSystemTrayIconPrivate::showMessage_sys(const QString &message, + const QString &title, + QSystemTrayIcon::MessageIcon icon, + int msecs) +{ + if (!qpa_sys) + return; + + QIcon notificationIcon; + switch (icon) { + case QSystemTrayIcon::Information: + notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); + break; + case QSystemTrayIcon::Warning: + notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); + break; + case QSystemTrayIcon::Critical: + notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); + break; + default: + break; + } + qpa_sys->showMessage(message, title, notificationIcon, + static_cast(icon), msecs); +} + +QT_END_NAMESPACE + +#endif // QT_NO_SYSTEMTRAYICON