diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 7e56c73c2..3b4c44ffc 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -948,6 +948,8 @@ PRIVATE platform/linux/file_utilities_linux.h platform/linux/launcher_linux.cpp platform/linux/launcher_linux.h + platform/linux/integration_linux.cpp + platform/linux/integration_linux.h platform/linux/main_window_linux.cpp platform/linux/main_window_linux.h platform/linux/notifications_manager_linux_dummy.cpp @@ -959,6 +961,8 @@ PRIVATE platform/mac/file_utilities_mac.h platform/mac/launcher_mac.mm platform/mac/launcher_mac.h + platform/mac/integration_mac.mm + platform/mac/integration_mac.h platform/mac/mac_iconv_helper.c platform/mac/main_window_mac.mm platform/mac/main_window_mac.h @@ -993,6 +997,8 @@ PRIVATE platform/win/file_utilities_win.h platform/win/launcher_win.cpp platform/win/launcher_win.h + platform/win/integration_win.cpp + platform/win/integration_win.h platform/win/main_window_win.cpp platform/win/main_window_win.h platform/win/notifications_manager_win.cpp @@ -1003,8 +1009,6 @@ PRIVATE platform/win/windows_app_user_model_id.h platform/win/windows_dlls.cpp platform/win/windows_dlls.h - platform/win/windows_event_filter.cpp - platform/win/windows_event_filter.h platform/win/windows_autostart_task.cpp platform/win/windows_autostart_task.h platform/win/windows_toast_activator.cpp @@ -1012,6 +1016,8 @@ PRIVATE platform/platform_audio.h platform/platform_file_utilities.h platform/platform_launcher.h + platform/platform_integration.cpp + platform/platform_integration.h platform/platform_main_window.h platform/platform_notifications_manager.h platform/platform_specific.h diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index b1e2278b9..7855d9c59 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/base_platform_last_input.h" #include "base/platform/base_platform_info.h" #include "platform/platform_specific.h" +#include "platform/platform_integration.h" #include "mainwindow.h" #include "dialogs/dialogs_entry.h" #include "history/history.h" @@ -130,6 +131,7 @@ Application::Application(not_null launcher) : QObject() , _launcher(launcher) , _private(std::make_unique()) +, _platformIntegration(Platform::Integration::Create()) , _databases(std::make_unique()) , _animationsManager(std::make_unique()) , _clearEmojiImageLoaderTimer([=] { clearEmojiSourceImages(); }) @@ -145,6 +147,8 @@ Application::Application(not_null launcher) , _autoLockTimer([=] { checkAutoLock(); }) { Ui::Integration::Set(&_private->uiIntegration); + _platformIntegration->init(); + passcodeLockChanges( ) | rpl::start_with_next([=] { _shouldLockAt = 0; diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index da8f1cf96..7dd72d81d 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -17,6 +17,10 @@ class MainWidget; class FileUploader; class Translator; +namespace Platform { +class Integration; +} // namespace Platform + namespace Storage { class Databases; } // namespace Storage @@ -115,8 +119,11 @@ public: Application &operator=(const Application &other) = delete; ~Application(); - [[nodiscard]] not_null launcher() const { - return _launcher; + [[nodiscard]] Launcher &launcher() const { + return *_launcher; + } + [[nodiscard]] Platform::Integration &platformIntegration() const { + return *_platformIntegration; } void run(); @@ -317,13 +324,13 @@ private: }; InstanceSetter _setter = { this }; - not_null _launcher; + const not_null _launcher; rpl::event_stream _proxyChanges; // Some fields are just moved from the declaration. struct Private; const std::unique_ptr _private; - Settings _settings; + const std::unique_ptr _platformIntegration; const std::unique_ptr _databases; const std::unique_ptr _animationsManager; diff --git a/Telegram/SourceFiles/platform/linux/integration_linux.cpp b/Telegram/SourceFiles/platform/linux/integration_linux.cpp new file mode 100644 index 000000000..bb58615cd --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/integration_linux.cpp @@ -0,0 +1,9 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "platform/linux/integration_linux.h" + diff --git a/Telegram/SourceFiles/platform/linux/integration_linux.h b/Telegram/SourceFiles/platform/linux/integration_linux.h new file mode 100644 index 000000000..73e006325 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/integration_linux.h @@ -0,0 +1,9 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + diff --git a/Telegram/SourceFiles/platform/mac/integration_mac.h b/Telegram/SourceFiles/platform/mac/integration_mac.h new file mode 100644 index 000000000..73e006325 --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/integration_mac.h @@ -0,0 +1,9 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + diff --git a/Telegram/SourceFiles/platform/mac/integration_mac.mm b/Telegram/SourceFiles/platform/mac/integration_mac.mm new file mode 100644 index 000000000..91d22ce7f --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/integration_mac.mm @@ -0,0 +1,9 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "platform/mac/integration_mac.h" + diff --git a/Telegram/SourceFiles/platform/platform_integration.cpp b/Telegram/SourceFiles/platform/platform_integration.cpp new file mode 100644 index 000000000..021024c6f --- /dev/null +++ b/Telegram/SourceFiles/platform/platform_integration.cpp @@ -0,0 +1,43 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "platform/platform_integration.h" + +#ifdef Q_OS_MAC +#include "platform/mac/integration_mac.h" +#elif defined Q_OS_UNIX // Q_OS_MAC +#include "platform/linux/integration_linux.h" +#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX +#include "platform/win/integration_win.h" +#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WINRT || Q_OS_WIN + +namespace Platform { +namespace { + +Integration *GlobalInstance/* = nullptr*/; + +} // namespace + +Integration::~Integration() { + GlobalInstance = nullptr; +} + +std::unique_ptr Integration::Create() { + Expects(GlobalInstance == nullptr); + + auto result = CreateIntegration(); + GlobalInstance = result.get(); + return result; +} + +Integration &Integration::Instance() { + Expects(GlobalInstance != nullptr); + + return *GlobalInstance; +}; + +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/platform_integration.h b/Telegram/SourceFiles/platform/platform_integration.h new file mode 100644 index 000000000..36ad0b7b7 --- /dev/null +++ b/Telegram/SourceFiles/platform/platform_integration.h @@ -0,0 +1,23 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Platform { + +class Integration { +public: + virtual void init() { + } + + virtual ~Integration(); + + [[nodiscard]] static std::unique_ptr Create(); + [[nodiscard]] static Integration &Instance(); +}; + +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/integration_win.cpp b/Telegram/SourceFiles/platform/win/integration_win.cpp new file mode 100644 index 000000000..0b0da418d --- /dev/null +++ b/Telegram/SourceFiles/platform/win/integration_win.cpp @@ -0,0 +1,99 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "platform/win/integration_win.h" + +#include "platform/platform_integration.h" +#include "platform/platform_specific.h" +#include "core/application.h" +#include "core/sandbox.h" +#include "app.h" + +#include +#include + +namespace Platform { +namespace { + +class WindowsIntegration final + : public Integration + , public QAbstractNativeEventFilter { +public: + void init() override; + +private: + bool nativeEventFilter( + const QByteArray &eventType, + void *message, + long *result) override; + bool processEvent( + HWND hWnd, + UINT msg, + WPARAM wParam, + LPARAM lParam, + LRESULT *result); + +}; + +void WindowsIntegration::init() { + QCoreApplication::instance()->installNativeEventFilter(this); +} + +bool WindowsIntegration::nativeEventFilter( + const QByteArray &eventType, + void *message, + long *result) { + return Core::Sandbox::Instance().customEnterFromEventLoop([&] { + const auto msg = static_cast(message); + return processEvent( + msg->hwnd, + msg->message, + msg->wParam, + msg->lParam, + (LRESULT*)result); + }); +} + +bool WindowsIntegration::processEvent( + HWND hWnd, + UINT msg, + WPARAM wParam, + LPARAM lParam, + LRESULT *result) { + switch (msg) { + case WM_ENDSESSION: + App::quit(); + break; + + case WM_TIMECHANGE: + Core::App().checkAutoLockIn(100); + break; + + case WM_WTSSESSION_CHANGE: + if (wParam == WTS_SESSION_LOGOFF + || wParam == WTS_SESSION_LOCK) { + Core::App().setScreenIsLocked(true); + } else if (wParam == WTS_SESSION_LOGON + || wParam == WTS_SESSION_UNLOCK) { + Core::App().setScreenIsLocked(false); + } + break; + + case WM_SETTINGCHANGE: + Core::App().settings().setSystemDarkMode(Platform::IsDarkMode()); + break; + } + return false; +} + +} // namespace + +std::unique_ptr CreateIntegration() { + return std::make_unique(); +} + +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/integration_win.h b/Telegram/SourceFiles/platform/win/integration_win.h new file mode 100644 index 000000000..11b203214 --- /dev/null +++ b/Telegram/SourceFiles/platform/win/integration_win.h @@ -0,0 +1,16 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Platform { + +class Integration; + +[[nodiscard]] std::unique_ptr CreateIntegration(); + +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index 7a0a9ebd4..ccd341333 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/platform_specific.h" #include "platform/platform_notifications_manager.h" #include "platform/win/windows_dlls.h" -#include "platform/win/windows_event_filter.h" #include "window/notifications_manager.h" #include "window/window_session_controller.h" #include "mainwindow.h" @@ -20,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/win/base_windows_wrl.h" #include "base/platform/base_platform_info.h" #include "core/application.h" +#include "core/sandbox.h" #include "lang/lang_keys.h" #include "storage/localstorage.h" #include "ui/widgets/popup_menu.h" @@ -58,8 +58,33 @@ namespace { // icon click (both left or right button) was made from the active app. constexpr auto kKeepActiveForTrayIcon = crl::time(500); +class EventFilter final : public QAbstractNativeEventFilter { +public: + explicit EventFilter(not_null window); + +private: + bool nativeEventFilter( + const QByteArray &eventType, + void *message, + long *result) override; + + bool mainWindowEvent( + HWND hWnd, + UINT msg, + WPARAM wParam, + LPARAM lParam, + LRESULT *result); + + const not_null _window; + +}; + using namespace Microsoft::WRL; +ComPtr taskbarList; +bool handleSessionNotification = false; +uint32 kTaskbarCreatedMsgId = 0; + [[nodiscard]] HICON NativeIcon(const QIcon &icon, QSize size) { if (!icon.isNull()) { const auto pixmap = icon.pixmap(icon.actualSize(size)); @@ -133,22 +158,88 @@ using namespace Microsoft::WRL; return result; } -ComPtr taskbarList; -bool handleSessionNotification = false; -uint32 kTaskbarCreatedMsgId = 0; +EventFilter::EventFilter(not_null window) : _window(window) { +} + +bool EventFilter::nativeEventFilter( + const QByteArray &eventType, + void *message, + long *result) { + return Core::Sandbox::Instance().customEnterFromEventLoop([&] { + const auto msg = static_cast(message); + if (msg->hwnd == _window->psHwnd() + || msg->hwnd && !_window->psHwnd()) { + return mainWindowEvent( + msg->hwnd, + msg->message, + msg->wParam, + msg->lParam, + (LRESULT*)result); + } + return false; + }); +} + +bool EventFilter::mainWindowEvent( + HWND hWnd, + UINT msg, + WPARAM wParam, + LPARAM lParam, + LRESULT *result) { + if (const auto tbCreatedMsgId = kTaskbarCreatedMsgId) { + if (msg == tbCreatedMsgId) { + HRESULT hr = CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&taskbarList)); + if (!SUCCEEDED(hr)) { + taskbarList.Reset(); + } + } + } + + switch (msg) { + + case WM_DESTROY: { + _window->destroyedFromSystem(); + } return false; + + case WM_ACTIVATE: { + if (LOWORD(wParam) != WA_INACTIVE) { + _window->shadowsActivate(); + } else { + _window->shadowsDeactivate(); + } + } return false; + + case WM_SIZE: { + if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED) { + if (wParam == SIZE_RESTORED && _window->windowState() == Qt::WindowNoState) { + _window->positionUpdated(); + } + } + } return false; + + case WM_MOVE: { + _window->positionUpdated(); + } return false; + + } + return false; +} } // namespace struct MainWindow::Private { + explicit Private(not_null window) : filter(window) { + } + + EventFilter filter; ComPtr viewSettings; }; MainWindow::MainWindow(not_null controller) : Window::MainWindow(controller) -, _private(std::make_unique()) +, _private(std::make_unique(this)) , _taskbarHiderWindow(std::make_unique()) { - QCoreApplication::instance()->installNativeEventFilter( - EventFilter::CreateInstance(this)); + qApp->installNativeEventFilter(&_private->filter); if (!kTaskbarCreatedMsgId) { kTaskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated"); @@ -178,17 +269,6 @@ void MainWindow::setupNativeWindowFrame() { }, lifetime()); } -uint32 MainWindow::TaskbarCreatedMsgId() { - return kTaskbarCreatedMsgId; -} - -void MainWindow::TaskbarCreated() { - HRESULT hr = CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&taskbarList)); - if (!SUCCEEDED(hr)) { - taskbarList.Reset(); - } -} - void MainWindow::shadowsActivate() { _hasActiveFrame = true; } @@ -201,6 +281,10 @@ void MainWindow::psShowTrayMenu() { trayIconMenu->popup(QCursor::pos()); } +void MainWindow::destroyedFromSystem() { + App::quit(); +} + int32 MainWindow::screenNameChecksum(const QString &name) const { constexpr int DeviceNameSize = base::array_size(MONITORINFOEX().szDevice); wchar_t buffer[DeviceNameSize] = { 0 }; @@ -212,7 +296,7 @@ int32 MainWindow::screenNameChecksum(const QString &name) const { return base::crc32(buffer, sizeof(buffer)); } -void MainWindow::psRefreshTaskbarIcon() { +void MainWindow::forceIconRefresh() { const auto refresher = std::make_unique(this); refresher->setWindowFlags(static_cast(Qt::Tool) | Qt::FramelessWindowHint); refresher->setGeometry(x() + 1, y() + 1, 1, 1); @@ -267,20 +351,20 @@ void MainWindow::workmodeUpdated(Core::Settings::WorkMode mode) { switch (mode) { case WorkMode::WindowAndTray: { psSetupTrayIcon(); - HWND psOwner = (HWND)GetWindowLongPtr(ps_hWnd, GWLP_HWNDPARENT); + HWND psOwner = (HWND)GetWindowLongPtr(_hWnd, GWLP_HWNDPARENT); if (psOwner) { - SetWindowLongPtr(ps_hWnd, GWLP_HWNDPARENT, 0); + SetWindowLongPtr(_hWnd, GWLP_HWNDPARENT, 0); windowHandle()->setTransientParent(nullptr); - psRefreshTaskbarIcon(); + forceIconRefresh(); } } break; case WorkMode::TrayOnly: { psSetupTrayIcon(); - HWND psOwner = (HWND)GetWindowLongPtr(ps_hWnd, GWLP_HWNDPARENT); + HWND psOwner = (HWND)GetWindowLongPtr(_hWnd, GWLP_HWNDPARENT); if (!psOwner) { const auto hwnd = _taskbarHiderWindow->winId(); - SetWindowLongPtr(ps_hWnd, GWLP_HWNDPARENT, (LONG_PTR)hwnd); + SetWindowLongPtr(_hWnd, GWLP_HWNDPARENT, (LONG_PTR)hwnd); windowHandle()->setTransientParent(_taskbarHiderWindow.get()); } } break; @@ -292,11 +376,11 @@ void MainWindow::workmodeUpdated(Core::Settings::WorkMode mode) { } trayIcon = 0; - HWND psOwner = (HWND)GetWindowLongPtr(ps_hWnd, GWLP_HWNDPARENT); + HWND psOwner = (HWND)GetWindowLongPtr(_hWnd, GWLP_HWNDPARENT); if (psOwner) { - SetWindowLongPtr(ps_hWnd, GWLP_HWNDPARENT, 0); + SetWindowLongPtr(_hWnd, GWLP_HWNDPARENT, 0); windowHandle()->setTransientParent(nullptr); - psRefreshTaskbarIcon(); + forceIconRefresh(); } } break; } @@ -403,11 +487,11 @@ void MainWindow::updateIconCounters() { trayIcon->setIcon(forTrayIcon); } - psDestroyIcons(); - ps_iconSmall = NativeIcon(iconSmall, iconSizeSmall); - ps_iconBig = NativeIcon(iconBig, iconSizeBig); - SendMessage(ps_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)ps_iconSmall); - SendMessage(ps_hWnd, WM_SETICON, ICON_BIG, (LPARAM)(ps_iconBig ? ps_iconBig : ps_iconSmall)); + destroyCachedIcons(); + _iconSmall = NativeIcon(iconSmall, iconSizeSmall); + _iconBig = NativeIcon(iconBig, iconSizeBig); + SendMessage(_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)_iconSmall); + SendMessage(_hWnd, WM_SETICON, ICON_BIG, (LPARAM)(_iconBig ? _iconBig : _iconSmall)); if (taskbarList) { if (counter > 0) { const auto pixmap = [&](int size) { @@ -417,27 +501,23 @@ void MainWindow::updateIconCounters() { QIcon iconOverlay; iconOverlay.addPixmap(pixmap(16)); iconOverlay.addPixmap(pixmap(32)); - ps_iconOverlay = NativeIcon(iconOverlay, iconSizeSmall); + _iconOverlay = NativeIcon(iconOverlay, iconSizeSmall); } const auto description = (counter > 0) ? tr::lng_unread_bar(tr::now, lt_count, counter).toStdWString() : std::wstring(); - taskbarList->SetOverlayIcon(ps_hWnd, ps_iconOverlay, description.c_str()); + taskbarList->SetOverlayIcon(_hWnd, _iconOverlay, description.c_str()); } - SetWindowPos(ps_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + SetWindowPos(_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } void MainWindow::initHook() { - ps_hWnd = reinterpret_cast(winId()); - if (!ps_hWnd) { + _hWnd = reinterpret_cast(winId()); + if (!_hWnd) { return; } - handleSessionNotification = (Dlls::WTSRegisterSessionNotification != nullptr) - && (Dlls::WTSUnRegisterSessionNotification != nullptr); - if (handleSessionNotification) { - Dlls::WTSRegisterSessionNotification(ps_hWnd, NOTIFY_FOR_THIS_SESSION); - } + WTSRegisterSessionNotification(_hWnd, NOTIFY_FOR_THIS_SESSION); using namespace base::Platform; auto factory = ComPtr(); @@ -449,7 +529,7 @@ void MainWindow::initHook() { if (factory) { // NB! No such method (or IUIViewSettingsInterop) in C++/WinRT :( factory->GetForWindow( - ps_hWnd, + _hWnd, IID_PPV_ARGS(&_private->viewSettings)); } } @@ -462,7 +542,7 @@ void MainWindow::initHook() { void MainWindow::validateWindowTheme(bool native, bool night) { if (!IsWindows8OrGreater()) { const auto empty = native ? nullptr : L" "; - SetWindowTheme(ps_hWnd, empty, empty); + SetWindowTheme(_hWnd, empty, empty); QApplication::setStyle(QStyleFactory::create(u"Windows"_q)); #if 0 } else if (!Platform::IsDarkModeSupported()/* @@ -473,7 +553,7 @@ void MainWindow::validateWindowTheme(bool native, bool night) { return; #endif } else if (!native) { - SetWindowTheme(ps_hWnd, nullptr, nullptr); + SetWindowTheme(_hWnd, nullptr, nullptr); return; } @@ -491,13 +571,13 @@ void MainWindow::validateWindowTheme(bool native, bool night) { &darkValue, sizeof(darkValue) }; - Dlls::SetWindowCompositionAttribute(ps_hWnd, &data); + Dlls::SetWindowCompositionAttribute(_hWnd, &data); } else if (kSystemVersion.microVersion() >= 17763) { static const auto kDWMWA_USE_IMMERSIVE_DARK_MODE = (kSystemVersion.microVersion() >= 18985) ? DWORD(20) : DWORD(19); DwmSetWindowAttribute( - ps_hWnd, + _hWnd, kDWMWA_USE_IMMERSIVE_DARK_MODE, &darkValue, sizeof(darkValue)); @@ -514,7 +594,7 @@ void MainWindow::validateWindowTheme(bool native, bool night) { //const auto updateWindowTheme = [&] { // const auto set = [&](LPCWSTR name) { - // return SetWindowTheme(ps_hWnd, name, nullptr); + // return SetWindowTheme(_hWnd, name, nullptr); // }; // if (!night || FAILED(set(L"DarkMode_Explorer"))) { // set(L"Explorer"); @@ -527,14 +607,14 @@ void MainWindow::validateWindowTheme(bool native, bool night) { // } else { // Dlls::AllowDarkModeForApp(TRUE); // } - // Dlls::AllowDarkModeForWindow(ps_hWnd, TRUE); + // Dlls::AllowDarkModeForWindow(_hWnd, TRUE); // updateWindowTheme(); // updateStyle(); // Dlls::FlushMenuThemes(); // Dlls::RefreshImmersiveColorPolicyState(); //} else { // updateWindowTheme(); - // Dlls::AllowDarkModeForWindow(ps_hWnd, FALSE); + // Dlls::AllowDarkModeForWindow(_hWnd, FALSE); // updateStyle(); // Dlls::FlushMenuThemes(); // Dlls::RefreshImmersiveColorPolicyState(); @@ -546,8 +626,8 @@ void MainWindow::validateWindowTheme(bool native, bool night) { //} // Didn't find any other way to definitely repaint with the new style. - SendMessage(ps_hWnd, WM_NCACTIVATE, _hasActiveFrame ? 0 : 1, 0); - SendMessage(ps_hWnd, WM_NCACTIVATE, _hasActiveFrame ? 1 : 0, 0); + SendMessage(_hWnd, WM_NCACTIVATE, _hasActiveFrame ? 0 : 1, 0); + SendMessage(_hWnd, WM_NCACTIVATE, _hasActiveFrame ? 1 : 0, 0); } void MainWindow::showFromTrayMenu() { @@ -562,36 +642,28 @@ void MainWindow::showFromTrayMenu() { } HWND MainWindow::psHwnd() const { - return ps_hWnd; + return _hWnd; } -void MainWindow::psDestroyIcons() { - if (ps_iconBig) { - DestroyIcon(ps_iconBig); - ps_iconBig = 0; - } - if (ps_iconSmall) { - DestroyIcon(ps_iconSmall); - ps_iconSmall = 0; - } - if (ps_iconOverlay) { - DestroyIcon(ps_iconOverlay); - ps_iconOverlay = 0; - } +void MainWindow::destroyCachedIcons() { + const auto destroy = [](HICON &icon) { + if (icon) { + DestroyIcon(icon); + icon = nullptr; + } + }; + destroy(_iconBig); + destroy(_iconSmall); + destroy(_iconOverlay); } MainWindow::~MainWindow() { - if (handleSessionNotification) { - Dlls::WTSUnRegisterSessionNotification(ps_hWnd); - } + WTSUnRegisterSessionNotification(_hWnd); _private->viewSettings.Reset(); if (taskbarList) { taskbarList.Reset(); } - - psDestroyIcons(); - - EventFilter::Destroy(); + destroyCachedIcons(); } } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index 02a6efd62..09a801524 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -28,11 +28,6 @@ public: void updateWindowIcon() override; bool isActiveForTrayMenu() override; - void psRefreshTaskbarIcon(); - - [[nodiscard]] static uint32 TaskbarCreatedMsgId(); - static void TaskbarCreated(); - // Custom shadows. void shadowsActivate(); void shadowsDeactivate(); @@ -41,6 +36,8 @@ public: void psShowTrayMenu(); + void destroyedFromSystem(); + ~MainWindow(); protected: @@ -72,22 +69,23 @@ private: void setupNativeWindowFrame(); void updateIconCounters(); void validateWindowTheme(bool native, bool night); - void psDestroyIcons(); + + void forceIconRefresh(); + void destroyCachedIcons(); const std::unique_ptr _private; + const std::unique_ptr _taskbarHiderWindow; - bool _hasActiveFrame = false; + HWND _hWnd = nullptr; + HICON _iconBig = nullptr; + HICON _iconSmall = nullptr; + HICON _iconOverlay = nullptr; // Workarounds for activation from tray icon. crl::time _lastDeactivateTime = 0; rpl::lifetime _showFromTrayLifetime; - HWND ps_hWnd = nullptr; - HICON ps_iconBig = nullptr; - HICON ps_iconSmall = nullptr; - HICON ps_iconOverlay = nullptr; - - const std::unique_ptr _taskbarHiderWindow; + bool _hasActiveFrame = false; }; diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index b761b06fa..eebe67cdf 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/qthelp_url.h" #include "platform/win/windows_app_user_model_id.h" #include "platform/win/windows_toast_activator.h" -#include "platform/win/windows_event_filter.h" #include "platform/win/windows_dlls.h" #include "platform/win/specific_win.h" #include "history/history.h" diff --git a/Telegram/SourceFiles/platform/win/windows_dlls.cpp b/Telegram/SourceFiles/platform/win/windows_dlls.cpp index 4d2e75309..f728fcce2 100644 --- a/Telegram/SourceFiles/platform/win/windows_dlls.cpp +++ b/Telegram/SourceFiles/platform/win/windows_dlls.cpp @@ -53,10 +53,6 @@ SafeIniter::SafeIniter() { // } //} - const auto LibWtsApi32 = LoadLibrary(L"wtsapi32.dll"); - LOAD_SYMBOL(LibWtsApi32, WTSRegisterSessionNotification); - LOAD_SYMBOL(LibWtsApi32, WTSUnRegisterSessionNotification); - const auto LibPropSys = LoadLibrary(L"propsys.dll"); LOAD_SYMBOL(LibPropSys, PSStringFromPropertyKey); diff --git a/Telegram/SourceFiles/platform/win/windows_dlls.h b/Telegram/SourceFiles/platform/win/windows_dlls.h index 4579c8ce9..b3695f269 100644 --- a/Telegram/SourceFiles/platform/win/windows_dlls.h +++ b/Telegram/SourceFiles/platform/win/windows_dlls.h @@ -68,14 +68,6 @@ inline void(__stdcall *SHChangeNotify)( inline HRESULT(__stdcall *SetCurrentProcessExplicitAppUserModelID)( __in PCWSTR AppID); -// WTSAPI32.DLL - -inline BOOL(__stdcall *WTSRegisterSessionNotification)( - HWND hWnd, - DWORD dwFlags); -inline BOOL(__stdcall *WTSUnRegisterSessionNotification)( - HWND hWnd); - // PROPSYS.DLL inline HRESULT(__stdcall *PSStringFromPropertyKey)( diff --git a/Telegram/SourceFiles/platform/win/windows_event_filter.cpp b/Telegram/SourceFiles/platform/win/windows_event_filter.cpp deleted file mode 100644 index 4d0127bbb..000000000 --- a/Telegram/SourceFiles/platform/win/windows_event_filter.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#include "platform/win/windows_event_filter.h" - -#include "platform/win/specific_win.h" -#include "core/sandbox.h" -#include "core/core_settings.h" -#include "core/application.h" -#include "mainwindow.h" -#include "app.h" - -#include - -namespace Platform { -namespace { - -EventFilter *instance = nullptr; - -} // namespace - -EventFilter *EventFilter::CreateInstance(not_null window) { - Expects(instance == nullptr); - - return (instance = new EventFilter(window)); -} - -void EventFilter::Destroy() { - Expects(instance != nullptr); - - delete instance; - instance = nullptr; -} - -EventFilter::EventFilter(not_null window) : _window(window) { -} - -bool EventFilter::nativeEventFilter( - const QByteArray &eventType, - void *message, - long *result) { - return Core::Sandbox::Instance().customEnterFromEventLoop([&] { - const auto msg = static_cast(message); - if (msg->message == WM_ENDSESSION) { - App::quit(); - return false; - } - if (msg->hwnd == _window->psHwnd() - || msg->hwnd && !_window->psHwnd()) { - return mainWindowEvent( - msg->hwnd, - msg->message, - msg->wParam, - msg->lParam, - (LRESULT*)result); - } - return false; - }); -} - -bool EventFilter::mainWindowEvent( - HWND hWnd, - UINT msg, - WPARAM wParam, - LPARAM lParam, - LRESULT *result) { - if (const auto tbCreatedMsgId = Platform::MainWindow::TaskbarCreatedMsgId()) { - if (msg == tbCreatedMsgId) { - Platform::MainWindow::TaskbarCreated(); - } - } - - switch (msg) { - - case WM_TIMECHANGE: { - Core::App().checkAutoLockIn(100); - } return false; - - case WM_WTSSESSION_CHANGE: { - if (wParam == WTS_SESSION_LOGOFF || wParam == WTS_SESSION_LOCK) { - Core::App().setScreenIsLocked(true); - } else if (wParam == WTS_SESSION_LOGON || wParam == WTS_SESSION_UNLOCK) { - Core::App().setScreenIsLocked(false); - } - } return false; - - case WM_DESTROY: { - App::quit(); - } return false; - - case WM_ACTIVATE: { - if (LOWORD(wParam) != WA_INACTIVE) { - _window->shadowsActivate(); - } else { - _window->shadowsDeactivate(); - } - } return false; - - case WM_SIZE: { - if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED) { - if (wParam == SIZE_RESTORED && _window->windowState() == Qt::WindowNoState) { - _window->positionUpdated(); - } - } - } return false; - - case WM_MOVE: { - _window->positionUpdated(); - } return false; - - case WM_SETTINGCHANGE: { - Core::App().settings().setSystemDarkMode(Platform::IsDarkMode()); - } return false; - - } - return false; -} - -} // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/windows_event_filter.h b/Telegram/SourceFiles/platform/win/windows_event_filter.h deleted file mode 100644 index c313f29cf..000000000 --- a/Telegram/SourceFiles/platform/win/windows_event_filter.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#pragma once - -#include "base/platform/win/base_windows_h.h" - -#include - -namespace Platform { - -class MainWindow; - -class EventFilter : public QAbstractNativeEventFilter { -public: - bool nativeEventFilter(const QByteArray &eventType, void *message, long *result); - bool mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result); - - static EventFilter *CreateInstance(not_null window); - static void Destroy(); - -private: - explicit EventFilter(not_null window); - - not_null _window; - -}; - -} // namespace Platform diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 73c49355b..25b0f0850 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -340,6 +340,14 @@ Main::Account &MainWindow::account() const { return _controller->account(); } +PeerData *MainWindow::singlePeer() const { + return _controller->singlePeer(); +} + +bool MainWindow::isPrimary() const { + return _controller->isPrimary(); +} + Window::SessionController *MainWindow::sessionController() const { return _controller->sessionController(); } diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index 99c30d392..50b73d4ee 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -62,6 +62,8 @@ public: [[nodiscard]] Window::Controller &controller() const { return *_controller; } + [[nodiscard]] PeerData *singlePeer() const; + [[nodiscard]] bool isPrimary() const; [[nodiscard]] Main::Account &account() const; [[nodiscard]] Window::SessionController *sessionController() const; diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index f69b3ac7e..921e17958 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -63,7 +63,7 @@ Controller::~Controller() { } void Controller::showAccount(not_null account) { - Expects(!_singlePeer || &_singlePeer->account() == account); + Expects(isPrimary() || &_singlePeer->account() == account); const auto prevSessionUniqueId = (_account && _account->sessionExists()) ? _account->session().uniqueId() diff --git a/Telegram/SourceFiles/window/window_controller.h b/Telegram/SourceFiles/window/window_controller.h index ce83903bc..f6b8b8b60 100644 --- a/Telegram/SourceFiles/window/window_controller.h +++ b/Telegram/SourceFiles/window/window_controller.h @@ -32,6 +32,9 @@ public: void showAccount(not_null account); [[nodiscard]] PeerData *singlePeer() const; + [[nodiscard]] bool isPrimary() const { + return (singlePeer() == nullptr); + } [[nodiscard]] not_null<::MainWindow*> widget() { return &_widget;