2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-11-17 18:52:06 +00:00

feat: add modman favicon handler for windows

This commit is contained in:
Jan Laupetin
2025-10-31 20:56:19 +01:00
parent 5879fe3bb3
commit 87d65b99fb
4 changed files with 171 additions and 0 deletions

View File

@@ -0,0 +1,151 @@
#include "AssetHandlerWindows.h"
#if defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)
#include "PlatformUtilsWindows.h"
#include "Web/UiAssets.h"
#include <Windows.h>
#include <format>
#include <gdiplus.h>
#include <iostream>
#include <sstream>
#include <webview/detail/backends/win32_edge.hh>
#include <wrl/event.h>
using namespace PLATFORM_NAMESPACE_WINDOWS;
namespace
{
class UniqueHIcon
{
public:
UniqueHIcon()
: m_icon(nullptr)
{
}
~UniqueHIcon()
{
if (m_icon)
{
DestroyIcon(m_icon);
m_icon = nullptr;
}
}
UniqueHIcon(const UniqueHIcon& other) = default;
UniqueHIcon(UniqueHIcon&& other) noexcept
: m_icon(other.m_icon)
{
other.m_icon = nullptr;
}
UniqueHIcon& operator=(const UniqueHIcon& other) = default;
UniqueHIcon& operator=(UniqueHIcon&& other) noexcept
{
m_icon = other.m_icon;
other.m_icon = nullptr;
return *this;
}
HICON& get()
{
return m_icon;
}
private:
HICON m_icon;
};
std::unordered_map<HWND, UniqueHIcon> icons;
HRESULT HandleFaviconChanged(ICoreWebView2_15* core15, HWND window)
{
LPWSTR url;
if (!SUCCEEDED(core15->get_FaviconUri(&url)))
{
std::cerr << "Failed to get favicon uri\n";
return S_FALSE;
}
const std::wstring strUrl(url);
CoTaskMemFree(url);
if (strUrl.empty())
{
icons.erase(icons.find(window));
SendMessage(window, WM_SETICON, ICON_SMALL, (LPARAM)NULL);
}
else
{
if (!SUCCEEDED(core15->GetFavicon(COREWEBVIEW2_FAVICON_IMAGE_FORMAT_PNG,
Microsoft::WRL::Callback<ICoreWebView2GetFaviconCompletedHandler>(
[window](HRESULT errorCode, IStream* iconStream) -> HRESULT
{
Gdiplus::Bitmap iconBitmap(iconStream);
UniqueHIcon icon;
if (iconBitmap.GetHICON(&icon.get()) == Gdiplus::Status::Ok)
{
SendMessage(window, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icon.get()));
icons.emplace(window, std::move(icon)).first->second.get();
}
else
{
icons.erase(icons.find(window));
SendMessage(window, WM_SETICON, ICON_SMALL, NULL);
}
return S_OK;
})
.Get())))
{
std::cerr << "Failed to get favicon\n";
return S_FALSE;
}
}
return S_OK;
}
} // namespace
namespace PLATFORM_NAMESPACE_WINDOWS
{
void InstallFaviconHandler(webview::webview& wv)
{
const auto controller = static_cast<ICoreWebView2Controller*>(wv.browser_controller().value());
auto window = static_cast<HWND>(wv.window().value());
Microsoft::WRL::ComPtr<ICoreWebView2> core;
if (!SUCCEEDED(controller->get_CoreWebView2(&core)))
{
std::cerr << "Failed to get webview\n";
return;
}
Microsoft::WRL::ComPtr<ICoreWebView2_15> core15;
if (!SUCCEEDED(core->QueryInterface(IID_PPV_ARGS(&core15))))
{
std::cerr << "Failed to get core15\n";
return;
}
const Gdiplus::GdiplusStartupInput gdiPlusStartupInput;
ULONG_PTR gdiPlusToken;
Gdiplus::GdiplusStartup(&gdiPlusToken, &gdiPlusStartupInput, nullptr);
EventRegistrationToken token;
if (!SUCCEEDED(core15->add_FaviconChanged(Microsoft::WRL::Callback<ICoreWebView2FaviconChangedEventHandler>(
[core15, window](ICoreWebView2* sender, IUnknown* args) -> HRESULT
{
return HandleFaviconChanged(core15.Get(), window);
})
.Get(),
&token)))
{
std::cerr << "Failed to add favicon handler\n";
}
}
} // namespace PLATFORM_NAMESPACE_WINDOWS
#endif

View File

@@ -0,0 +1,16 @@
#pragma once
#include "Web/Platform/Platform.h"
#include <webview/macros.h>
#if defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)
#include "Web/WebViewLib.h"
namespace PLATFORM_NAMESPACE_WINDOWS
{
void InstallFaviconHandler(webview::webview& wv);
} // namespace PLATFORM_NAMESPACE_WINDOWS
#endif

View File

@@ -3,6 +3,7 @@
#include "ModManArgs.h" #include "ModManArgs.h"
#include "Web/Binds/Binds.h" #include "Web/Binds/Binds.h"
#include "Web/Platform/AssetHandler.h" #include "Web/Platform/AssetHandler.h"
#include "Web/Platform/Windows/FaviconHandlerWindows.h"
#include "Web/UiCommunication.h" #include "Web/UiCommunication.h"
#include "Web/ViteAssets.h" #include "Web/ViteAssets.h"
#include "Web/WebViewLib.h" #include "Web/WebViewLib.h"
@@ -32,6 +33,7 @@ namespace
{ {
context.m_dev_tools_webview = std::make_unique<webview::webview>(false, nullptr); context.m_dev_tools_webview = std::make_unique<webview::webview>(false, nullptr);
auto& newWindow = *context.m_dev_tools_webview; auto& newWindow = *context.m_dev_tools_webview;
InstallFaviconHandler(newWindow);
newWindow.set_title("Devtools"); newWindow.set_title("Devtools");
newWindow.set_size(640, 480, WEBVIEW_HINT_NONE); newWindow.set_size(640, 480, WEBVIEW_HINT_NONE);
@@ -66,6 +68,7 @@ namespace
newWindow.set_size(640, 480, WEBVIEW_HINT_MIN); newWindow.set_size(640, 480, WEBVIEW_HINT_MIN);
InstallAssetHandler(newWindow); InstallAssetHandler(newWindow);
InstallFaviconHandler(newWindow);
ui::RegisterAllBinds(newWindow); ui::RegisterAllBinds(newWindow);
#ifdef _DEBUG #ifdef _DEBUG

View File

@@ -13,6 +13,7 @@ function webview:link(links)
if os.host() == "windows" then if os.host() == "windows" then
links:add("WebView2LoaderStatic") links:add("WebView2LoaderStatic")
links:add("gdiplus.lib")
filter "platforms:x86" filter "platforms:x86"
libdirs { libdirs {