init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
This commit is contained in:
189
Telegram/SourceFiles/platform/win/integration_win.cpp
Normal file
189
Telegram/SourceFiles/platform/win/integration_win.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
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
|
||||
Reference in New Issue
Block a user