mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
fix: 修复消息弹出动画错误 (#1142)
This commit is contained in:
parent
cff8876e80
commit
db310ef355
6 changed files with 60 additions and 14 deletions
|
|
@ -220,5 +220,6 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natstepfilter" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "pch.h"
|
||||
#include "pch.h"
|
||||
#include "ToastPage.h"
|
||||
#if __has_include("ToastPage.g.cpp")
|
||||
#include "ToastPage.g.cpp"
|
||||
|
|
@ -15,6 +15,7 @@ using namespace winrt::Magpie::implementation;
|
|||
using namespace winrt;
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
using namespace Windows::UI::Xaml::Controls::Primitives;
|
||||
using namespace Windows::UI::Xaml::Media::Imaging;
|
||||
|
||||
namespace winrt::Magpie::implementation {
|
||||
|
|
@ -85,6 +86,8 @@ static void UpdateToastPosition(HWND hwndToast, const RECT& frameRect, bool upda
|
|||
}
|
||||
|
||||
fire_and_forget ToastPage::ShowMessageOnWindow(std::wstring title, std::wstring message, HWND hwndTarget, bool showLogo) {
|
||||
CoreDispatcher dispatcher = Dispatcher();
|
||||
|
||||
// !!! HACK !!!
|
||||
// 重用 TeachingTip 有一个 bug: 前一个 Toast 正在消失时新的 Toast 不会显示。为了
|
||||
// 规避它,我们每次都创建新的 TeachingTip,但要保留旧对象的引用,因为播放动画时销毁
|
||||
|
|
@ -96,16 +99,6 @@ fire_and_forget ToastPage::ShowMessageOnWindow(std::wstring title, std::wstring
|
|||
oldTeachingTip = std::move(_oldTeachingTip);
|
||||
}
|
||||
|
||||
CoreDispatcher dispatcher = Dispatcher();
|
||||
auto weakThis = get_weak();
|
||||
|
||||
// oldTeachingTip 卸载后弹窗不会立刻隐藏,稍微等待防止弹窗闪烁
|
||||
co_await resume_foreground(dispatcher, CoreDispatcherPriority::Low);
|
||||
|
||||
if (!weakThis.get()) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
RECT frameRect;
|
||||
if (!Win32Helper::GetWindowFrameRect(hwndTarget, frameRect)) {
|
||||
co_return;
|
||||
|
|
@ -145,9 +138,9 @@ fire_and_forget ToastPage::ShowMessageOnWindow(std::wstring title, std::wstring
|
|||
MessageTextBlock().Text(message);
|
||||
|
||||
// !!! HACK !!!
|
||||
// 移除关闭按钮。必须在模板加载完成后做,TeachingTip 没有 Opening 事件,但可以监听 MessageTextBlock 的
|
||||
// LayoutUpdated 事件,它在 TeachingTip 显示前必然会被引发。
|
||||
MessageTextBlock().LayoutUpdated([weak(weak_ref(curTeachingTip))](IInspectable const&, IInspectable const&) {
|
||||
// 移除关闭按钮和修复弹出动画。必须在模板加载完成后做,TeachingTip 没有 Opening 事件,但可以监听
|
||||
// MessageTextBlock 的 LayoutUpdated 事件,它在 TeachingTip 显示前必然会被引发。
|
||||
MessageTextBlock().LayoutUpdated([this, weak(weak_ref(curTeachingTip))](IInspectable const&, IInspectable const&) {
|
||||
auto teachingTip = weak.get();
|
||||
if (!teachingTip) {
|
||||
return;
|
||||
|
|
@ -159,6 +152,28 @@ fire_and_forget ToastPage::ShowMessageOnWindow(std::wstring title, std::wstring
|
|||
if (DependencyObject closeButton = protectedAccessor.GetTemplateChild(L"AlternateCloseButton")) {
|
||||
closeButton.as<FrameworkElement>().Visibility(Visibility::Collapsed);
|
||||
}
|
||||
|
||||
// 检查 Tag 记录,修复弹出动画只需执行一次
|
||||
if (teachingTip.Tag()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XAML Islands 中 TeachingTip 弹出动画存在 bug,在弹出前有一瞬间会完全显示。为了修复它,这里
|
||||
// 手动将弹窗隐藏,动画开始后再恢复。
|
||||
for (const Popup& popup : VisualTreeHelper::GetOpenPopupsForXamlRoot(XamlRoot())) {
|
||||
// 查找 TeachingTip 的弹窗
|
||||
if (XamlHelper::ContainsControl(popup.Child(), MessageTextBlock())) {
|
||||
popup.Visibility(Visibility::Collapsed);
|
||||
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::Low, [popup]() {
|
||||
popup.Visibility(Visibility::Visible);
|
||||
});
|
||||
|
||||
// 修复后使用 Tag 记录
|
||||
teachingTip.Tag(box_value(0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 应用内消息无需显示 logo
|
||||
|
|
@ -181,6 +196,8 @@ fire_and_forget ToastPage::ShowMessageOnWindow(std::wstring title, std::wstring
|
|||
}
|
||||
}(dispatcher, curTeachingTip, oldTeachingTip);
|
||||
|
||||
auto weakThis = get_weak();
|
||||
|
||||
// 定期更新弹窗位置
|
||||
RECT prevframeRect{};
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -129,4 +129,28 @@ void XamlHelper::UpdateThemeOfTooltips(const DependencyObject& root, ElementThem
|
|||
} while (!elems.empty());
|
||||
}
|
||||
|
||||
bool XamlHelper::ContainsControl(const DependencyObject& parent, const DependencyObject& target) {
|
||||
std::vector<DependencyObject> elems{ parent };
|
||||
do {
|
||||
std::vector<DependencyObject> temp;
|
||||
|
||||
for (const DependencyObject& elem : elems) {
|
||||
const int count = VisualTreeHelper::GetChildrenCount(elem);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
DependencyObject current = VisualTreeHelper::GetChild(elem, i);
|
||||
|
||||
if (current == target) {
|
||||
return true;
|
||||
}
|
||||
|
||||
temp.emplace_back(std::move(current));
|
||||
}
|
||||
}
|
||||
|
||||
elems = std::move(temp);
|
||||
} while (!elems.empty());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ struct XamlHelper {
|
|||
static void RepositionXamlPopups(const winrt::XamlRoot& root, bool closeFlyoutPresenter);
|
||||
|
||||
static void UpdateThemeOfTooltips(const winrt::DependencyObject& root, winrt::ElementTheme theme);
|
||||
|
||||
static bool ContainsControl(const winrt::DependencyObject& parent, const winrt::DependencyObject& target);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natstepfilter" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="app.manifest" />
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natstepfilter" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue