Last active
June 23, 2020 09:31
-
-
Save riccardobl/18603f9de508b1ab6c9e to your computer and use it in GitHub Desktop.
JavaFX Transparent WebView PATCH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Riccardo Balbo | |
* @description This patch aims to make the WebView capable to correctly render transparent pages. | |
* @license | |
* Copyright (c) 2015 Riccardo Balbo < riccardo @ forkforge . net > | |
* | |
* This software is provided 'as-is', without any express or implied | |
* warranty. In no event will the authors be held liable for any | |
* damages arising from the use of this software. | |
* | |
* Permission is granted to anyone to use this software for any | |
* purpose, including commercial applications, and to alter it and | |
* redistribute it freely, subject to the following restrictions: | |
* | |
* 1. The origin of this software must not be misrepresented; you must | |
* not claim that you wrote the original software. If you use this | |
* software in a product, an acknowledgment in the product | |
* documentation would be appreciated but is not required. | |
* | |
* 2. Altered source versions must be plainly marked as such, and must | |
* not be misrepresented as being the original software. | |
* | |
* 3. This notice may not be removed or altered from any source | |
* distribution. | |
*/ | |
import java.io.ByteArrayInputStream; | |
import java.lang.instrument.ClassFileTransformer; | |
import java.lang.instrument.IllegalClassFormatException; | |
import java.security.ProtectionDomain; | |
import java.lang.instrument.Instrumentation; | |
import javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtMethod; | |
public class TransparentWebViewPatch implements ClassFileTransformer{ | |
private final ClassPool _CLASS_POOL=ClassPool.getDefault(); | |
public static void premain(String agentArguments,Instrumentation instrumentation){ | |
instrumentation.addTransformer(new TransparentWebViewPatch()); | |
} | |
// This patch aims to make the WebView capable to correctly render | |
// transparent pages. | |
@Override | |
public byte[] transform(ClassLoader loader, String class_name, Class<?> class_being_redefined, ProtectionDomain protection_domain, byte[] byte_code) throws IllegalClassFormatException { | |
if(class_name.equals("com/sun/webkit/WebPage")){ | |
System.out.println("> Patching "+class_name+" ..."); | |
try{ | |
CtClass ct_class=_CLASS_POOL.makeClass(new ByteArrayInputStream(byte_code)); | |
// First thing to do is edit the fireLoadEvent in order to force | |
// the page to set its own | |
// background to transparent black (0x00000000 argb) each time | |
// it changes | |
CtMethod fireLoadEvent_method=ct_class.getDeclaredMethod("fireLoadEvent"); | |
fireLoadEvent_method.insertBefore("{\n"+" " | |
+ "setBackgroundColor(0);\n" | |
+"}"); | |
// DEPRECATED CODE: NOT WORKING FROM JAVA 1.8.0_66 | |
// Then, we edit the the paint2GC method in order to call | |
// clearRect every time right before it | |
// start to draw a clip (clips are parts of the rendered frame). | |
// We need this because when the webpage is rendered with the | |
// backbuffer enabled, | |
// every clip is just drawn over the old rendered frame without | |
// care about the alpha channel. | |
// NOTE: there is a system property | |
// com.sun.webkit.pagebackbuffer that could do the trick without | |
// this entire patch, but i didn't succeed in getting anything | |
// useful out of it... | |
// CtMethod | |
// paint2GC_method=ct_class.getDeclaredMethod("paint2GC"); | |
// paint2GC_method.insertAt(696, | |
// "{\n" + | |
// " com.sun.webkit.graphics.WCRectangle clip=$1.getClip(); \n" | |
// + | |
// " | |
// $1.clearRect(clip.getX(),clip.getY(),clip.getWidth(),clip.getHeight());\n" | |
// + | |
// "}" | |
// ); | |
// END OF DEPRECATED CODE | |
// Then we replace the scroll method body in order to force the | |
// repaint of the entire frame | |
// when the page is scrolled | |
CtMethod scroll_method=ct_class.getDeclaredMethod("scroll"); | |
scroll_method.setBody( | |
"{\n"+" " | |
+ "addDirtyRect(new com.sun.webkit.graphics.WCRectangle(0f,0f,(float)width,(float)height));\n" | |
+"}" | |
); | |
byte_code=ct_class.toBytecode(); | |
ct_class.detach(); | |
}catch(Exception e){ | |
System.out.println("/!\\ "+class_name+" patching failed :("); | |
e.printStackTrace(); | |
return byte_code; | |
} | |
System.out.println("> "+class_name+" patching succeeded!"); | |
}else if(class_name.equals("com/sun/javafx/webkit/prism/WCGraphicsPrismContext")){ | |
System.out.println("> Patching "+class_name+" ..."); | |
try{ | |
CtClass ct_class=_CLASS_POOL.makeClass(new ByteArrayInputStream(byte_code)); | |
// Then, we edit the the WCGraphicsPrismContext.setClip method | |
// in order to call clearRect over the area of the clip. | |
CtClass signature[]=new CtClass[]{_CLASS_POOL.get("com.sun.webkit.graphics.WCRectangle")}; | |
CtMethod setClip_method=ct_class.getDeclaredMethod("setClip",signature); | |
setClip_method.insertBefore( | |
"{"+" " | |
+ " $0.clearRect($1.getX(),$1.getY(),$1.getWidth(),$1.getHeight());" | |
+"}"); | |
byte_code=ct_class.toBytecode(); | |
ct_class.detach(); | |
}catch(Exception e){ | |
System.out.println("/!\\ "+class_name+" patching failed :("); | |
e.printStackTrace(); | |
return byte_code; | |
} | |
System.out.println("> "+class_name+" patching succeeded!"); | |
} | |
return byte_code; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
origin_dir=$PWD | |
rm -R build | |
mkdir build | |
rm -R /tmp/buildTransparentWebViewPatch | |
mkdir /tmp/buildTransparentWebViewPatch | |
cp TransparentWebViewPatch.java /tmp/buildTransparentWebViewPatch | |
cd /tmp/buildTransparentWebViewPatch | |
echo "Downloading jboss javassist..." | |
wget https://github.com/jboss-javassist/javassist/releases/download/rel_3_20_0_ga/javassist.jar > /dev/null 2>&1 | |
echo "Compiling..." | |
javac -cp javassist.jar TransparentWebViewPatch.java | |
echo "Building jar..." | |
sed -n '/\/\*\*/,/\*\//p' TransparentWebViewPatch.java > INFO.txt | |
echo "Premain-Class: TransparentWebViewPatch" > manifest.txt | |
jar -cvfm TransparentWebViewPatch.jar manifest.txt INFO.txt TransparentWebViewPatch.class TransparentWebViewPatch.java | |
cp TransparentWebViewPatch.jar $origin_dir/build/ | |
cp javassist.jar $origin_dir/build/ | |
rm -R /tmp/buildTransparentWebViewPatch | |
echo "Done!" |
I used jdk 11 :D not sure if that creates an issue. As javafx 14 says it needs jdk 11+. Not sure about the rest but you should find it in the repo
javassist.version=3.23.1-GA
And these vm parameters of which many should not be related -DnativeDir=build/resources/native -Dprism.dirtyopts=false -Xms128m -Xmx712m -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=33 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseStringDeduplication -javaagent:webview-patch/build/libs/webview-patch.jar -Djava.net.preferIPv4Stack=true -XX:TieredStopAtLevel=1 -noverify
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi axel1200.
I have used your version.
Console show msg.
But the webview background still not transparent
I use JDK 14, javaassist 3.27.0-GA, and Java Fx 14.
Can you tell me what u are using? Thank a lot.