PluginWebView icon indicating copy to clipboard operation
PluginWebView copied to clipboard

Pretty Nice -> But in my case not working as expected - getMeasure fails

Open LORDofDOOM opened this issue 3 years ago • 4 comments

First of all: This is a great plugin, thank you for that

I've currently have some issues on every plugin that use "getMeasure" -> It just throw "Cant find measure" in Rainmeter and also fails in the javascript (because of the same error)

Another question: Is there any option to move (drag) a widget on desktop (something like middle mouse button and drag or something - Because of the way how it's implemented it makes sense that the left mouse button dont works to drag)

Thank you very much :-)

LORDofDOOM avatar Jan 26 '22 08:01 LORDofDOOM

Have to agree, getmeasure just always returns null every time.

jonseppanen avatar Mar 06 '22 02:03 jonseppanen

Another question: Is there any option to move (drag) a widget on desktop (something like middle mouse button and drag or something - Because of the way how it's implemented it makes sense that the left mouse button dont works to drag)

If one wants to drag or have the Rainmeter context menu in a skin having a WebView plugin measure when the CTRL key is pressed (as it's customary for Rainmeter), this should be added to the <body> element from the HTML (you can remove , {passive: false} from these if the browser doesn't support it):

<script>
  document.body.addEventListener('pointerdown', function(e) {if (e.button == 0 && e.ctrlKey) {e.preventDefault(); rm = true; clientX = e.clientX; clientY = e.clientY; try {controls.enabled = false;} catch {document.body.setPointerCapture(e.pointerId);};};}, {passive: false});
  document.body.addEventListener('pointermove', function(e) {if (typeof rm !== "undefined" && rm) {e.preventDefault(); RainmeterAPI.Bang("[!Move " + (e.screenX - clientX) + " " + (e.screenY - clientY) + "]");};}, {passive: false});
  document.body.addEventListener('pointerup',   function(e) {if (e.button == 0) {e.preventDefault(); rm = false; try {controls.enabled = true;} catch {document.body.releasePointerCapture(e.pointerId);};};}, {passive: false});
  document.body.addEventListener('contextmenu', function(e) {if (e.button == 2 && e.ctrlKey) {e.preventDefault(); RainmeterAPI.Bang("[!SkinMenu]");};}, {passive: false});
</script>

Basically, you'd have to add the appropriate event listeners in the Javascript from your HTML.

It should work even if one drags the mouse outside the page, via setPointerCapture(), while also temporarily disabling a Three.js control like OrbitControls represented by the global variable called controls (TrackballControlls seems to "remember" the mouse move and keep doing it afterwards, due to some code differences compared to OrbitControls that I still need to investigate). This will work even if one doesn't have any controls in his page and the controls variable doesn't exist, via the try {} catch {} system. All the other variables are created globally and on the fly, no declaration required.

If by any chance the WebView page doesn't extend over all the skin area, simply subtract whatever left and top "margins" there are between the top-left corner of the skin and the top-left corner of the page / measure relative to the skin in the !Move bang formulas (e.g. if the WebView measure is positioned at X=8 and Y=8 in the skin, subtract 8 in both X and Y formulas) - I guess this can be done automatically via the RainmeterAPI as well, assuming the name of the measure is known.

Similarly, you can add a 'wheel' event listener if you have the proper code in your skin and webpage, and you want to scale your skin along with the webpage. In my case, it looks like this (it isn't very fast for me, but maybe it can be improved):

  document.body.addEventListener('wheel',       function(e) {if (e.ctrlKey) {e.preventDefault(); try {controls.enabled = false;} catch {}; RainmeterAPI.Bang("[!SetVariable Span (Clamp(" + RainmeterAPI.GetVariable("Span") + "+" + Math.sign(- e.deltaY) + "*" + RainmeterAPI.GetVariable("SpanRate") + "," + RainmeterAPI.GetVariable("SpanRate") + ",10))][!Update]");};}, {passive: false});

Span and SpanRate are how I named the "scale" and "scale step" variables in my skin. Obviously, you'd have to set the relevant WebView measure(s) and meters' coordinates and dimensions to be multiple of whatever "scale" variable you use. The , {passive: false} part is required here, since the Chromium based browsers now set the passive property to true by default in order to increase the speed of touch based systems, which has the unwanted effect of ignoring the needed .preventDefault() method above.

Yincognyto avatar Apr 27 '22 22:04 Yincognyto

I've currently have some issues on every plugin that use "getMeasure" -> It just throw "Cant find measure" in Rainmeter and also fails in the javascript (because of the same error)

Have to agree, getmeasure just always returns null every time.

Yep, it happens for me too - it looks like a bug. In the meantime, you might want to export the value of the measure to a variable in the measure's OnUpdateAction, and then use GetVariable('SomeVariable') in Javascript to get the desired value, as a (hopefully, temporary) workaround.

Yincognyto avatar Apr 27 '22 23:04 Yincognyto

Any update on a fix for getMeasure?

jumpsplat120 avatar Feb 13 '23 08:02 jumpsplat120