Skip to content

Commit 1db6d10

Browse files
authored
Merge pull request #7 from RicardoTM05/working2
Adding new options and actions.
2 parents ab008f6 + 2834a3a commit 1db6d10

3 files changed

Lines changed: 312 additions & 32 deletions

File tree

WebView2/Plugin.cpp

Lines changed: 148 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
5151
// Measure constructor
5252
Measure::Measure() : rm(nullptr), skin(nullptr), skinWindow(nullptr),
5353
measureName(nullptr),
54-
width(800), height(600), x(0), y(0),
55-
visible(true), initialized(false), clickthrough(false), webMessageToken{}
54+
width(800), height(600), x(0), y(0), zoomFactor(1.0),
55+
visible(true), initialized(false), clickthrough(false), allowDualControl(true), webMessageToken{}
5656
{
5757
// Initialize COM for this thread if not already done
5858
if (!g_comInitialized)
@@ -129,6 +129,54 @@ void UpdateClickthrough(Measure* measure)
129129
}
130130
}
131131

132+
// Inject AllowDualControl script into the WebView
133+
void InjectAllowDualControl(Measure* measure)
134+
{
135+
if (!measure->webView) return;
136+
// Inject script to capture page load events for drag/move and context menu
137+
measure->webView->ExecuteScript(
138+
L"let rm_AllowDualControl=false,rm_AllowDualControlOn=false,rm_AllowDualControlClientX=0,rm_AllowDualControlClientY=0;function rm_SetAllowDualControl(v){rm_AllowDualControl=!!v;if(!rm_AllowDualControl)rm_AllowDualControlOn=false;}document.body.onpointerdown=e=>{if(!rm_AllowDualControl)return;if(e.button===0&&e.ctrlKey){e.preventDefault();e.stopImmediatePropagation();rm_AllowDualControlOn=true;rm_AllowDualControlClientX=e.clientX;rm_AllowDualControlClientY=e.clientY;try{document.body.setPointerCapture(e.pointerId);}catch{}}};document.body.onpointermove=e=>{if(!rm_AllowDualControl||!rm_AllowDualControlOn)return;e.preventDefault();RainmeterAPI.Bang('[!Move '+(e.screenX-RainmeterAPI.ReadFormula('X',0)-rm_AllowDualControlClientX)+' '+(e.screenY-RainmeterAPI.ReadFormula('Y',0)-rm_AllowDualControlClientY)+']');};document.body.onpointerup=e=>{if(!rm_AllowDualControl)return;if(e.button===0){e.preventDefault();rm_AllowDualControlOn=false;try{document.body.releasePointerCapture(e.pointerId);}catch{}}};document.body.oncontextmenu=e=>{if(!rm_AllowDualControl)return;if(e.button===2&&e.ctrlKey){e.preventDefault();RainmeterAPI.Bang('[!SkinMenu]');}};",
139+
Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
140+
[measure](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT
141+
{
142+
return S_OK;
143+
}
144+
).Get()
145+
);
146+
measure->isAllowDualControlInjected = true;
147+
UpdateAllowDualControl(measure);
148+
}
149+
150+
// Update AllowDualControl state in the WebView
151+
void UpdateAllowDualControl(Measure* measure)
152+
{
153+
if (!measure->webView) return;
154+
155+
if (measure->allowDualControl)
156+
{
157+
measure->webView->ExecuteScript(
158+
L"rm_SetAllowDualControl(true);",
159+
Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
160+
[measure](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT
161+
{
162+
return S_OK;
163+
}
164+
).Get()
165+
);
166+
}
167+
else {
168+
measure->webView->ExecuteScript(
169+
L"rm_SetAllowDualControl(false);",
170+
Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
171+
[measure](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT
172+
{
173+
return S_OK;
174+
}
175+
).Get()
176+
);
177+
}
178+
}
179+
132180
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
133181
{
134182
Measure* measure = (Measure*)data;
@@ -182,12 +230,72 @@ PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
182230
int newHeight = RmReadInt(rm, L"H", 600);
183231
int newX = RmReadInt(rm, L"X", 0);
184232
int newY = RmReadInt(rm, L"Y", 0);
185-
bool newVisible = RmReadInt(rm, L"Hidden", 0) == 0;
186-
bool newClickthrough = RmReadInt(rm, L"Clickthrough", 0) != 0;
187-
233+
double newZoomFactor = RmReadFormula(rm, L"ZoomFactor", 1.0);
234+
bool newVisible = RmReadInt(rm, L"Hidden", 0) <= 0;
235+
bool newClickthrough = RmReadInt(rm, L"Clickthrough", 0) >= 1;
236+
237+
// Read AllowDualControl for Yincognito's script injection
238+
bool newAllowDualControl = RmReadInt(rm, L"AllowDualControl", 1) >= 1;
239+
240+
// Read OnWebViewLoadAction
241+
std::wstring newOnWebViewLoadAction;
242+
LPCWSTR onWebViewLoadOption = RmReadString(rm, L"OnWebViewLoadAction", L"", FALSE);
243+
if (onWebViewLoadOption && wcslen(onWebViewLoadOption) > 0)
244+
{
245+
newOnWebViewLoadAction = onWebViewLoadOption;
246+
}
247+
248+
// Read OnWebViewFailAction
249+
std::wstring newOnWebViewFailAction;
250+
LPCWSTR onWebViewFailOption = RmReadString(rm, L"OnWebViewFailAction", L"", FALSE);
251+
if (onWebViewFailOption && wcslen(onWebViewFailOption) > 0)
252+
{
253+
newOnWebViewFailAction = onWebViewFailOption;
254+
}
255+
256+
// Read OnPageLoadStartAction
257+
std::wstring newOnPageLoadStartAction;
258+
LPCWSTR onPageLoadStartOption = RmReadString(rm, L"OnPageLoadStartAction", L"", FALSE);
259+
if (onPageLoadStartOption && wcslen(onPageLoadStartOption) > 0)
260+
{
261+
newOnPageLoadStartAction = onPageLoadStartOption;
262+
}
263+
264+
// Read OnPageLoadingAction
265+
std::wstring newOnPageLoadingAction;
266+
LPCWSTR onPageLoadingOption = RmReadString(rm, L"OnPageLoadingAction", L"", FALSE);
267+
if (onPageLoadingOption && wcslen(onPageLoadingOption) > 0)
268+
{
269+
newOnPageLoadingAction = onPageLoadingOption;
270+
}
271+
272+
// Read OnPageLoadFinishAction
273+
std::wstring newOnPageLoadFinishAction;
274+
LPCWSTR onPageLoadFinishOption = RmReadString(rm, L"OnPageLoadFinishAction", L"", FALSE);
275+
if (onPageLoadFinishOption && wcslen(onPageLoadFinishOption) > 0)
276+
{
277+
newOnPageLoadFinishAction = onPageLoadFinishOption;
278+
}
279+
280+
// Read OnPageFirstLoadAction
281+
std::wstring newOnPageFirstLoadAction;
282+
LPCWSTR onPageFirstLoadOption = RmReadString(rm, L"OnPageFirstLoadAction", L"", FALSE);
283+
if (onPageFirstLoadOption && wcslen(onPageFirstLoadOption) > 0)
284+
{
285+
newOnPageFirstLoadAction = onPageFirstLoadOption;
286+
}
287+
288+
// Read OnPageReloadAction
289+
std::wstring newOnPageReloadAction;
290+
LPCWSTR onPageReloadOption = RmReadString(rm, L"OnPageReloadAction", L"", FALSE);
291+
if (onPageReloadOption && wcslen(onPageReloadOption) > 0)
292+
{
293+
newOnPageReloadAction = onPageReloadOption;
294+
}
295+
188296
// Check if URL has changed (requires recreation)
189297
bool urlChanged = (newUrl != measure->url);
190-
298+
191299
// Check if dimensions or position changed (can be updated dynamically)
192300
bool dimensionsChanged = (newWidth != measure->width ||
193301
newHeight != measure->height ||
@@ -196,16 +304,27 @@ PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
196304

197305
bool visibilityChanged = (newVisible != measure->visible);
198306
bool clickthroughChanged = (newClickthrough != measure->clickthrough);
199-
307+
bool allowDualControlChanged = (newAllowDualControl != measure->allowDualControl);
308+
bool zoomFactorChanged = (newZoomFactor != measure->zoomFactor);
309+
200310
// Update stored values
201311
measure->url = newUrl;
202312
measure->width = newWidth;
203313
measure->height = newHeight;
204314
measure->x = newX;
205315
measure->y = newY;
316+
measure->zoomFactor = newZoomFactor;
206317
measure->visible = newVisible;
207318
measure->clickthrough = newClickthrough;
208-
319+
measure->allowDualControl = newAllowDualControl;
320+
measure->onWebViewLoadAction = newOnWebViewLoadAction;
321+
measure->onWebViewFailAction = newOnWebViewFailAction;
322+
measure->onPageLoadStartAction = newOnPageLoadStartAction;
323+
measure->onPageLoadingAction = newOnPageLoadingAction;
324+
measure->onPageLoadFinishAction = newOnPageLoadFinishAction;
325+
measure->onPageFirstLoadAction = newOnPageFirstLoadAction;
326+
measure->onPageReloadAction = newOnPageReloadAction;
327+
209328
// Only create WebView2 if not initialized OR if URL changed
210329
if (!measure->initialized || urlChanged)
211330
{
@@ -220,6 +339,11 @@ PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
220339
else
221340
{
222341
// First initialization - create WebView2
342+
if (measure->isCreationInProgress)
343+
{
344+
// Avoid re-entrancy if creation is already in progress
345+
return;
346+
}
223347
CreateWebView2(measure);
224348
}
225349
}
@@ -241,11 +365,26 @@ PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
241365
{
242366
measure->webViewController->put_IsVisible(measure->visible ? TRUE : FALSE);
243367
}
368+
369+
if (zoomFactorChanged && measure->webViewController)
370+
{
371+
measure->webViewController->put_ZoomFactor(measure->zoomFactor);
372+
}
244373

245374
if (clickthroughChanged)
246375
{
247376
UpdateClickthrough(measure);
248377
}
378+
379+
if (allowDualControlChanged)
380+
{
381+
if (!measure->isAllowDualControlInjected)
382+
{
383+
InjectAllowDualControl(measure);
384+
}
385+
else
386+
UpdateAllowDualControl(measure);
387+
}
249388
}
250389
}
251390

@@ -275,13 +414,6 @@ PLUGIN_EXPORT double Update(void* data)
275414
{
276415
measure->callbackResult = result;
277416
}
278-
279-
// Trigger Rainmeter redraw after callback completes
280-
if (measure->skin)
281-
{
282-
RmExecute(measure->skin, L"!UpdateMeter *");
283-
RmExecute(measure->skin, L"!Redraw");
284-
}
285417
}
286418
return S_OK;
287419
}
@@ -304,6 +436,7 @@ PLUGIN_EXPORT LPCWSTR GetString(void* data)
304436

305437
return L"0";
306438
}
439+
307440
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args)
308441
{
309442
Measure* measure = (Measure*)data;

WebView2/Plugin.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,41 @@ struct Measure
2020
void* skin;
2121
HWND skinWindow;
2222
LPCWSTR measureName;
23-
23+
2424
std::wstring url;
25+
std::wstring currentUrl;
2526
int width;
2627
int height;
2728
int x;
2829
int y;
30+
double zoomFactor;
2931
bool visible;
3032
bool initialized;
3133
bool clickthrough;
32-
34+
bool isCreationInProgress = false;
35+
bool isFirstLoad = true;
36+
bool allowDualControl;
37+
bool isAllowDualControlInjected = false;
38+
39+
std::wstring onWebViewLoadAction;
40+
std::wstring onWebViewFailAction;
41+
std::wstring onPageFirstLoadAction;
42+
std::wstring onPageLoadStartAction;
43+
std::wstring onPageLoadingAction;
44+
std::wstring onPageLoadFinishAction;
45+
std::wstring onPageReloadAction;
46+
3347
wil::com_ptr<ICoreWebView2Controller> webViewController;
3448
wil::com_ptr<ICoreWebView2> webView;
3549
EventRegistrationToken webMessageToken;
36-
50+
3751
std::wstring buffer; // Buffer for section variable return values
3852
std::wstring callbackResult; // Stores return value from OnInitialize/OnUpdate callbacks
3953
std::map<std::wstring, std::wstring> jsResults; // Cache for CallJS results
40-
54+
4155
Measure();
4256
~Measure();
43-
57+
4458
// Member callback functions for WebView2 creation
4559
HRESULT CreateEnvironmentHandler(HRESULT result, ICoreWebView2Environment* env);
4660
HRESULT CreateControllerHandler(HRESULT result, ICoreWebView2Controller* controller);
@@ -49,4 +63,7 @@ struct Measure
4963
// WebView2 functions
5064
void CreateWebView2(Measure* measure);
5165
void UpdateClickthrough(Measure* measure);
66+
void InjectAllowDualControl(Measure* measure);
67+
void UpdateAllowDualControl(Measure* measure);
68+
5269

0 commit comments

Comments
 (0)