From f20a655df37004e901b5550a71650940839428d8 Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Wed, 3 Dec 2025 13:33:58 +0500 Subject: [PATCH 1/9] Add WebView2 host object for JavaScript interaction with Rainmeter API. --- README.md | 47 ++++ .../@Resources/CompleteDemo/index.html | 237 ++++++++++++++++++ .../WebView2/CompleteDemo/CompleteDemo.ini | 185 ++++++++++++++ WebView2/HostObject.idl | 4 + WebView2/HostObjectRmAPI.cpp | 18 ++ WebView2/HostObjectRmAPI.h | 4 + WebView2/Plugin.cpp | 121 ++++++++- WebView2/Plugin.h | 5 + WebView2/WebView2.cpp | 26 ++ 9 files changed, 641 insertions(+), 6 deletions(-) create mode 100644 Resources/Skins/WebView2/@Resources/CompleteDemo/index.html create mode 100644 Resources/Skins/WebView2/CompleteDemo/CompleteDemo.ini diff --git a/README.md b/README.md index 17b6b99..d036144 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,46 @@ Execute commands from your skin using `[!CommandMeasure MeasureName "Command"]`: | `ExecuteScript + + diff --git a/Resources/Skins/WebView2/CompleteDemo/CompleteDemo.ini b/Resources/Skins/WebView2/CompleteDemo/CompleteDemo.ini new file mode 100644 index 0000000..522ffe0 --- /dev/null +++ b/Resources/Skins/WebView2/CompleteDemo/CompleteDemo.ini @@ -0,0 +1,185 @@ +[Rainmeter] +Update=1000 +AccurateText=1 +DynamicWindowSize=1 + +[Metadata] +Name=WebView2 Complete Demo +Author=nstechbytes +Information=Comprehensive demo of all WebView2 features: callbacks, section variables, and JavaScript integration +Version=1.0 +License=MIT + +; ================================================== +; WebView2 Plugin +; ================================================== + +[MeasureWebView] +Measure=Plugin +Plugin=WebView2 +URL=#@#CompleteDemo\index.html +W=800 +H=600 +X=25 +Y=25 + +; ================================================== +; Background +; ================================================== + +[MeterBackground] +Meter=Shape +Shape=Rectangle 0,0,850,1050 | FillColor 0,0,0,2 | StrokeWidth 0 + +; ================================================== +; Feature Displays Below WebView +; ================================================== + +[MeterTitle] +Meter=String +X=25 +Y=640 +FontSize=16 +FontColor=255,255,255 +FontWeight=700 +Text=Live Feature Demonstrations +AntiAlias=1 + +; --- Feature 1: OnUpdate Return Value --- +[MeterFeature1Title] +Meter=String +X=25 +Y=20R +FontSize=12 +FontColor=100,200,255 +FontWeight=600 +Text=1. OnUpdate() Return Value: +AntiAlias=1 + +[MeterOnUpdateValue] +Meter=String +MeasureName=MeasureWebView +X=25 +Y=5R +FontSize=14 +FontColor=100,255,100 +FontWeight=700 +Text=%1 +AntiAlias=1 +DynamicVariables=1 + +; --- Feature 2: CallJS Examples --- +[MeterFeature2Title] +Meter=String +X=25 +Y=20R +FontSize=12 +FontColor=100,200,255 +FontWeight=600 +Text=2. CallJS() - Call Any JavaScript Function: +AntiAlias=1 + +[MeterTempLabel] +Meter=String +X=25 +Y=8R +FontSize=10 +FontColor=200,200,200 +Text=getTemperature(): +AntiAlias=1 + +[MeterTemp] +Meter=String +X=150 +Y=0r +FontSize=10 +FontColor=255,255,255 +Text=[MeasureWebView:CallJS('getTemperature')] +AntiAlias=1 +DynamicVariables=1 + +[MeterUserLabel] +Meter=String +X=25 +Y=5R +FontSize=10 +FontColor=200,200,200 +Text=getUserName(): +AntiAlias=1 + +[MeterUser] +Meter=String +X=150 +Y=0r +FontSize=10 +FontColor=255,255,255 +Text=[MeasureWebView:CallJS('getUserName')] +AntiAlias=1 +DynamicVariables=1 + +[MeterTimeLabel] +Meter=String +X=25 +Y=5R +FontSize=10 +FontColor=200,200,200 +Text=getCurrentTime(): +AntiAlias=1 + +[MeterTime] +Meter=String +X=150 +Y=0r +FontSize=10 +FontColor=255,255,255 +Text=[MeasureWebView:CallJS('getCurrentTime')] +AntiAlias=1 +DynamicVariables=1 + +[MeterRandomLabel] +Meter=String +X=25 +Y=5R +FontSize=10 +FontColor=200,200,200 +Text=getRandomNumber(): +AntiAlias=1 + +[MeterRandom] +Meter=String +X=150 +Y=0r +FontSize=10 +FontColor=255,255,255 +Text=[MeasureWebView:CallJS('getRandomNumber')] +AntiAlias=1 +DynamicVariables=1 + +[MeterSystemLabel] +Meter=String +X=25 +Y=5R +FontSize=10 +FontColor=200,200,200 +Text=getSystemInfo(): +AntiAlias=1 + +[MeterSystem] +Meter=String +X=150 +Y=0r +FontSize=10 +FontColor=255,255,255 +Text=[MeasureWebView:CallJS('getSystemInfo')] +AntiAlias=1 +DynamicVariables=1 + +; --- Info --- +[MeterInfo] +Meter=String +X=25 +Y=20R +FontSize=9 +FontColor=150,150,150 +Text=All values update every second • Define any function in JS and call it with CallJS() +AntiAlias=1 diff --git a/WebView2/HostObject.idl b/WebView2/HostObject.idl index afb2274..c524103 100644 --- a/WebView2/HostObject.idl +++ b/WebView2/HostObject.idl @@ -23,6 +23,10 @@ library WebView2Library HRESULT ReadDoubleFromSection([in] BSTR section, [in] BSTR option, [in, optional] VARIANT defaultValue, [out, retval] double* result); HRESULT ReadFormulaFromSection([in] BSTR section, [in] BSTR option, [in, optional] VARIANT defaultValue, [out, retval] double* result); + // Lifecycle methods + HRESULT Initialize(); + HRESULT Update([out, retval] double* result); + // Utility functions HRESULT ReplaceVariables([in] BSTR text, [out, retval] BSTR* result); HRESULT GetVariable([in] BSTR variableName, [out, retval] BSTR* result); diff --git a/WebView2/HostObjectRmAPI.cpp b/WebView2/HostObjectRmAPI.cpp index 2bfffb2..d444bc9 100644 --- a/WebView2/HostObjectRmAPI.cpp +++ b/WebView2/HostObjectRmAPI.cpp @@ -263,6 +263,24 @@ STDMETHODIMP HostObjectRmAPI::ReadFormulaFromSection(BSTR section, BSTR option, return S_OK; } +// Lifecycle methods +STDMETHODIMP HostObjectRmAPI::Initialize() +{ + // This method can be called from JavaScript to check if the API is ready + // Simply return S_OK to indicate success + return S_OK; +} + +STDMETHODIMP HostObjectRmAPI::Update(double* result) +{ + if (!result || !measure) + return E_INVALIDARG; + + // Return 1.0 if initialized, 0.0 otherwise (mirrors the C++ Update function) + *result = measure->initialized ? 1.0 : 0.0; + return S_OK; +} + // Utility functions STDMETHODIMP HostObjectRmAPI::ReplaceVariables(BSTR text, BSTR* result) { diff --git a/WebView2/HostObjectRmAPI.h b/WebView2/HostObjectRmAPI.h index 1a1841d..661e3cb 100644 --- a/WebView2/HostObjectRmAPI.h +++ b/WebView2/HostObjectRmAPI.h @@ -28,6 +28,10 @@ class HostObjectRmAPI : public Microsoft::WRL::RuntimeClass< STDMETHODIMP ReadDoubleFromSection(BSTR section, BSTR option, VARIANT defaultValue, double* result) override; STDMETHODIMP ReadFormulaFromSection(BSTR section, BSTR option, VARIANT defaultValue, double* result) override; + // Lifecycle methods + STDMETHODIMP Initialize() override; + STDMETHODIMP Update(double* result) override; + // Utility functions STDMETHODIMP ReplaceVariables(BSTR text, BSTR* result) override; STDMETHODIMP GetVariable(BSTR variableName, BSTR* result) override; diff --git a/WebView2/Plugin.cpp b/WebView2/Plugin.cpp index 1c41c3b..9992bff 100644 --- a/WebView2/Plugin.cpp +++ b/WebView2/Plugin.cpp @@ -197,24 +197,64 @@ PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) PLUGIN_EXPORT double Update(void* data) { Measure* measure = (Measure*)data; + + // Call JavaScript OnUpdate callback if WebView is initialized + if (measure->initialized && measure->webView) + { + measure->webView->ExecuteScript( + L"(function() { if (typeof window.OnUpdate === 'function') { var result = window.OnUpdate(); return result !== undefined ? String(result) : ''; } return ''; })();", + Callback( + [measure](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT + { + if (SUCCEEDED(errorCode) && resultObjectAsJson) + { + // Remove quotes from JSON string result + std::wstring result = resultObjectAsJson; + if (result.length() >= 2 && result.front() == L'"' && result.back() == L'"') + { + result = result.substr(1, result.length() - 2); + } + + // Store the callback result + if (!result.empty() && result != L"null") + { + measure->callbackResult = result; + } + + // Trigger Rainmeter update after callback completes to sync values + if (measure->rm) + { + RmExecute(measure->skin, L"!UpdateMeasure #CURRENTSECTION#"); + RmExecute(measure->skin, L"!UpdateMeter *"); + RmExecute(measure->skin, L"!Redraw"); + } + } + return S_OK; + } + ).Get() + ); + } + return measure->initialized ? 1.0 : 0.0; } PLUGIN_EXPORT LPCWSTR GetString(void* data) { Measure* measure = (Measure*)data; - static std::wstring result; - if (measure->initialized) + // Return the callback result if available, otherwise return status + if (!measure->callbackResult.empty()) { - result = L"WebView2 Initialized"; + return measure->callbackResult.c_str(); + } + else if (measure->initialized) + { + return L"WebView2 Initialized"; } else { - result = L"WebView2 Initializing..."; + return L"WebView2 Initializing..."; } - - return result.c_str(); } PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) @@ -278,6 +318,75 @@ PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) } +// Generic JavaScript function caller +PLUGIN_EXPORT LPCWSTR CallJS(void* data, const int argc, const WCHAR* argv[]) +{ + Measure* measure = (Measure*)data; + + if (!measure || !measure->initialized || !measure->webView) + return L""; + + if (argc == 0 || !argv[0]) + return L""; + + // Build unique key for this call: functionName|arg1|arg2... + std::wstring key = argv[0]; + for (int i = 1; i < argc; i++) + { + key += L"|"; + key += argv[i]; + } + + // Build JavaScript call: functionName(arg1, arg2, ...) + std::wstring jsCode = L"(function() { try { if (typeof " + std::wstring(argv[0]) + L" === 'function') { var result = " + std::wstring(argv[0]) + L"("; + + // Add arguments if provided + for (int i = 1; i < argc; i++) + { + if (i > 1) jsCode += L", "; + jsCode += L"'" + std::wstring(argv[i]) + L"'"; + } + + jsCode += L"); return result !== undefined ? String(result) : ''; } return 'Function not found'; } catch(e) { return 'Error: ' + e.message; } })();"; + + // Execute asynchronously and update cache + measure->webView->ExecuteScript( + jsCode.c_str(), + Callback( + [measure, key](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT + { + if (SUCCEEDED(errorCode) && resultObjectAsJson) + { + std::wstring result = resultObjectAsJson; + if (result.length() >= 2 && result.front() == L'"' && result.back() == L'"') + { + result = result.substr(1, result.length() - 2); + } + + if (!result.empty() && result != L"null") + { + // Update cache for this specific call + measure->jsResults[key] = result; + } + } + return S_OK; + } + ).Get() + ); + + // Return cached result if available, otherwise "Calling..." + if (measure->jsResults.find(key) != measure->jsResults.end()) + { + measure->buffer = measure->jsResults[key]; + } + else + { + measure->buffer = L"Calling..."; + } + + return measure->buffer.c_str(); +} + PLUGIN_EXPORT void Finalize(void* data) { Measure* measure = (Measure*)data; diff --git a/WebView2/Plugin.h b/WebView2/Plugin.h index dfca19c..0cc8e88 100644 --- a/WebView2/Plugin.h +++ b/WebView2/Plugin.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,10 @@ struct Measure wil::com_ptr webView; EventRegistrationToken webMessageToken; + std::wstring buffer; // Buffer for section variable return values + std::wstring callbackResult; // Stores return value from OnInitialize/OnUpdate callbacks + std::map jsResults; // Cache for CallJS results + Measure(); ~Measure(); diff --git a/WebView2/WebView2.cpp b/WebView2/WebView2.cpp index e86ce02..b7aae13 100644 --- a/WebView2/WebView2.cpp +++ b/WebView2/WebView2.cpp @@ -154,5 +154,31 @@ HRESULT Measure::CreateControllerHandler(HRESULT result, ICoreWebView2Controller if (rm) RmLog(rm, LOG_NOTICE, L"WebView2: Initialized successfully with COM Host Objects"); + // Call JavaScript OnInitialize callback if it exists and capture return value + webView->ExecuteScript( + L"(function() { if (typeof window.OnInitialize === 'function') { var result = window.OnInitialize(); return result !== undefined ? String(result) : ''; } return ''; })();", + Callback( + [this](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT + { + if (SUCCEEDED(errorCode) && resultObjectAsJson) + { + // Remove quotes from JSON string result + std::wstring result = resultObjectAsJson; + if (result.length() >= 2 && result.front() == L'"' && result.back() == L'"') + { + result = result.substr(1, result.length() - 2); + } + + // Store the callback result + if (!result.empty() && result != L"null") + { + callbackResult = result; + } + } + return S_OK; + } + ).Get() + ); + return S_OK; } From c51b22a4a25fe14703c2253d27f1fb8d388e09b0 Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Wed, 3 Dec 2025 17:35:32 +0500 Subject: [PATCH 2/9] Implement WebView2 Rainmeter plugin with COM initialization, lifecycle management, and JavaScript interaction. --- WebView2/Plugin.cpp | 21 +++++-------- WebView2/WebView2.cpp | 69 +++++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/WebView2/Plugin.cpp b/WebView2/Plugin.cpp index 9992bff..c6e9c48 100644 --- a/WebView2/Plugin.cpp +++ b/WebView2/Plugin.cpp @@ -221,10 +221,9 @@ PLUGIN_EXPORT double Update(void* data) measure->callbackResult = result; } - // Trigger Rainmeter update after callback completes to sync values - if (measure->rm) + // Trigger Rainmeter redraw after callback completes + if (measure->skin) { - RmExecute(measure->skin, L"!UpdateMeasure #CURRENTSECTION#"); RmExecute(measure->skin, L"!UpdateMeter *"); RmExecute(measure->skin, L"!Redraw"); } @@ -242,19 +241,13 @@ PLUGIN_EXPORT LPCWSTR GetString(void* data) { Measure* measure = (Measure*)data; - // Return the callback result if available, otherwise return status + // Return the callback result if available, otherwise return "0" if (!measure->callbackResult.empty()) { return measure->callbackResult.c_str(); } - else if (measure->initialized) - { - return L"WebView2 Initialized"; - } - else - { - return L"WebView2 Initializing..."; - } + + return L"0"; } PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) @@ -374,14 +367,14 @@ PLUGIN_EXPORT LPCWSTR CallJS(void* data, const int argc, const WCHAR* argv[]) ).Get() ); - // Return cached result if available, otherwise "Calling..." + // Return cached result if available, otherwise "0" if (measure->jsResults.find(key) != measure->jsResults.end()) { measure->buffer = measure->jsResults[key]; } else { - measure->buffer = L"Calling..."; + measure->buffer = L"0"; } return measure->buffer.c_str(); diff --git a/WebView2/WebView2.cpp b/WebView2/WebView2.cpp index b7aae13..1e25761 100644 --- a/WebView2/WebView2.cpp +++ b/WebView2/WebView2.cpp @@ -143,6 +143,49 @@ HRESULT Measure::CreateControllerHandler(HRESULT result, ICoreWebView2Controller nullptr ); + // Add NavigationCompleted event to call OnInitialize after page loads + webView->add_NavigationCompleted( + Callback( + [this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) -> HRESULT + { + // Call JavaScript OnInitialize callback if it exists and capture return value + webView->ExecuteScript( + L"(function() { if (typeof window.OnInitialize === 'function') { var result = window.OnInitialize(); return result !== undefined ? String(result) : ''; } return ''; })();", + Callback( + [this](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT + { + if (SUCCEEDED(errorCode) && resultObjectAsJson) + { + // Remove quotes from JSON string result + std::wstring result = resultObjectAsJson; + if (result.length() >= 2 && result.front() == L'"' && result.back() == L'"') + { + result = result.substr(1, result.length() - 2); + } + + // Store the callback result + if (!result.empty() && result != L"null") + { + callbackResult = result; + + // Trigger Rainmeter redraw after callback completes + if (skin) + { + RmExecute(skin, L"!UpdateMeter *"); + RmExecute(skin, L"!Redraw"); + } + } + } + return S_OK; + } + ).Get() + ); + return S_OK; + } + ).Get(), + nullptr + ); + // Navigate to URL if (!url.empty()) { @@ -154,31 +197,5 @@ HRESULT Measure::CreateControllerHandler(HRESULT result, ICoreWebView2Controller if (rm) RmLog(rm, LOG_NOTICE, L"WebView2: Initialized successfully with COM Host Objects"); - // Call JavaScript OnInitialize callback if it exists and capture return value - webView->ExecuteScript( - L"(function() { if (typeof window.OnInitialize === 'function') { var result = window.OnInitialize(); return result !== undefined ? String(result) : ''; } return ''; })();", - Callback( - [this](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT - { - if (SUCCEEDED(errorCode) && resultObjectAsJson) - { - // Remove quotes from JSON string result - std::wstring result = resultObjectAsJson; - if (result.length() >= 2 && result.front() == L'"' && result.back() == L'"') - { - result = result.substr(1, result.length() - 2); - } - - // Store the callback result - if (!result.empty() && result != L"null") - { - callbackResult = result; - } - } - return S_OK; - } - ).Get() - ); - return S_OK; } From 8427fd50e8ae6c8180575973a9493813edab4a7c Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Wed, 3 Dec 2025 18:22:24 +0500 Subject: [PATCH 3/9] Add WebView2 plugin implementation and enhance README with comprehensive details and a new clickthrough option. --- README.md | 735 ++++++++++++++++++++++++++++++------------ WebView2/Plugin.cpp | 68 +++- WebView2/Plugin.h | 2 + WebView2/WebView2.cpp | 3 + 4 files changed, 597 insertions(+), 211 deletions(-) diff --git a/README.md b/README.md index d036144..64352d6 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,154 @@ # WebView2 Plugin for Rainmeter -A powerful Rainmeter plugin that embeds Microsoft Edge WebView2 into your skins, enabling modern web content with full JavaScript interop capabilities. +
-![Version](https://img.shields.io/badge/version-0.0.3-blue) -![License](https://img.shields.io/badge/license-MIT-green) -![Rainmeter](https://img.shields.io/badge/rainmeter-4.5%2B-orange) +![WebView2 Plugin Banner](https://img.shields.io/badge/WebView2-Rainmeter_Plugin-0078D4?style=for-the-badge&logo=microsoft-edge&logoColor=white) -## 🌟 Features +**Embed modern web content directly into your Rainmeter skins with full JavaScript interactivity** -- **Modern Web Engine**: Leverage Microsoft Edge WebView2 for rendering modern HTML5, CSS3, and JavaScript -- **JavaScript Bridge**: Seamless two-way communication between Rainmeter and web content -- **Rainmeter API Access**: Full access to Rainmeter's API from JavaScript -- **Dynamic Content**: Load local HTML files or remote URLs -- **Event Handling**: Support for custom events and callbacks -- **Multiple Skins**: Run multiple WebView2 instances simultaneously +[![Version](https://img.shields.io/badge/version-0.0.3-blue?style=flat-square)](../../releases) +[![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE) +[![Rainmeter](https://img.shields.io/badge/rainmeter-4.5+-orange?style=flat-square)](https://www.rainmeter.net/) +[![Windows](https://img.shields.io/badge/windows-10%2B-0078D6?style=flat-square&logo=windows&logoColor=white)](https://www.microsoft.com/windows) + +[📥 Download](#-installation) • [📖 Documentation](#-quick-start) • [💡 Examples](#-examples) • [🤝 Contributing](#-contributing) + +
+ +--- + +## ✨ What Can You Build? + + + + + + + +
+Clock
+Animated Widgets
+Create stunning animated clocks, weather displays, and visualizers +
+Web
+Web Dashboards
+Embed live web content and interactive dashboards +
+API
+Smart Integrations
+Connect to APIs and control Rainmeter with JavaScript +
+ +--- + +## 🎯 Key Features + +
+🚀 Modern Web Engine + +Powered by Microsoft Edge WebView2, supporting: +- ✅ HTML5, CSS3, JavaScript ES6+ +- ✅ Modern frameworks (React, Vue, Svelte) +- ✅ WebGL, Canvas, SVG animations +- ✅ Transparent backgrounds by default + +
+ +
+🔌 Seamless JavaScript Bridge + +Two-way communication between web and Rainmeter: +- ✅ Call Rainmeter API from JavaScript +- ✅ Execute JavaScript from Rainmeter +- ✅ Real-time data synchronization +- ✅ Custom events and callbacks + +
+ +
+⚡ Dynamic & Flexible + +- ✅ Load local HTML or remote URLs +- ✅ Multiple WebView instances per skin +- ✅ Hot-reload without flickering +- ✅ Developer tools (F12) built-in + +
+ +--- ## 📋 Requirements -- **Windows**: Windows 10 version 1803 or later (Windows 11 recommended) -- **Rainmeter**: Version 4.5 or higher -- **WebView2 Runtime**: [Download here](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) (usually pre-installed on Windows 11) +> **Before you begin**, make sure you have: + +| Requirement | Version | Status | +|------------|---------|---------| +| **Windows** | 10 (1803+) or 11 | ![Windows](https://img.shields.io/badge/required-critical-red?style=flat-square) | +| **Rainmeter** | 4.5 or higher | ![Rainmeter](https://img.shields.io/badge/required-critical-red?style=flat-square) | +| **WebView2 Runtime** | Latest | ![WebView2](https://img.shields.io/badge/required-critical-red?style=flat-square) | + +
+📦 Don't have WebView2 Runtime? + +
+ +**Good news!** Windows 11 includes it by default. For Windows 10: + +1. 🔗 [Download WebView2 Runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) +2. 🎯 Choose "Evergreen Standalone Installer" +3. ⚡ Run the installer (takes ~1 minute) + +
+ +--- + +## 📥 Installation + +### 🎁 Method 1: One-Click Install (Recommended) + +
+ +**The easiest way to get started!** -## 🚀 Installation +1. 📦 [Download the `.rmskin` file](../../releases/latest) +2. 🖱️ Double-click to install +3. ✨ Done! Plugin and examples are ready to use -### Method 1: RMSKIN Package (Recommended) +Rainmeter will automatically install everything you need -1. Download the latest `.rmskin` file from the [Releases](../../releases) page -2. Double-click the `.rmskin` file to install -3. Rainmeter will automatically install the plugin and example skins +
-### Method 2: Manual Installation +### 🛠️ Method 2: Manual Installation -1. Download the plugin DLLs from the [Releases](../../releases) page -2. Extract the appropriate DLL for your system: - - `x64/WebView2.dll` for 64-bit Rainmeter - - `x32/WebView2.dll` for 32-bit Rainmeter -3. Place the DLL in your Rainmeter plugins folder: - - `%AppData%\Rainmeter\Plugins\` +
+Click to expand manual installation steps -## 📖 Usage +
-### Basic Skin Configuration +1. **Download** the plugin DLLs from [Releases](../../releases) + +2. **Choose** the right version: + ``` + 📁 x64/WebView2.dll ← For 64-bit Rainmeter (most common) + 📁 x32/WebView2.dll ← For 32-bit Rainmeter + ``` + +3. **Copy** to your Rainmeter plugins folder: + ``` + %AppData%\Rainmeter\Plugins\ + ``` + +4. **Restart** Rainmeter + +
+ +--- + +## 🚀 Quick Start + +### Your First WebView Skin + +Create a new skin with this minimal configuration: ```ini [Rainmeter] @@ -50,276 +158,495 @@ Update=1000 Measure=Plugin Plugin=WebView2 URL=file:///#@#index.html -Width=800 -Height=600 +W=800 +H=600 +``` + +Create `index.html` in your `@Resources` folder: + +```html + + + + + + +

🎉 Hello Rainmeter!

+ + +``` + +**That's it!** Load the skin and see your first WebView in action. + +--- + +## ⚙️ Configuration Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescriptionDefaultExample
URL🌐 HTML file or web URL
Supports: file:///, http://, https://
Requiredfile:///#@#index.html
W📏 Width in pixels8001920
H📏 Height in pixels6001080
X↔️ Horizontal position offset0100
Y↕️ Vertical position offset050
Hidden👁️ Start hidden
0 = visible, 1 = hidden
01
Clickthrough🖱️ Mouse interaction
0 = interactive, 1 = clickthrough
01
DynamicVariables🔄 Enable live updates01
+ +> **💡 Pro Tip:** When `DynamicVariables=1`, the WebView updates smartly: +> - **URL changes** → Navigates without recreating +> - **Size/Position changes** → Applied instantly, no flicker +> - **Visibility changes** → Instant toggle + +--- + +## 🎮 Bang Commands + +Control your WebView with Rainmeter bangs: + + + + + + +
+ +**Navigation Commands** + +```ini +; Go to a URL +[!CommandMeasure MeasureWebView "Navigate https://example.com"] + +; Reload current page +[!CommandMeasure MeasureWebView "Reload"] + +; Browser history +[!CommandMeasure MeasureWebView "GoBack"] +[!CommandMeasure MeasureWebView "GoForward"] ``` -### Plugin Options + -| Option | Description | Default | Required | -|--------|-------------|---------|----------| -| `URL` | Path to HTML file or web URL (supports `file:///`, `http://`, `https://`) | - | Yes | -| `W` | Width of the WebView in pixels | 800 | No | -| `H` | Height of the WebView in pixels | 600 | No | -| `X` | X position offset in pixels | 0 | No | -| `Y` | Y position offset in pixels | 0 | No | -| `Hidden` | Hide the WebView on load (0 = visible, 1 = hidden) | 0 | No | -| `DynamicVariables` | Enable dynamic variable updates (0 or 1) | 0 | No | +**Control Commands** -**Notes**: -- Transparent background is always enabled by default. Developer tools (F12) are always available. -- When `DynamicVariables=1`, the plugin intelligently handles updates: - - **URL changes**: Navigates to the new URL without recreating the WebView - - **Dimension/Position changes** (`W`, `H`, `X`, `Y`): Applied instantly without flickering - - **Visibility changes** (`Hidden`): Applied instantly - - The WebView is only created once on first load, preventing flickering issues +```ini +; Execute JavaScript +[!CommandMeasure MeasureWebView "ExecuteScript alert('Hi!')"] +; Developer tools +[!CommandMeasure MeasureWebView "OpenDevTools"] -### Bang Commands +; Mouse interaction +[!CommandMeasure MeasureWebView "ToggleClickthrough"] +[!CommandMeasure MeasureWebView "EnableClickthrough"] +[!CommandMeasure MeasureWebView "DisableClickthrough"] +``` -Execute commands from your skin using `[!CommandMeasure MeasureName "Command"]`: +
-| Command | Description | Example | -|---------|-------------|---------| -| `Navigate ` | Navigate to a URL (web or file path) | `[!CommandMeasure MeasureWebView "Navigate https://example.com"]` | -| `Reload` | Reload the current page | `[!CommandMeasure MeasureWebView "Reload"]` | -| `GoBack` | Navigate to the previous page in history | `[!CommandMeasure MeasureWebView "GoBack"]` | -| `GoForward` | Navigate to the next page in history | `[!CommandMeasure MeasureWebView "GoForward"]` | -| `ExecuteScript - - diff --git a/Resources/Skins/WebView2/CompleteDemo/CompleteDemo.ini b/Resources/Skins/WebView2/CompleteDemo/CompleteDemo.ini deleted file mode 100644 index 522ffe0..0000000 --- a/Resources/Skins/WebView2/CompleteDemo/CompleteDemo.ini +++ /dev/null @@ -1,185 +0,0 @@ -[Rainmeter] -Update=1000 -AccurateText=1 -DynamicWindowSize=1 - -[Metadata] -Name=WebView2 Complete Demo -Author=nstechbytes -Information=Comprehensive demo of all WebView2 features: callbacks, section variables, and JavaScript integration -Version=1.0 -License=MIT - -; ================================================== -; WebView2 Plugin -; ================================================== - -[MeasureWebView] -Measure=Plugin -Plugin=WebView2 -URL=#@#CompleteDemo\index.html -W=800 -H=600 -X=25 -Y=25 - -; ================================================== -; Background -; ================================================== - -[MeterBackground] -Meter=Shape -Shape=Rectangle 0,0,850,1050 | FillColor 0,0,0,2 | StrokeWidth 0 - -; ================================================== -; Feature Displays Below WebView -; ================================================== - -[MeterTitle] -Meter=String -X=25 -Y=640 -FontSize=16 -FontColor=255,255,255 -FontWeight=700 -Text=Live Feature Demonstrations -AntiAlias=1 - -; --- Feature 1: OnUpdate Return Value --- -[MeterFeature1Title] -Meter=String -X=25 -Y=20R -FontSize=12 -FontColor=100,200,255 -FontWeight=600 -Text=1. OnUpdate() Return Value: -AntiAlias=1 - -[MeterOnUpdateValue] -Meter=String -MeasureName=MeasureWebView -X=25 -Y=5R -FontSize=14 -FontColor=100,255,100 -FontWeight=700 -Text=%1 -AntiAlias=1 -DynamicVariables=1 - -; --- Feature 2: CallJS Examples --- -[MeterFeature2Title] -Meter=String -X=25 -Y=20R -FontSize=12 -FontColor=100,200,255 -FontWeight=600 -Text=2. CallJS() - Call Any JavaScript Function: -AntiAlias=1 - -[MeterTempLabel] -Meter=String -X=25 -Y=8R -FontSize=10 -FontColor=200,200,200 -Text=getTemperature(): -AntiAlias=1 - -[MeterTemp] -Meter=String -X=150 -Y=0r -FontSize=10 -FontColor=255,255,255 -Text=[MeasureWebView:CallJS('getTemperature')] -AntiAlias=1 -DynamicVariables=1 - -[MeterUserLabel] -Meter=String -X=25 -Y=5R -FontSize=10 -FontColor=200,200,200 -Text=getUserName(): -AntiAlias=1 - -[MeterUser] -Meter=String -X=150 -Y=0r -FontSize=10 -FontColor=255,255,255 -Text=[MeasureWebView:CallJS('getUserName')] -AntiAlias=1 -DynamicVariables=1 - -[MeterTimeLabel] -Meter=String -X=25 -Y=5R -FontSize=10 -FontColor=200,200,200 -Text=getCurrentTime(): -AntiAlias=1 - -[MeterTime] -Meter=String -X=150 -Y=0r -FontSize=10 -FontColor=255,255,255 -Text=[MeasureWebView:CallJS('getCurrentTime')] -AntiAlias=1 -DynamicVariables=1 - -[MeterRandomLabel] -Meter=String -X=25 -Y=5R -FontSize=10 -FontColor=200,200,200 -Text=getRandomNumber(): -AntiAlias=1 - -[MeterRandom] -Meter=String -X=150 -Y=0r -FontSize=10 -FontColor=255,255,255 -Text=[MeasureWebView:CallJS('getRandomNumber')] -AntiAlias=1 -DynamicVariables=1 - -[MeterSystemLabel] -Meter=String -X=25 -Y=5R -FontSize=10 -FontColor=200,200,200 -Text=getSystemInfo(): -AntiAlias=1 - -[MeterSystem] -Meter=String -X=150 -Y=0r -FontSize=10 -FontColor=255,255,255 -Text=[MeasureWebView:CallJS('getSystemInfo')] -AntiAlias=1 -DynamicVariables=1 - -; --- Info --- -[MeterInfo] -Meter=String -X=25 -Y=20R -FontSize=9 -FontColor=150,150,150 -Text=All values update every second • Define any function in JS and call it with CallJS() -AntiAlias=1 From d5f44138e01d0fe3cbdb639f6e7eacd1ba7093e7 Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Wed, 3 Dec 2025 18:51:23 +0500 Subject: [PATCH 5/9] Introduce a WebView2 Rainmeter skin demonstrating JavaScript interaction with OnInitialize, OnUpdate, and CallJS. --- .../@Resources/JSInteraction/index.html | 44 ++++++ .../@Resources/JSInteraction/script.js | 46 +++++++ .../@Resources/JSInteraction/style.css | 128 ++++++++++++++++++ .../WebView2/JSInteraction/JSInteraction.ini | 93 +++++++++++++ 4 files changed, 311 insertions(+) create mode 100644 Resources/Skins/WebView2/@Resources/JSInteraction/index.html create mode 100644 Resources/Skins/WebView2/@Resources/JSInteraction/script.js create mode 100644 Resources/Skins/WebView2/@Resources/JSInteraction/style.css create mode 100644 Resources/Skins/WebView2/JSInteraction/JSInteraction.ini diff --git a/Resources/Skins/WebView2/@Resources/JSInteraction/index.html b/Resources/Skins/WebView2/@Resources/JSInteraction/index.html new file mode 100644 index 0000000..7a2cbe8 --- /dev/null +++ b/Resources/Skins/WebView2/@Resources/JSInteraction/index.html @@ -0,0 +1,44 @@ + + + + + + JS Interaction Demo + + + +

JS Interaction

+ +
+
+
+ OnUpdate Cycle + Updates every second +
+
Waiting...
+
+ +
+
+ Event Log + Recent activity +
+
+
+ +
+
+ CallJS Demo +
+

+ Rainmeter is calling addNumbers(15, 25) via section variable. +

+

+ Check the Rainmeter skin to see the result! +

+
+
+ + + + diff --git a/Resources/Skins/WebView2/@Resources/JSInteraction/script.js b/Resources/Skins/WebView2/@Resources/JSInteraction/script.js new file mode 100644 index 0000000..e517c45 --- /dev/null +++ b/Resources/Skins/WebView2/@Resources/JSInteraction/script.js @@ -0,0 +1,46 @@ +let updateCount = 0; + +// Called once when the plugin is ready +window.OnInitialize = function() { + log("🚀 OnInitialize called!"); + return "Initialized!"; +}; + +// Called on every Rainmeter update cycle +window.OnUpdate = function() { + updateCount++; + const message = `Update #${updateCount}`; + + // Update the display in HTML + const display = document.getElementById('update-display'); + if (display) { + display.textContent = message; + } + + // Return value updates the measure's string value in Rainmeter + return message; +}; + +// Function callable from Rainmeter via [Measure:CallJS('addNumbers', 'a', 'b')] +window.addNumbers = function(a, b) { + const sum = parseInt(a) + parseInt(b); + log(`🧮 addNumbers called: ${a} + ${b} = ${sum}`); + return sum; +}; + +// Helper to log to HTML +function log(message) { + const container = document.getElementById('log-container'); + if (container) { + const entry = document.createElement('div'); + entry.className = 'log-entry'; + entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`; + container.insertBefore(entry, container.firstChild); + + // Keep log size manageable + if (container.children.length > 50) { + container.removeChild(container.lastChild); + } + } + console.log(message); +} diff --git a/Resources/Skins/WebView2/@Resources/JSInteraction/style.css b/Resources/Skins/WebView2/@Resources/JSInteraction/style.css new file mode 100644 index 0000000..fad14ef --- /dev/null +++ b/Resources/Skins/WebView2/@Resources/JSInteraction/style.css @@ -0,0 +1,128 @@ +:root { + --primary: #6366f1; + --secondary: #a855f7; + --bg: #0f172a; + --card-bg: rgba(30, 41, 59, 0.7); + --text: #f8fafc; + --text-muted: #94a3b8; + --success: #22c55e; + --error: #ef4444; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', system-ui, sans-serif; + background: var(--bg); + color: var(--text); + height: 100vh; + overflow: hidden; + display: flex; + flex-direction: column; + padding: 20px; +} + +h1 { + font-size: 1.5rem; + margin-bottom: 1rem; + background: linear-gradient(to right, var(--primary), var(--secondary)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + text-align: center; +} + +.container { + flex: 1; + display: flex; + flex-direction: column; + gap: 1rem; + overflow-y: auto; + padding-right: 5px; +} + +.card { + background: var(--card-bg); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; + padding: 1rem; + transition: transform 0.2s; +} + +.card:hover { + transform: translateY(-2px); + border-color: rgba(255, 255, 255, 0.2); +} + +.card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.5rem; +} + +.card-title { + font-weight: 600; + color: var(--text); +} + +.card-subtitle { + font-size: 0.8rem; + color: var(--text-muted); +} + +.value-display { + font-family: 'Consolas', monospace; + background: rgba(0, 0, 0, 0.3); + padding: 0.5rem; + border-radius: 6px; + color: var(--success); + word-break: break-all; + text-align: center; + font-size: 1.2rem; +} + +.log-container { + font-family: 'Consolas', monospace; + font-size: 0.8rem; + color: var(--text-muted); + background: rgba(0, 0, 0, 0.3); + padding: 0.5rem; + border-radius: 6px; + height: 150px; + overflow-y: auto; +} + +.log-entry { + margin-bottom: 4px; + border-bottom: 1px solid rgba(255,255,255,0.05); + padding-bottom: 2px; +} + +/* Custom Scrollbar */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.05); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + background: linear-gradient(to bottom, var(--primary), var(--secondary)); + border-radius: 4px; + border: 2px solid transparent; + background-clip: content-box; +} + +::-webkit-scrollbar-thumb:hover { + background: linear-gradient(to bottom, var(--secondary), var(--primary)); + border-radius: 2px solid transparent; + background-clip: content-box; +} diff --git a/Resources/Skins/WebView2/JSInteraction/JSInteraction.ini b/Resources/Skins/WebView2/JSInteraction/JSInteraction.ini new file mode 100644 index 0000000..fbd42e7 --- /dev/null +++ b/Resources/Skins/WebView2/JSInteraction/JSInteraction.ini @@ -0,0 +1,93 @@ +[Rainmeter] +Update=1000 +AccurateText=1 +DynamicWindowSize=1 + +[Metadata] +Name=JSInteraction +Author=nstechbytes +Information=Demonstrates JavaScript interaction (OnInitialize, OnUpdate, CallJS) with the WebView2 plugin. +Version=1.0 +License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 + +; ======================================== +; Measure +; ======================================== +[MeasureWebView] +Measure=Plugin +Plugin=WebView2 +URL=file://#@#JSInteraction\index.html +W=400 +H=450 +X=25 +Y=25 +DynamicVariables=1 + +; ================================================== +; Background +; ================================================== + +[MeterBackground] +Meter=Shape +Shape=Rectangle 0,0,450,650,12 | FillColor 136,93,244,200 | StrokeWidth 0 + +; ================================================== +; Meters +; ================================================== + +[MeterTitle] +Meter=String +MeasureName=MeasureWebView +X=225 +Y=500 +W=400 +H=20 +FontFace=Segoe UI +FontSize=14 +FontWeight=700 +FontColor=255,255,255,255 +StringAlign=Center +AntiAlias=1 +Text=JS Interaction Demo + +[MeterStatus] +Meter=String +MeasureName=MeasureWebView +X=225 +Y=5R +W=400 +H=40 +FontFace=Consolas +FontSize=10 +FontColor=100,255,100,255 +StringAlign=Center +AntiAlias=1 +Text=Status: %1 + +[MeterCallJSResult] +Meter=String +X=225 +Y=5R +W=400 +H=40 +FontFace=Segoe UI +FontSize=11 +FontColor=200,200,255,255 +StringAlign=Center +AntiAlias=1 +Text=Result from JS: [MeasureWebView:CallJS('addNumbers', '15', '25')] +DynamicVariables=1 + +[MeterInstruction] +Meter=String +X=225 +Y=5R +W=380 +H=40 +FontFace=Segoe UI +FontSize=9 +FontColor=150,150,150,255 +StringAlign=Center +AntiAlias=1 +Text=Check the console (F12) for logs +ClipString=1 From 49b1381b0a00d7dec9046a50b686d3ed05048ea1 Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Wed, 3 Dec 2025 18:56:35 +0500 Subject: [PATCH 6/9] Add new WebView2 example skins for JavaScript interaction, weather, bang commands, calendar, clock, section/measure reading, utility functions, information properties, and Islamic date. --- Resources/Skins/WebView2/BangCommand/BangCommand.ini | 2 +- Resources/Skins/WebView2/Calendar/Calendar.ini | 4 ++-- Resources/Skins/WebView2/Clock/Clock.ini | 4 ++-- .../WebView2/InformationProperty/InformationProperty.ini | 2 +- Resources/Skins/WebView2/IslamicDate/IslamicDate.ini | 4 ++-- Resources/Skins/WebView2/JSInteraction/JSInteraction.ini | 2 +- .../Skins/WebView2/ReadMeasureOption/ReadMeasureOption.ini | 2 +- .../Skins/WebView2/ReadSectionOption/ReadSectionOption.ini | 4 ++-- Resources/Skins/WebView2/UtilityFunction/UtilityFunction.ini | 2 +- Resources/Skins/WebView2/Weather/Weather.ini | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Resources/Skins/WebView2/BangCommand/BangCommand.ini b/Resources/Skins/WebView2/BangCommand/BangCommand.ini index 76556eb..8de6710 100644 --- a/Resources/Skins/WebView2/BangCommand/BangCommand.ini +++ b/Resources/Skins/WebView2/BangCommand/BangCommand.ini @@ -7,7 +7,7 @@ DynamicWindowSize=1 Name=BangCommand Author=nstechbytes Information=Demonstrates controlling WebView2 via !CommandMeasure bangs. -Version=1.0 +Version=0.0.6 License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 [Variables] diff --git a/Resources/Skins/WebView2/Calendar/Calendar.ini b/Resources/Skins/WebView2/Calendar/Calendar.ini index 5179e61..f1fcfc0 100644 --- a/Resources/Skins/WebView2/Calendar/Calendar.ini +++ b/Resources/Skins/WebView2/Calendar/Calendar.ini @@ -5,8 +5,8 @@ Update=1000 Name=Calendar Author=nstechbytes Information=Calendar Widget using WebView2 -Version=0.0.3 -License=MIT +Version=0.0.6 +License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 ; ======================================== ; Measure ; ======================================== diff --git a/Resources/Skins/WebView2/Clock/Clock.ini b/Resources/Skins/WebView2/Clock/Clock.ini index 9ba8325..830ef3d 100644 --- a/Resources/Skins/WebView2/Clock/Clock.ini +++ b/Resources/Skins/WebView2/Clock/Clock.ini @@ -5,8 +5,8 @@ Update=1000 Name=Calendar Author=nstechbytes Information=Calendar Widget using WebView2 -Version=0.0.3 -License=MIT +Version=0.0.6 +License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 ; ======================================== ; Measure ; ======================================== diff --git a/Resources/Skins/WebView2/InformationProperty/InformationProperty.ini b/Resources/Skins/WebView2/InformationProperty/InformationProperty.ini index 46f7e05..021bcb2 100644 --- a/Resources/Skins/WebView2/InformationProperty/InformationProperty.ini +++ b/Resources/Skins/WebView2/InformationProperty/InformationProperty.ini @@ -7,7 +7,7 @@ DynamicWindowSize=1 Name=InformationProperty Author=nstechbytes Information=Shows Rainmeter information properties via WebView2. -Version=1.0 +Version=0.0.6 License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 ; ======================================== ; Measure diff --git a/Resources/Skins/WebView2/IslamicDate/IslamicDate.ini b/Resources/Skins/WebView2/IslamicDate/IslamicDate.ini index 05573e0..fa8609d 100644 --- a/Resources/Skins/WebView2/IslamicDate/IslamicDate.ini +++ b/Resources/Skins/WebView2/IslamicDate/IslamicDate.ini @@ -5,8 +5,8 @@ Update=1000 Name=Islamic Date Author=nstechbytes Information=Islamic (Hijri) Date Widget using WebView2 -Version=0.0.1 -License=MIT +Version=0.0.6 +License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 ; ======================================== ; Measure ; ======================================== diff --git a/Resources/Skins/WebView2/JSInteraction/JSInteraction.ini b/Resources/Skins/WebView2/JSInteraction/JSInteraction.ini index fbd42e7..71833fd 100644 --- a/Resources/Skins/WebView2/JSInteraction/JSInteraction.ini +++ b/Resources/Skins/WebView2/JSInteraction/JSInteraction.ini @@ -7,7 +7,7 @@ DynamicWindowSize=1 Name=JSInteraction Author=nstechbytes Information=Demonstrates JavaScript interaction (OnInitialize, OnUpdate, CallJS) with the WebView2 plugin. -Version=1.0 +Version=0.0.6 License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 ; ======================================== diff --git a/Resources/Skins/WebView2/ReadMeasureOption/ReadMeasureOption.ini b/Resources/Skins/WebView2/ReadMeasureOption/ReadMeasureOption.ini index 5bc0e87..cc2110b 100644 --- a/Resources/Skins/WebView2/ReadMeasureOption/ReadMeasureOption.ini +++ b/Resources/Skins/WebView2/ReadMeasureOption/ReadMeasureOption.ini @@ -7,7 +7,7 @@ DynamicWindowSize=1 Name=ReadMeasureOption Author=nstechbytes Information=Demonstrates reading options from the current measure using the WebView2 plugin. -Version=1.0 +Version=0.0.6 License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 ; ======================================== ; Measure diff --git a/Resources/Skins/WebView2/ReadSectionOption/ReadSectionOption.ini b/Resources/Skins/WebView2/ReadSectionOption/ReadSectionOption.ini index bde28e0..f19dc6a 100644 --- a/Resources/Skins/WebView2/ReadSectionOption/ReadSectionOption.ini +++ b/Resources/Skins/WebView2/ReadSectionOption/ReadSectionOption.ini @@ -7,8 +7,8 @@ DynamicWindowSize=1 Name=ReadSectionOption Demo Author=nstechbytes Information=Demonstrates reading options from other sections using WebView2 -Version=1.0 -License=MIT +Version=0.0.6 +License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 [Variables] TestVar=Hello from Variables! diff --git a/Resources/Skins/WebView2/UtilityFunction/UtilityFunction.ini b/Resources/Skins/WebView2/UtilityFunction/UtilityFunction.ini index 6374b9d..90b87e3 100644 --- a/Resources/Skins/WebView2/UtilityFunction/UtilityFunction.ini +++ b/Resources/Skins/WebView2/UtilityFunction/UtilityFunction.ini @@ -7,7 +7,7 @@ DynamicWindowSize=1 Name=UtilityFunction Author=nstechbytes Information=Demonstrates RainmeterAPI utility functions using the WebView2 plugin. -Version=1.0 +Version=0.0.6 License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 [Variables] diff --git a/Resources/Skins/WebView2/Weather/Weather.ini b/Resources/Skins/WebView2/Weather/Weather.ini index 99eff65..02b8340 100644 --- a/Resources/Skins/WebView2/Weather/Weather.ini +++ b/Resources/Skins/WebView2/Weather/Weather.ini @@ -5,8 +5,8 @@ Update=1000 Name=Weather Author=nstechbytes Information=Weather Widget using WebView2 -Version=0.0.1 -License=MIT +Version=0.0.6 +License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0 ; ======================================== ; Measure ; ======================================== From 7c4082ff38008fc44bf7770e48151cbabb5a470c Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Wed, 3 Dec 2025 18:59:07 +0500 Subject: [PATCH 7/9] Add skin definition and resource file for WebView2 project. --- Resources/skin_definition.json | 4 ++-- WebView2/WebView2.rc | Bin 1624 -> 1624 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/skin_definition.json b/Resources/skin_definition.json index 5e39e2c..8c25266 100644 --- a/Resources/skin_definition.json +++ b/Resources/skin_definition.json @@ -1,6 +1,6 @@ { "skinDir": ".\\Resources\\Skins", - "version": "0.0.5", + "version": "0.0.6", "minimumVersion": "4.5", "author": "nstechbytes", "variableFiles": "", @@ -17,5 +17,5 @@ "load": "WebView2\\Clock\\Clock.ini", "headerImage": ".\\Resources\\banner.bmp", "configPrefix": "WebView2", - "output": ".\\dist\\WebView2_v0.0.5_Alpha5.rmskin" + "output": ".\\dist\\WebView2_v0.0.6_Alpha6.rmskin" } diff --git a/WebView2/WebView2.rc b/WebView2/WebView2.rc index 883788c0d5ecc39b837d179fa9dd5c0c02ffdd43..89c9450b92785dfa43f3749c9c0feab48bc84180 100644 GIT binary patch delta 24 gcmcb?bAxBX5k|9#N9~!-7?dXaGm3APW3*xg0B<7)PXGV_ delta 24 gcmcb?bAxBX5k}LAN9~zS8I&gbGm3APW3*xg0B;5dO#lD@ From ce0d41ca63cc0f4ea76944378cc59c1df4569320 Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Wed, 3 Dec 2025 19:24:10 +0500 Subject: [PATCH 8/9] update README JS example to expose function globally --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 64352d6..70e7a7a 100644 --- a/README.md +++ b/README.md @@ -344,9 +344,9 @@ DynamicVariables=1 ```javascript // In your HTML -function getTemperature() { +window.getTemperature = function() { return 72; -} +}; ``` --- @@ -635,7 +635,7 @@ git push origin feature/AmazingFeature Built with powerful tools and inspired by the community -**[Microsoft Edge WebView2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/)** • **[Rainmeter API](https://docs.rainmeter.net/developers/plugin/)** • **Rainmeter Community** +**[Microsoft Edge WebView2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/)** • **[Rainmeter API](https://docs.rainmeter.net/developers/plugin/plugin-anatomy/)** • **Rainmeter Community** From 43f136329b84bf704536963bfdf7a612039521a3 Mon Sep 17 00:00:00 2001 From: nstechbytes Date: Thu, 4 Dec 2025 07:39:43 +0500 Subject: [PATCH 9/9] Implement WebView2 Rainmeter plugin with URL loading, dynamic sizing, and mouse interaction, while removing outdated mouse interaction commands from the README. --- README.md | 5 ----- WebView2/Plugin.cpp | 15 --------------- 2 files changed, 20 deletions(-) diff --git a/README.md b/README.md index 70e7a7a..1bf468b 100644 --- a/README.md +++ b/README.md @@ -296,11 +296,6 @@ Control your WebView with Rainmeter bangs: ; Developer tools [!CommandMeasure MeasureWebView "OpenDevTools"] - -; Mouse interaction -[!CommandMeasure MeasureWebView "ToggleClickthrough"] -[!CommandMeasure MeasureWebView "EnableClickthrough"] -[!CommandMeasure MeasureWebView "DisableClickthrough"] ``` diff --git a/WebView2/Plugin.cpp b/WebView2/Plugin.cpp index 27a604a..cc41929 100644 --- a/WebView2/Plugin.cpp +++ b/WebView2/Plugin.cpp @@ -348,21 +348,6 @@ PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) { measure->webView->OpenDevToolsWindow(); } - else if (_wcsicmp(action.c_str(), L"EnableClickthrough") == 0) - { - measure->clickthrough = true; - UpdateClickthrough(measure); - } - else if (_wcsicmp(action.c_str(), L"DisableClickthrough") == 0) - { - measure->clickthrough = false; - UpdateClickthrough(measure); - } - else if (_wcsicmp(action.c_str(), L"ToggleClickthrough") == 0) - { - measure->clickthrough = !measure->clickthrough; - UpdateClickthrough(measure); - } } // Generic JavaScript function caller