-
-
Save riccardobl/18603f9de508b1ab6c9e to your computer and use it in GitHub Desktop.
/** | |
* @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; | |
} | |
} |
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!" |
Caused by: java.lang.ClassFormatError: Nest member class_info_index 63 has bad constant type in class file com/sun/webkit/WebPage
Well I removed patching the "scroll" method now it runs and works as well. No idea what I did but seems working :D
Ok in the end that was not the solution instead:
scroll_method.insertBefore(
"{\n" + " "
+ "addDirtyRect(new com.sun.webkit.graphics.WCRectangle(0f,0f,(float)width,(float)height));\n"
+ "return;"
+ "}"
);
works, setBody(...) somehow does not work.
I have problem with javafx 14.
javassist.CannotCompileException: [source error] no such class: com.sun.webkit.graphics.WCRectangle
javassist.NotFoundException: com.sun.webkit.graphics.WCRectangle
Can you give me some advice? Thanks you.
I have fixed above problem
Console show msg
Patching com/sun/webkit/WebPage ...
com/sun/webkit/WebPage patching succeeded!
Patching com/sun/javafx/webkit/prism/WCGraphicsPrismContext ...
com/sun/javafx/webkit/prism/WCGraphicsPrismContext patching succeeded!
But the webview background still not transparent
Worked for me when I used java fx 14 https://github.com/FAForever/downlords-faf-client/blob/develop/webview-patch/src/main/java/com/faforever/client/webviewpatcher/TransparentWebViewPatch.java I went back on java fx 11 tho for other reasons.
Hi axel1200.
I have used your version.
Console show msg.
Patching com/sun/webkit/WebPage ...
com/sun/webkit/WebPage patching succeeded!
Patching com/sun/javafx/webkit/prism/WCGraphicsPrismContext ...
com/sun/javafx/webkit/prism/WCGraphicsPrismContext patching succeeded!
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.
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
Breaks when I update to java fx 14