fix: process more shortcuts

This commit is contained in:
AlexeyZavar 2025-01-16 16:40:43 +03:00
parent 0609288250
commit 62c4b1f30b
7 changed files with 179 additions and 42 deletions

View file

@ -6108,13 +6108,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_DontSendOnlinePackets" = "Don't Send Online"; "ayu_DontSendOnlinePackets" = "Don't Send Online";
"ayu_DontSendUploadProgress" = "Don't Send Typing"; "ayu_DontSendUploadProgress" = "Don't Send Typing";
"ayu_SendOfflinePacketAfterOnline" = "Go Offline Automatically"; "ayu_SendOfflinePacketAfterOnline" = "Go Offline Automatically";
"ayu_GhostModeOptionLongTapDescription" = "Long tap on any option to prevent it from changing on toggling Ghost Mode.";
"ayu_MarkReadAfterAction" = "Read on Interact"; "ayu_MarkReadAfterAction" = "Read on Interact";
"ayu_MarkReadAfterActionDescription" = "Automatically reads message when you send a new one or tap a reaction."; "ayu_MarkReadAfterActionDescription" = "Automatically reads message when you send a new one or tap a reaction.";
"ayu_MarkReadAfterSend" = "Send"; "ayu_MarkReadAfterSend" = "Send";
"ayu_MarkReadAfterReaction" = "Reaction"; "ayu_MarkReadAfterReaction" = "Reaction";
"ayu_MarkReadAfterPoll" = "Poll"; "ayu_MarkReadAfterPoll" = "Poll";
"ayu_UseScheduledMessages" = "Schedule Messages"; "ayu_UseScheduledMessages" = "Schedule Messages";
"ayu_UseScheduledMessagesDescription" = "Automatically schedules outgoing messages for ~12 seconds, and more for media. Don't use on bad networks."; "ayu_UseScheduledMessagesDescription" = "Automatically schedules outgoing messages for ~12 seconds, and more for media. Sending messages this way, you won't appear online.\nDon't use on bad networks.";
"ayu_SendWithoutSoundByDefault" = "Send without Sound"; "ayu_SendWithoutSoundByDefault" = "Send without Sound";
"ayu_SendWithoutSoundByDefaultDescription" = "Automatically sends outgoing messages without sound."; "ayu_SendWithoutSoundByDefaultDescription" = "Automatically sends outgoing messages without sound.";
"ayu_SuggestGhostModeBeforeViewingStory" = "Story Ghost Mode Alert"; "ayu_SuggestGhostModeBeforeViewingStory" = "Story Ghost Mode Alert";
@ -6146,6 +6147,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_DisableCustomBackgrounds" = "Disable Custom Backgrounds"; "ayu_DisableCustomBackgrounds" = "Disable Custom Backgrounds";
"ayu_DisableNotificationsDelay" = "Disable Notify Delay"; "ayu_DisableNotificationsDelay" = "Disable Notify Delay";
"ayu_LocalPremium" = "Local Telegram Premium"; "ayu_LocalPremium" = "Local Telegram Premium";
"ayu_DisplayGhostStatus" = "Display Ghost Mode Status";
"ayu_CopyUsernameAsLink" = "Copy Username as Link"; "ayu_CopyUsernameAsLink" = "Copy Username as Link";
"ayu_CustomizationHeader" = "Customization"; "ayu_CustomizationHeader" = "Customization";
"ayu_DeletedMarkText" = "Deleted Mark"; "ayu_DeletedMarkText" = "Deleted Mark";
@ -6154,6 +6156,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_DeletedMarkCross" = "Cross"; "ayu_DeletedMarkCross" = "Cross";
"ayu_DeletedMarkEyeCrossed" = "Eye Crossed"; "ayu_DeletedMarkEyeCrossed" = "Eye Crossed";
"ayu_EditedMarkText" = "Edited Mark"; "ayu_EditedMarkText" = "Edited Mark";
"ayu_ReplaceMarksWithIcons" = "Replace with Icons";
"ayu_SemiTransparentDeletedMessages" = "Translucent Deleted Messages"; "ayu_SemiTransparentDeletedMessages" = "Translucent Deleted Messages";
"ayu_HideNotificationCounters" = "Hide Notification Counters"; "ayu_HideNotificationCounters" = "Hide Notification Counters";
"ayu_HideNotificationBadge" = "Hide Notification Badge"; "ayu_HideNotificationBadge" = "Hide Notification Badge";
@ -6224,6 +6227,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_RegexFilterQuickAdd" = "Add Filter"; "ayu_RegexFilterQuickAdd" = "Add Filter";
"ayu_RegexFilterBulletinText" = "Filter added to the **Shared filters**."; "ayu_RegexFilterBulletinText" = "Filter added to the **Shared filters**.";
"ayu_RegexFilterBulletinAction" = "To Current Chat"; "ayu_RegexFilterBulletinAction" = "To Current Chat";
"ayu_RegexFiltersListEmpty" = "No filters here yet.";
"ayu_FiltersMenuSelectChat" = "Select Chat"; "ayu_FiltersMenuSelectChat" = "Select Chat";
"ayu_FiltersMenuImport" = "Import"; "ayu_FiltersMenuImport" = "Import";
"ayu_FiltersMenuExport" = "Export"; "ayu_FiltersMenuExport" = "Export";
@ -6302,6 +6306,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_DisableGhostModeTray" = "Disable Ghost Mode"; "ayu_DisableGhostModeTray" = "Disable Ghost Mode";
"ayu_GhostModeEnabled" = "Ghost Mode turned on"; "ayu_GhostModeEnabled" = "Ghost Mode turned on";
"ayu_GhostModeDisabled" = "Ghost Mode turned off"; "ayu_GhostModeDisabled" = "Ghost Mode turned off";
"ayu_GhostModeGlobalSettings" = "Global Settings";
"ayu_GhostModeGlobalSettingsDescription" = "Same for all accounts";
"ayu_GhostModeSwitchedToGlobalSettings" = "Switched to same settings for all accounts.";
"ayu_GhostModeSwitchedToIndividualSettings" = "Switched to individual settings for each account.";
"ayu_StreamerModeToggle" = "Streamer Mode"; "ayu_StreamerModeToggle" = "Streamer Mode";
"ayu_EnableStreamerModeTray" = "Enable Streamer Mode"; "ayu_EnableStreamerModeTray" = "Enable Streamer Mode";
"ayu_DisableStreamerModeTray" = "Disable Streamer Mode"; "ayu_DisableStreamerModeTray" = "Disable Streamer Mode";
@ -6311,6 +6319,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_ClearDeletedMenuText" = "Clear Deleted"; "ayu_ClearDeletedMenuText" = "Clear Deleted";
"ayu_ViewDeletedMenuText" = "View Deleted"; "ayu_ViewDeletedMenuText" = "View Deleted";
"ayu_ViewFiltersMenuText" = "View Filters"; "ayu_ViewFiltersMenuText" = "View Filters";
"ayu_ReadExclusionMenuText" = "Read Exclusion";
"ayu_TypingExclusionMenuText" = "Typing Exclusion";
"ayu_ExclusionTitle" = "Select exclusion type";
"ayu_ExclusionUseDefault" = "Default";
"ayu_ExclusionDontRead" = "Never Read";
"ayu_ExclusionAlwaysRead" = "Always Read";
"ayu_ExclusionDontType" = "Never Type";
"ayu_ExclusionAlwaysType" = "Always Type";
"ayu_PeekOnlineSuccess" = "Peeked via"; "ayu_PeekOnlineSuccess" = "Peeked via";
"ayu_OneViewTTL" = "one view"; "ayu_OneViewTTL" = "one view";
"ayu_OnePlayTTL" = "one play"; "ayu_OnePlayTTL" = "one play";
@ -6327,9 +6343,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_SuggestGhostModeStoryText" = "Do you want to enable **Ghost Mode** before viewing the story?"; "ayu_SuggestGhostModeStoryText" = "Do you want to enable **Ghost Mode** before viewing the story?";
"ayu_SuggestGhostModeStoryActionTextYes" = "Yes"; "ayu_SuggestGhostModeStoryActionTextYes" = "Yes";
"ayu_SuggestGhostModeStoryActionTextNo" = "No"; "ayu_SuggestGhostModeStoryActionTextNo" = "No";
"ayu_ClearAttachmentsFolderWarning" = "Are you sure you want to clear the **attachments folder**? This action cannot be undone.";
"ayu_ClearMessagesDatabaseWarning" = "Are you sure you want to clear **all deleted & edited messages**? This action cannot be undone.";
"ayu_ClearTelegramDatabaseWarning" = "Are you sure you want to clear the **Telegram internal database**? This action cannot be undone.";
"ayu_FirstLaunchAlert" = "AyuGram is **free** software and should only be obtained from our **official sources**. You assume **full responsibility** for using this application with your account.";
"ayu_LocalPremiumAlert" = "With local Telegram Premium you won't have increased limits and won't be able to send animated emojis. Other users won't see your premium emoji and quote color.";
"ayu_ExteraChatsAlert" = "Don't ask questions related to **AyuGram** in **exteraGram** chats. If you need help, ask in the official **AyuGram** chat.";
"ayu_HideNextViewsDescriptionAyu" = "Hide my views forever, until Ghost Mode disabled."; "ayu_HideNextViewsDescriptionAyu" = "Hide my views forever, until Ghost Mode disabled.";
"ayu_EnableGhostModeStories" = "Enable Ghost Mode"; "ayu_EnableGhostModeStories" = "Enable Ghost Mode";
"ayu_GhostModeIsActive" = "Ghost Mode Is Active"; "ayu_GhostModeIsActive" = "Ghost Mode is Active";
"ayu_SimpleQuotesAndReplies" = "Disable Colorful Replies"; "ayu_SimpleQuotesAndReplies" = "Disable Colorful Replies";
"ayu_DisableSimilarChannels" = "Disable Similar Channels"; "ayu_DisableSimilarChannels" = "Disable Similar Channels";
"ayu_CollapseSimilarChannels" = "Collapse Similar Channels"; "ayu_CollapseSimilarChannels" = "Collapse Similar Channels";
@ -6376,7 +6398,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_ContextHideMessage" = "Hide"; "ayu_ContextHideMessage" = "Hide";
"ayu_ContextCopyCallbackData" = "Copy Callback Data"; "ayu_ContextCopyCallbackData" = "Copy Callback Data";
"ayu_RegisterURLScheme" = "Register URL Scheme"; "ayu_RegisterURLScheme" = "Register URL Scheme";
"ayu_LocalPremiumNotice" = "You're using **local** Telegram Premium.\nIt **won't** give you any benefits, except translator.\n**Enjoy the star near your nickname!**"; "ayu_LocalPremiumNotice" = "You're using **local** Telegram Premium.\nIt **won't** give you any benefits.\n**Enjoy the star near your nickname!**";
"ayu_SettingsWatermark" = "AyuGram developed and maintained by Radolyn Labs."; "ayu_SettingsWatermark" = "AyuGram developed and maintained by Radolyn Labs.";
"ayu_ConfirmationSticker" = "Do you want to send this sticker?"; "ayu_ConfirmationSticker" = "Do you want to send this sticker?";
"ayu_ConfirmationGIF" = "Do you want to send this GIF?"; "ayu_ConfirmationGIF" = "Do you want to send this GIF?";

View file

@ -1460,7 +1460,7 @@ void SetupMarks(not_null<Ui::VerticalLayout*> container) {
AddButtonWithIcon( AddButtonWithIcon(
container, container,
rpl::single(QString("Replace with Icons")), tr::ayu_ReplaceMarksWithIcons(),
st::settingsButtonNoIcon st::settingsButtonNoIcon
)->toggleOn( )->toggleOn(
rpl::single(settings->replaceBottomInfoWithIcons) rpl::single(settings->replaceBottomInfoWithIcons)

View file

@ -8,46 +8,158 @@
#include "windows_utils.h" #include "windows_utils.h"
#include "base/platform/win/base_windows_winrt.h"
#include "platform/win/windows_app_user_model_id.h"
#include <ShlObj_core.h> #include <ShlObj_core.h>
#include <propvarutil.h>
void reloadAppIconFromTaskBar() { void processIcon(QString shortcut, QString iconPath) {
QString appdata = QDir::fromNativeSeparators(qgetenv("APPDATA"));
QString ayugramIconPath = appdata + "/AyuGram.ico";
QString shortcut = appdata + "/Microsoft/Internet Explorer/Quick Launch/User Pinned/TaskBar/AyuGram Desktop.lnk";
if (!QFile::exists(shortcut)) { if (!QFile::exists(shortcut)) {
shortcut = appdata + "/Microsoft/Internet Explorer/Quick Launch/User Pinned/TaskBar/AyuGram.lnk"; return;
} }
if (QFile::exists(shortcut)) { IShellLink *pShellLink = NULL;
IShellLink *pShellLink = NULL; IPersistFile *pPersistFile = NULL;
IPersistFile *pPersistFile = NULL;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, HRESULT hr = CoCreateInstance(CLSID_ShellLink,
NULL, NULL,
CLSCTX_INPROC_SERVER, CLSCTX_INPROC_SERVER,
IID_IShellLink, IID_IShellLink,
(void**) &pShellLink); (void**) &pShellLink);
if (SUCCEEDED(hr)) {
hr = pShellLink->QueryInterface(IID_IPersistFile, (void**) &pPersistFile);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = pShellLink->QueryInterface(IID_IPersistFile, (void**) &pPersistFile); WCHAR wszShortcutPath[MAX_PATH];
if (SUCCEEDED(hr)) { shortcut.toWCharArray(wszShortcutPath);
WCHAR wszShortcutPath[MAX_PATH]; wszShortcutPath[shortcut.length()] = '\0';
shortcut.toWCharArray(wszShortcutPath);
wszShortcutPath[shortcut.length()] = '\0';
if (SUCCEEDED(pPersistFile->Load(wszShortcutPath, STGM_READWRITE))) { if (SUCCEEDED(pPersistFile->Load(wszShortcutPath, STGM_READWRITE))) {
pShellLink->SetIconLocation(ayugramIconPath.toStdWString().c_str(), 0); pShellLink->SetIconLocation(iconPath.toStdWString().c_str(), 0);
pPersistFile->Save(wszShortcutPath, TRUE); pPersistFile->Save(wszShortcutPath, TRUE);
}
pPersistFile->Release();
} }
pShellLink->Release(); pPersistFile->Release();
} }
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); pShellLink->Release();
} }
} }
void processLegacy(const QString &appdata, const QString &iconPath) {
auto shortcut = appdata + "/Microsoft/Internet Explorer/Quick Launch/User Pinned/TaskBar/AyuGram Desktop.lnk";
if (!QFile::exists(shortcut)) {
shortcut = appdata + "/Microsoft/Internet Explorer/Quick Launch/User Pinned/TaskBar/AyuGram.lnk";
}
if (!QFile::exists(shortcut)) {
return;
}
processIcon(shortcut, iconPath);
}
void processNewPinned(const QString &iconPath) {
if (!SUCCEEDED(CoInitialize(0))) {
return;
}
const auto coGuard = gsl::finally([]
{
CoUninitialize();
});
const auto path = Platform::AppUserModelId::PinnedIconsPath();
const auto native = QDir::toNativeSeparators(path).toStdWString();
const auto srcid = Platform::AppUserModelId::MyExecutablePathId();
if (!srcid) {
return;
}
WIN32_FIND_DATA findData;
HANDLE findHandle = FindFirstFileEx(
(native + L"*").c_str(),
FindExInfoStandard,
&findData,
FindExSearchNameMatch,
0,
0);
if (findHandle == INVALID_HANDLE_VALUE) {
return;
}
do {
std::wstring fname = native + findData.cFileName;
const auto filePath = QString::fromStdWString(fname);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
continue;
}
DWORD attributes = GetFileAttributes(fname.c_str());
if (attributes >= 0xFFFFFFF) {
continue; // file does not exist
}
auto shellLink = base::WinRT::TryCreateInstance<IShellLink>(
CLSID_ShellLink);
if (!shellLink) {
continue;
}
auto persistFile = shellLink.try_as<IPersistFile>();
if (!persistFile) {
continue;
}
auto hr = persistFile->Load(fname.c_str(), STGM_READWRITE);
if (!SUCCEEDED(hr)) continue;
WCHAR dst[MAX_PATH] = {0};
hr = shellLink->GetPath(dst, MAX_PATH, nullptr, 0);
if (!SUCCEEDED(hr)) continue;
if (Platform::AppUserModelId::GetUniqueFileId(dst) == srcid) {
auto propertyStore = shellLink.try_as<IPropertyStore>();
if (!propertyStore) {
continue;
}
processIcon(filePath, iconPath);
}
} while (FindNextFile(findHandle, &findData));
DWORD errorCode = GetLastError();
if (errorCode && errorCode != ERROR_NO_MORE_FILES) {
return;
}
FindClose(findHandle);
}
void processNewShortcuts(const QString &iconPath) {
const auto path = Platform::AppUserModelId::systemShortcutPath();
if (path.isEmpty()) {
return;
}
const auto shortcut = path + u"AyuGram Desktop/AyuGram.lnk"_q;
const auto native = QDir::toNativeSeparators(path).toStdWString();
DWORD attributes = GetFileAttributes(native.c_str());
if (attributes >= 0xFFFFFFF) {
return; // file does not exist
}
const auto normalizedPath = QString::fromStdWString(native);
processIcon(normalizedPath, iconPath);
}
void reloadAppIconFromTaskBar() {
QString appdata = QDir::fromNativeSeparators(qgetenv("APPDATA"));
QString iconPath = appdata + "/AyuGram.ico";
processNewPinned(iconPath);
processNewShortcuts(iconPath);
processLegacy(appdata, iconPath);
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
}
#endif #endif

View file

@ -357,7 +357,7 @@ Cover::Cover(
return controller->isGifPausedAtLeastFor( return controller->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer); Window::GifPauseReason::Layer);
})) }))
, _devBadge( , _exteraBadge(
std::make_unique<Badge>( std::make_unique<Badge>(
this, this,
st::infoPeerBadge, st::infoPeerBadge,
@ -419,14 +419,14 @@ Cover::Cover(
}, _name->lifetime()); }, _name->lifetime());
if (isExteraPeer(getBareID(_peer))) { if (isExteraPeer(getBareID(_peer))) {
_devBadge->setContent(Info::Profile::Badge::Content{BadgeType::Extera}); _exteraBadge->setContent(Info::Profile::Badge::Content{BadgeType::Extera});
} else if (isSupporterPeer(getBareID(_peer))) { } else if (isSupporterPeer(getBareID(_peer))) {
_devBadge->setContent(Info::Profile::Badge::Content{BadgeType::ExteraSupporter}); _exteraBadge->setContent(Info::Profile::Badge::Content{BadgeType::ExteraSupporter});
} else { } else {
_devBadge->setContent(Info::Profile::Badge::Content{BadgeType::None}); _exteraBadge->setContent(Info::Profile::Badge::Content{BadgeType::None});
} }
_devBadge->updated() | rpl::start_with_next( _exteraBadge->updated() | rpl::start_with_next(
[=] [=]
{ {
refreshNameGeometry(width()); refreshNameGeometry(width());
@ -769,7 +769,7 @@ void Cover::refreshNameGeometry(int newWidth) {
if (const auto widget = _badge->widget()) { if (const auto widget = _badge->widget()) {
nameWidth -= st::infoVerifiedCheckPosition.x() + widget->width(); nameWidth -= st::infoVerifiedCheckPosition.x() + widget->width();
} }
if (const auto widget = _devBadge->widget()) { if (const auto widget = _exteraBadge->widget()) {
nameWidth -= st::infoVerifiedCheckPosition.x() nameWidth -= st::infoVerifiedCheckPosition.x()
+ widget->width() + widget->width()
+ (_badge->widget() + (_badge->widget()
@ -800,7 +800,7 @@ void Cover::refreshNameGeometry(int newWidth) {
: 0); : 0);
const auto devBadgeTop = _st.nameTop; const auto devBadgeTop = _st.nameTop;
const auto devBadgeBottom = _st.nameTop + _name->height(); const auto devBadgeBottom = _st.nameTop + _name->height();
_devBadge->move(devBadgeLeft, devBadgeTop, devBadgeBottom); _exteraBadge->move(devBadgeLeft, devBadgeTop, devBadgeBottom);
} }
void Cover::refreshStatusGeometry(int newWidth) { void Cover::refreshStatusGeometry(int newWidth) {

View file

@ -149,7 +149,7 @@ private:
const std::unique_ptr<EmojiStatusPanel> _emojiStatusPanel; const std::unique_ptr<EmojiStatusPanel> _emojiStatusPanel;
const std::unique_ptr<Badge> _verify; const std::unique_ptr<Badge> _verify;
const std::unique_ptr<Badge> _badge; const std::unique_ptr<Badge> _badge;
const std::unique_ptr<Badge> _devBadge; const std::unique_ptr<Badge> _exteraBadge;
rpl::variable<int> _onlineCount; rpl::variable<int> _onlineCount;
const object_ptr<Ui::UserpicButton> _userpic; const object_ptr<Ui::UserpicButton> _userpic;

View file

@ -31,7 +31,9 @@ const WCHAR AppUserModelIdBase[] = L"AyuGram.AyuGramDesktop.Store";
const WCHAR AppUserModelIdBase[] = L"AyuGram.AyuGramDesktop"; const WCHAR AppUserModelIdBase[] = L"AyuGram.AyuGramDesktop";
#endif // OS_WIN_STORE #endif // OS_WIN_STORE
[[nodiscard]] QString PinnedIconsPath() { } // namespace
QString PinnedIconsPath() {
WCHAR wstrPath[kMaxFileLen] = {}; WCHAR wstrPath[kMaxFileLen] = {};
if (GetEnvironmentVariable(L"APPDATA", wstrPath, kMaxFileLen)) { if (GetEnvironmentVariable(L"APPDATA", wstrPath, kMaxFileLen)) {
auto appData = QDir(QString::fromStdWString(std::wstring(wstrPath))); auto appData = QDir(QString::fromStdWString(std::wstring(wstrPath)));
@ -41,8 +43,6 @@ const WCHAR AppUserModelIdBase[] = L"AyuGram.AyuGramDesktop";
return QString(); return QString();
} }
} // namespace
const std::wstring &MyExecutablePath() { const std::wstring &MyExecutablePath() {
static const auto Path = [&] { static const auto Path = [&] {
auto result = std::wstring(kMaxFileLen, 0); auto result = std::wstring(kMaxFileLen, 0);

View file

@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform { namespace Platform {
namespace AppUserModelId { namespace AppUserModelId {
[[nodiscard]] QString PinnedIconsPath();
QString systemShortcutPath();
void CleanupShortcut(); void CleanupShortcut();
void CheckPinned(); void CheckPinned();