| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /*
- 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 "base/platform/win/base_windows_winrt.h"
- #include "core/application.h"
- #include "core/core_settings.h"
- #include "core/sandbox.h"
- #include "lang/lang_keys.h"
- #include "platform/win/windows_app_user_model_id.h"
- #include "platform/win/tray_win.h"
- #include "platform/platform_integration.h"
- #include "platform/platform_specific.h"
- #include "tray.h"
- #include "styles/style_window.h"
- #include <QtCore/QAbstractNativeEventFilter>
- #include <private/qguiapplication_p.h>
- #include <propvarutil.h>
- #include <propkey.h>
- namespace Platform {
- void WindowsIntegration::init() {
- #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
- using namespace QNativeInterface::Private;
- const auto native = qApp->nativeInterface<QWindowsApplication>();
- if (native) {
- native->setHasBorderInFullScreenDefault(true);
- }
- #endif // Qt >= 6.5.0
- QCoreApplication::instance()->installNativeEventFilter(this);
- _taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated");
- }
- ITaskbarList3 *WindowsIntegration::taskbarList() const {
- return _taskbarList.get();
- }
- WindowsIntegration &WindowsIntegration::Instance() {
- return static_cast<WindowsIntegration&>(Integration::Instance());
- }
- bool WindowsIntegration::nativeEventFilter(
- const QByteArray &eventType,
- void *message,
- native_event_filter_result *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);
- });
- }
- void WindowsIntegration::createCustomJumpList() {
- _jumpList = base::WinRT::TryCreateInstance<ICustomDestinationList>(
- CLSID_DestinationList);
- if (_jumpList) {
- refreshCustomJumpList();
- }
- }
- void WindowsIntegration::refreshCustomJumpList() {
- auto added = false;
- auto maxSlots = UINT();
- auto removed = (IObjectArray*)nullptr;
- auto hr = _jumpList->BeginList(&maxSlots, IID_PPV_ARGS(&removed));
- if (!SUCCEEDED(hr)) {
- return;
- }
- const auto guard = gsl::finally([&] {
- if (added) {
- _jumpList->CommitList();
- } else {
- _jumpList->AbortList();
- }
- });
- auto shellLink = base::WinRT::TryCreateInstance<IShellLink>(
- CLSID_ShellLink);
- if (!shellLink) {
- return;
- }
- // Set the path to your application and the command-line argument for quitting
- const auto exe = QDir::toNativeSeparators(cExeDir() + cExeName());
- const auto dir = QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath());
- const auto icon = Tray::QuitJumpListIconPath();
- shellLink->SetArguments(L"-quit");
- shellLink->SetPath(exe.toStdWString().c_str());
- shellLink->SetWorkingDirectory(dir.toStdWString().c_str());
- shellLink->SetIconLocation(icon.toStdWString().c_str(), 0);
- if (const auto propertyStore = shellLink.try_as<IPropertyStore>()) {
- auto appIdPropVar = PROPVARIANT();
- hr = InitPropVariantFromString(
- AppUserModelId::Id().c_str(),
- &appIdPropVar);
- if (SUCCEEDED(hr)) {
- hr = propertyStore->SetValue(
- AppUserModelId::Key(),
- appIdPropVar);
- PropVariantClear(&appIdPropVar);
- }
- auto titlePropVar = PROPVARIANT();
- hr = InitPropVariantFromString(
- tr::lng_quit_from_tray(tr::now).toStdWString().c_str(),
- &titlePropVar);
- if (SUCCEEDED(hr)) {
- hr = propertyStore->SetValue(PKEY_Title, titlePropVar);
- PropVariantClear(&titlePropVar);
- }
- propertyStore->Commit();
- }
- auto collection = base::WinRT::TryCreateInstance<IObjectCollection>(
- CLSID_EnumerableObjectCollection);
- if (!collection) {
- return;
- }
- collection->AddObject(shellLink.get());
- _jumpList->AddUserTasks(collection.get());
- added = true;
- }
- bool WindowsIntegration::processEvent(
- HWND hWnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam,
- LRESULT *result) {
- if (msg && msg == _taskbarCreatedMsgId && !_taskbarList) {
- _taskbarList = base::WinRT::TryCreateInstance<ITaskbarList3>(
- CLSID_TaskbarList,
- CLSCTX_ALL);
- if (_taskbarList) {
- createCustomJumpList();
- }
- }
- switch (msg) {
- case WM_ENDSESSION:
- Core::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:
- RefreshTaskbarThemeValue();
- #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
- Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
- #endif // Qt < 6.5.0
- Core::App().tray().updateIconCounters();
- if (_jumpList) {
- refreshCustomJumpList();
- }
- break;
- }
- return false;
- }
- std::unique_ptr<Integration> CreateIntegration() {
- return std::make_unique<WindowsIntegration>();
- }
- } // namespace Platform
|