mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Query Focus Assist state on Windows.
This commit is contained in:
parent
3a28be1e16
commit
2730ab1596
5 changed files with 233 additions and 26 deletions
Telegram
|
@ -37,6 +37,11 @@ include(cmake/td_scheme.cmake)
|
|||
include(cmake/td_ui.cmake)
|
||||
include(cmake/generate_appdata_changelog.cmake)
|
||||
|
||||
if (WIN32)
|
||||
include(cmake/generate_midl.cmake)
|
||||
generate_midl(Telegram ${src_loc}/platform/win/windows_quiethours.idl)
|
||||
endif()
|
||||
|
||||
set_target_properties(Telegram PROPERTIES AUTOMOC ON AUTORCC ON)
|
||||
|
||||
target_link_libraries(Telegram
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/core_settings.h"
|
||||
#include "main/main_session.h"
|
||||
#include "mainwindow.h"
|
||||
#include "windows_quiethours_h.h"
|
||||
|
||||
#include <Shobjidl.h>
|
||||
#include <shellapi.h>
|
||||
|
@ -632,27 +633,30 @@ namespace {
|
|||
bool QuietHoursEnabled = false;
|
||||
DWORD QuietHoursValue = 0;
|
||||
|
||||
bool useQuietHoursRegistryEntry() {
|
||||
// Taken from QSysInfo.
|
||||
OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0,{ '\0' } };
|
||||
if (const auto library = GetModuleHandle(L"ntdll.dll")) {
|
||||
using RtlGetVersionFunction = NTSTATUS(NTAPI*)(LPOSVERSIONINFO);
|
||||
const auto RtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
|
||||
GetProcAddress(library, "RtlGetVersion"));
|
||||
if (RtlGetVersion) {
|
||||
RtlGetVersion(&result);
|
||||
[[nodiscard]] bool UseQuietHoursRegistryEntry() {
|
||||
static const bool result = [] {
|
||||
// Taken from QSysInfo.
|
||||
OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0,{ '\0' } };
|
||||
if (const auto library = GetModuleHandle(L"ntdll.dll")) {
|
||||
using RtlGetVersionFunction = NTSTATUS(NTAPI*)(LPOSVERSIONINFO);
|
||||
const auto RtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
|
||||
GetProcAddress(library, "RtlGetVersion"));
|
||||
if (RtlGetVersion) {
|
||||
RtlGetVersion(&result);
|
||||
}
|
||||
}
|
||||
}
|
||||
// At build 17134 (Redstone 4) the "Quiet hours" was replaced
|
||||
// by "Focus assist" and it looks like it doesn't use registry.
|
||||
return (result.dwMajorVersion == 10
|
||||
&& result.dwMinorVersion == 0
|
||||
&& result.dwBuildNumber < 17134);
|
||||
// At build 17134 (Redstone 4) the "Quiet hours" was replaced
|
||||
// by "Focus assist" and it looks like it doesn't use registry.
|
||||
return (result.dwMajorVersion == 10
|
||||
&& result.dwMinorVersion == 0
|
||||
&& result.dwBuildNumber < 17134);
|
||||
}();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Thanks https://stackoverflow.com/questions/35600128/get-windows-quiet-hours-from-win32-or-c-sharp-api
|
||||
void queryQuietHours() {
|
||||
if (!useQuietHoursRegistryEntry()) {
|
||||
void QueryQuietHours() {
|
||||
if (!UseQuietHoursRegistryEntry()) {
|
||||
// There are quiet hours in Windows starting from Windows 8.1
|
||||
// But there were several reports about the notifications being shut
|
||||
// down according to the registry while no quiet hours were enabled.
|
||||
|
@ -683,9 +687,82 @@ void queryQuietHours() {
|
|||
}
|
||||
}
|
||||
|
||||
bool FocusAssistBlocks = false;
|
||||
|
||||
void QueryFocusAssist() {
|
||||
ComPtr<IQuietHoursSettings> quietHoursSettings;
|
||||
auto hr = CoCreateInstance(
|
||||
CLSID_QuietHoursSettings,
|
||||
nullptr,
|
||||
CLSCTX_LOCAL_SERVER,
|
||||
IID_PPV_ARGS(&quietHoursSettings));
|
||||
if (!SUCCEEDED(hr) || !quietHoursSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto profileId = LPWSTR{};
|
||||
const auto guardProfileId = gsl::finally([&] {
|
||||
if (profileId) CoTaskMemFree(profileId);
|
||||
});
|
||||
hr = quietHoursSettings->get_UserSelectedProfile(&profileId);
|
||||
if (!SUCCEEDED(hr) || !profileId) {
|
||||
return;
|
||||
}
|
||||
const auto profileName = QString::fromWCharArray(profileId);
|
||||
if (profileName.endsWith(".unrestricted", Qt::CaseInsensitive)) {
|
||||
if (FocusAssistBlocks) {
|
||||
LOG(("Focus Assist: Unrestricted."));
|
||||
FocusAssistBlocks = false;
|
||||
}
|
||||
return;
|
||||
} else if (profileName.endsWith(".alarmsonly", Qt::CaseInsensitive)) {
|
||||
if (!FocusAssistBlocks) {
|
||||
LOG(("Focus Assist: Alarms Only."));
|
||||
FocusAssistBlocks = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto appUserModelId = std::wstring(AppUserModelId::getId());
|
||||
auto blocked = true;
|
||||
const auto guard = gsl::finally([&] {
|
||||
if (FocusAssistBlocks != blocked) {
|
||||
LOG(("Focus Assist: %1, AppUserModelId: %2, Blocks: %3"
|
||||
).arg(profileName
|
||||
).arg(QString::fromStdWString(appUserModelId)
|
||||
).arg(Logs::b(blocked)));
|
||||
FocusAssistBlocks = blocked;
|
||||
}
|
||||
});
|
||||
|
||||
ComPtr<IQuietHoursProfile> profile;
|
||||
hr = quietHoursSettings->GetProfile(profileId, &profile);
|
||||
if (!SUCCEEDED(hr) || !profile) {
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 count = 0;
|
||||
auto apps = (LPWSTR*)nullptr;
|
||||
const auto guardApps = gsl::finally([&] {
|
||||
if (apps) CoTaskMemFree(apps);
|
||||
});
|
||||
hr = profile->GetAllowedApps(&count, &apps);
|
||||
if (!SUCCEEDED(hr) || !apps) {
|
||||
return;
|
||||
}
|
||||
for (UINT32 i = 0; i < count; i++) {
|
||||
auto app = apps[i];
|
||||
const auto guardApp = gsl::finally([&] {
|
||||
if (app) CoTaskMemFree(app);
|
||||
});
|
||||
if (app == appUserModelId) {
|
||||
blocked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QUERY_USER_NOTIFICATION_STATE UserNotificationState = QUNS_ACCEPTS_NOTIFICATIONS;
|
||||
|
||||
void queryUserNotificationState() {
|
||||
void QueryUserNotificationState() {
|
||||
if (Dlls::SHQueryUserNotificationState != nullptr) {
|
||||
QUERY_USER_NOTIFICATION_STATE state;
|
||||
if (SUCCEEDED(Dlls::SHQueryUserNotificationState(&state))) {
|
||||
|
@ -697,24 +774,26 @@ void queryUserNotificationState() {
|
|||
static constexpr auto kQuerySettingsEachMs = 1000;
|
||||
crl::time LastSettingsQueryMs = 0;
|
||||
|
||||
void querySystemNotificationSettings() {
|
||||
void QuerySystemNotificationSettings() {
|
||||
auto ms = crl::now();
|
||||
if (LastSettingsQueryMs > 0 && ms <= LastSettingsQueryMs + kQuerySettingsEachMs) {
|
||||
return;
|
||||
}
|
||||
LastSettingsQueryMs = ms;
|
||||
queryQuietHours();
|
||||
queryUserNotificationState();
|
||||
QueryQuietHours();
|
||||
QueryFocusAssist();
|
||||
QueryUserNotificationState();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool SkipAudio() {
|
||||
querySystemNotificationSettings();
|
||||
QuerySystemNotificationSettings();
|
||||
|
||||
if (UserNotificationState == QUNS_NOT_PRESENT
|
||||
|| UserNotificationState == QUNS_PRESENTATION_MODE
|
||||
|| QuietHoursEnabled) {
|
||||
|| QuietHoursEnabled
|
||||
|| FocusAssistBlocks) {
|
||||
return true;
|
||||
}
|
||||
if (const auto filter = EventFilter::GetInstance()) {
|
||||
|
@ -726,12 +805,13 @@ bool SkipAudio() {
|
|||
}
|
||||
|
||||
bool SkipToast() {
|
||||
querySystemNotificationSettings();
|
||||
QuerySystemNotificationSettings();
|
||||
|
||||
if (UserNotificationState == QUNS_PRESENTATION_MODE
|
||||
|| UserNotificationState == QUNS_RUNNING_D3D_FULL_SCREEN
|
||||
//|| UserNotificationState == QUNS_BUSY
|
||||
|| QuietHoursEnabled) {
|
||||
|| QuietHoursEnabled
|
||||
|| FocusAssistBlocks) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
79
Telegram/SourceFiles/platform/win/windows_quiethours.idl
Normal file
79
Telegram/SourceFiles/platform/win/windows_quiethours.idl
Normal file
|
@ -0,0 +1,79 @@
|
|||
// © Rafael Rivera
|
||||
// License: MIT
|
||||
|
||||
import "oaidl.idl";
|
||||
|
||||
[uuid(e0b5ef8b-a9b4-497a-8f71-08dd5c8ab2bf)]
|
||||
library QuietHours
|
||||
{
|
||||
[uuid(f53321fa-34f8-4b7f-b9a3-361877cb94cf)]
|
||||
coclass QuietHoursSettings
|
||||
{
|
||||
[default] interface IQuietHoursSettings;
|
||||
}
|
||||
|
||||
[uuid(af86e2e0-b12d-4c6a-9c5a-d7aa65101e90)]
|
||||
interface IQuietMoment : IUnknown
|
||||
{
|
||||
// Incomplete
|
||||
}
|
||||
|
||||
[uuid(e813fe81-62b6-417d-b951-9d2e08486ac1)]
|
||||
interface IQuietHoursProfile : IUnknown
|
||||
{
|
||||
[propget] HRESULT DisplayName([out, string, retval] LPWSTR* displayName);
|
||||
[propget] HRESULT ProfileId([out, string, retval] LPWSTR* profileId);
|
||||
HRESULT GetSetting(int setting, [out, retval] int* value);
|
||||
HRESULT PutSetting(int setting, int value);
|
||||
[propget] HRESULT IsCustomizable([out, retval] BOOL* result);
|
||||
HRESULT GetAllowedContacts([out] UINT32* count, [out, retval] LPWSTR* allowedContacts);
|
||||
HRESULT AddAllowedContact([in, string] LPWSTR allowedContact);
|
||||
HRESULT RemoveAllowedContact([in, string] LPWSTR allowedContact);
|
||||
HRESULT GetAllowedApps([out] UINT32* count, [out, retval] LPWSTR** allowedApps);
|
||||
HRESULT AddAllowedApp([in, string] LPWSTR allowedApp);
|
||||
HRESULT RemoveAllowedApp([in, string] LPWSTR allowedApp);
|
||||
[propget] HRESULT Description([out, string, retval] LPWSTR* description);
|
||||
[propget] HRESULT CustomizeLinkText([out, string, retval] LPWSTR* linkText);
|
||||
[propget] HRESULT RestrictiveLevel([out, string, retval] LPWSTR* restrictiveLevel);
|
||||
}
|
||||
|
||||
[uuid(cd86a976-8ea9-404b-a197-42e73dbaa901)]
|
||||
interface IQuietHoursPinnedContactManager : IUnknown
|
||||
{
|
||||
HRESULT GetPinnedContactList([out] UINT32* count, [out, string, retval] LPWSTR* pinnedContacts);
|
||||
}
|
||||
|
||||
[uuid(b0217783-87b7-422c-b902-5c148c14f150)]
|
||||
interface IQuietMomentsManager : IUnknown
|
||||
{
|
||||
HRESULT GetAllQuietMomentModes([out] UINT32* count, [out, retval] UINT32** quietMomentModes);
|
||||
HRESULT GetQuietMoment([in] UINT32 quietMomentId, [out, retval] IQuietMoment** quietMoment);
|
||||
HRESULT TurnOffCurrentlyActiveQuietMoment();
|
||||
HRESULT GetActiveQuietMoment([out, retval] UINT32* quietMomentId);
|
||||
}
|
||||
|
||||
typedef struct _QH_PROFILE_DATA
|
||||
{
|
||||
char do_not_use__incomplete; // Incomplete
|
||||
} QH_PROFILE_DATA;
|
||||
|
||||
[uuid(6bff4732-81ec-4ffb-ae67-b6c1bc29631f)]
|
||||
interface IQuietHoursSettings : IUnknown
|
||||
{
|
||||
[propget] HRESULT UserSelectedProfile([out, string, retval] LPWSTR* profileId);
|
||||
[propput] HRESULT UserSelectedProfile([in] LPWSTR profileId);
|
||||
HRESULT GetProfile([in, string] LPWSTR profileId, [out, retval] IQuietHoursProfile**);
|
||||
HRESULT GetAllProfileData(UINT32* count, QH_PROFILE_DATA*);
|
||||
HRESULT GetDisplayNameForProfile([in, string] LPWSTR profileId, [out, string, retval] LPWSTR* displayName);
|
||||
[propget] HRESULT QuietMomentsManager([out, retval] IQuietMomentsManager**);
|
||||
[propget] HRESULT OffProfileId([out, string, retval] LPWSTR* profileId);
|
||||
[propget] HRESULT ActiveQuietMomentProfile([out, string, retval] LPWSTR* profileId);
|
||||
[propput] HRESULT ActiveQuietMomentProfile([in] LPWSTR profileId);
|
||||
[propget] HRESULT ActiveProfile([out, string, retval] LPWSTR* profileId);
|
||||
[propget] HRESULT QuietHoursPinnedContactManager([out, retval] IQuietHoursPinnedContactManager**);
|
||||
[propput] HRESULT QuietMomentsShowSummaryEnabled([out, retval] BOOL* isEnabled);
|
||||
HRESULT GetAlwaysAllowedApps([out] UINT32* count, [out, string, retval] LPWSTR** allowedApps);
|
||||
HRESULT StartProcessing();
|
||||
HRESULT StopProcessing();
|
||||
}
|
||||
}
|
43
Telegram/cmake/generate_midl.cmake
Normal file
43
Telegram/cmake/generate_midl.cmake
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
|
||||
|
||||
function(generate_midl target_name idl_file)
|
||||
set(gen_dst ${CMAKE_CURRENT_BINARY_DIR}/gen)
|
||||
file(MAKE_DIRECTORY ${gen_dst})
|
||||
|
||||
get_filename_component(idl_file_name ${idl_file} NAME_WLE)
|
||||
|
||||
set(gen_timestamp ${gen_dst}/midl_${idl_file_name}.timestamp)
|
||||
set(gen_files
|
||||
${gen_dst}/${idl_file_name}_i.c
|
||||
${gen_dst}/${idl_file_name}_h.h
|
||||
)
|
||||
|
||||
if (build_win64)
|
||||
set(env x64)
|
||||
else()
|
||||
set(env win32)
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${gen_timestamp}
|
||||
BYPRODUCTS
|
||||
${gen_files}
|
||||
COMMAND
|
||||
midl
|
||||
/out ${gen_dst}
|
||||
/h ${idl_file_name}_h.h
|
||||
/env ${env}
|
||||
/notlb
|
||||
${idl_file}
|
||||
COMMAND
|
||||
echo 1> ${gen_timestamp}
|
||||
COMMENT "Generating header from IDL (${target_name})"
|
||||
DEPENDS
|
||||
${idl_file}
|
||||
)
|
||||
generate_target(${target_name} midl ${gen_timestamp} "${gen_files}" ${gen_dst})
|
||||
endfunction()
|
|
@ -1 +1 @@
|
|||
Subproject commit 053ab218dfb65e9cbd7c7a1d9594fa886ba27f0b
|
||||
Subproject commit 3d256df61ebf4b92b79bf9eba39a33f7a885b1d3
|
Loading…
Add table
Reference in a new issue