mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Move global event filter to Platform::Integration on Windows.
This commit is contained in:
parent
20411be9bd
commit
8b0725650d
22 changed files with 410 additions and 262 deletions
|
@ -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
|
||||
|
|
|
@ -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*> launcher)
|
|||
: QObject()
|
||||
, _launcher(launcher)
|
||||
, _private(std::make_unique<Private>())
|
||||
, _platformIntegration(Platform::Integration::Create())
|
||||
, _databases(std::make_unique<Storage::Databases>())
|
||||
, _animationsManager(std::make_unique<Ui::Animations::Manager>())
|
||||
, _clearEmojiImageLoaderTimer([=] { clearEmojiSourceImages(); })
|
||||
|
@ -145,6 +147,8 @@ Application::Application(not_null<Launcher*> launcher)
|
|||
, _autoLockTimer([=] { checkAutoLock(); }) {
|
||||
Ui::Integration::Set(&_private->uiIntegration);
|
||||
|
||||
_platformIntegration->init();
|
||||
|
||||
passcodeLockChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
_shouldLockAt = 0;
|
||||
|
|
|
@ -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*> 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*> _launcher;
|
||||
const not_null<Launcher*> _launcher;
|
||||
rpl::event_stream<ProxyChange> _proxyChanges;
|
||||
|
||||
// Some fields are just moved from the declaration.
|
||||
struct Private;
|
||||
const std::unique_ptr<Private> _private;
|
||||
Settings _settings;
|
||||
const std::unique_ptr<Platform::Integration> _platformIntegration;
|
||||
|
||||
const std::unique_ptr<Storage::Databases> _databases;
|
||||
const std::unique_ptr<Ui::Animations::Manager> _animationsManager;
|
||||
|
|
|
@ -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"
|
||||
|
9
Telegram/SourceFiles/platform/linux/integration_linux.h
Normal file
9
Telegram/SourceFiles/platform/linux/integration_linux.h
Normal file
|
@ -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
|
||||
|
9
Telegram/SourceFiles/platform/mac/integration_mac.h
Normal file
9
Telegram/SourceFiles/platform/mac/integration_mac.h
Normal file
|
@ -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
|
||||
|
9
Telegram/SourceFiles/platform/mac/integration_mac.mm
Normal file
9
Telegram/SourceFiles/platform/mac/integration_mac.mm
Normal file
|
@ -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"
|
||||
|
43
Telegram/SourceFiles/platform/platform_integration.cpp
Normal file
43
Telegram/SourceFiles/platform/platform_integration.cpp
Normal file
|
@ -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> Integration::Create() {
|
||||
Expects(GlobalInstance == nullptr);
|
||||
|
||||
auto result = CreateIntegration();
|
||||
GlobalInstance = result.get();
|
||||
return result;
|
||||
}
|
||||
|
||||
Integration &Integration::Instance() {
|
||||
Expects(GlobalInstance != nullptr);
|
||||
|
||||
return *GlobalInstance;
|
||||
};
|
||||
|
||||
} // namespace Platform
|
23
Telegram/SourceFiles/platform/platform_integration.h
Normal file
23
Telegram/SourceFiles/platform/platform_integration.h
Normal file
|
@ -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<Integration> Create();
|
||||
[[nodiscard]] static Integration &Instance();
|
||||
};
|
||||
|
||||
} // namespace Platform
|
99
Telegram/SourceFiles/platform/win/integration_win.cpp
Normal file
99
Telegram/SourceFiles/platform/win/integration_win.cpp
Normal file
|
@ -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 <QtCore/QCoreApplication>
|
||||
#include <QtCore/QAbstractNativeEventFilter>
|
||||
|
||||
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<MSG*>(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<Integration> CreateIntegration() {
|
||||
return std::make_unique<WindowsIntegration>();
|
||||
}
|
||||
|
||||
} // namespace Platform
|
16
Telegram/SourceFiles/platform/win/integration_win.h
Normal file
16
Telegram/SourceFiles/platform/win/integration_win.h
Normal file
|
@ -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<Integration> CreateIntegration();
|
||||
|
||||
} // namespace Platform
|
|
@ -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<MainWindow*> 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<MainWindow*> _window;
|
||||
|
||||
};
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
ComPtr<ITaskbarList3> 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<ITaskbarList3> taskbarList;
|
||||
bool handleSessionNotification = false;
|
||||
uint32 kTaskbarCreatedMsgId = 0;
|
||||
EventFilter::EventFilter(not_null<MainWindow*> window) : _window(window) {
|
||||
}
|
||||
|
||||
bool EventFilter::nativeEventFilter(
|
||||
const QByteArray &eventType,
|
||||
void *message,
|
||||
long *result) {
|
||||
return Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
const auto msg = static_cast<MSG*>(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<MainWindow*> window) : filter(window) {
|
||||
}
|
||||
|
||||
EventFilter filter;
|
||||
ComPtr<ViewManagement::IUIViewSettings> viewSettings;
|
||||
};
|
||||
|
||||
MainWindow::MainWindow(not_null<Window::Controller*> controller)
|
||||
: Window::MainWindow(controller)
|
||||
, _private(std::make_unique<Private>())
|
||||
, _private(std::make_unique<Private>(this))
|
||||
, _taskbarHiderWindow(std::make_unique<QWindow>()) {
|
||||
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<QWidget>(this);
|
||||
refresher->setWindowFlags(static_cast<Qt::WindowFlags>(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<HWND>(winId());
|
||||
if (!ps_hWnd) {
|
||||
_hWnd = reinterpret_cast<HWND>(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<IUIViewSettingsInterop>();
|
||||
|
@ -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
|
||||
|
|
|
@ -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> _private;
|
||||
const std::unique_ptr<QWindow> _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<QWindow> _taskbarHiderWindow;
|
||||
bool _hasActiveFrame = false;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)(
|
||||
|
|
|
@ -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 <QtGui/QWindow>
|
||||
|
||||
namespace Platform {
|
||||
namespace {
|
||||
|
||||
EventFilter *instance = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
EventFilter *EventFilter::CreateInstance(not_null<MainWindow*> window) {
|
||||
Expects(instance == nullptr);
|
||||
|
||||
return (instance = new EventFilter(window));
|
||||
}
|
||||
|
||||
void EventFilter::Destroy() {
|
||||
Expects(instance != nullptr);
|
||||
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
EventFilter::EventFilter(not_null<MainWindow*> window) : _window(window) {
|
||||
}
|
||||
|
||||
bool EventFilter::nativeEventFilter(
|
||||
const QByteArray &eventType,
|
||||
void *message,
|
||||
long *result) {
|
||||
return Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
const auto msg = static_cast<MSG*>(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
|
|
@ -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 <QtCore/QAbstractNativeEventFilter>
|
||||
|
||||
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<MainWindow*> window);
|
||||
static void Destroy();
|
||||
|
||||
private:
|
||||
explicit EventFilter(not_null<MainWindow*> window);
|
||||
|
||||
not_null<MainWindow*> _window;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Platform
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ Controller::~Controller() {
|
|||
}
|
||||
|
||||
void Controller::showAccount(not_null<Main::Account*> account) {
|
||||
Expects(!_singlePeer || &_singlePeer->account() == account);
|
||||
Expects(isPrimary() || &_singlePeer->account() == account);
|
||||
|
||||
const auto prevSessionUniqueId = (_account && _account->sessionExists())
|
||||
? _account->session().uniqueId()
|
||||
|
|
|
@ -32,6 +32,9 @@ public:
|
|||
|
||||
void showAccount(not_null<Main::Account*> account);
|
||||
[[nodiscard]] PeerData *singlePeer() const;
|
||||
[[nodiscard]] bool isPrimary() const {
|
||||
return (singlePeer() == nullptr);
|
||||
}
|
||||
|
||||
[[nodiscard]] not_null<::MainWindow*> widget() {
|
||||
return &_widget;
|
||||
|
|
Loading…
Add table
Reference in a new issue